diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index d369354ac9..b08637211f 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -54,7 +54,7 @@ SYSTEM_BIN = "[" addattr alert arp base64 basename bash bc beep bootman bzip2 safemode screen_blanker screenmode sdiff setdecor settype setversion setvolume seq sha1sum shar shred shuf shutdown sleep sort spamdbm split stat strace stty su sum sync sysinfo - tac tail tar tcpdump tcptester tee telnet telnetd test timeout top touch + tac tail tcpdump tcptester tee telnet telnetd test timeout top touch tput tr traceroute translate trash true truncate tsort tty uname unchop unexpand unmount uniq unlink unrar unshar unzip unzipsfx updatedb uptime urlwrapper useradd uudecode uuencode diff --git a/src/bin/Jamfile b/src/bin/Jamfile index 07d20f752d..3a7c121eee 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -248,4 +248,4 @@ SubInclude HAIKU_TOP src bin unzip ; SubInclude HAIKU_TOP src bin zip ; SubInclude HAIKU_TOP src bin gzip ; SubInclude HAIKU_TOP src bin bzip2 ; -SubInclude HAIKU_TOP src bin tar ; +#SubInclude HAIKU_TOP src bin tar ; diff --git a/src/bin/tar/COPYING b/src/bin/tar/COPYING deleted file mode 100644 index 4432540474..0000000000 --- a/src/bin/tar/COPYING +++ /dev/null @@ -1,676 +0,0 @@ - - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -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: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - 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 -. - diff --git a/src/bin/tar/Jamfile b/src/bin/tar/Jamfile deleted file mode 100644 index c194959643..0000000000 --- a/src/bin/tar/Jamfile +++ /dev/null @@ -1,9 +0,0 @@ -SubDir HAIKU_TOP src bin tar ; - -# filter warnings we don't want here -TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS) - : -Wall -Wmissing-prototypes -Wsign-compare ] ; - -SubInclude HAIKU_TOP src bin tar lib ; -SubInclude HAIKU_TOP src bin tar rmt ; -SubInclude HAIKU_TOP src bin tar src ; diff --git a/src/bin/tar/config.h b/src/bin/tar/config.h deleted file mode 100644 index 5345a59e89..0000000000 --- a/src/bin/tar/config.h +++ /dev/null @@ -1,1199 +0,0 @@ -/* config.h. Generated from config.hin by configure. */ -/* config.hin. Generated from configure.ac by autoheader. */ - -/* Define to the number of bits in type 'ptrdiff_t'. */ -#define BITSIZEOF_PTRDIFF_T 32 - -/* Define to the number of bits in type 'sig_atomic_t'. */ -#define BITSIZEOF_SIG_ATOMIC_T 32 - -/* Define to the number of bits in type 'size_t'. */ -#define BITSIZEOF_SIZE_T 32 - -/* Define to the number of bits in type 'wchar_t'. */ -#define BITSIZEOF_WCHAR_T 32 - -/* Define to the number of bits in type 'wint_t'. */ -#define BITSIZEOF_WINT_T 32 - -/* Define if chown is not POSIX compliant regarding IDs of -1. */ -#define CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE 1 - -/* Define if chown modifies symlinks. */ -/* #undef CHOWN_MODIFIES_SYMLINK */ - -/* 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 1 if using `alloca.c'. */ -/* #undef C_ALLOCA */ - -/* Define to a string giving the full name of the default archive file. */ -#define DEFAULT_ARCHIVE "-" - -/* By default produce archives of this format */ -#define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT - -/* Define to a number giving the default blocking size for archives. */ -#define DEFAULT_BLOCKING 20 - -/* Define to a default quoting style (see lib/quoteargs.c for the list) */ -#define DEFAULT_QUOTING_STYLE escape_quoting_style - -/* Define full file name of rmt program. */ -/* #undef DEFAULT_RMT_COMMAND */ - -/* Define to 1 if density may be indicated by [lmh] at end of device. */ -/* #undef DENSITY_LETTER */ - -/* Define to a string giving the prefix of the default device, without the - part specifying the unit and density. */ -/* #undef DEVICE_PREFIX */ - -/* the name of the file descriptor member of DIR */ -/* #undef DIR_FD_MEMBER_NAME */ - -#ifdef DIR_FD_MEMBER_NAME -# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME) -#else -# define DIR_TO_FD(Dir_p) -1 -#endif - - -/* Define to 1 if // is a file system root distinct from /. */ -/* #undef DOUBLE_SLASH_IS_DISTINCT_ROOT */ - -/* Define if struct dirent has a member d_ino that actually works. */ -#define D_INO_IN_DIRENT 1 - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -/* #undef ENABLE_NLS */ - -/* Define as good substitute value for EOVERFLOW. */ -/* #undef EOVERFLOW */ - -/* Define if gnulib's fchdir() replacement is used. */ -/* #undef FCHDIR_REPLACEMENT */ - -/* Define on systems for which file names may have a so-called `drive letter' - prefix, define this to compute the length of that prefix, including the - colon. */ -#define FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0 - -/* Define if the backslash character may also serve as a file name component - separator. */ -#define FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0 - -/* Define if a drive letter prefix denotes a relative path if it is not - followed by a file name component separator. */ -#define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 - -/* Define if gettimeofday clobbers the localtime buffer. */ -/* #undef GETTIMEOFDAY_CLOBBERS_LOCALTIME */ - -/* Define to make the limit macros in visible. */ -#define GL_TRIGGER_STDC_LIMIT_MACROS 1 - -/* Define to 1 when using the gnulib module close-stream. */ -#define GNULIB_CLOSE_STREAM 1 - -/* Define to 1 when using the gnulib module fcntl-safer. */ -#define GNULIB_FCNTL_SAFER 1 - -/* Define to 1 to add extern declaration of program_invocation_name to argp.h - */ -#define GNULIB_PROGRAM_INVOCATION_NAME 1 - -/* Define to 1 to add extern declaration of program_invocation_short_name to - argp.h */ -#define GNULIB_PROGRAM_INVOCATION_SHORT_NAME 1 - -/* Define to 1 if you have the `alarm' function. */ -#define HAVE_ALARM 1 - -/* Define to 1 if you have 'alloca' after including , a header that - may be supplied by this distribution. */ -#define HAVE_ALLOCA 1 - -/* Define HAVE_ALLOCA_H for backward compatibility with older code that - includes only if HAVE_ALLOCA_H is defined. */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_BP_SYM_H */ - -/* Define to 1 if you have the `btowc' function. */ -#define HAVE_BTOWC 1 - -/* Define to 1 if you have the `canonicalize_file_name' function. */ -/* #undef HAVE_CANONICALIZE_FILE_NAME */ - -/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the - CoreFoundation framework. */ -/* #undef HAVE_CFLOCALECOPYCURRENT */ - -/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in - the CoreFoundation framework. */ -/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ - -/* Define to 1 if your system has a working `chown' function. */ -/* #undef HAVE_CHOWN */ - -/* Define to 1 if you have the `chsize' function. */ -/* #undef HAVE_CHSIZE */ - -/* Define to 1 if you have the `clock_gettime' function. */ -/* #undef HAVE_CLOCK_GETTIME */ - -/* Define to 1 if you have the `clock_settime' function. */ -/* #undef HAVE_CLOCK_SETTIME */ - -/* Define if you have compound literals. */ -#define HAVE_COMPOUND_LITERALS 1 - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -/* #undef HAVE_DCGETTEXT */ - -/* Define to 1 if you have the declaration of `canonicalize_file_name', and to - 0 if you don't. */ -#define HAVE_DECL_CANONICALIZE_FILE_NAME 0 - -/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_CLEARERR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't. - */ -#define HAVE_DECL_DIRFD 0 - -/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you - don't. */ -#define HAVE_DECL_FEOF_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FERROR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FFLUSH_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FGETS_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FPUTC_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FPUTS_UNLOCKED 0 - -/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FREAD_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_FWRITE_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_GETCHAR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `getcwd', and to 0 if you don't. - */ -#define HAVE_DECL_GETCWD 1 - -/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you - don't. */ -#define HAVE_DECL_GETC_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `getdelim', and to 0 if you - don't. */ -#define HAVE_DECL_GETDELIM 0 - -/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't. - */ -#define HAVE_DECL_GETENV 1 - -/* Define to 1 if you have the declaration of `getgrgid', and to 0 if you - don't. */ -#define HAVE_DECL_GETGRGID 1 - -/* Define to 1 if you have the declaration of `getline', and to 0 if you - don't. */ -#define HAVE_DECL_GETLINE 0 - -/* Define to 1 if you have the declaration of `getpwuid', and to 0 if you - don't. */ -#define HAVE_DECL_GETPWUID 1 - -/* Define to 1 if you have the declaration of `imaxabs', and to 0 if you - don't. */ -#define HAVE_DECL_IMAXABS 0 - -/* Define to 1 if you have the declaration of `imaxdiv', and to 0 if you - don't. */ -#define HAVE_DECL_IMAXDIV 0 - -/* Define to 1 if you have the declaration of `isblank', and to 0 if you - don't. */ -#define HAVE_DECL_ISBLANK 0 - -/* Define to 1 if you have the declaration of `memrchr', and to 0 if you - don't. */ -#define HAVE_DECL_MEMRCHR 0 - -/* Define to 1 if you have the declaration of `mkdir', and to 0 if you don't. - */ -#define HAVE_DECL_MKDIR 1 - -/* Define if program_invocation_name is declared */ -/* #undef HAVE_DECL_PROGRAM_INVOCATION_NAME */ - -/* Define if program_invocation_short_name is declared */ -/* #undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME */ - -/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if - you don't. */ -#define HAVE_DECL_PUTCHAR_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you - don't. */ -#define HAVE_DECL_PUTC_UNLOCKED 1 - -/* Define to 1 if you have the declaration of `strdup', and to 0 if you don't. - */ -#define HAVE_DECL_STRDUP 1 - -/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you - don't. */ -#define HAVE_DECL_STRERROR_R 1 - -/* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you - don't. */ -#define HAVE_DECL_STRNCASECMP 1 - -/* Define to 1 if you have the declaration of `strndup', and to 0 if you - don't. */ -#define HAVE_DECL_STRNDUP 0 - -/* Define to 1 if you have the declaration of `strnlen', and to 0 if you - don't. */ -#define HAVE_DECL_STRNLEN 0 - -/* Define to 1 if you have the declaration of `strtoimax', and to 0 if you - don't. */ -#define HAVE_DECL_STRTOIMAX 1 - -/* Define to 1 if you have the declaration of `strtoll', and to 0 if you - don't. */ -/* #undef HAVE_DECL_STRTOLL */ - -/* Define to 1 if you have the declaration of `strtoull', and to 0 if you - don't. */ -/* #undef HAVE_DECL_STRTOULL */ - -/* Define to 1 if you have the declaration of `strtoumax', and to 0 if you - don't. */ -#define HAVE_DECL_STRTOUMAX 1 - -/* Define to 1 if you have the declaration of `time', and to 0 if you don't. - */ -#define HAVE_DECL_TIME 1 - -/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. - */ -/* #undef HAVE_DECL_TZNAME */ - -/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you - don't. */ -#define HAVE_DECL_VSNPRINTF 1 - -/* Define to 1 if you have the declaration of `wcwidth', and to 0 if you - don't. */ -#define HAVE_DECL_WCWIDTH 0 - -/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you - don't. */ -#define HAVE_DECL__SNPRINTF 0 - -/* Define to 1 if you have the declaration of `__fpending', and to 0 if you - don't. */ -#define HAVE_DECL___FPENDING 0 - -/* Define to 1 if you have the header file. */ -#define HAVE_DIRENT_H 1 - -/* Define to 1 if you have the `dirfd' function. */ -#define HAVE_DIRFD 1 - -/* Define to 1 if you have the `dup2' function. */ -#define HAVE_DUP2 1 - -/* Define if you have the declaration of environ. */ -/* #undef HAVE_ENVIRON_DECL */ - -/* Define to 1 if you have the `fchdir' function. */ -#define HAVE_FCHDIR 1 - -/* Define to 1 if you have the `fchmodat' function. */ -/* #undef HAVE_FCHMODAT */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `fdopendir' function. */ -/* #undef HAVE_FDOPENDIR */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_FEATURES_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FLOAT_H 1 - -/* Define to 1 if you have the `flockfile' function. */ -#define HAVE_FLOCKFILE 1 - -/* Define to 1 if you have the `fsync' function. */ -#define HAVE_FSYNC 1 - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define to 1 if you have the `funlockfile' function. */ -#define HAVE_FUNLOCKFILE 1 - -/* Define to 1 if you have the `futimes' function. */ -/* #undef HAVE_FUTIMES */ - -/* Define to 1 if you have the `futimesat' function. */ -/* #undef HAVE_FUTIMESAT */ - -/* Define to 1 if you have the `getcwd' function. */ -#define HAVE_GETCWD 1 - -/* Define to 1 if you have the `getdelim' function. */ -#define HAVE_GETDELIM 1 - -/* Define to 1 if you have the `getdtablesize' function. */ -#define HAVE_GETDTABLESIZE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_GETOPT_H 1 - -/* Define to 1 if you have the `getopt_long_only' function. */ -#define HAVE_GETOPT_LONG_ONLY 1 - -/* Define to 1 if you have the `getpagesize' function. */ -/* #undef HAVE_GETPAGESIZE */ - -/* Define if the GNU gettext() function is already present or preinstalled. */ -/* #undef HAVE_GETTEXT */ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define if you have the iconv() function and it works. */ -/* #undef HAVE_ICONV */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ICONV_H */ - -/* Define if your compiler supports the #include_next directive. */ -#define HAVE_INCLUDE_NEXT 1 - -/* Define to 1 if the compiler supports one of the keywords 'inline', - '__inline__', '__inline' and effectively inlines functions marked as such. - */ -#define HAVE_INLINE 1 - -/* Define if you have the 'intmax_t' type in or . */ -#define HAVE_INTMAX_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define if exists, doesn't clash with , and - declares uintmax_t. */ -#define HAVE_INTTYPES_H_WITH_UINTMAX 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IO_H */ - -/* Define to 1 if you have the `isblank' function. */ -#define HAVE_ISBLANK 1 - -/* Define to 1 if you have the `iswcntrl' function. */ -#define HAVE_ISWCNTRL 1 - -/* Define to 1 if you have the `iswctype' function. */ -#define HAVE_ISWCTYPE 1 - -/* Define if you have and nl_langinfo(CODESET). */ -/* #undef HAVE_LANGINFO_CODESET */ - -/* Define to 1 if you have the `lchmod' function. */ -/* #undef HAVE_LCHMOD */ - -/* Define to 1 if you have the `lchown' function. */ -/* #undef HAVE_LCHOWN */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINEWRAP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINUX_FD_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you support file names longer than 14 characters. */ -#define HAVE_LONG_FILE_NAMES 1 - -/* Define if you have the 'long long' type. */ -#define HAVE_LONG_LONG 1 - -/* Define to 1 if the system has the type `long long int'. */ -#define HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the `lstat' function. */ -#define HAVE_LSTAT 1 - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC 1 - -/* Define if the 'malloc' function is POSIX compliant. */ -#define HAVE_MALLOC_POSIX 1 - -/* Define to 1 if you have the `mbrtowc' function. */ -#define HAVE_MBRTOWC 1 - -/* Define to 1 if you have the `mbsinit' function. */ -#define HAVE_MBSINIT 1 - -/* Define to 1 if you have the `mbsrtowcs' function. */ -#define HAVE_MBSRTOWCS 1 - -/* Define to 1 if declares mbstate_t. */ -#define HAVE_MBSTATE_T 1 - -/* Define to 1 if you have the `memchr' function. */ -#define HAVE_MEMCHR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mempcpy' function. */ -/* #undef HAVE_MEMPCPY */ - -/* Define to 1 if you have the `memrchr' function. */ -/* #undef HAVE_MEMRCHR */ - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the `mkdirat' function. */ -/* #undef HAVE_MKDIRAT */ - -/* Define to 1 if you have the `mkdtemp' function. */ -/* #undef HAVE_MKDTEMP */ - -/* Define to 1 if you have the `mkfifo' function. */ -#define HAVE_MKFIFO 1 - -/* Define to 1 if you have the `nanotime' function. */ -/* #undef HAVE_NANOTIME */ - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETDB_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NET_ERRNO_H */ - -/* Define to 1 if libc includes obstacks. */ -#define HAVE_OBSTACK 1 - -/* Define to 1 if you have the `openat' function. */ -/* #undef HAVE_OPENAT */ - -/* Define to 1 if you have the header file. */ -#define HAVE_OS_H 1 - -/* Define to 1 if getcwd works, except it sometimes fails when it shouldn't, - setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If __GETCWD_PREFIX is not - defined, it doesn't matter whether HAVE_PARTLY_WORKING_GETCWD is defined. - */ -/* #undef HAVE_PARTLY_WORKING_GETCWD */ - -/* Define to 1 if you have the `pathconf' function. */ -#define HAVE_PATHCONF 1 - -/* Define to 1 if you have the `pipe' function. */ -#define HAVE_PIPE 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PRIV_H */ - -/* Define if program_invocation_name is defined */ -/* #undef HAVE_PROGRAM_INVOCATION_NAME */ - -/* Define if program_invocation_short_name is defined */ -/* #undef HAVE_PROGRAM_INVOCATION_SHORT_NAME */ - -/* Define to 1 if the system has the type `ptrdiff_t'. */ -#define HAVE_PTRDIFF_T 1 - -/* Define to 1 if you have the `readlink' function. */ -#define HAVE_READLINK 1 - -/* Define if the 'realloc' function is POSIX compliant. */ -#define HAVE_REALLOC_POSIX 1 - -/* Define to 1 if you have the `rmdir' function. */ -#define HAVE_RMDIR 1 - -/* Define to 1 if you have the `rpmatch' function. */ -/* #undef HAVE_RPMATCH */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SEARCH_H */ - -/* Define to 1 if you have the `setenv' function. */ -#define HAVE_SETENV 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SGTTY_H */ - -/* Define to 1 if 'sig_atomic_t' is a signed integer type. */ -#define HAVE_SIGNED_SIG_ATOMIC_T 1 - -/* Define to 1 if 'wchar_t' is a signed integer type. */ -#define HAVE_SIGNED_WCHAR_T 1 - -/* Define to 1 if 'wint_t' is a signed integer type. */ -/* #undef HAVE_SIGNED_WINT_T */ - -/* Define to 1 if you have the `sleep' function. */ -#define HAVE_SLEEP 1 - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if stdbool.h conforms to C99. */ -/* #undef HAVE_STDBOOL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define if exists, doesn't clash with , and declares - uintmax_t. */ -/* #undef HAVE_STDINT_H_WITH_UINTMAX */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDIO_EXT_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `stpcpy' function. */ -#define HAVE_STPCPY 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strchrnul' function. */ -/* #undef HAVE_STRCHRNUL */ - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strncasecmp' function. */ -#define HAVE_STRNCASECMP 1 - -/* Define if you have the strndup() function and it works. */ -/* #undef HAVE_STRNDUP */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STROPTS_H */ - -/* Define to 1 if you have the `strtoimax' function. */ -#define HAVE_STRTOIMAX 1 - -/* Define to 1 if you have the `strtol' function. */ -#define HAVE_STRTOL 1 - -/* Define to 1 if you have the `strtoll' function. */ -#define HAVE_STRTOLL 1 - -/* Define to 1 if you have the `strtoul' function. */ -#define HAVE_STRTOUL 1 - -/* Define to 1 if you have the `strtoull' function. */ -#define HAVE_STRTOULL 1 - -/* Define to 1 if you have the `strtoumax' function. */ -#define HAVE_STRTOUMAX 1 - -/* Define to 1 if `st_atimensec' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */ - -/* Define to 1 if `st_atimespec.tv_nsec' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */ - -/* Define to 1 if `st_atim.st__tim.tv_nsec' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */ - -/* Define to 1 if `st_atim.tv_nsec' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC */ - -/* Define to 1 if `st_birthtimensec' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC */ - -/* Define to 1 if `st_birthtimespec.tv_nsec' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC */ - -/* Define to 1 if `st_birthtim.tv_nsec' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC */ - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 - -/* Define to 1 if `st_blocks' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BLOCKS */ - -/* Define to 1 if `tm_zone' is member of `struct tm'. */ -#define HAVE_STRUCT_TM_TM_ZONE 1 - -/* Define if struct utimbuf is declared -- usually in . Some systems - have utime.h but don't declare the struct anywhere. */ -#define HAVE_STRUCT_UTIMBUF 1 - -/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use - `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */ -#define HAVE_ST_BLKSIZE 1 - -/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use - `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ -/* #undef HAVE_ST_BLOCKS */ - -/* Define if struct stat has a char st_fstype[] member. */ -/* #undef HAVE_ST_FSTYPE_STRING */ - -/* Define to 1 if you have the `symlink' function. */ -#define HAVE_SYMLINK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYSEXITS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_BITYPES_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_BUF_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_DEVICE_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_FILIO_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_GENTAPE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_INET_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_INTTYPES_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_IO_TRIOCTL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_MTIO_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TAPE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TIMEB_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TPRINTF_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define if struct tm has the tm_gmtoff member. */ -#define HAVE_TM_GMTOFF 1 - -/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use - `HAVE_STRUCT_TM_TM_ZONE' instead. */ -#define HAVE_TM_ZONE 1 - -/* Define to 1 if you have the `tsearch' function. */ -/* #undef HAVE_TSEARCH */ - -/* Define to 1 if you don't have `tm_zone' but do have the external array - `tzname'. */ -/* #undef HAVE_TZNAME */ - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `unsetenv' function. */ -#define HAVE_UNSETENV 1 - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#define HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* Define to 1 if you have the `utimes' function. */ -/* #undef HAVE_UTIMES */ - -/* Define if utimes accepts a null argument */ -/* #undef HAVE_UTIMES_NULL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */ -#define HAVE_UTIME_NULL 1 - -/* Define to 1 if you have the `vasnprintf' function. */ -/* #undef HAVE_VASNPRINTF */ - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if you have the `waitpid' function. */ -#define HAVE_WAITPID 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCHAR_H 1 - -/* Define if you have the 'wchar_t' type. */ -#define HAVE_WCHAR_T 1 - -/* Define to 1 if you have the `wcrtomb' function. */ -#define HAVE_WCRTOMB 1 - -/* Define to 1 if you have the `wcscoll' function. */ -#define HAVE_WCSCOLL 1 - -/* Define to 1 if you have the `wcslen' function. */ -#define HAVE_WCSLEN 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCTYPE_H 1 - -/* Define to 1 if you have the `wcwidth' function. */ -/* #undef HAVE_WCWIDTH */ - -/* Define if you have the 'wint_t' type. */ -#define HAVE_WINT_T 1 - -/* Define to 1 if you have the `wmemchr' function. */ -#define HAVE_WMEMCHR 1 - -/* Define to 1 if you have the `wmemcpy' function. */ -#define HAVE_WMEMCPY 1 - -/* Define to 1 if you have the `wmempcpy' function. */ -/* #undef HAVE_WMEMPCPY */ - -/* Define to 1 if O_NOATIME works. */ -#define HAVE_WORKING_O_NOATIME 0 - -/* Define to 1 if O_NOFOLLOW works. */ -#define HAVE_WORKING_O_NOFOLLOW 0 - -/* Define if utimes works properly. */ -/* #undef HAVE_WORKING_UTIMES */ - -/* Define to 1 if the system has the type `_Bool'. */ -/* #undef HAVE__BOOL */ - -/* Define to 1 if you have the `_ftime' function. */ -/* #undef HAVE__FTIME */ - -/* Define to 1 if you have the `__fpending' function. */ -/* #undef HAVE___FPENDING */ - -/* Define as const if the declaration of iconv() needs const. */ -/* #undef ICONV_CONST */ - -#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#else -# define ISSLASH(C) ((C) == '/') -#endif - -/* Define to 1 if `lstat' dereferences a symlink specified with a trailing - slash. */ -#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 - -/* Define to 1 if `major', `minor', and `makedev' are declared in . - */ -/* #undef MAJOR_IN_MKDEV */ - -/* Define to 1 if `major', `minor', and `makedev' are declared in - . */ -#define MAJOR_IN_SYSMACROS 0 - -/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */ -#define MALLOC_0_IS_NONNULL 1 - -/* Define to mt_model (v.g., for DG/UX), else to mt_type. */ -#define MTIO_CHECK_FIELD mt_type - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "tar" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "bug-tar@gnu.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "GNU tar" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "GNU tar 1.19" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "tar" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.19" - -/* the number of pending output bytes on stream `fp' */ -#define PENDING_OUTPUT_N_BYTES fp->_IO_write_ptr - fp->_IO_write_base - -/* Define if exists and defines unusable PRI* macros. */ -/* #undef PRI_MACROS_BROKEN */ - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'ptrdiff_t'. */ -#define PTRDIFF_T_SUFFIX l - -/* Define to the full path of your rsh, if any. */ -/* #undef REMOTE_SHELL */ - -/* Define this to 1 if strerror is broken. */ -/* #undef REPLACE_STRERROR */ - -/* Define if vasnprintf exists but is overridden by gnulib. */ -/* #undef REPLACE_VASNPRINTF */ - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'sig_atomic_t'. */ -#define SIG_ATOMIC_T_SUFFIX - -/* Define as the maximum value of type 'size_t', if the system doesn't define - it. */ -// #define SIZE_MAX (((1UL << 31) - 1) * 2 + 1) - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'size_t'. */ -#define SIZE_T_SUFFIX ul - -/* 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 runtime. - 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 to 1 if the `S_IS*' macros in do not work properly. */ -/* #undef STAT_MACROS_BROKEN */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if strerror_r returns char *. */ -/* #undef STRERROR_R_CHAR_P */ - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Define to 1 if your declares `struct tm'. */ -/* #undef TM_IN_SYS_TIME */ - -/* Define to 1 if the type of the st_atim member of a struct stat is struct - timespec. */ -/* #undef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC */ - -/* Define to 1 if unlink (dir) cannot possibly succeed. */ -/* #undef UNLINK_CANNOT_UNLINK_DIR */ - -/* Define to 1 if you want getc etc. to use unlocked I/O if available. - Unlocked I/O can improve performance in unithreaded apps, but it is not - safe for multithreaded apps. */ -#define USE_UNLOCKED_IO 1 - -/* Version number of package */ -#define VERSION "1.19" - -/* Define if unsetenv() returns void, not int. */ -#define VOID_UNSETENV 1 - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'wchar_t'. */ -#define WCHAR_T_SUFFIX - -/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type - 'wint_t'. */ -#define WINT_T_SUFFIX u - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define if you want regoff_t to be at least as wide POSIX requires. */ -#define _REGEX_LARGE_OFFSETS 1 - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Define to rpl_ if the getopt replacement functions and variables should be - used. */ -#define __GETOPT_PREFIX rpl_ - -/* Define to rpl_ if the openat replacement function should be used. */ -#define __OPENAT_PREFIX rpl_ - -/* Ensure that defines the limit macros, since gnulib's - relies on them. */ -#if defined __cplusplus && !defined __STDC_LIMIT_MACROS && GL_TRIGGER_STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS 1 -#endif - - -/* Define to `unsigned' if does not define. */ -/* #undef dev_t */ - -/* Define to rpl_fchownat if the replacement function should be used. */ -#define fchownat rpl_fchownat - -/* Define to a replacement function name for fnmatch(). */ -#define fnmatch gnu_fnmatch - -/* Define to `int' if doesn't define. */ -/* #undef gid_t */ - -/* A replacement for va_copy, if needed. */ -#define gl_va_copy(a,b) ((a) = (b)) - -/* Define to rpl_gmtime if the replacement function should be used. */ -/* #undef gmtime */ - -/* Conversion descriptor type */ -#define iconv_t int - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned' if does not define. */ -/* #undef ino_t */ - -/* Define to long or long long if and don't define. */ -/* #undef intmax_t */ - -/* Define to rpl_localtime if the replacement function should be used. */ -/* #undef localtime */ - -/* Type of major device numbers. */ -#define major_t int - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to a type if does not define. */ -// #define mbstate_t int - -/* Type of minor device numbers. */ -#define minor_t int - -/* Define to rpl_mktime if the replacement function should be used. */ -#define mktime rpl_mktime - -/* Define to `int' if does not define. */ -/* #undef mode_t */ - -/* Define to `long int' if does not define. */ -/* #undef off_t */ - -/* Define to `int' if does not define. */ -/* #undef pid_t */ - -/* Define to rpl_re_comp if the replacement should be used. */ -#define re_comp rpl_re_comp - -/* Define to rpl_re_compile_fastmap if the replacement should be used. */ -#define re_compile_fastmap rpl_re_compile_fastmap - -/* Define to rpl_re_compile_pattern if the replacement should be used. */ -#define re_compile_pattern rpl_re_compile_pattern - -/* Define to rpl_re_exec if the replacement should be used. */ -#define re_exec rpl_re_exec - -/* Define to rpl_re_match if the replacement should be used. */ -#define re_match rpl_re_match - -/* Define to rpl_re_match_2 if the replacement should be used. */ -#define re_match_2 rpl_re_match_2 - -/* Define to rpl_re_search if the replacement should be used. */ -#define re_search rpl_re_search - -/* Define to rpl_re_search_2 if the replacement should be used. */ -#define re_search_2 rpl_re_search_2 - -/* Define to rpl_re_set_registers if the replacement should be used. */ -#define re_set_registers rpl_re_set_registers - -/* Define to rpl_re_set_syntax if the replacement should be used. */ -#define re_set_syntax rpl_re_set_syntax - -/* Define to rpl_re_syntax_options if the replacement should be used. */ -#define re_syntax_options rpl_re_syntax_options - -/* Define to a replacement function name for realpath(). */ -#define realpath rpl_realpath - -/* Define to rpl_regcomp if the replacement should be used. */ -//#define regcomp rpl_regcomp - -/* Define to rpl_regerror if the replacement should be used. */ -//#define regerror rpl_regerror - -/* Define to rpl_regexec if the replacement should be used. */ -//#define regexec rpl_regexec - -/* Define to rpl_regfree if the replacement should be used. */ -//#define regfree rpl_regfree - -/* Define to equivalent of C99 restrict keyword, or to nothing if this is not - supported. Do not define if restrict is supported directly. */ -#define restrict __restrict - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define as a signed type of the same size as size_t. */ -/* #undef ssize_t */ - -/* Define to rpl_strnlen if the replacement function should be used. */ -/* #undef strnlen */ - -/* Define to `int' if doesn't define. */ -/* #undef uid_t */ - -/* Define to rpl_utime if the replacement function should be used. */ -/* #undef utime */ - -/* Define as a macro for copying va_list variables. */ -#if __GNUC__ < 3 -#define va_copy __va_copy -#endif - -#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) -#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) -#include diff --git a/src/bin/tar/lib/Jamfile b/src/bin/tar/lib/Jamfile deleted file mode 100644 index eeac931d2c..0000000000 --- a/src/bin/tar/lib/Jamfile +++ /dev/null @@ -1,103 +0,0 @@ -SubDir HAIKU_TOP src bin tar lib ; - -SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; -SubDirSysHdrs [ FDirName $(SUBDIR) ] ; - -# set some additional defines -{ - SubDirCcFlags -DHAVE_CONFIG_H ; -} - - -StaticLibrary libtar.a : - argmatch.c - argp-eexst.c - argp-fmtstream.c - argp-help.c - argp-parse.c - argp-pin.c - argp-pvh.c - argp-xinl.c - backupfile.c - basename.c - chdir-long.c - chown.c - close-stream.c - closeout.c - dirname.c - dup-safer.c - error.c - exclude.c - exitfail.c - fd-safer.c - fileblocks.c - fnmatch.c - fpending.c - ftruncate.c - full-write.c - getdate.c - getline.c - getopt.c - getopt1.c - gettime.c - hash.c - human.c - imaxtostr.c - lchown.c - malloc.c - mbchar.c - mbscasecmp.c - mempcpy.c - memrchr.c - memset.c - mkdtemp.c - mktime.c - modechange.c - obstack.c - offtostr.c - open-safer.c - openat.c - openat-die.c - openat-proc.c - paxerror.c - paxexit.c - paxnames.c - prepargs.c - quote.c - quotearg.c - realloc.c - rmdir.c - rpmatch.c - rtapelib.c - safe-read.c - safe-write.c - save-cwd.c - savedir.c - stdopen.c - stpcpy.c - strcasecmp.c - stripslash.c - strnlen1.c - strncasecmp.c - strndup.c - strtol.c - strtoul.c - strtoull.c - tempname.c - time_r.c - umaxtostr.c - unlinkdir.c - utime.c - utimens.c - version-etc.c - version-etc-fsf.c - waitpid.c - xalloc-die.c - xgetcwd.c - xmalloc.c - xstrndup.c - xstrtol.c - xstrtoul.c - xstrtoumax.c -; - diff --git a/src/bin/tar/lib/Makefile.am b/src/bin/tar/lib/Makefile.am deleted file mode 100644 index 466a477a7f..0000000000 --- a/src/bin/tar/lib/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile for GNU tar library. -*- Makefile -*- - -# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, -# 2005, 2006, 2007 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. - -# 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., -# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -include gnulib.mk - -rmt-command.h : Makefile - rm -f $@-t $@ - echo "#ifndef DEFAULT_RMT_COMMAND" >> $@-t - echo "# define DEFAULT_RMT_COMMAND \"$(DEFAULT_RMT_DIR)/`echo rmt | sed '$(transform)'`$(EXEEXT)\"" >> $@-t - echo "#endif" >> $@-t - mv $@-t $@ -BUILT_SOURCES += rmt-command.h -CLEANFILES += rmt-command.h rmt-command.h-t - -noinst_HEADERS += system.h system-ioctl.h rmt.h paxlib.h stdopen.h -libtar_a_SOURCES += \ - paxerror.c paxexit.c paxlib.h paxnames.c \ - prepargs.c prepargs.h \ - rtapelib.c \ - rmt.h \ - stdopen.c stdopen.h \ - system.h system-ioctl.h - -libtar_a_LIBADD += $(LIBOBJS) -libtar_a_DEPENDENCIES += $(LIBOBJS) diff --git a/src/bin/tar/lib/Makefile.in b/src/bin/tar/lib/Makefile.in deleted file mode 100644 index 2dede636a0..0000000000 --- a/src/bin/tar/lib/Makefile.in +++ /dev/null @@ -1,1541 +0,0 @@ -# Makefile.in generated by automake 1.9.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile for GNU tar library. -*- Makefile -*- - -# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, -# 2005, 2006, 2007 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. - -# 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., -# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -# Copyright (C) 2004-2007 Free Software Foundation, Inc. -# -# This file is free software, distributed under the terms of the GNU -# General Public License. As a special exception to the GNU General -# Public License, this file may be distributed as part of a program -# that contains a configuration script generated by Autoconf, under -# the same distribution terms as the rest of that program. -# -# Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl --lib=libtar --source-base=.#bootmp/lib --m4-base=.#bootmp/m4 --doc-base=.#bootmp/doc --aux-dir=.#bootmp/build-aux --avoid=lock --avoid=size_max --no-libtool --macro-prefix=gl alloca argmatch argp backupfile closeout configmake dirname error exclude exitfail fileblocks fnmatch-gnu ftruncate full-write getdate getline getopt getpagesize gettext gettime hash human inttostr inttypes lchown localcharset memset mkdtemp modechange obstack quote quotearg rmdir rpmatch safe-read save-cwd savedir setenv stat-time stdbool stdint stpcpy strdup strerror strtol strtoul timespec unlinkdir unlocked-io utime utimens version-etc-fsf xalloc xalloc-die xgetcwd xstrtoumax - - - -SOURCES = $(libtar_a_SOURCES) $(EXTRA_libtar_a_SOURCES) - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/gnulib.mk alloca.c getdate.c \ - waitpid.c -subdir = lib -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/alloca.m4 \ - $(top_srcdir)/m4/argmatch.m4 $(top_srcdir)/m4/argp.m4 \ - $(top_srcdir)/m4/backupfile.m4 $(top_srcdir)/m4/bison.m4 \ - $(top_srcdir)/m4/canonicalize-lgpl.m4 \ - $(top_srcdir)/m4/chdir-long.m4 $(top_srcdir)/m4/chown.m4 \ - $(top_srcdir)/m4/clock_time.m4 \ - $(top_srcdir)/m4/close-stream.m4 $(top_srcdir)/m4/closeout.m4 \ - $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/d-ino.m4 \ - $(top_srcdir)/m4/dirfd.m4 $(top_srcdir)/m4/dirname.m4 \ - $(top_srcdir)/m4/dos.m4 $(top_srcdir)/m4/double-slash-root.m4 \ - $(top_srcdir)/m4/dup2.m4 $(top_srcdir)/m4/eealloc.m4 \ - $(top_srcdir)/m4/eoverflow.m4 $(top_srcdir)/m4/error.m4 \ - $(top_srcdir)/m4/exclude.m4 $(top_srcdir)/m4/exitfail.m4 \ - $(top_srcdir)/m4/extensions.m4 $(top_srcdir)/m4/fchdir.m4 \ - $(top_srcdir)/m4/fcntl-safer.m4 $(top_srcdir)/m4/fcntl_h.m4 \ - $(top_srcdir)/m4/fileblocks.m4 $(top_srcdir)/m4/float_h.m4 \ - $(top_srcdir)/m4/fnmatch.m4 $(top_srcdir)/m4/fpending.m4 \ - $(top_srcdir)/m4/ftruncate.m4 \ - $(top_srcdir)/m4/getcwd-abort-bug.m4 \ - $(top_srcdir)/m4/getcwd-path-max.m4 $(top_srcdir)/m4/getcwd.m4 \ - $(top_srcdir)/m4/getdate.m4 $(top_srcdir)/m4/getdelim.m4 \ - $(top_srcdir)/m4/getline.m4 $(top_srcdir)/m4/getopt.m4 \ - $(top_srcdir)/m4/getpagesize.m4 $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gettime.m4 $(top_srcdir)/m4/gettimeofday.m4 \ - $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \ - $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/hash.m4 \ - $(top_srcdir)/m4/human.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inline.m4 \ - $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intmax_t.m4 \ - $(top_srcdir)/m4/inttostr.m4 $(top_srcdir)/m4/inttypes-pri.m4 \ - $(top_srcdir)/m4/inttypes.m4 $(top_srcdir)/m4/inttypes_h.m4 \ - $(top_srcdir)/m4/lchown.m4 $(top_srcdir)/m4/lib-ld.m4 \ - $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ - $(top_srcdir)/m4/localcharset.m4 $(top_srcdir)/m4/longlong.m4 \ - $(top_srcdir)/m4/lstat.m4 $(top_srcdir)/m4/malloc.m4 \ - $(top_srcdir)/m4/malloca.m4 $(top_srcdir)/m4/mbchar.m4 \ - $(top_srcdir)/m4/mbiter.m4 $(top_srcdir)/m4/mbrtowc.m4 \ - $(top_srcdir)/m4/mbscasecmp.m4 $(top_srcdir)/m4/mbstate_t.m4 \ - $(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/mempcpy.m4 \ - $(top_srcdir)/m4/memrchr.m4 $(top_srcdir)/m4/memset.m4 \ - $(top_srcdir)/m4/mkdtemp.m4 $(top_srcdir)/m4/mktime.m4 \ - $(top_srcdir)/m4/modechange.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/openat.m4 $(top_srcdir)/m4/pathmax.m4 \ - $(top_srcdir)/m4/paxutils.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/quote.m4 \ - $(top_srcdir)/m4/quotearg.m4 $(top_srcdir)/m4/readlink.m4 \ - $(top_srcdir)/m4/realloc.m4 $(top_srcdir)/m4/regex.m4 \ - $(top_srcdir)/m4/rmdir.m4 $(top_srcdir)/m4/rmt.m4 \ - $(top_srcdir)/m4/rpmatch.m4 $(top_srcdir)/m4/rtapelib.m4 \ - $(top_srcdir)/m4/safe-read.m4 $(top_srcdir)/m4/safe-write.m4 \ - $(top_srcdir)/m4/save-cwd.m4 $(top_srcdir)/m4/savedir.m4 \ - $(top_srcdir)/m4/setenv.m4 $(top_srcdir)/m4/sleep.m4 \ - $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stat-time.m4 \ - $(top_srcdir)/m4/stdarg.m4 $(top_srcdir)/m4/stdbool.m4 \ - $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \ - $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \ - $(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strcase.m4 \ - $(top_srcdir)/m4/strchrnul.m4 $(top_srcdir)/m4/strdup.m4 \ - $(top_srcdir)/m4/strerror.m4 $(top_srcdir)/m4/string_h.m4 \ - $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \ - $(top_srcdir)/m4/strtoimax.m4 $(top_srcdir)/m4/strtol.m4 \ - $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/strtoul.m4 \ - $(top_srcdir)/m4/strtoull.m4 $(top_srcdir)/m4/strtoumax.m4 \ - $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \ - $(top_srcdir)/m4/sysexits.m4 $(top_srcdir)/m4/system.m4 \ - $(top_srcdir)/m4/tempname.m4 $(top_srcdir)/m4/time_h.m4 \ - $(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/timespec.m4 \ - $(top_srcdir)/m4/tm_gmtoff.m4 $(top_srcdir)/m4/unistd-safer.m4 \ - $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/unlinkdir.m4 \ - $(top_srcdir)/m4/unlocked-io.m4 $(top_srcdir)/m4/utimbuf.m4 \ - $(top_srcdir)/m4/utime.m4 $(top_srcdir)/m4/utimens.m4 \ - $(top_srcdir)/m4/utimes-null.m4 $(top_srcdir)/m4/utimes.m4 \ - $(top_srcdir)/m4/vasnprintf.m4 $(top_srcdir)/m4/vsnprintf.m4 \ - $(top_srcdir)/m4/wchar.m4 $(top_srcdir)/m4/wchar_t.m4 \ - $(top_srcdir)/m4/wctype.m4 $(top_srcdir)/m4/wcwidth.m4 \ - $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/xalloc.m4 \ - $(top_srcdir)/m4/xgetcwd.m4 $(top_srcdir)/m4/xsize.m4 \ - $(top_srcdir)/m4/xstrndup.m4 $(top_srcdir)/m4/xstrtol.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -LIBRARIES = $(noinst_LIBRARIES) -AR = ar -ARFLAGS = cru -libtar_a_AR = $(AR) $(ARFLAGS) -am__DEPENDENCIES_1 = -am__DEPENDENCIES_2 = @LIBOBJS@ -am__dirstamp = $(am__leading_dot)dirstamp -am_libtar_a_OBJECTS = argp-ba.$(OBJEXT) argp-eexst.$(OBJEXT) \ - argp-fmtstream.$(OBJEXT) argp-fs-xinl.$(OBJEXT) \ - argp-help.$(OBJEXT) argp-parse.$(OBJEXT) argp-pin.$(OBJEXT) \ - argp-pv.$(OBJEXT) argp-pvh.$(OBJEXT) argp-xinl.$(OBJEXT) \ - full-write.$(OBJEXT) getdate.$(OBJEXT) localcharset.$(OBJEXT) \ - malloca.$(OBJEXT) mbchar.$(OBJEXT) mbscasecmp.$(OBJEXT) \ - openat-die.$(OBJEXT) strnlen1.$(OBJEXT) \ - uniwidth/width.$(OBJEXT) version-etc.$(OBJEXT) \ - version-etc-fsf.$(OBJEXT) xalloc-die.$(OBJEXT) \ - xstrndup.$(OBJEXT) xstrtoumax.$(OBJEXT) paxerror.$(OBJEXT) \ - paxexit.$(OBJEXT) paxnames.$(OBJEXT) prepargs.$(OBJEXT) \ - rtapelib.$(OBJEXT) stdopen.$(OBJEXT) -libtar_a_OBJECTS = $(am_libtar_a_OBJECTS) -LTLIBRARIES = $(noinst_LTLIBRARIES) -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) -SOURCES = $(libtar_a_SOURCES) $(EXTRA_libtar_a_SOURCES) -DIST_SOURCES = $(libtar_a_SOURCES) $(EXTRA_libtar_a_SOURCES) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ -ALLOCA_H = @ALLOCA_H@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOM4TE = @AUTOM4TE@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BACKUP_LIBEXEC_SCRIPTS = @BACKUP_LIBEXEC_SCRIPTS@ -BACKUP_SBIN_SCRIPTS = @BACKUP_SBIN_SCRIPTS@ -BACKUP_SED_COND = @BACKUP_SED_COND@ -BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ -BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ -BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ -BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ -BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFAULT_ARCHIVE = @DEFAULT_ARCHIVE@ -DEFAULT_ARCHIVE_FORMAT = @DEFAULT_ARCHIVE_FORMAT@ -DEFAULT_BLOCKING = @DEFAULT_BLOCKING@ -DEFAULT_QUOTING_STYLE = @DEFAULT_QUOTING_STYLE@ -DEFAULT_RMT_COMMAND = @DEFAULT_RMT_COMMAND@ -DEFAULT_RMT_DIR = @DEFAULT_RMT_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DIRENT_H = @DIRENT_H@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EOVERFLOW = @EOVERFLOW@ -EXEEXT = @EXEEXT@ -FCNTL_H = @FCNTL_H@ -FLOAT_H = @FLOAT_H@ -FNMATCH_H = @FNMATCH_H@ -GETOPT_H = @GETOPT_H@ -GLIBC21 = @GLIBC21@ -GL_COND_LIBTOOL_FALSE = @GL_COND_LIBTOOL_FALSE@ -GL_COND_LIBTOOL_TRUE = @GL_COND_LIBTOOL_TRUE@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@ -GNULIB_CHOWN = @GNULIB_CHOWN@ -GNULIB_DUP2 = @GNULIB_DUP2@ -GNULIB_FCHDIR = @GNULIB_FCHDIR@ -GNULIB_FFLUSH = @GNULIB_FFLUSH@ -GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@ -GNULIB_FSEEK = @GNULIB_FSEEK@ -GNULIB_FSEEKO = @GNULIB_FSEEKO@ -GNULIB_FTELL = @GNULIB_FTELL@ -GNULIB_FTELLO = @GNULIB_FTELLO@ -GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@ -GNULIB_GETCWD = @GNULIB_GETCWD@ -GNULIB_GETDELIM = @GNULIB_GETDELIM@ -GNULIB_GETLINE = @GNULIB_GETLINE@ -GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@ -GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@ -GNULIB_IMAXABS = @GNULIB_IMAXABS@ -GNULIB_IMAXDIV = @GNULIB_IMAXDIV@ -GNULIB_LCHOWN = @GNULIB_LCHOWN@ -GNULIB_LSEEK = @GNULIB_LSEEK@ -GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@ -GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@ -GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@ -GNULIB_MBSCHR = @GNULIB_MBSCHR@ -GNULIB_MBSCSPN = @GNULIB_MBSCSPN@ -GNULIB_MBSLEN = @GNULIB_MBSLEN@ -GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@ -GNULIB_MBSNLEN = @GNULIB_MBSNLEN@ -GNULIB_MBSPBRK = @GNULIB_MBSPBRK@ -GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@ -GNULIB_MBSRCHR = @GNULIB_MBSRCHR@ -GNULIB_MBSSEP = @GNULIB_MBSSEP@ -GNULIB_MBSSPN = @GNULIB_MBSSPN@ -GNULIB_MBSSTR = @GNULIB_MBSSTR@ -GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@ -GNULIB_MEMMEM = @GNULIB_MEMMEM@ -GNULIB_MEMPCPY = @GNULIB_MEMPCPY@ -GNULIB_MEMRCHR = @GNULIB_MEMRCHR@ -GNULIB_MKDTEMP = @GNULIB_MKDTEMP@ -GNULIB_MKSTEMP = @GNULIB_MKSTEMP@ -GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@ -GNULIB_READLINK = @GNULIB_READLINK@ -GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@ -GNULIB_SLEEP = @GNULIB_SLEEP@ -GNULIB_SNPRINTF = @GNULIB_SNPRINTF@ -GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@ -GNULIB_STPCPY = @GNULIB_STPCPY@ -GNULIB_STPNCPY = @GNULIB_STPNCPY@ -GNULIB_STRCASESTR = @GNULIB_STRCASESTR@ -GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@ -GNULIB_STRDUP = @GNULIB_STRDUP@ -GNULIB_STRERROR = @GNULIB_STRERROR@ -GNULIB_STRNDUP = @GNULIB_STRNDUP@ -GNULIB_STRNLEN = @GNULIB_STRNLEN@ -GNULIB_STRPBRK = @GNULIB_STRPBRK@ -GNULIB_STRSEP = @GNULIB_STRSEP@ -GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@ -GNULIB_STRTOK_R = @GNULIB_STRTOK_R@ -GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@ -GNULIB_VASPRINTF = @GNULIB_VASPRINTF@ -GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@ -GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@ -GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@ -GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@ -GNULIB_WCWIDTH = @GNULIB_WCWIDTH@ -GREP = @GREP@ -HAVE_CALLOC_POSIX = @HAVE_CALLOC_POSIX@ -HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@ -HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@ -HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@ -HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ -HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ -HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@ -HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@ -HAVE_DECL_MKDIR = @HAVE_DECL_MKDIR@ -HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@ -HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@ -HAVE_DECL_STRERROR = @HAVE_DECL_STRERROR@ -HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@ -HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@ -HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@ -HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@ -HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@ -HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@ -HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@ -HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ -HAVE_DUP2 = @HAVE_DUP2@ -HAVE_FSEEKO = @HAVE_FSEEKO@ -HAVE_FTELLO = @HAVE_FTELLO@ -HAVE_FTRUNCATE = @HAVE_FTRUNCATE@ -HAVE_GETSUBOPT = @HAVE_GETSUBOPT@ -HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ -HAVE_IO_H = @HAVE_IO_H@ -HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ -HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ -HAVE_LSTAT = @HAVE_LSTAT@ -HAVE_MALLOC_POSIX = @HAVE_MALLOC_POSIX@ -HAVE_MEMPCPY = @HAVE_MEMPCPY@ -HAVE_MKDTEMP = @HAVE_MKDTEMP@ -HAVE_READLINK = @HAVE_READLINK@ -HAVE_REALLOC_POSIX = @HAVE_REALLOC_POSIX@ -HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ -HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ -HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ -HAVE_SLEEP = @HAVE_SLEEP@ -HAVE_STDINT_H = @HAVE_STDINT_H@ -HAVE_STPCPY = @HAVE_STPCPY@ -HAVE_STPNCPY = @HAVE_STPNCPY@ -HAVE_STRCASECMP = @HAVE_STRCASECMP@ -HAVE_STRCASESTR = @HAVE_STRCASESTR@ -HAVE_STRCHRNUL = @HAVE_STRCHRNUL@ -HAVE_STRNDUP = @HAVE_STRNDUP@ -HAVE_STRPBRK = @HAVE_STRPBRK@ -HAVE_STRSEP = @HAVE_STRSEP@ -HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ -HAVE_SYSEXITS_H = @HAVE_SYSEXITS_H@ -HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ -HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ -HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ -HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ -HAVE_UNISTD_H = @HAVE_UNISTD_H@ -HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ -HAVE_VASPRINTF = @HAVE_VASPRINTF@ -HAVE_WCHAR_H = @HAVE_WCHAR_H@ -HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ -HAVE_WINT_T = @HAVE_WINT_T@ -HAVE__BOOL = @HAVE__BOOL@ -INCLUDE_NEXT = @INCLUDE_NEXT@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INTLLIBS = @INTLLIBS@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -INTTYPES_H = @INTTYPES_H@ -LDFLAGS = @LDFLAGS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTAR_LIBDEPS = @LIBTAR_LIBDEPS@ -LIBTAR_LTLIBDEPS = @LIBTAR_LTLIBDEPS@ -LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@ -LIB_SETSOCKOPT = @LIB_SETSOCKOPT@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEXT_DIRENT_H = @NEXT_DIRENT_H@ -NEXT_FCNTL_H = @NEXT_FCNTL_H@ -NEXT_FLOAT_H = @NEXT_FLOAT_H@ -NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ -NEXT_STDINT_H = @NEXT_STDINT_H@ -NEXT_STDIO_H = @NEXT_STDIO_H@ -NEXT_STDLIB_H = @NEXT_STDLIB_H@ -NEXT_STRING_H = @NEXT_STRING_H@ -NEXT_SYSEXITS_H = @NEXT_SYSEXITS_H@ -NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@ -NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ -NEXT_TIME_H = @NEXT_TIME_H@ -NEXT_UNISTD_H = @NEXT_UNISTD_H@ -NEXT_WCHAR_H = @NEXT_WCHAR_H@ -NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -POSUB = @POSUB@ -PRIPTR_PREFIX = @PRIPTR_PREFIX@ -PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ -PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ -PU_RMT_PROG = @PU_RMT_PROG@ -RANLIB = @RANLIB@ -REPLACE_CHOWN = @REPLACE_CHOWN@ -REPLACE_FCHDIR = @REPLACE_FCHDIR@ -REPLACE_FFLUSH = @REPLACE_FFLUSH@ -REPLACE_FPRINTF = @REPLACE_FPRINTF@ -REPLACE_FSEEK = @REPLACE_FSEEK@ -REPLACE_FSEEKO = @REPLACE_FSEEKO@ -REPLACE_FTELL = @REPLACE_FTELL@ -REPLACE_FTELLO = @REPLACE_FTELLO@ -REPLACE_GETCWD = @REPLACE_GETCWD@ -REPLACE_GETLINE = @REPLACE_GETLINE@ -REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ -REPLACE_LCHOWN = @REPLACE_LCHOWN@ -REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ -REPLACE_LSEEK = @REPLACE_LSEEK@ -REPLACE_MKSTEMP = @REPLACE_MKSTEMP@ -REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ -REPLACE_PRINTF = @REPLACE_PRINTF@ -REPLACE_SNPRINTF = @REPLACE_SNPRINTF@ -REPLACE_SPRINTF = @REPLACE_SPRINTF@ -REPLACE_STRERROR = @REPLACE_STRERROR@ -REPLACE_STRPTIME = @REPLACE_STRPTIME@ -REPLACE_TIMEGM = @REPLACE_TIMEGM@ -REPLACE_VASPRINTF = @REPLACE_VASPRINTF@ -REPLACE_VFPRINTF = @REPLACE_VFPRINTF@ -REPLACE_VPRINTF = @REPLACE_VPRINTF@ -REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@ -REPLACE_VSPRINTF = @REPLACE_VSPRINTF@ -REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ -SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ -STDBOOL_H = @STDBOOL_H@ -STDINT_H = @STDINT_H@ -STRIP = @STRIP@ -SYSEXITS_H = @SYSEXITS_H@ -SYS_STAT_H = @SYS_STAT_H@ -SYS_TIME_H = @SYS_TIME_H@ -SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ -TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WCHAR_H = @WCHAR_H@ -WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ -WCTYPE_H = @WCTYPE_H@ -WINT_T_SUFFIX = @WINT_T_SUFFIX@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -ac_ct_CC = @ac_ct_CC@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -gl_LIBOBJS = @gl_LIBOBJS@ -gl_LTLIBOBJS = @gl_LTLIBOBJS@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects -noinst_HEADERS = system.h system-ioctl.h rmt.h paxlib.h stdopen.h -noinst_LIBRARIES = libtar.a -noinst_LTLIBRARIES = - -# This is for those projects which use "gettextize --intl" to put a source-code -# copy of libintl into their package. In such projects, every Makefile.am needs -# -I$(top_builddir)/intl, so that can be found in this directory. -# For the Makefile.ams in other directories it is the maintainer's -# responsibility; for the one from gnulib we do it here. -# This option has no effect when the user disables NLS (because then the intl -# directory contains no libintl.h file) or when the project does not use -# "gettextize --intl". -#AM_CPPFLAGS += -I$(top_builddir)/intl -EXTRA_DIST = alloca.c alloca.in.h argmatch.c argmatch.h backupfile.c \ - backupfile.h canonicalize-lgpl.c canonicalize.h chdir-long.c \ - chdir-long.h chown.c fchown-stub.c close-stream.c \ - close-stream.h closeout.c closeout.h dirfd.c dirfd.h \ - basename.c dirname.c dirname.h stripslash.c dup2.c error.c \ - error.h exclude.c exclude.h exitfail.c exitfail.h dirent.in.h \ - fchdir.c fcntl.in.h creat-safer.c fcntl--.h fcntl-safer.h \ - open-safer.c fileblocks.c float.in.h fnmatch.c fnmatch.in.h \ - fnmatch_loop.c fpending.c fpending.h ftruncate.c getcwd.c \ - getdate.c getdate.h getdelim.c getline.c getopt.c getopt.in.h \ - getopt1.c getopt_int.h getpagesize.h \ - $(top_srcdir)/build-aux/config.rpath gettime.c gettimeofday.c \ - hash.c hash.h $(top_srcdir)/build-aux/config.rpath human.c \ - human.h intprops.h imaxtostr.c inttostr.c inttostr.h \ - offtostr.c uinttostr.c umaxtostr.c inttypes.in.h lchown.c \ - $(top_srcdir)/build-aux/link-warning.h config.charset \ - ref-add.sin ref-del.sin lstat.c lstat.h malloc.c malloc.c \ - malloca.h malloca.valgrind mbchar.h memchr.c mempcpy.c \ - memrchr.c memset.c mkdtemp.c mktime.c modechange.c \ - modechange.h obstack.c obstack.h at-func.c fchmodat.c \ - fchownat.c fstatat.c mkdirat.c openat-priv.h openat-proc.c \ - openat.c openat.h pathmax.h quote.c quote.h quotearg.c \ - quotearg.h readlink.c realloc.c regcomp.c regex.c regex.h \ - regex_internal.c regex_internal.h regexec.c rmdir.c rpmatch.c \ - safe-read.c safe-read.h safe-write.c safe-write.h same-inode.h \ - save-cwd.c save-cwd.h savedir.c savedir.h setenv.c setenv.h \ - unsetenv.c sleep.c stat-macros.h stat-time.h stdbool.in.h \ - stdint.in.h stdio.in.h stdlib.in.h stpcpy.c strcasecmp.c \ - strncasecmp.c strchrnul.c strdup.c streq.h strerror.c \ - string.in.h strndup.c strnlen.c strtoimax.c strtol.c strtoll.c \ - strtoul.c strtoull.c strtoumax.c sys_stat.in.h sys_time.in.h \ - sysexits.in.h tempname.c tempname.h time.in.h time_r.c \ - timespec.h unistd.in.h dup-safer.c fd-safer.c pipe-safer.c \ - unistd--.h unistd-safer.h unitypes.h localcharset.h uniwidth.h \ - uniwidth/cjk.h unlinkdir.c unlinkdir.h unlocked-io.h utime.c \ - utimens.c utimens.h asnprintf.c float+.h printf-args.c \ - printf-args.h printf-parse.c printf-parse.h vasnprintf.c \ - vasnprintf.h vsnprintf.c wchar.in.h wctype.in.h wcwidth.c \ - xalloc.h xmalloc.c xgetcwd.c xgetcwd.h xstrtol-error.c \ - xstrtol.c xstrtol.h xstrtoul.c -BUILT_SOURCES = $(ALLOCA_H) configmake.h $(DIRENT_H) $(FCNTL_H) \ - $(FLOAT_H) $(FNMATCH_H) getdate.c $(GETOPT_H) $(INTTYPES_H) \ - $(STDBOOL_H) $(STDINT_H) stdio.h stdlib.h string.h \ - $(SYS_STAT_H) $(SYS_TIME_H) $(SYSEXITS_H) time.h unistd.h \ - $(WCHAR_H) $(WCTYPE_H) rmt-command.h -SUFFIXES = .sed .sin -MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t dirent.h \ - dirent.h-t fcntl.h fcntl.h-t float.h float.h-t fnmatch.h \ - fnmatch.h-t getopt.h getopt.h-t inttypes.h inttypes.h-t \ - stdbool.h stdbool.h-t stdint.h stdint.h-t stdio.h stdio.h-t \ - stdlib.h stdlib.h-t string.h string.h-t sys/stat.h \ - sys/stat.h-t sys/time.h sys/time.h-t sysexits.h sysexits.h-t \ - time.h time.h-t unistd.h unistd.h-t wchar.h wchar.h-t wctype.h \ - wctype.h-t -MOSTLYCLEANDIRS = sys -CLEANFILES = configmake.h configmake.h-t charset.alias ref-add.sed \ - ref-del.sed rmt-command.h rmt-command.h-t -DISTCLEANFILES = -MAINTAINERCLEANFILES = getdate.c -AM_CPPFLAGS = -libtar_a_SOURCES = argp.h argp-ba.c argp-eexst.c argp-fmtstream.c \ - argp-fmtstream.h argp-fs-xinl.c argp-help.c argp-namefrob.h \ - argp-parse.c argp-pin.c argp-pv.c argp-pvh.c argp-xinl.c \ - full-write.h full-write.c getdate.y gettext.h localcharset.h \ - localcharset.c malloca.c mbchar.c mbscasecmp.c mbuiter.h \ - openat-die.c strnlen1.h strnlen1.c uniwidth/width.c verify.h \ - version-etc.h version-etc.c version-etc-fsf.c xalloc-die.c \ - xsize.h xstrndup.h xstrndup.c xstrtoumax.c paxerror.c \ - paxexit.c paxlib.h paxnames.c prepargs.c prepargs.h rtapelib.c \ - rmt.h stdopen.c stdopen.h system.h system-ioctl.h -libtar_a_LIBADD = $(gl_LIBOBJS) @ALLOCA@ $(LIBOBJS) -libtar_a_DEPENDENCIES = $(gl_LIBOBJS) @ALLOCA@ $(LIBOBJS) -EXTRA_libtar_a_SOURCES = alloca.c argmatch.c backupfile.c \ - canonicalize-lgpl.c chdir-long.c chown.c fchown-stub.c \ - close-stream.c closeout.c dirfd.c basename.c dirname.c \ - stripslash.c dup2.c error.c exclude.c exitfail.c fchdir.c \ - creat-safer.c open-safer.c fileblocks.c fnmatch.c \ - fnmatch_loop.c fpending.c ftruncate.c getcwd.c getdelim.c \ - getline.c getopt.c getopt1.c gettime.c gettimeofday.c hash.c \ - human.c imaxtostr.c inttostr.c offtostr.c uinttostr.c \ - umaxtostr.c lchown.c lstat.c malloc.c malloc.c memchr.c \ - mempcpy.c memrchr.c memset.c mkdtemp.c mktime.c modechange.c \ - obstack.c at-func.c fchmodat.c fchownat.c fstatat.c mkdirat.c \ - openat-proc.c openat.c quote.c quotearg.c readlink.c realloc.c \ - regcomp.c regex.c regex_internal.c regexec.c rmdir.c rpmatch.c \ - safe-read.c safe-write.c save-cwd.c savedir.c setenv.c \ - unsetenv.c sleep.c stpcpy.c strcasecmp.c strncasecmp.c \ - strchrnul.c strdup.c strerror.c strndup.c strnlen.c \ - strtoimax.c strtol.c strtoll.c strtoul.c strtoull.c \ - strtoumax.c tempname.c time_r.c dup-safer.c fd-safer.c \ - pipe-safer.c unlinkdir.c utime.c utimens.c asnprintf.c \ - printf-args.c printf-parse.c vasnprintf.c vsnprintf.c \ - wcwidth.c xmalloc.c xgetcwd.c xstrtol-error.c xstrtol.c \ - xstrtoul.c - -# Use this preprocessor expression to decide whether #include_next works. -# Do not rely on a 'configure'-time test for this, since the expression -# might appear in an installed header, which is used by some other compiler. -HAVE_INCLUDE_NEXT = (__GNUC__ || 60000000 <= __DECC_VER) -LINK_WARNING_H = $(top_srcdir)/build-aux/link-warning.h -charset_alias = $(DESTDIR)$(libdir)/charset.alias -charset_tmp = $(DESTDIR)$(libdir)/charset.tmp -all: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .sed .sin .c .o .obj .y -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/gnulib.mk $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits lib/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnits lib/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -uniwidth/$(am__dirstamp): - @$(mkdir_p) uniwidth - @: > uniwidth/$(am__dirstamp) -uniwidth/$(DEPDIR)/$(am__dirstamp): - @$(mkdir_p) uniwidth/$(DEPDIR) - @: > uniwidth/$(DEPDIR)/$(am__dirstamp) -uniwidth/width.$(OBJEXT): uniwidth/$(am__dirstamp) \ - uniwidth/$(DEPDIR)/$(am__dirstamp) -libtar.a: $(libtar_a_OBJECTS) $(libtar_a_DEPENDENCIES) - -rm -f libtar.a - $(libtar_a_AR) libtar.a $(libtar_a_OBJECTS) $(libtar_a_LIBADD) - $(RANLIB) libtar.a - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f uniwidth/width.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/alloca.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/waitpid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloca.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argmatch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-ba.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-eexst.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-fmtstream.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-fs-xinl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-help.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-parse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pv.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-pvh.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-xinl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asnprintf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/at-func.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backupfile.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basename.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canonicalize-lgpl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chdir-long.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chown.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/close-stream.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closeout.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/creat-safer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirfd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirname.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dup-safer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dup2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exclude.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exitfail.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchdir.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchmodat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchown-stub.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fchownat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fd-safer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileblocks.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnmatch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnmatch_loop.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpending.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstatat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftruncate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/full-write.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getcwd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdelim.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettime.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettimeofday.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/human.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imaxtostr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inttostr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lchown.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localcharset.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloca.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbchar.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbscasecmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memchr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mempcpy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memrchr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memset.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkdirat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkdtemp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modechange.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obstack.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/offtostr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open-safer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat-die.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat-proc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paxerror.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paxexit.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paxnames.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipe-safer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prepargs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf-args.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf-parse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quote.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quotearg.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlink.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realloc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regcomp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex_internal.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regexec.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmdir.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpmatch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtapelib.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe-read.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe-write.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/save-cwd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/savedir.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setenv.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sleep.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdopen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stpcpy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcasecmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strchrnul.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strdup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strerror.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stripslash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strncasecmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strndup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnlen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnlen1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoimax.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtol.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoll.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoul.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoull.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoumax.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tempname.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_r.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uinttostr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/umaxtostr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unlinkdir.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unsetenv.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utime.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utimens.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vasnprintf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version-etc-fsf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version-etc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsnprintf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcwidth.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xalloc-die.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetcwd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmalloc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrndup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtol-error.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtol.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtoul.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xstrtoumax.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@uniwidth/$(DEPDIR)/width.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`; \ -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$$depbase.Tpo" -c -o $@ $<; \ -@am__fastdepCC_TRUE@ then mv -f "$$depbase.Tpo" "$$depbase.Po"; else rm -f "$$depbase.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`; \ -@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$$depbase.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ -@am__fastdepCC_TRUE@ then mv -f "$$depbase.Tpo" "$$depbase.Po"; else rm -f "$$depbase.Tpo"; exit 1; fi -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.y.c: - $(YACCCOMPILE) $< - if test -f y.tab.h; then \ - to=`echo "$*_H" | sed \ - -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ - -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \ - sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \ - y.tab.h >$*.ht; \ - rm -f y.tab.h; \ - if cmp -s $*.ht $*.h; then \ - rm -f $*.ht ;\ - else \ - mv $*.ht $*.h; \ - fi; \ - fi - if test -f y.output; then \ - mv y.output $*.output; \ - fi - sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@ - rm -f y.tab.c -uninstall-info-am: - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - $(mkdir_p) $(distdir)/$(top_srcdir)/build-aux $(distdir)/uniwidth - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) all-local -installdirs: -install: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -rm -f uniwidth/$(DEPDIR)/$(am__dirstamp) - -rm -f uniwidth/$(am__dirstamp) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -rm -f getdate.c - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf $(DEPDIR) ./$(DEPDIR) uniwidth/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: install-exec-local - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf $(DEPDIR) ./$(DEPDIR) uniwidth/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-local - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am uninstall-local - -.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \ - clean-generic clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ - ctags distclean distclean-compile distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-exec \ - install-exec-am install-exec-local install-info \ - install-info-am install-man install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-local pdf pdf-am ps ps-am tags \ - uninstall uninstall-am uninstall-info-am uninstall-local - - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -alloca.h: alloca.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/alloca.in.h; \ - } > $@-t - mv -f $@-t $@ - -# Retrieve values of the variables through 'configure' followed by -# 'make', not directly through 'configure', so that a user who -# sets some of these variables consistently on the 'make' command -# line gets correct results. -# -# One advantage of this approach, compared to the classical -# approach of adding -DLIBDIR=\"$(libdir)\" etc. to AM_CPPFLAGS, -# is that it protects against the use of undefined variables. -# If, say, $(libdir) is not set in the Makefile, LIBDIR is not -# defined by this module, and code using LIBDIR gives a -# compilation error. -# -# Another advantage is that 'make' output is shorter. -# -# Listed in the same order as the GNU makefile conventions. -# The Automake-defined pkg* macros are appended, in the order -# listed in the Automake 1.10a+ documentation. -configmake.h: Makefile - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - echo '#define PREFIX "$(prefix)"'; \ - echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ - echo '#define BINDIR "$(bindir)"'; \ - echo '#define SBINDIR "$(sbindir)"'; \ - echo '#define LIBEXECDIR "$(libexecdir)"'; \ - echo '#define DATAROOTDIR "$(datarootdir)"'; \ - echo '#define DATADIR "$(datadir)"'; \ - echo '#define SYSCONFDIR "$(sysconfdir)"'; \ - echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ - echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ - echo '#define INCLUDEDIR "$(includedir)"'; \ - echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ - echo '#define DOCDIR "$(docdir)"'; \ - echo '#define INFODIR "$(infodir)"'; \ - echo '#define HTMLDIR "$(htmldir)"'; \ - echo '#define DVIDIR "$(dvidir)"'; \ - echo '#define PDFDIR "$(pdfdir)"'; \ - echo '#define PSDIR "$(psdir)"'; \ - echo '#define LIBDIR "$(libdir)"'; \ - echo '#define LISPDIR "$(lispdir)"'; \ - echo '#define LOCALEDIR "$(localedir)"'; \ - echo '#define MANDIR "$(mandir)"'; \ - echo '#define MANEXT "$(manext)"'; \ - echo '#define PKGDATADIR "$(pkgdatadir)"'; \ - echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ - echo '#define PKGLIBDIR "$(pkglibdir)"'; \ - echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ - } | sed '/""/d' > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -dirent.h: dirent.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''NEXT_DIRENT_H''@|$(NEXT_DIRENT_H)|g' \ - -e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \ - < $(srcdir)/dirent.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -fcntl.h: fcntl.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \ - < $(srcdir)/fcntl.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -float.h: float.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ - < $(srcdir)/float.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that supports the required API. -fnmatch.h: fnmatch.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/fnmatch.in.h; \ - } > $@-t - mv -f $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -getopt.h: getopt.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/getopt.in.h; \ - } > $@-t - mv -f $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -inttypes.h: inttypes.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_INTTYPES_H''@|$(NEXT_INTTYPES_H)|g' \ - -e 's/@''PRI_MACROS_BROKEN''@/$(PRI_MACROS_BROKEN)/g' \ - -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ - -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ - -e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \ - -e 's/@''GNULIB_IMAXABS''@/$(GNULIB_IMAXABS)/g' \ - -e 's/@''GNULIB_IMAXDIV''@/$(GNULIB_IMAXDIV)/g' \ - -e 's/@''GNULIB_STRTOIMAX''@/$(GNULIB_STRTOIMAX)/g' \ - -e 's/@''GNULIB_STRTOUMAX''@/$(GNULIB_STRTOUMAX)/g' \ - -e 's/@''HAVE_DECL_IMAXABS''@/$(HAVE_DECL_IMAXABS)/g' \ - -e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \ - -e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \ - -e 's/@''HAVE_DECL_STRTOUMAX''@/$(HAVE_DECL_STRTOUMAX)/g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/inttypes.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to install a simple file in $(libdir) -# which is shared with other installed packages. We use a list of referencing -# packages so that "make uninstall" will remove the file if and only if it -# is not used by another installed package. -# On systems with glibc-2.1 or newer, the file is redundant, therefore we -# avoid installing it. - -all-local: charset.alias ref-add.sed ref-del.sed -install-exec-local: all-local - test $(GLIBC21) != no || $(mkinstalldirs) $(DESTDIR)$(libdir) - if test -f $(charset_alias); then \ - sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - else \ - if test $(GLIBC21) = no; then \ - sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - fi ; \ - fi - -uninstall-local: all-local - if test -f $(charset_alias); then \ - sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ - if grep '^# Packages using this file: $$' $(charset_tmp) \ - > /dev/null; then \ - rm -f $(charset_alias); \ - else \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ - fi; \ - rm -f $(charset_tmp); \ - fi - -charset.alias: config.charset - rm -f t-$@ $@ - $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ - mv t-$@ $@ -.sin.sed: - rm -f t-$@ $@ - sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ - mv t-$@ $@ - -# We need the following in order to create when the system -# doesn't have one that works. -stdbool.h: stdbool.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdint.h: stdint.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ - -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ - -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ - -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ - -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ - -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ - -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ - -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ - -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ - -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ - -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ - -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ - -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ - -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ - < $(srcdir)/stdint.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdio.h: stdio.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ - -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ - -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ - -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ - -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ - -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ - -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ - -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ - -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ - -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ - -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \ - -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \ - -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ - -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ - -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ - -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ - -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ - -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ - -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ - -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ - -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ - -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ - -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ - -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ - -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ - -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ - -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ - -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ - -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ - -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \ - -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ - -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/stdio.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdlib.h: stdlib.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ - -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ - -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \ - -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \ - -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ - -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ - -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ - -e 's|@''HAVE_CALLOC_POSIX''@|$(HAVE_CALLOC_POSIX)|g' \ - -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ - -e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \ - -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ - -e 's|@''HAVE_REALLOC_POSIX''@|$(HAVE_REALLOC_POSIX)|g' \ - -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/stdlib.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -string.h: string.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ - -e 's|@''GNULIB_MBSLEN''@|$(GNULIB_MBSLEN)|g' \ - -e 's|@''GNULIB_MBSNLEN''@|$(GNULIB_MBSNLEN)|g' \ - -e 's|@''GNULIB_MBSCHR''@|$(GNULIB_MBSCHR)|g' \ - -e 's|@''GNULIB_MBSRCHR''@|$(GNULIB_MBSRCHR)|g' \ - -e 's|@''GNULIB_MBSSTR''@|$(GNULIB_MBSSTR)|g' \ - -e 's|@''GNULIB_MBSCASECMP''@|$(GNULIB_MBSCASECMP)|g' \ - -e 's|@''GNULIB_MBSNCASECMP''@|$(GNULIB_MBSNCASECMP)|g' \ - -e 's|@''GNULIB_MBSPCASECMP''@|$(GNULIB_MBSPCASECMP)|g' \ - -e 's|@''GNULIB_MBSCASESTR''@|$(GNULIB_MBSCASESTR)|g' \ - -e 's|@''GNULIB_MBSCSPN''@|$(GNULIB_MBSCSPN)|g' \ - -e 's|@''GNULIB_MBSPBRK''@|$(GNULIB_MBSPBRK)|g' \ - -e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \ - -e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \ - -e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \ - -e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \ - -e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \ - -e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \ - -e 's|@''GNULIB_STPCPY''@|$(GNULIB_STPCPY)|g' \ - -e 's|@''GNULIB_STPNCPY''@|$(GNULIB_STPNCPY)|g' \ - -e 's|@''GNULIB_STRCHRNUL''@|$(GNULIB_STRCHRNUL)|g' \ - -e 's|@''GNULIB_STRDUP''@|$(GNULIB_STRDUP)|g' \ - -e 's|@''GNULIB_STRNDUP''@|$(GNULIB_STRNDUP)|g' \ - -e 's|@''GNULIB_STRNLEN''@|$(GNULIB_STRNLEN)|g' \ - -e 's|@''GNULIB_STRPBRK''@|$(GNULIB_STRPBRK)|g' \ - -e 's|@''GNULIB_STRSEP''@|$(GNULIB_STRSEP)|g' \ - -e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \ - -e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \ - -e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \ - -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ - -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ - -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ - -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \ - -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ - -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ - -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ - -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ - -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ - -e 's|@''HAVE_STRNDUP''@|$(HAVE_STRNDUP)|g' \ - -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ - -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ - -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ - -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ - -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ - -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ - -e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \ - -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/string.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# has one that is incomplete. -sys/stat.h: sys_stat.in.h - @MKDIR_P@ sys - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \ - -e 's|@''HAVE_IO_H''@|$(HAVE_IO_H)|g' \ - -e 's|@''HAVE_LSTAT''@|$(HAVE_LSTAT)|g' \ - -e 's|@''HAVE_DECL_MKDIR''@|$(HAVE_DECL_MKDIR)|g' \ - < $(srcdir)/sys_stat.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -sys/time.h: sys_time.in.h - @MKDIR_P@ sys - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_SYS_TIME_H''@/$(HAVE_SYS_TIME_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_SYS_TIME_H''@|$(NEXT_SYS_TIME_H)|g' \ - -e 's/@''REPLACE_GETTIMEOFDAY''@/$(REPLACE_GETTIMEOFDAY)/g' \ - -e 's/@''HAVE_STRUCT_TIMEVAL''@/$(HAVE_STRUCT_TIMEVAL)/g' \ - < $(srcdir)/sys_time.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -sysexits.h: sysexits.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_H)|g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \ - < $(srcdir)/sysexits.in.h; \ - } > $@-t - mv -f $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -time.h: time.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ - -e 's|@REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ - -e 's|@REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ - -e 's|@REPLACE_STRPTIME''@|$(REPLACE_STRPTIME)|g' \ - -e 's|@REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|g' \ - -e 's|@SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ - -e 's|@TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ - < $(srcdir)/time.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create an empty placeholder for -# when the system doesn't have one. -unistd.h: unistd.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ - -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \ - -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \ - -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \ - -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \ - -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \ - -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \ - -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ - -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ - -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ - -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ - -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ - -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ - -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ - -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ - -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \ - -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ - -e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \ - -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ - -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ - -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ - < $(srcdir)/unistd.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# version does not work standalone. -wchar.h: wchar.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ - -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ - -e 's|@''GNULIB_WCWIDTH''@|$(GNULIB_WCWIDTH)|g' \ - -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ - -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/wchar.in.h; \ - } > $@-t - mv $@-t $@ - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -wctype.h: wctype.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ - -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ - -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ - < $(srcdir)/wctype.in.h; \ - } > $@-t - mv $@-t $@ - -mostlyclean-local: mostlyclean-generic - @for dir in '' $(MOSTLYCLEANDIRS); do \ - if test -n "$$dir" && test -d $$dir; then \ - echo "rmdir $$dir"; rmdir $$dir; \ - fi; \ - done; \ - : - -rmt-command.h : Makefile - rm -f $@-t $@ - echo "#ifndef DEFAULT_RMT_COMMAND" >> $@-t - echo "# define DEFAULT_RMT_COMMAND \"$(DEFAULT_RMT_DIR)/`echo rmt | sed '$(transform)'`$(EXEEXT)\"" >> $@-t - echo "#endif" >> $@-t - mv $@-t $@ -# 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: diff --git a/src/bin/tar/lib/alloca.c b/src/bin/tar/lib/alloca.c deleted file mode 100644 index 3a1f4e273a..0000000000 --- a/src/bin/tar/lib/alloca.c +++ /dev/null @@ -1,489 +0,0 @@ -/* 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 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. */ - -#include - -#include - -#include -#include - -#ifdef emacs -# include "lisp.h" -# include "blockinput.h" -# ifdef EMACS_FREE -# undef free -# define free EMACS_FREE -# endif -#else -# define memory_full() abort () -#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 -/* Using #error here is not wise since this file should work for - old and obscure compilers. */ -# 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 - -/* 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 (void) -{ - 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. */ - -void * -alloca (size_t 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 (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. */ - - { - /* Address of header. */ - register header *new; - - size_t combined_size = sizeof (header) + size; - if (combined_size < sizeof (header)) - memory_full (); - - new = malloc (combined_size); - - if (! new) - memory_full (); - - new->h.next = last_alloca_header; - new->h.deep = depth; - - last_alloca_header = new; - - /* User storage begins just after header. */ - - return (void *) (new + 1); - } -} - -# if defined (CRAY) && defined (CRAY_STACKSEG_END) - -# ifdef DEBUG_I00AFUNC -# include -# 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 */ diff --git a/src/bin/tar/lib/alloca.in.h b/src/bin/tar/lib/alloca.in.h deleted file mode 100644 index af274b9e75..0000000000 --- a/src/bin/tar/lib/alloca.in.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Memory allocation on the stack. - - Copyright (C) 1995, 1999, 2001-2004, 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H - means there is a real alloca function. */ -#ifndef _GL_ALLOCA_H -#define _GL_ALLOCA_H - -/* alloca (N) returns a pointer to N bytes of memory - allocated on the stack, which will last until the function returns. - Use of alloca should be avoided: - - inside arguments of function calls - undefined behaviour, - - in inline functions - the allocation may actually last until the - calling function returns, - - for huge N (say, N >= 65536) - you never know how large (or small) - the stack is, and when the stack cannot fulfill the memory allocation - request, the program just crashes. - */ - -#ifndef alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# else -# include -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#endif /* _GL_ALLOCA_H */ diff --git a/src/bin/tar/lib/argmatch.c b/src/bin/tar/lib/argmatch.c deleted file mode 100644 index 72d92483ec..0000000000 --- a/src/bin/tar/lib/argmatch.c +++ /dev/null @@ -1,278 +0,0 @@ -/* argmatch.c -- find a match for a string in an array - - Copyright (C) 1990, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie - Modified by Akim Demaille */ - -#include - -/* Specification. */ -#include "argmatch.h" - -#include -#include -#include -#include - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -#include "error.h" -#include "quotearg.h" -#include "quote.h" - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -/* When reporting an invalid argument, show nonprinting characters - by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use - literal_quoting_style. */ -#ifndef ARGMATCH_QUOTING_STYLE -# define ARGMATCH_QUOTING_STYLE locale_quoting_style -#endif - -/* Non failing version of argmatch call this function after failing. */ -#ifndef ARGMATCH_DIE -# include "exitfail.h" -# define ARGMATCH_DIE exit (exit_failure) -#endif - -#ifdef ARGMATCH_DIE_DECL -ARGMATCH_DIE_DECL; -#endif - -static void -__argmatch_die (void) -{ - ARGMATCH_DIE; -} - -/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h. - Default to __argmatch_die, but allow caller to change this at run-time. */ -argmatch_exit_fn argmatch_die = __argmatch_die; - - -/* If ARG is an unambiguous match for an element of the - NULL-terminated array ARGLIST, return the index in ARGLIST - of the matched element, else -1 if it does not match any element - or -2 if it is ambiguous (is a prefix of more than one element). - - If VALLIST is none null, use it to resolve ambiguities limited to - synonyms, i.e., for - "yes", "yop" -> 0 - "no", "nope" -> 1 - "y" is a valid argument, for `0', and "n" for `1'. */ - -ptrdiff_t -argmatch (const char *arg, const char *const *arglist, - const char *vallist, size_t valsize) -{ - size_t i; /* Temporary index in ARGLIST. */ - size_t arglen; /* Length of ARG. */ - ptrdiff_t matchind = -1; /* Index of first nonexact match. */ - bool ambiguous = false; /* If true, multiple nonexact match(es). */ - - arglen = strlen (arg); - - /* Test all elements for either exact match or abbreviated matches. */ - for (i = 0; arglist[i]; i++) - { - if (!strncmp (arglist[i], arg, arglen)) - { - if (strlen (arglist[i]) == arglen) - /* Exact match found. */ - return i; - else if (matchind == -1) - /* First nonexact match found. */ - matchind = i; - else - { - /* Second nonexact match found. */ - if (vallist == NULL - || memcmp (vallist + valsize * matchind, - vallist + valsize * i, valsize)) - { - /* There is a real ambiguity, or we could not - disambiguate. */ - ambiguous = true; - } - } - } - } - if (ambiguous) - return -2; - else - return matchind; -} - -/* Error reporting for argmatch. - CONTEXT is a description of the type of entity that was being matched. - VALUE is the invalid value that was given. - PROBLEM is the return value from argmatch. */ - -void -argmatch_invalid (const char *context, const char *value, ptrdiff_t problem) -{ - char const *format = (problem == -1 - ? _("invalid argument %s for %s") - : _("ambiguous argument %s for %s")); - - error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value), - quote_n (1, context)); -} - -/* List the valid arguments for argmatch. - ARGLIST is the same as in argmatch. - VALLIST is a pointer to an array of values. - VALSIZE is the size of the elements of VALLIST */ -void -argmatch_valid (const char *const *arglist, - const char *vallist, size_t valsize) -{ - size_t i; - const char *last_val = NULL; - - /* We try to put synonyms on the same line. The assumption is that - synonyms follow each other */ - fprintf (stderr, _("Valid arguments are:")); - for (i = 0; arglist[i]; i++) - if ((i == 0) - || memcmp (last_val, vallist + valsize * i, valsize)) - { - fprintf (stderr, "\n - `%s'", arglist[i]); - last_val = vallist + valsize * i; - } - else - { - fprintf (stderr, ", `%s'", arglist[i]); - } - putc ('\n', stderr); -} - -/* Never failing versions of the previous functions. - - CONTEXT is the context for which argmatch is called (e.g., - "--version-control", or "$VERSION_CONTROL" etc.). Upon failure, - calls the (supposed never to return) function EXIT_FN. */ - -ptrdiff_t -__xargmatch_internal (const char *context, - const char *arg, const char *const *arglist, - const char *vallist, size_t valsize, - argmatch_exit_fn exit_fn) -{ - ptrdiff_t res = argmatch (arg, arglist, vallist, valsize); - if (res >= 0) - /* Success. */ - return res; - - /* We failed. Explain why. */ - argmatch_invalid (context, arg, res); - argmatch_valid (arglist, vallist, valsize); - (*exit_fn) (); - - return -1; /* To please the compilers. */ -} - -/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and - return the first corresponding argument in ARGLIST */ -const char * -argmatch_to_argument (const char *value, - const char *const *arglist, - const char *vallist, size_t valsize) -{ - size_t i; - - for (i = 0; arglist[i]; i++) - if (!memcmp (value, vallist + valsize * i, valsize)) - return arglist[i]; - return NULL; -} - -#ifdef TEST -/* - * Based on "getversion.c" by David MacKenzie - */ -char *program_name; - -/* When to make backup files. */ -enum backup_type -{ - /* Never make backups. */ - no_backups, - - /* Make simple backups of every file. */ - simple_backups, - - /* Make numbered backups of files that already have numbered backups, - and simple backups of the others. */ - numbered_existing_backups, - - /* Make numbered backups of every file. */ - numbered_backups -}; - -/* Two tables describing arguments (keys) and their corresponding - values */ -static const char *const backup_args[] = -{ - "no", "none", "off", - "simple", "never", - "existing", "nil", - "numbered", "t", - 0 -}; - -static const enum backup_type backup_vals[] = -{ - no_backups, no_backups, no_backups, - simple_backups, simple_backups, - numbered_existing_backups, numbered_existing_backups, - numbered_backups, numbered_backups -}; - -int -main (int argc, const char *const *argv) -{ - const char *cp; - enum backup_type backup_type = no_backups; - - program_name = (char *) argv[0]; - - if (argc > 2) - { - fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name); - exit (1); - } - - if ((cp = getenv ("VERSION_CONTROL"))) - backup_type = XARGMATCH ("$VERSION_CONTROL", cp, - backup_args, backup_vals); - - if (argc == 2) - backup_type = XARGMATCH (program_name, argv[1], - backup_args, backup_vals); - - printf ("The version control is `%s'\n", - ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals)); - - return 0; -} -#endif diff --git a/src/bin/tar/lib/argmatch.h b/src/bin/tar/lib/argmatch.h deleted file mode 100644 index f2dfe59bda..0000000000 --- a/src/bin/tar/lib/argmatch.h +++ /dev/null @@ -1,103 +0,0 @@ -/* argmatch.h -- definitions and prototypes for argmatch.c - - Copyright (C) 1990, 1998, 1999, 2001, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie - Modified by Akim Demaille */ - -#ifndef ARGMATCH_H_ -# define ARGMATCH_H_ 1 - -# include - -# include "verify.h" - -# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) - -/* Assert there are as many real arguments as there are values - (argument list ends with a NULL guard). */ - -# define ARGMATCH_VERIFY(Arglist, Vallist) \ - verify (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1) - -/* Return the index of the element of ARGLIST (NULL terminated) that - matches with ARG. If VALLIST is not NULL, then use it to resolve - false ambiguities (i.e., different matches of ARG but corresponding - to the same values in VALLIST). */ - -ptrdiff_t argmatch (char const *arg, char const *const *arglist, - char const *vallist, size_t valsize); - -# define ARGMATCH(Arg, Arglist, Vallist) \ - argmatch (Arg, Arglist, (char const *) (Vallist), sizeof *(Vallist)) - -/* xargmatch calls this function when it fails. This function should not - return. By default, this is a function that calls ARGMATCH_DIE which - in turn defaults to `exit (exit_failure)'. */ -typedef void (*argmatch_exit_fn) (void); -extern argmatch_exit_fn argmatch_die; - -/* Report on stderr why argmatch failed. Report correct values. */ - -void argmatch_invalid (char const *context, char const *value, - ptrdiff_t problem); - -/* Left for compatibility with the old name invalid_arg */ - -# define invalid_arg(Context, Value, Problem) \ - argmatch_invalid (Context, Value, Problem) - - - -/* Report on stderr the list of possible arguments. */ - -void argmatch_valid (char const *const *arglist, - char const *vallist, size_t valsize); - -# define ARGMATCH_VALID(Arglist, Vallist) \ - argmatch_valid (Arglist, (char const *) (Vallist), sizeof *(Vallist)) - - - -/* Same as argmatch, but upon failure, reports a explanation on the - failure, and exits using the function EXIT_FN. */ - -ptrdiff_t __xargmatch_internal (char const *context, - char const *arg, char const *const *arglist, - char const *vallist, size_t valsize, - argmatch_exit_fn exit_fn); - -/* Programmer friendly interface to __xargmatch_internal. */ - -# define XARGMATCH(Context, Arg, Arglist, Vallist) \ - ((Vallist) [__xargmatch_internal (Context, Arg, Arglist, \ - (char const *) (Vallist), \ - sizeof *(Vallist), \ - argmatch_die)]) - -/* Convert a value into a corresponding argument. */ - -char const *argmatch_to_argument (char const *value, - char const *const *arglist, - char const *vallist, size_t valsize); - -# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \ - argmatch_to_argument (Value, Arglist, \ - (char const *) (Vallist), sizeof *(Vallist)) - -#endif /* ARGMATCH_H_ */ diff --git a/src/bin/tar/lib/argp-ba.c b/src/bin/tar/lib/argp-ba.c deleted file mode 100644 index 8bb7309fde..0000000000 --- a/src/bin/tar/lib/argp-ba.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Default definition for ARGP_PROGRAM_BUG_ADDRESS. - Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* If set by the user program, it should point to string that is the - bug-reporting address for the program. It will be printed by argp_help if - the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help - messages), embedded in a sentence that says something like `Report bugs to - ADDR.'. */ -const char *argp_program_bug_address; diff --git a/src/bin/tar/lib/argp-eexst.c b/src/bin/tar/lib/argp-eexst.c deleted file mode 100644 index bcab1c0c17..0000000000 --- a/src/bin/tar/lib/argp-eexst.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Default definition for ARGP_ERR_EXIT_STATUS - Copyright (C) 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "argp.h" - -/* The exit status that argp will use when exiting due to a parsing error. - If not defined or set by the user program, this defaults to EX_USAGE from - . */ -error_t argp_err_exit_status = EX_USAGE; diff --git a/src/bin/tar/lib/argp-fmtstream.c b/src/bin/tar/lib/argp-fmtstream.c deleted file mode 100644 index 0dd9256f57..0000000000 --- a/src/bin/tar/lib/argp-fmtstream.c +++ /dev/null @@ -1,435 +0,0 @@ -/* Word-wrapping and line-truncating streams - Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This package emulates glibc `line_wrap_stream' semantics for systems that - don't have that. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include - -#include "argp-fmtstream.h" -#include "argp-namefrob.h" - -#ifndef ARGP_FMTSTREAM_USE_LINEWRAP - -#ifndef isblank -#define isblank(ch) ((ch)==' ' || (ch)=='\t') -#endif - -#if defined _LIBC && defined USE_IN_LIBIO -# include -# include -# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) -#endif - -#define INIT_BUF_SIZE 200 -#define PRINTF_SIZE_GUESS 150 - -/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines - written on it with LMARGIN spaces and limits them to RMARGIN columns - total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by - replacing the whitespace before them with a newline and WMARGIN spaces. - Otherwise, chars beyond RMARGIN are simply dropped until a newline. - Returns NULL if there was an error. */ -argp_fmtstream_t -__argp_make_fmtstream (FILE *stream, - size_t lmargin, size_t rmargin, ssize_t wmargin) -{ - argp_fmtstream_t fs; - - fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream)); - if (fs != NULL) - { - fs->stream = stream; - - fs->lmargin = lmargin; - fs->rmargin = rmargin; - fs->wmargin = wmargin; - fs->point_col = 0; - fs->point_offs = 0; - - fs->buf = (char *) malloc (INIT_BUF_SIZE); - if (! fs->buf) - { - free (fs); - fs = 0; - } - else - { - fs->p = fs->buf; - fs->end = fs->buf + INIT_BUF_SIZE; - } - } - - return fs; -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_make_fmtstream, argp_make_fmtstream) -#endif -#endif - -/* Flush FS to its stream, and free it (but don't close the stream). */ -void -__argp_fmtstream_free (argp_fmtstream_t fs) -{ - __argp_fmtstream_update (fs); - if (fs->p > fs->buf) - { -#ifdef USE_IN_LIBIO - __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); -#else - fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); -#endif - } - free (fs->buf); - free (fs); -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_fmtstream_free, argp_fmtstream_free) -#endif -#endif - -/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the - end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ -void -__argp_fmtstream_update (argp_fmtstream_t fs) -{ - char *buf, *nl; - size_t len; - - /* Scan the buffer for newlines. */ - buf = fs->buf + fs->point_offs; - while (buf < fs->p) - { - size_t r; - - if (fs->point_col == 0 && fs->lmargin != 0) - { - /* We are starting a new line. Print spaces to the left margin. */ - const size_t pad = fs->lmargin; - if (fs->p + pad < fs->end) - { - /* We can fit in them in the buffer by moving the - buffer text up and filling in the beginning. */ - memmove (buf + pad, buf, fs->p - buf); - fs->p += pad; /* Compensate for bigger buffer. */ - memset (buf, ' ', pad); /* Fill in the spaces. */ - buf += pad; /* Don't bother searching them. */ - } - else - { - /* No buffer space for spaces. Must flush. */ - size_t i; - for (i = 0; i < pad; i++) - { -#ifdef USE_IN_LIBIO - if (_IO_fwide (fs->stream, 0) > 0) - putwc_unlocked (L' ', fs->stream); - else -#endif - putc_unlocked (' ', fs->stream); - } - } - fs->point_col = pad; - } - - len = fs->p - buf; - nl = memchr (buf, '\n', len); - - if (fs->point_col < 0) - fs->point_col = 0; - - if (!nl) - { - /* The buffer ends in a partial line. */ - - if (fs->point_col + len < fs->rmargin) - { - /* The remaining buffer text is a partial line and fits - within the maximum line width. Advance point for the - characters to be written and stop scanning. */ - fs->point_col += len; - break; - } - else - /* Set the end-of-line pointer for the code below to - the end of the buffer. */ - nl = fs->p; - } - else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin) - { - /* The buffer contains a full line that fits within the maximum - line width. Reset point and scan the next line. */ - fs->point_col = 0; - buf = nl + 1; - continue; - } - - /* This line is too long. */ - r = fs->rmargin - 1; - - if (fs->wmargin < 0) - { - /* Truncate the line by overwriting the excess with the - newline and anything after it in the buffer. */ - if (nl < fs->p) - { - memmove (buf + (r - fs->point_col), nl, fs->p - nl); - fs->p -= buf + (r - fs->point_col) - nl; - /* Reset point for the next line and start scanning it. */ - fs->point_col = 0; - buf += r + 1; /* Skip full line plus \n. */ - } - else - { - /* The buffer ends with a partial line that is beyond the - maximum line width. Advance point for the characters - written, and discard those past the max from the buffer. */ - fs->point_col += len; - fs->p -= fs->point_col - r; - break; - } - } - else - { - /* Do word wrap. Go to the column just past the maximum line - width and scan back for the beginning of the word there. - Then insert a line break. */ - - char *p, *nextline; - int i; - - p = buf + (r + 1 - fs->point_col); - while (p >= buf && !isblank (*p)) - --p; - nextline = p + 1; /* This will begin the next line. */ - - if (nextline > buf) - { - /* Swallow separating blanks. */ - if (p >= buf) - do - --p; - while (p >= buf && isblank (*p)); - nl = p + 1; /* The newline will replace the first blank. */ - } - else - { - /* A single word that is greater than the maximum line width. - Oh well. Put it on an overlong line by itself. */ - p = buf + (r + 1 - fs->point_col); - /* Find the end of the long word. */ - if (p < nl) - do - ++p; - while (p < nl && !isblank (*p)); - if (p == nl) - { - /* It already ends a line. No fussing required. */ - fs->point_col = 0; - buf = nl + 1; - continue; - } - /* We will move the newline to replace the first blank. */ - nl = p; - /* Swallow separating blanks. */ - do - ++p; - while (isblank (*p)); - /* The next line will start here. */ - nextline = p; - } - - /* Note: There are a bunch of tests below for - NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall - at the end of the buffer, and NEXTLINE is in fact empty (and so - we need not be careful to maintain its contents). */ - - if ((nextline == buf + len + 1 - ? fs->end - nl < fs->wmargin + 1 - : nextline - (nl + 1) < fs->wmargin) - && fs->p > nextline) - { - /* The margin needs more blanks than we removed. */ - if (fs->end - fs->p > fs->wmargin + 1) - /* Make some space for them. */ - { - size_t mv = fs->p - nextline; - memmove (nl + 1 + fs->wmargin, nextline, mv); - nextline = nl + 1 + fs->wmargin; - len = nextline + mv - buf; - *nl++ = '\n'; - } - else - /* Output the first line so we can use the space. */ - { -#ifdef _LIBC - __fxprintf (fs->stream, "%.*s\n", - (int) (nl - fs->buf), fs->buf); -#else - if (nl > fs->buf) - fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream); - putc_unlocked ('\n', fs->stream); -#endif - - len += buf - fs->buf; - nl = buf = fs->buf; - } - } - else - /* We can fit the newline and blanks in before - the next word. */ - *nl++ = '\n'; - - if (nextline - nl >= fs->wmargin - || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin)) - /* Add blanks up to the wrap margin column. */ - for (i = 0; i < fs->wmargin; ++i) - *nl++ = ' '; - else - for (i = 0; i < fs->wmargin; ++i) -#ifdef USE_IN_LIBIO - if (_IO_fwide (fs->stream, 0) > 0) - putwc_unlocked (L' ', fs->stream); - else -#endif - putc_unlocked (' ', fs->stream); - - /* Copy the tail of the original buffer into the current buffer - position. */ - if (nl < nextline) - memmove (nl, nextline, buf + len - nextline); - len -= nextline - buf; - - /* Continue the scan on the remaining lines in the buffer. */ - buf = nl; - - /* Restore bufp to include all the remaining text. */ - fs->p = nl + len; - - /* Reset the counter of what has been output this line. If wmargin - is 0, we want to avoid the lmargin getting added, so we set - point_col to a magic value of -1 in that case. */ - fs->point_col = fs->wmargin ? fs->wmargin : -1; - } - } - - /* Remember that we've scanned as far as the end of the buffer. */ - fs->point_offs = fs->p - fs->buf; -} - -/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by - growing the buffer, or by flushing it. True is returned iff we succeed. */ -int -__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) -{ - if ((size_t) (fs->end - fs->p) < amount) - { - ssize_t wrote; - - /* Flush FS's buffer. */ - __argp_fmtstream_update (fs); - -#ifdef _LIBC - __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); - wrote = fs->p - fs->buf; -#else - wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); -#endif - if (wrote == fs->p - fs->buf) - { - fs->p = fs->buf; - fs->point_offs = 0; - } - else - { - fs->p -= wrote; - fs->point_offs -= wrote; - memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf); - return 0; - } - - if ((size_t) (fs->end - fs->buf) < amount) - /* Gotta grow the buffer. */ - { - size_t old_size = fs->end - fs->buf; - size_t new_size = old_size + amount; - char *new_buf; - - if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size))) - { - __set_errno (ENOMEM); - return 0; - } - - fs->buf = new_buf; - fs->end = new_buf + new_size; - fs->p = fs->buf; - } - } - - return 1; -} - -ssize_t -__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) -{ - int out; - size_t avail; - size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ - - do - { - va_list args; - - if (! __argp_fmtstream_ensure (fs, size_guess)) - return -1; - - va_start (args, fmt); - avail = fs->end - fs->p; - out = __vsnprintf (fs->p, avail, fmt, args); - va_end (args); - if ((size_t) out >= avail) - size_guess = out + 1; - } - while ((size_t) out >= avail); - - fs->p += out; - - return out; -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) -#endif -#endif - -#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ diff --git a/src/bin/tar/lib/argp-fmtstream.h b/src/bin/tar/lib/argp-fmtstream.h deleted file mode 100644 index e045a723da..0000000000 --- a/src/bin/tar/lib/argp-fmtstream.h +++ /dev/null @@ -1,301 +0,0 @@ -/* Word-wrapping and line-truncating streams. - Copyright (C) 1997, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This package emulates glibc `line_wrap_stream' semantics for systems that - don't have that. If the system does have it, it is just a wrapper for - that. This header file is only used internally while compiling argp, and - shouldn't be installed. */ - -#ifndef _ARGP_FMTSTREAM_H -#define _ARGP_FMTSTREAM_H - -#include -#include -#include - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__ -# define __format__ format -# define __printf__ printf -# endif -#endif - -#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ - || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)) -/* line_wrap_stream is available, so use that. */ -#define ARGP_FMTSTREAM_USE_LINEWRAP -#endif - -#ifdef ARGP_FMTSTREAM_USE_LINEWRAP -/* Just be a simple wrapper for line_wrap_stream; the semantics are - *slightly* different, as line_wrap_stream doesn't actually make a new - object, it just modifies the given stream (reversibly) to do - line-wrapping. Since we control who uses this code, it doesn't matter. */ - -#include - -typedef FILE *argp_fmtstream_t; - -#define argp_make_fmtstream line_wrap_stream -#define __argp_make_fmtstream line_wrap_stream -#define argp_fmtstream_free line_unwrap_stream -#define __argp_fmtstream_free line_unwrap_stream - -#define __argp_fmtstream_putc(fs,ch) putc(ch,fs) -#define argp_fmtstream_putc(fs,ch) putc(ch,fs) -#define __argp_fmtstream_puts(fs,str) fputs(str,fs) -#define argp_fmtstream_puts(fs,str) fputs(str,fs) -#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) -#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) -#define __argp_fmtstream_printf fprintf -#define argp_fmtstream_printf fprintf - -#define __argp_fmtstream_lmargin line_wrap_lmargin -#define argp_fmtstream_lmargin line_wrap_lmargin -#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin -#define argp_fmtstream_set_lmargin line_wrap_set_lmargin -#define __argp_fmtstream_rmargin line_wrap_rmargin -#define argp_fmtstream_rmargin line_wrap_rmargin -#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin -#define argp_fmtstream_set_rmargin line_wrap_set_rmargin -#define __argp_fmtstream_wmargin line_wrap_wmargin -#define argp_fmtstream_wmargin line_wrap_wmargin -#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin -#define argp_fmtstream_set_wmargin line_wrap_set_wmargin -#define __argp_fmtstream_point line_wrap_point -#define argp_fmtstream_point line_wrap_point - -#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ -/* Guess we have to define our own version. */ - -struct argp_fmtstream -{ - FILE *stream; /* The stream we're outputting to. */ - - size_t lmargin, rmargin; /* Left and right margins. */ - ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */ - - /* Point in buffer to which we've processed for wrapping, but not output. */ - size_t point_offs; - /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */ - ssize_t point_col; - - char *buf; /* Output buffer. */ - char *p; /* Current end of text in BUF. */ - char *end; /* Absolute end of BUF. */ -}; - -typedef struct argp_fmtstream *argp_fmtstream_t; - -/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines - written on it with LMARGIN spaces and limits them to RMARGIN columns - total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by - replacing the whitespace before them with a newline and WMARGIN spaces. - Otherwise, chars beyond RMARGIN are simply dropped until a newline. - Returns NULL if there was an error. */ -extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream, - size_t __lmargin, - size_t __rmargin, - ssize_t __wmargin); -extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream, - size_t __lmargin, - size_t __rmargin, - ssize_t __wmargin); - -/* Flush __FS to its stream, and free it (but don't close the stream). */ -extern void __argp_fmtstream_free (argp_fmtstream_t __fs); -extern void argp_fmtstream_free (argp_fmtstream_t __fs); - -extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, - const char *__fmt, ...) - __attribute__ ((__format__ (printf, 2, 3))); -extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, - const char *__fmt, ...) - __attribute__ ((__format__ (printf, 2, 3))); - -extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); -extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); - -extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); -extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); - -extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len); -extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len); - -/* Access macros for various bits of state. */ -#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) -#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin) -#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin) -#define __argp_fmtstream_lmargin argp_fmtstream_lmargin -#define __argp_fmtstream_rmargin argp_fmtstream_rmargin -#define __argp_fmtstream_wmargin argp_fmtstream_wmargin - -/* Set __FS's left margin to LMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, - size_t __lmargin); -extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, - size_t __lmargin); - -/* Set __FS's right margin to __RMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, - size_t __rmargin); -extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, - size_t __rmargin); - -/* Set __FS's wrap margin to __WMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, - size_t __wmargin); -extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, - size_t __wmargin); - -/* Return the column number of the current output point in __FS. */ -extern size_t argp_fmtstream_point (argp_fmtstream_t __fs); -extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs); - -/* Internal routines. */ -extern void _argp_fmtstream_update (argp_fmtstream_t __fs); -extern void __argp_fmtstream_update (argp_fmtstream_t __fs); -extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); -extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); - -#ifdef __OPTIMIZE__ -/* Inline versions of above routines. */ - -#if !_LIBC -#define __argp_fmtstream_putc argp_fmtstream_putc -#define __argp_fmtstream_puts argp_fmtstream_puts -#define __argp_fmtstream_write argp_fmtstream_write -#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin -#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin -#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin -#define __argp_fmtstream_point argp_fmtstream_point -#define __argp_fmtstream_update _argp_fmtstream_update -#define __argp_fmtstream_ensure _argp_fmtstream_ensure -#endif - -#ifndef ARGP_FS_EI -#define ARGP_FS_EI extern inline -#endif - -ARGP_FS_EI size_t -__argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len) -{ - if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) - { - memcpy (__fs->p, __str, __len); - __fs->p += __len; - return __len; - } - else - return 0; -} - -ARGP_FS_EI int -__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str) -{ - size_t __len = strlen (__str); - if (__len) - { - size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); - return __wrote == __len ? 0 : -1; - } - else - return 0; -} - -ARGP_FS_EI int -__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) -{ - if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) - return *__fs->p++ = __ch; - else - return EOF; -} - -/* Set __FS's left margin to __LMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->lmargin; - __fs->lmargin = __lmargin; - return __old; -} - -/* Set __FS's right margin to __RMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->rmargin; - __fs->rmargin = __rmargin; - return __old; -} - -/* Set FS's wrap margin to __WMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->wmargin; - __fs->wmargin = __wmargin; - return __old; -} - -/* Return the column number of the current output point in __FS. */ -ARGP_FS_EI size_t -__argp_fmtstream_point (argp_fmtstream_t __fs) -{ - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - return __fs->point_col >= 0 ? __fs->point_col : 0; -} - -#if !_LIBC -#undef __argp_fmtstream_putc -#undef __argp_fmtstream_puts -#undef __argp_fmtstream_write -#undef __argp_fmtstream_set_lmargin -#undef __argp_fmtstream_set_rmargin -#undef __argp_fmtstream_set_wmargin -#undef __argp_fmtstream_point -#undef __argp_fmtstream_update -#undef __argp_fmtstream_ensure -#endif - -#endif /* __OPTIMIZE__ */ - -#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ - -#endif /* argp-fmtstream.h */ diff --git a/src/bin/tar/lib/argp-fs-xinl.c b/src/bin/tar/lib/argp-fs-xinl.c deleted file mode 100644 index 3b4c917e02..0000000000 --- a/src/bin/tar/lib/argp-fs-xinl.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Real definitions for extern inline functions in argp-fmtstream.h - Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#define ARGP_FS_EI -#undef __OPTIMIZE__ -#define __OPTIMIZE__ 1 -#include "argp-fmtstream.h" - -#if 0 -/* Not exported. */ -/* Add weak aliases. */ -#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias) - -weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc) -weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts) -weak_alias (__argp_fmtstream_write, argp_fmtstream_write) -weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin) -weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin) -weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin) -weak_alias (__argp_fmtstream_point, argp_fmtstream_point) - -#endif -#endif diff --git a/src/bin/tar/lib/argp-help.c b/src/bin/tar/lib/argp-help.c deleted file mode 100644 index 1a4131fd99..0000000000 --- a/src/bin/tar/lib/argp-help.c +++ /dev/null @@ -1,1954 +0,0 @@ -/* Hierarchial argument parsing help output - Copyright (C) 1995-2005, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_IN_LIBIO -# include -#endif - -#ifdef _LIBC -# include -# undef dgettext -# define dgettext(domain, msgid) \ - INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) -#else -# include "gettext.h" -#endif - -#include "argp.h" -#include "argp-fmtstream.h" -#include "argp-namefrob.h" - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* User-selectable (using an environment variable) formatting parameters. - - These may be specified in an environment variable called `ARGP_HELP_FMT', - with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2 - Where VALn must be a positive integer. The list of variables is in the - UPARAM_NAMES vector, below. */ - -/* Default parameters. */ -#define DUP_ARGS 0 /* True if option argument can be duplicated. */ -#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */ -#define SHORT_OPT_COL 2 /* column in which short options start */ -#define LONG_OPT_COL 6 /* column in which long options start */ -#define DOC_OPT_COL 2 /* column in which doc options start */ -#define OPT_DOC_COL 29 /* column in which option text starts */ -#define HEADER_COL 1 /* column in which group headers are printed */ -#define USAGE_INDENT 12 /* indentation of wrapped usage lines */ -#define RMARGIN 79 /* right margin used for wrapping */ - -/* User-selectable (using an environment variable) formatting parameters. - They must all be of type `int' for the parsing code to work. */ -struct uparams -{ - /* If true, arguments for an option are shown with both short and long - options, even when a given option has both, e.g. `-x ARG, --longx=ARG'. - If false, then if an option has both, the argument is only shown with - the long one, e.g., `-x, --longx=ARG', and a message indicating that - this really means both is printed below the options. */ - int dup_args; - - /* This is true if when DUP_ARGS is false, and some duplicate arguments have - been suppressed, an explanatory message should be printed. */ - int dup_args_note; - - /* Various output columns. */ - int short_opt_col; /* column in which short options start */ - int long_opt_col; /* column in which long options start */ - int doc_opt_col; /* column in which doc options start */ - int opt_doc_col; /* column in which option text starts */ - int header_col; /* column in which group headers are printed */ - int usage_indent; /* indentation of wrapped usage lines */ - int rmargin; /* right margin used for wrapping */ - - int valid; /* True when the values in here are valid. */ -}; - -/* This is a global variable, as user options are only ever read once. */ -static struct uparams uparams = { - DUP_ARGS, DUP_ARGS_NOTE, - SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL, - USAGE_INDENT, RMARGIN, - 0 -}; - -/* A particular uparam, and what the user name is. */ -struct uparam_name -{ - const char *name; /* User name. */ - int is_bool; /* Whether it's `boolean'. */ - size_t uparams_offs; /* Location of the (int) field in UPARAMS. */ -}; - -/* The name-field mappings we know about. */ -static const struct uparam_name uparam_names[] = -{ - { "dup-args", 1, offsetof (struct uparams, dup_args) }, - { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) }, - { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) }, - { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) }, - { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) }, - { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) }, - { "header-col", 0, offsetof (struct uparams, header_col) }, - { "usage-indent", 0, offsetof (struct uparams, usage_indent) }, - { "rmargin", 0, offsetof (struct uparams, rmargin) }, - { 0 } -}; - -static void -validate_uparams (const struct argp_state *state, struct uparams *upptr) -{ - const struct uparam_name *up; - - for (up = uparam_names; up->name; up++) - { - if (up->is_bool - || up->uparams_offs == offsetof (struct uparams, rmargin)) - continue; - if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) - { - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -ARGP_HELP_FMT: %s value is less than or equal to %s"), - "rmargin", up->name); - return; - } - } - uparams = *upptr; - uparams.valid = 1; -} - -/* Read user options from the environment, and fill in UPARAMS appropiately. */ -static void -fill_in_uparams (const struct argp_state *state) -{ - const char *var = getenv ("ARGP_HELP_FMT"); - struct uparams new_params = uparams; - -#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0); - - if (var) - { - /* Parse var. */ - while (*var) - { - SKIPWS (var); - - if (isalpha ((unsigned char) *var)) - { - size_t var_len; - const struct uparam_name *un; - int unspec = 0, val = 0; - const char *arg = var; - - while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_') - arg++; - var_len = arg - var; - - SKIPWS (arg); - - if (*arg == '\0' || *arg == ',') - unspec = 1; - else if (*arg == '=') - { - arg++; - SKIPWS (arg); - } - - if (unspec) - { - if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') - { - val = 0; - var += 3; - var_len -= 3; - } - else - val = 1; - } - else if (isdigit ((unsigned char) *arg)) - { - val = atoi (arg); - while (isdigit ((unsigned char) *arg)) - arg++; - SKIPWS (arg); - } - - for (un = uparam_names; un->name; un++) - if (strlen (un->name) == var_len - && strncmp (var, un->name, var_len) == 0) - { - if (unspec && !un->is_bool) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -%.*s: ARGP_HELP_FMT parameter requires a value"), - (int) var_len, var); - else if (val < 0) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -%.*s: ARGP_HELP_FMT parameter must be positive"), - (int) var_len, var); - else - *(int *)((char *)&new_params + un->uparams_offs) = val; - break; - } - if (! un->name) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, "\ -%.*s: Unknown ARGP_HELP_FMT parameter"), - (int) var_len, var); - - var = arg; - if (*var == ',') - var++; - } - else if (*var) - { - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "Garbage in ARGP_HELP_FMT: %s"), var); - break; - } - } - validate_uparams (state, &new_params); - } -} - -/* Returns true if OPT hasn't been marked invisible. Visibility only affects - whether OPT is displayed or used in sorting, not option shadowing. */ -#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN)) - -/* Returns true if OPT is an alias for an earlier option. */ -#define oalias(opt) ((opt)->flags & OPTION_ALIAS) - -/* Returns true if OPT is an documentation-only entry. */ -#define odoc(opt) ((opt)->flags & OPTION_DOC) - -/* Returns true if OPT should not be translated */ -#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS) - -/* Returns true if OPT is the end-of-list marker for a list of options. */ -#define oend(opt) __option_is_end (opt) - -/* Returns true if OPT has a short option. */ -#define oshort(opt) __option_is_short (opt) - -/* - The help format for a particular option is like: - - -xARG, -yARG, --long1=ARG, --long2=ARG Documentation... - - Where ARG will be omitted if there's no argument, for this option, or - will be surrounded by "[" and "]" appropiately if the argument is - optional. The documentation string is word-wrapped appropiately, and if - the list of options is long enough, it will be started on a separate line. - If there are no short options for a given option, the first long option is - indented slighly in a way that's supposed to make most long options appear - to be in a separate column. - - For example, the following output (from ps): - - -p PID, --pid=PID List the process PID - --pgrp=PGRP List processes in the process group PGRP - -P, -x, --no-parent Include processes without parents - -Q, --all-fields Don't elide unusable fields (normally if there's - some reason ps can't print a field for any - process, it's removed from the output entirely) - -r, --reverse, --gratuitously-long-reverse-option - Reverse the order of any sort - --session[=SID] Add the processes from the session SID (which - defaults to the sid of the current process) - - Here are some more options: - -f ZOT, --foonly=ZOT Glork a foonly - -z, --zaza Snit a zar - - -?, --help Give this help list - --usage Give a short usage message - -V, --version Print program version - - The struct argp_option array for the above could look like: - - { - {"pid", 'p', "PID", 0, "List the process PID"}, - {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"}, - {"no-parent", 'P', 0, 0, "Include processes without parents"}, - {0, 'x', 0, OPTION_ALIAS}, - {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" - " if there's some reason ps can't" - " print a field for any process, it's" - " removed from the output entirely)" }, - {"reverse", 'r', 0, 0, "Reverse the order of any sort"}, - {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, - {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL, - "Add the processes from the session" - " SID (which defaults to the sid of" - " the current process)" }, - - {0,0,0,0, "Here are some more options:"}, - {"foonly", 'f', "ZOT", 0, "Glork a foonly"}, - {"zaza", 'z', 0, 0, "Snit a zar"}, - - {0} - } - - Note that the last three options are automatically supplied by argp_parse, - unless you tell it not to with ARGP_NO_HELP. - -*/ - -/* Returns true if CH occurs between BEG and END. */ -static int -find_char (char ch, char *beg, char *end) -{ - while (beg < end) - if (*beg == ch) - return 1; - else - beg++; - return 0; -} - -struct hol_cluster; /* fwd decl */ - -struct hol_entry -{ - /* First option. */ - const struct argp_option *opt; - /* Number of options (including aliases). */ - unsigned num; - - /* A pointers into the HOL's short_options field, to the first short option - letter for this entry. The order of the characters following this point - corresponds to the order of options pointed to by OPT, and there are at - most NUM. A short option recorded in a option following OPT is only - valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's - probably been shadowed by some other entry). */ - char *short_options; - - /* Entries are sorted by their group first, in the order: - 1, 2, ..., n, 0, -m, ..., -2, -1 - and then alphabetically within each group. The default is 0. */ - int group; - - /* The cluster of options this entry belongs to, or 0 if none. */ - struct hol_cluster *cluster; - - /* The argp from which this option came. */ - const struct argp *argp; - - /* Position in the array */ - unsigned ord; -}; - -/* A cluster of entries to reflect the argp tree structure. */ -struct hol_cluster -{ - /* A descriptive header printed before options in this cluster. */ - const char *header; - - /* Used to order clusters within the same group with the same parent, - according to the order in which they occurred in the parent argp's child - list. */ - int index; - - /* How to sort this cluster with respect to options and other clusters at the - same depth (clusters always follow options in the same group). */ - int group; - - /* The cluster to which this cluster belongs, or 0 if it's at the base - level. */ - struct hol_cluster *parent; - - /* The argp from which this cluster is (eventually) derived. */ - const struct argp *argp; - - /* The distance this cluster is from the root. */ - int depth; - - /* Clusters in a given hol are kept in a linked list, to make freeing them - possible. */ - struct hol_cluster *next; -}; - -/* A list of options for help. */ -struct hol -{ - /* An array of hol_entry's. */ - struct hol_entry *entries; - /* The number of entries in this hol. If this field is zero, the others - are undefined. */ - unsigned num_entries; - - /* A string containing all short options in this HOL. Each entry contains - pointers into this string, so the order can't be messed with blindly. */ - char *short_options; - - /* Clusters of entries in this hol. */ - struct hol_cluster *clusters; -}; - -/* Create a struct hol from the options in ARGP. CLUSTER is the - hol_cluster in which these entries occur, or 0, if at the root. */ -static struct hol * -make_hol (const struct argp *argp, struct hol_cluster *cluster) -{ - char *so; - const struct argp_option *o; - const struct argp_option *opts = argp->options; - struct hol_entry *entry; - unsigned num_short_options = 0; - struct hol *hol = malloc (sizeof (struct hol)); - - assert (hol); - - hol->num_entries = 0; - hol->clusters = 0; - - if (opts) - { - int cur_group = 0; - - /* The first option must not be an alias. */ - assert (! oalias (opts)); - - /* Calculate the space needed. */ - for (o = opts; ! oend (o); o++) - { - if (! oalias (o)) - hol->num_entries++; - if (oshort (o)) - num_short_options++; /* This is an upper bound. */ - } - - hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries); - hol->short_options = malloc (num_short_options + 1); - - assert (hol->entries && hol->short_options); - if (SIZE_MAX <= UINT_MAX) - assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry)); - - /* Fill in the entries. */ - so = hol->short_options; - for (o = opts, entry = hol->entries; ! oend (o); entry++) - { - entry->opt = o; - entry->num = 0; - entry->short_options = so; - entry->group = cur_group = - o->group - ? o->group - : ((!o->name && !o->key) - ? cur_group + 1 - : cur_group); - entry->cluster = cluster; - entry->argp = argp; - - do - { - entry->num++; - if (oshort (o) && ! find_char (o->key, hol->short_options, so)) - /* O has a valid short option which hasn't already been used.*/ - *so++ = o->key; - o++; - } - while (! oend (o) && oalias (o)); - } - *so = '\0'; /* null terminated so we can find the length */ - } - - return hol; -} - -/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the - associated argp child list entry), INDEX, and PARENT, and return a pointer - to it. ARGP is the argp that this cluster results from. */ -static struct hol_cluster * -hol_add_cluster (struct hol *hol, int group, const char *header, int index, - struct hol_cluster *parent, const struct argp *argp) -{ - struct hol_cluster *cl = malloc (sizeof (struct hol_cluster)); - if (cl) - { - cl->group = group; - cl->header = header; - - cl->index = index; - cl->parent = parent; - cl->argp = argp; - cl->depth = parent ? parent->depth + 1 : 0; - - cl->next = hol->clusters; - hol->clusters = cl; - } - return cl; -} - -/* Free HOL and any resources it uses. */ -static void -hol_free (struct hol *hol) -{ - struct hol_cluster *cl = hol->clusters; - - while (cl) - { - struct hol_cluster *next = cl->next; - free (cl); - cl = next; - } - - if (hol->num_entries > 0) - { - free (hol->entries); - free (hol->short_options); - } - - free (hol); -} - -static int -hol_entry_short_iterate (const struct hol_entry *entry, - int (*func)(const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie), - const char *domain, void *cookie) -{ - unsigned nopts; - int val = 0; - const struct argp_option *opt, *real = entry->opt; - char *so = entry->short_options; - - for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) - if (oshort (opt) && *so == opt->key) - { - if (!oalias (opt)) - real = opt; - if (ovisible (opt)) - val = (*func)(opt, real, domain, cookie); - so++; - } - - return val; -} - -static inline int -__attribute__ ((always_inline)) -hol_entry_long_iterate (const struct hol_entry *entry, - int (*func)(const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie), - const char *domain, void *cookie) -{ - unsigned nopts; - int val = 0; - const struct argp_option *opt, *real = entry->opt; - - for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) - if (opt->name) - { - if (!oalias (opt)) - real = opt; - if (ovisible (opt)) - val = (*func)(opt, real, domain, cookie); - } - - return val; -} - -/* Iterator that returns true for the first short option. */ -static int -until_short (const struct argp_option *opt, const struct argp_option *real, - const char *domain, void *cookie) -{ - return oshort (opt) ? opt->key : 0; -} - -/* Returns the first valid short option in ENTRY, or 0 if there is none. */ -static char -hol_entry_first_short (const struct hol_entry *entry) -{ - return hol_entry_short_iterate (entry, until_short, - entry->argp->argp_domain, 0); -} - -/* Returns the first valid long option in ENTRY, or 0 if there is none. */ -static const char * -hol_entry_first_long (const struct hol_entry *entry) -{ - const struct argp_option *opt; - unsigned num; - for (opt = entry->opt, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - return opt->name; - return 0; -} - -/* Returns the entry in HOL with the long option name NAME, or 0 if there is - none. */ -static struct hol_entry * -hol_find_entry (struct hol *hol, const char *name) -{ - struct hol_entry *entry = hol->entries; - unsigned num_entries = hol->num_entries; - - while (num_entries-- > 0) - { - const struct argp_option *opt = entry->opt; - unsigned num_opts = entry->num; - - while (num_opts-- > 0) - if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0) - return entry; - else - opt++; - - entry++; - } - - return 0; -} - -/* If an entry with the long option NAME occurs in HOL, set it's special - sort position to GROUP. */ -static void -hol_set_group (struct hol *hol, const char *name, int group) -{ - struct hol_entry *entry = hol_find_entry (hol, name); - if (entry) - entry->group = group; -} - -/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. - EQ is what to return if GROUP1 and GROUP2 are the same. */ -static int -group_cmp (int group1, int group2, int eq) -{ - if (group1 == group2) - return eq; - else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0)) - return group1 - group2; - else - return group2 - group1; -} - -/* Compare clusters CL1 & CL2 by the order that they should appear in - output. */ -static int -hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2) -{ - /* If one cluster is deeper than the other, use its ancestor at the same - level, so that finding the common ancestor is straightforward. - - clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */ - while (cl1->depth > cl2->depth) - cl1 = cl1->parent; - while (cl2->depth > cl1->depth) - cl2 = cl2->parent; - - /* Now reduce both clusters to their ancestors at the point where both have - a common parent; these can be directly compared. */ - while (cl1->parent != cl2->parent) - cl1 = cl1->parent, cl2 = cl2->parent; - - return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index); -} - -/* Return the ancestor of CL that's just below the root (i.e., has a parent - of 0). */ -static struct hol_cluster * -hol_cluster_base (struct hol_cluster *cl) -{ - while (cl->parent) - cl = cl->parent; - return cl; -} - -/* Return true if CL1 is a child of CL2. */ -static int -hol_cluster_is_child (const struct hol_cluster *cl1, - const struct hol_cluster *cl2) -{ - while (cl1 && cl1 != cl2) - cl1 = cl1->parent; - return cl1 == cl2; -} - -/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail - that should be used for comparisons, and returns true iff it should be - treated as a non-option. */ -static int -canon_doc_option (const char **name) -{ - int non_opt; - - if (!*name) - non_opt = 1; - else - { - /* Skip initial whitespace. */ - while (isspace ((unsigned char) **name)) - (*name)++; - /* Decide whether this looks like an option (leading `-') or not. */ - non_opt = (**name != '-'); - /* Skip until part of name used for sorting. */ - while (**name && !isalnum ((unsigned char) **name)) - (*name)++; - } - return non_opt; -} - -#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1) - -/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help - listing. */ -static int -hol_entry_cmp (const struct hol_entry *entry1, - const struct hol_entry *entry2) -{ - /* The group numbers by which the entries should be ordered; if either is - in a cluster, then this is just the group within the cluster. */ - int group1 = entry1->group, group2 = entry2->group; - int rc; - - if (entry1->cluster != entry2->cluster) - { - /* The entries are not within the same cluster, so we can't compare them - directly, we have to use the appropiate clustering level too. */ - if (! entry1->cluster) - /* ENTRY1 is at the `base level', not in a cluster, so we have to - compare it's group number with that of the base cluster in which - ENTRY2 resides. Note that if they're in the same group, the - clustered option always comes laster. */ - return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1); - else if (! entry2->cluster) - /* Likewise, but ENTRY2's not in a cluster. */ - return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1); - else - /* Both entries are in clusters, we can just compare the clusters. */ - return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ? - rc : HOL_ENTRY_PTRCMP(entry1, entry2); - } - else if (group1 == group2) - /* The entries are both in the same cluster and group, so compare them - alphabetically. */ - { - int short1 = hol_entry_first_short (entry1); - int short2 = hol_entry_first_short (entry2); - int doc1 = odoc (entry1->opt); - int doc2 = odoc (entry2->opt); - const char *long1 = hol_entry_first_long (entry1); - const char *long2 = hol_entry_first_long (entry2); - - if (doc1) - doc1 = canon_doc_option (&long1); - if (doc2) - doc2 = canon_doc_option (&long2); - - if (doc1 != doc2) - /* `documentation' options always follow normal options (or - documentation options that *look* like normal options). */ - return doc1 - doc2; - else if (!short1 && !short2 && long1 && long2) - /* Only long options. */ - return (rc = __strcasecmp (long1, long2)) ? - rc : HOL_ENTRY_PTRCMP(entry1, entry2); - else - /* Compare short/short, long/short, short/long, using the first - character of long options. Entries without *any* valid - options (such as options with OPTION_HIDDEN set) will be put - first, but as they're not displayed, it doesn't matter where - they are. */ - { - char first1 = short1 ? short1 : long1 ? *long1 : 0; - char first2 = short2 ? short2 : long2 ? *long2 : 0; -#ifdef _tolower - int lower_cmp = _tolower (first1) - _tolower (first2); -#else - int lower_cmp = tolower (first1) - tolower (first2); -#endif - /* Compare ignoring case, except when the options are both the - same letter, in which case lower-case always comes first. */ - return lower_cmp ? lower_cmp : - (rc = first2 - first1) ? - rc : HOL_ENTRY_PTRCMP(entry1, entry2); - } - } - else - /* Within the same cluster, but not the same group, so just compare - groups. */ - return group_cmp (group1, group2, HOL_ENTRY_PTRCMP(entry1, entry2)); -} - -/* Version of hol_entry_cmp with correct signature for qsort. */ -static int -hol_entry_qcmp (const void *entry1_v, const void *entry2_v) -{ - return hol_entry_cmp (entry1_v, entry2_v); -} - -/* Sort HOL by group and alphabetically by option name (with short options - taking precedence over long). Since the sorting is for display purposes - only, the shadowing of options isn't effected. */ -static void -hol_sort (struct hol *hol) -{ - if (hol->num_entries > 0) - { - unsigned i; - struct hol_entry *e; - for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++) - e->ord = i; - qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry), - hol_entry_qcmp); - } -} - -/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow - any in MORE with the same name. */ -static void -hol_append (struct hol *hol, struct hol *more) -{ - struct hol_cluster **cl_end = &hol->clusters; - - /* Steal MORE's cluster list, and add it to the end of HOL's. */ - while (*cl_end) - cl_end = &(*cl_end)->next; - *cl_end = more->clusters; - more->clusters = 0; - - /* Merge entries. */ - if (more->num_entries > 0) - { - if (hol->num_entries == 0) - { - hol->num_entries = more->num_entries; - hol->entries = more->entries; - hol->short_options = more->short_options; - more->num_entries = 0; /* Mark MORE's fields as invalid. */ - } - else - /* Append the entries in MORE to those in HOL, taking care to only add - non-shadowed SHORT_OPTIONS values. */ - { - unsigned left; - char *so, *more_so; - struct hol_entry *e; - unsigned num_entries = hol->num_entries + more->num_entries; - struct hol_entry *entries = - malloc (num_entries * sizeof (struct hol_entry)); - unsigned hol_so_len = strlen (hol->short_options); - char *short_options = - malloc (hol_so_len + strlen (more->short_options) + 1); - - assert (entries && short_options); - if (SIZE_MAX <= UINT_MAX) - assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry)); - - __mempcpy (__mempcpy (entries, hol->entries, - hol->num_entries * sizeof (struct hol_entry)), - more->entries, - more->num_entries * sizeof (struct hol_entry)); - - __mempcpy (short_options, hol->short_options, hol_so_len); - - /* Fix up the short options pointers from HOL. */ - for (e = entries, left = hol->num_entries; left > 0; e++, left--) - e->short_options += (short_options - hol->short_options); - - /* Now add the short options from MORE, fixing up its entries - too. */ - so = short_options + hol_so_len; - more_so = more->short_options; - for (left = more->num_entries; left > 0; e++, left--) - { - int opts_left; - const struct argp_option *opt; - - e->short_options = so; - - for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--) - { - int ch = *more_so; - if (oshort (opt) && ch == opt->key) - /* The next short option in MORE_SO, CH, is from OPT. */ - { - if (! find_char (ch, short_options, - short_options + hol_so_len)) - /* The short option CH isn't shadowed by HOL's options, - so add it to the sum. */ - *so++ = ch; - more_so++; - } - } - } - - *so = '\0'; - - free (hol->entries); - free (hol->short_options); - - hol->entries = entries; - hol->num_entries = num_entries; - hol->short_options = short_options; - } - } - - hol_free (more); -} - -/* Inserts enough spaces to make sure STREAM is at column COL. */ -static void -indent_to (argp_fmtstream_t stream, unsigned col) -{ - int needed = col - __argp_fmtstream_point (stream); - while (needed-- > 0) - __argp_fmtstream_putc (stream, ' '); -} - -/* Output to STREAM either a space, or a newline if there isn't room for at - least ENSURE characters before the right margin. */ -static void -space (argp_fmtstream_t stream, size_t ensure) -{ - if (__argp_fmtstream_point (stream) + ensure - >= __argp_fmtstream_rmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - else - __argp_fmtstream_putc (stream, ' '); -} - -/* If the option REAL has an argument, we print it in using the printf - format REQ_FMT or OPT_FMT depending on whether it's a required or - optional argument. */ -static void -arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt, - const char *domain, argp_fmtstream_t stream) -{ - if (real->arg) - { - if (real->flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, opt_fmt, - dgettext (domain, real->arg)); - else - __argp_fmtstream_printf (stream, req_fmt, - dgettext (domain, real->arg)); - } -} - -/* Helper functions for hol_entry_help. */ - -/* State used during the execution of hol_help. */ -struct hol_help_state -{ - /* PREV_ENTRY should contain the previous entry printed, or 0. */ - struct hol_entry *prev_entry; - - /* If an entry is in a different group from the previous one, and SEP_GROUPS - is true, then a blank line will be printed before any output. */ - int sep_groups; - - /* True if a duplicate option argument was suppressed (only ever set if - UPARAMS.dup_args is false). */ - int suppressed_dup_arg; -}; - -/* Some state used while printing a help entry (used to communicate with - helper functions). See the doc for hol_entry_help for more info, as most - of the fields are copied from its arguments. */ -struct pentry_state -{ - const struct hol_entry *entry; - argp_fmtstream_t stream; - struct hol_help_state *hhstate; - - /* True if nothing's been printed so far. */ - int first; - - /* If non-zero, the state that was used to print this help. */ - const struct argp_state *state; -}; - -/* If a user doc filter should be applied to DOC, do so. */ -static const char * -filter_doc (const char *doc, int key, const struct argp *argp, - const struct argp_state *state) -{ - if (argp->help_filter) - /* We must apply a user filter to this output. */ - { - void *input = __argp_input (argp, state); - return (*argp->help_filter) (key, doc, input); - } - else - /* No filter. */ - return doc; -} - -/* Prints STR as a header line, with the margin lines set appropiately, and - notes the fact that groups should be separated with a blank line. ARGP is - the argp that should dictate any user doc filtering to take place. Note - that the previous wrap margin isn't restored, but the left margin is reset - to 0. */ -static void -print_header (const char *str, const struct argp *argp, - struct pentry_state *pest) -{ - const char *tstr = dgettext (argp->argp_domain, str); - const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state); - - if (fstr) - { - if (*fstr) - { - if (pest->hhstate->prev_entry) - /* Precede with a blank line. */ - __argp_fmtstream_putc (pest->stream, '\n'); - indent_to (pest->stream, uparams.header_col); - __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col); - __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col); - __argp_fmtstream_puts (pest->stream, fstr); - __argp_fmtstream_set_lmargin (pest->stream, 0); - __argp_fmtstream_putc (pest->stream, '\n'); - } - - pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */ - } - - if (fstr != tstr) - free ((char *) fstr); -} - -/* Inserts a comma if this isn't the first item on the line, and then makes - sure we're at least to column COL. If this *is* the first item on a line, - prints any pending whitespace/headers that should precede this line. Also - clears FIRST. */ -static void -comma (unsigned col, struct pentry_state *pest) -{ - if (pest->first) - { - const struct hol_entry *pe = pest->hhstate->prev_entry; - const struct hol_cluster *cl = pest->entry->cluster; - - if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group) - __argp_fmtstream_putc (pest->stream, '\n'); - - if (cl && cl->header && *cl->header - && (!pe - || (pe->cluster != cl - && !hol_cluster_is_child (pe->cluster, cl)))) - /* If we're changing clusters, then this must be the start of the - ENTRY's cluster unless that is an ancestor of the previous one - (in which case we had just popped into a sub-cluster for a bit). - If so, then print the cluster's header line. */ - { - int old_wm = __argp_fmtstream_wmargin (pest->stream); - print_header (cl->header, cl->argp, pest); - __argp_fmtstream_set_wmargin (pest->stream, old_wm); - } - - pest->first = 0; - } - else - __argp_fmtstream_puts (pest->stream, ", "); - - indent_to (pest->stream, col); -} - -/* Print help for ENTRY to STREAM. */ -static void -hol_entry_help (struct hol_entry *entry, const struct argp_state *state, - argp_fmtstream_t stream, struct hol_help_state *hhstate) -{ - unsigned num; - const struct argp_option *real = entry->opt, *opt; - char *so = entry->short_options; - int have_long_opt = 0; /* We have any long options. */ - /* Saved margins. */ - int old_lm = __argp_fmtstream_set_lmargin (stream, 0); - int old_wm = __argp_fmtstream_wmargin (stream); - /* PEST is a state block holding some of our variables that we'd like to - share with helper functions. */ - struct pentry_state pest; - - pest.entry = entry; - pest.stream = stream; - pest.hhstate = hhstate; - pest.first = 1; - pest.state = state; - - if (! odoc (real)) - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - { - have_long_opt = 1; - break; - } - - /* First emit short options. */ - __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */ - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (oshort (opt) && opt->key == *so) - /* OPT has a valid (non shadowed) short option. */ - { - if (ovisible (opt)) - { - comma (uparams.short_opt_col, &pest); - __argp_fmtstream_putc (stream, '-'); - __argp_fmtstream_putc (stream, *so); - if (!have_long_opt || uparams.dup_args) - arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream); - else if (real->arg) - hhstate->suppressed_dup_arg = 1; - } - so++; - } - - /* Now, long options. */ - if (odoc (real)) - /* A `documentation' option. */ - { - __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && *opt->name && ovisible (opt)) - { - comma (uparams.doc_opt_col, &pest); - /* Calling dgettext here isn't quite right, since sorting will - have been done on the original; but documentation options - should be pretty rare anyway... */ - __argp_fmtstream_puts (stream, - onotrans (opt) ? - opt->name : - dgettext (state->root_argp->argp_domain, - opt->name)); - } - } - else - /* A real long option. */ - { - int first_long_opt = 1; - - __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col); - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - { - comma (uparams.long_opt_col, &pest); - __argp_fmtstream_printf (stream, "--%s", opt->name); - if (first_long_opt || uparams.dup_args) - arg (real, "=%s", "[=%s]", state->root_argp->argp_domain, - stream); - else if (real->arg) - hhstate->suppressed_dup_arg = 1; - } - } - - /* Next, documentation strings. */ - __argp_fmtstream_set_lmargin (stream, 0); - - if (pest.first) - { - /* Didn't print any switches, what's up? */ - if (!oshort (real) && !real->name) - /* This is a group header, print it nicely. */ - print_header (real->doc, entry->argp, &pest); - else - /* Just a totally shadowed option or null header; print nothing. */ - goto cleanup; /* Just return, after cleaning up. */ - } - else - { - const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain, - real->doc) : 0; - const char *fstr = filter_doc (tstr, real->key, entry->argp, state); - if (fstr && *fstr) - { - unsigned int col = __argp_fmtstream_point (stream); - - __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col); - __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col); - - if (col > (unsigned int) (uparams.opt_doc_col + 3)) - __argp_fmtstream_putc (stream, '\n'); - else if (col >= (unsigned int) uparams.opt_doc_col) - __argp_fmtstream_puts (stream, " "); - else - indent_to (stream, uparams.opt_doc_col); - - __argp_fmtstream_puts (stream, fstr); - } - if (fstr && fstr != tstr) - free ((char *) fstr); - - /* Reset the left margin. */ - __argp_fmtstream_set_lmargin (stream, 0); - __argp_fmtstream_putc (stream, '\n'); - } - - hhstate->prev_entry = entry; - -cleanup: - __argp_fmtstream_set_lmargin (stream, old_lm); - __argp_fmtstream_set_wmargin (stream, old_wm); -} - -/* Output a long help message about the options in HOL to STREAM. */ -static void -hol_help (struct hol *hol, const struct argp_state *state, - argp_fmtstream_t stream) -{ - unsigned num; - struct hol_entry *entry; - struct hol_help_state hhstate = { 0, 0, 0 }; - - for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--) - hol_entry_help (entry, state, stream, &hhstate); - - if (hhstate.suppressed_dup_arg && uparams.dup_args_note) - { - const char *tstr = dgettext (state->root_argp->argp_domain, "\ -Mandatory or optional arguments to long options are also mandatory or \ -optional for any corresponding short options."); - const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE, - state ? state->root_argp : 0, state); - if (fstr && *fstr) - { - __argp_fmtstream_putc (stream, '\n'); - __argp_fmtstream_puts (stream, fstr); - __argp_fmtstream_putc (stream, '\n'); - } - if (fstr && fstr != tstr) - free ((char *) fstr); - } -} - -/* Helper functions for hol_usage. */ - -/* If OPT is a short option without an arg, append its key to the string - pointer pointer to by COOKIE, and advance the pointer. */ -static int -add_argless_short_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - char **snao_end = cookie; - if (!(opt->arg || real->arg) - && !((opt->flags | real->flags) & OPTION_NO_USAGE)) - *(*snao_end)++ = opt->key; - return 0; -} - -/* If OPT is a short option with an arg, output a usage entry for it to the - stream pointed at by COOKIE. */ -static int -usage_argful_short_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - argp_fmtstream_t stream = cookie; - const char *arg = opt->arg; - int flags = opt->flags | real->flags; - - if (! arg) - arg = real->arg; - - if (arg && !(flags & OPTION_NO_USAGE)) - { - arg = dgettext (domain, arg); - - if (flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg); - else - { - /* Manually do line wrapping so that it (probably) won't - get wrapped at the embedded space. */ - space (stream, 6 + strlen (arg)); - __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg); - } - } - - return 0; -} - -/* Output a usage entry for the long option opt to the stream pointed at by - COOKIE. */ -static int -usage_long_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - argp_fmtstream_t stream = cookie; - const char *arg = opt->arg; - int flags = opt->flags | real->flags; - - if (! arg) - arg = real->arg; - - if (! (flags & OPTION_NO_USAGE) && !odoc (opt)) - { - if (arg) - { - arg = dgettext (domain, arg); - if (flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg); - else - __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg); - } - else - __argp_fmtstream_printf (stream, " [--%s]", opt->name); - } - - return 0; -} - -/* Print a short usage description for the arguments in HOL to STREAM. */ -static void -hol_usage (struct hol *hol, argp_fmtstream_t stream) -{ - if (hol->num_entries > 0) - { - unsigned nentries; - struct hol_entry *entry; - char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1); - char *snao_end = short_no_arg_opts; - - /* First we put a list of short options without arguments. */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_short_iterate (entry, add_argless_short_opt, - entry->argp->argp_domain, &snao_end); - if (snao_end > short_no_arg_opts) - { - *snao_end++ = 0; - __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts); - } - - /* Now a list of short options *with* arguments. */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_short_iterate (entry, usage_argful_short_opt, - entry->argp->argp_domain, stream); - - /* Finally, a list of long options (whew!). */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_long_iterate (entry, usage_long_opt, - entry->argp->argp_domain, stream); - } -} - -/* Make a HOL containing all levels of options in ARGP. CLUSTER is the - cluster in which ARGP's entries should be clustered, or 0. */ -static struct hol * -argp_hol (const struct argp *argp, struct hol_cluster *cluster) -{ - const struct argp_child *child = argp->children; - struct hol *hol = make_hol (argp, cluster); - if (child) - while (child->argp) - { - struct hol_cluster *child_cluster = - ((child->group || child->header) - /* Put CHILD->argp within its own cluster. */ - ? hol_add_cluster (hol, child->group, child->header, - child - argp->children, cluster, argp) - /* Just merge it into the parent's cluster. */ - : cluster); - hol_append (hol, argp_hol (child->argp, child_cluster)) ; - child++; - } - return hol; -} - -/* Calculate how many different levels with alternative args strings exist in - ARGP. */ -static size_t -argp_args_levels (const struct argp *argp) -{ - size_t levels = 0; - const struct argp_child *child = argp->children; - - if (argp->args_doc && strchr (argp->args_doc, '\n')) - levels++; - - if (child) - while (child->argp) - levels += argp_args_levels ((child++)->argp); - - return levels; -} - -/* Print all the non-option args documented in ARGP to STREAM. Any output is - preceded by a space. LEVELS is a pointer to a byte vector the length - returned by argp_args_levels; it should be initialized to zero, and - updated by this routine for the next call if ADVANCE is true. True is - returned as long as there are more patterns to output. */ -static int -argp_args_usage (const struct argp *argp, const struct argp_state *state, - char **levels, int advance, argp_fmtstream_t stream) -{ - char *our_level = *levels; - int multiple = 0; - const struct argp_child *child = argp->children; - const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0; - const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state); - - if (fdoc) - { - const char *cp = fdoc; - nl = __strchrnul (cp, '\n'); - if (*nl != '\0') - /* This is a `multi-level' args doc; advance to the correct position - as determined by our state in LEVELS, and update LEVELS. */ - { - int i; - multiple = 1; - for (i = 0; i < *our_level; i++) - cp = nl + 1, nl = __strchrnul (cp, '\n'); - (*levels)++; - } - - /* Manually do line wrapping so that it (probably) won't get wrapped at - any embedded spaces. */ - space (stream, 1 + nl - cp); - - __argp_fmtstream_write (stream, cp, nl - cp); - } - if (fdoc && fdoc != tdoc) - free ((char *)fdoc); /* Free user's modified doc string. */ - - if (child) - while (child->argp) - advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream); - - if (advance && multiple) - { - /* Need to increment our level. */ - if (*nl) - /* There's more we can do here. */ - { - (*our_level)++; - advance = 0; /* Our parent shouldn't advance also. */ - } - else if (*our_level > 0) - /* We had multiple levels, but used them up; reset to zero. */ - *our_level = 0; - } - - return !advance; -} - -/* Print the documentation for ARGP to STREAM; if POST is false, then - everything preceeding a `\v' character in the documentation strings (or - the whole string, for those with none) is printed, otherwise, everything - following the `\v' character (nothing for strings without). Each separate - bit of documentation is separated a blank line, and if PRE_BLANK is true, - then the first is as well. If FIRST_ONLY is true, only the first - occurrence is output. Returns true if anything was output. */ -static int -argp_doc (const struct argp *argp, const struct argp_state *state, - int post, int pre_blank, int first_only, - argp_fmtstream_t stream) -{ - const char *text; - const char *inp_text; - size_t inp_text_len = 0; - const char *trans_text; - void *input = 0; - int anything = 0; - const struct argp_child *child = argp->children; - - if (argp->doc) - { - char *vt = strchr (argp->doc, '\v'); - if (vt) - { - if (post) - inp_text = vt + 1; - else - { - inp_text_len = vt - argp->doc; - inp_text = __strndup (argp->doc, inp_text_len); - } - } - else - inp_text = post ? 0 : argp->doc; - trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL; - } - else - trans_text = inp_text = 0; - - if (argp->help_filter) - /* We have to filter the doc strings. */ - { - input = __argp_input (argp, state); - text = - (*argp->help_filter) (post - ? ARGP_KEY_HELP_POST_DOC - : ARGP_KEY_HELP_PRE_DOC, - trans_text, input); - } - else - text = (const char *) trans_text; - - if (text) - { - if (pre_blank) - __argp_fmtstream_putc (stream, '\n'); - - __argp_fmtstream_puts (stream, text); - - if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - - anything = 1; - } - - if (text && text != trans_text) - free ((char *) text); /* Free TEXT returned from the help filter. */ - - if (inp_text && inp_text_len) - free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */ - - if (post && argp->help_filter) - /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */ - { - text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input); - if (text) - { - if (anything || pre_blank) - __argp_fmtstream_putc (stream, '\n'); - __argp_fmtstream_puts (stream, text); - free ((char *) text); - if (__argp_fmtstream_point (stream) - > __argp_fmtstream_lmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - anything = 1; - } - } - - if (child) - while (child->argp && !(first_only && anything)) - anything |= - argp_doc ((child++)->argp, state, - post, anything || pre_blank, first_only, - stream); - - return anything; -} - -/* Output a usage message for ARGP to STREAM. If called from - argp_state_help, STATE is the relevent parsing state. FLAGS are from the - set ARGP_HELP_*. NAME is what to use wherever a `program name' is - needed. */ -static void -_help (const struct argp *argp, const struct argp_state *state, FILE *stream, - unsigned flags, char *name) -{ - int anything = 0; /* Whether we've output anything. */ - struct hol *hol = 0; - argp_fmtstream_t fs; - - if (! stream) - return; - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - - if (! uparams.valid) - fill_in_uparams (state); - - fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); - if (! fs) - { -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - return; - } - - if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG)) - { - hol = argp_hol (argp, 0); - - /* If present, these options always come last. */ - hol_set_group (hol, "help", -1); - hol_set_group (hol, "version", -1); - - hol_sort (hol); - } - - if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE)) - /* Print a short `Usage:' message. */ - { - int first_pattern = 1, more_patterns; - size_t num_pattern_levels = argp_args_levels (argp); - char *pattern_levels = alloca (num_pattern_levels); - - memset (pattern_levels, 0, num_pattern_levels); - - do - { - int old_lm; - int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent); - char *levels = pattern_levels; - - if (first_pattern) - __argp_fmtstream_printf (fs, "%s %s", - dgettext (argp->argp_domain, "Usage:"), - name); - else - __argp_fmtstream_printf (fs, "%s %s", - dgettext (argp->argp_domain, " or: "), - name); - - /* We set the lmargin as well as the wmargin, because hol_usage - manually wraps options with newline to avoid annoying breaks. */ - old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent); - - if (flags & ARGP_HELP_SHORT_USAGE) - /* Just show where the options go. */ - { - if (hol->num_entries > 0) - __argp_fmtstream_puts (fs, dgettext (argp->argp_domain, - " [OPTION...]")); - } - else - /* Actually print the options. */ - { - hol_usage (hol, fs); - flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */ - } - - more_patterns = argp_args_usage (argp, state, &levels, 1, fs); - - __argp_fmtstream_set_wmargin (fs, old_wm); - __argp_fmtstream_set_lmargin (fs, old_lm); - - __argp_fmtstream_putc (fs, '\n'); - anything = 1; - - first_pattern = 0; - } - while (more_patterns); - } - - if (flags & ARGP_HELP_PRE_DOC) - anything |= argp_doc (argp, state, 0, 0, 1, fs); - - if (flags & ARGP_HELP_SEE) - { - __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\ -Try `%s --help' or `%s --usage' for more information.\n"), - name, name); - anything = 1; - } - - if (flags & ARGP_HELP_LONG) - /* Print a long, detailed help message. */ - { - /* Print info about all the options. */ - if (hol->num_entries > 0) - { - if (anything) - __argp_fmtstream_putc (fs, '\n'); - hol_help (hol, state, fs); - anything = 1; - } - } - - if (flags & ARGP_HELP_POST_DOC) - /* Print any documentation strings at the end. */ - anything |= argp_doc (argp, state, 1, anything, 0, fs); - - if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address) - { - if (anything) - __argp_fmtstream_putc (fs, '\n'); - __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, - "Report bugs to %s.\n"), - argp_program_bug_address); - anything = 1; - } - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - - if (hol) - hol_free (hol); - - __argp_fmtstream_free (fs); -} - -/* Output a usage message for ARGP to STREAM. FLAGS are from the set - ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */ -void __argp_help (const struct argp *argp, FILE *stream, - unsigned flags, char *name) -{ - struct argp_state state; - memset (&state, 0, sizeof state); - state.root_argp = argp; - _help (argp, &state, stream, flags, name); -} -#ifdef weak_alias -weak_alias (__argp_help, argp_help) -#endif - -#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME) -char * -__argp_short_program_name (void) -{ -# if HAVE_DECL_PROGRAM_INVOCATION_NAME - return __argp_base_name (program_invocation_name); -# else - /* FIXME: What now? Miles suggests that it is better to use NULL, - but currently the value is passed on directly to fputs_unlocked, - so that requires more changes. */ -# if __GNUC__ -# warning No reasonable value to return -# endif /* __GNUC__ */ - return ""; -# endif -} -#endif - -/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are - from the set ARGP_HELP_*. */ -void -__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) -{ - if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream) - { - if (state && (state->flags & ARGP_LONG_ONLY)) - flags |= ARGP_HELP_LONG_ONLY; - - _help (state ? state->root_argp : 0, state, stream, flags, - state ? state->name : __argp_short_program_name ()); - - if (!state || ! (state->flags & ARGP_NO_EXIT)) - { - if (flags & ARGP_HELP_EXIT_ERR) - exit (argp_err_exit_status); - if (flags & ARGP_HELP_EXIT_OK) - exit (0); - } - } -} -#ifdef weak_alias -weak_alias (__argp_state_help, argp_state_help) -#endif - -/* If appropriate, print the printf string FMT and following args, preceded - by the program name and `:', to stderr, and followed by a `Try ... --help' - message, then exit (1). */ -void -__argp_error (const struct argp_state *state, const char *fmt, ...) -{ - if (!state || !(state->flags & ARGP_NO_ERRS)) - { - FILE *stream = state ? state->err_stream : stderr; - - if (stream) - { - va_list ap; - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - - va_start (ap, fmt); - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - { - char *buf; - - if (__asprintf (&buf, fmt, ap) < 0) - buf = NULL; - - __fwprintf (stream, L"%s: %s\n", - state ? state->name : __argp_short_program_name (), - buf); - - free (buf); - } - else -#endif - { - fputs_unlocked (state - ? state->name : __argp_short_program_name (), - stream); - putc_unlocked (':', stream); - putc_unlocked (' ', stream); - - vfprintf (stream, fmt, ap); - - putc_unlocked ('\n', stream); - } - - __argp_state_help (state, stream, ARGP_HELP_STD_ERR); - - va_end (ap); - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - } - } -} -#ifdef weak_alias -weak_alias (__argp_error, argp_error) -#endif - -/* Similar to the standard gnu error-reporting function error(), but will - respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print - to STATE->err_stream. This is useful for argument parsing code that is - shared between program startup (when exiting is desired) and runtime - option parsing (when typically an error code is returned instead). The - difference between this function and argp_error is that the latter is for - *parsing errors*, and the former is for other problems that occur during - parsing but don't reflect a (syntactic) problem with the input. */ -void -__argp_failure (const struct argp_state *state, int status, int errnum, - const char *fmt, ...) -{ - if (!state || !(state->flags & ARGP_NO_ERRS)) - { - FILE *stream = state ? state->err_stream : stderr; - - if (stream) - { -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - __fwprintf (stream, L"%s", - state ? state->name : __argp_short_program_name ()); - else -#endif - fputs_unlocked (state - ? state->name : __argp_short_program_name (), - stream); - - if (fmt) - { - va_list ap; - - va_start (ap, fmt); -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - { - char *buf; - - if (__asprintf (&buf, fmt, ap) < 0) - buf = NULL; - - __fwprintf (stream, L": %s", buf); - - free (buf); - } - else -#endif - { - putc_unlocked (':', stream); - putc_unlocked (' ', stream); - - vfprintf (stream, fmt, ap); - } - - va_end (ap); - } - - if (errnum) - { - char buf[200]; - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - __fwprintf (stream, L": %s", - __strerror_r (errnum, buf, sizeof (buf))); - else -#endif - { - char const *s = NULL; - putc_unlocked (':', stream); - putc_unlocked (' ', stream); -#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P) - s = __strerror_r (errnum, buf, sizeof buf); -#elif HAVE_DECL_STRERROR_R - if (__strerror_r (errnum, buf, sizeof buf) == 0) - s = buf; -#endif -#if !_LIBC - if (! s && ! (s = strerror (errnum))) - s = dgettext (state->root_argp->argp_domain, - "Unknown system error"); -#endif - fputs (s, stream); - } - } - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - putwc_unlocked (L'\n', stream); - else -#endif - putc_unlocked ('\n', stream); - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - - if (status && (!state || !(state->flags & ARGP_NO_EXIT))) - exit (status); - } - } -} -#ifdef weak_alias -weak_alias (__argp_failure, argp_failure) -#endif diff --git a/src/bin/tar/lib/argp-namefrob.h b/src/bin/tar/lib/argp-namefrob.h deleted file mode 100644 index 6fe99cd7aa..0000000000 --- a/src/bin/tar/lib/argp-namefrob.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Name frobnication for compiling argp outside of glibc - Copyright (C) 1997, 2003, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if !_LIBC -/* This code is written for inclusion in gnu-libc, and uses names in the - namespace reserved for libc. If we're not compiling in libc, define those - names to be the normal ones instead. */ - -/* argp-parse functions */ -#undef __argp_parse -#define __argp_parse argp_parse -#undef __option_is_end -#define __option_is_end _option_is_end -#undef __option_is_short -#define __option_is_short _option_is_short -#undef __argp_input -#define __argp_input _argp_input - -/* argp-help functions */ -#undef __argp_help -#define __argp_help argp_help -#undef __argp_error -#define __argp_error argp_error -#undef __argp_failure -#define __argp_failure argp_failure -#undef __argp_state_help -#define __argp_state_help argp_state_help -#undef __argp_usage -#define __argp_usage argp_usage - -/* argp-fmtstream functions */ -#undef __argp_make_fmtstream -#define __argp_make_fmtstream argp_make_fmtstream -#undef __argp_fmtstream_free -#define __argp_fmtstream_free argp_fmtstream_free -#undef __argp_fmtstream_putc -#define __argp_fmtstream_putc argp_fmtstream_putc -#undef __argp_fmtstream_puts -#define __argp_fmtstream_puts argp_fmtstream_puts -#undef __argp_fmtstream_write -#define __argp_fmtstream_write argp_fmtstream_write -#undef __argp_fmtstream_printf -#define __argp_fmtstream_printf argp_fmtstream_printf -#undef __argp_fmtstream_set_lmargin -#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin -#undef __argp_fmtstream_set_rmargin -#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin -#undef __argp_fmtstream_set_wmargin -#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin -#undef __argp_fmtstream_point -#define __argp_fmtstream_point argp_fmtstream_point -#undef __argp_fmtstream_update -#define __argp_fmtstream_update _argp_fmtstream_update -#undef __argp_fmtstream_ensure -#define __argp_fmtstream_ensure _argp_fmtstream_ensure -#undef __argp_fmtstream_lmargin -#define __argp_fmtstream_lmargin argp_fmtstream_lmargin -#undef __argp_fmtstream_rmargin -#define __argp_fmtstream_rmargin argp_fmtstream_rmargin -#undef __argp_fmtstream_wmargin -#define __argp_fmtstream_wmargin argp_fmtstream_wmargin - -/* normal libc functions we call */ -#undef __flockfile -#define __flockfile flockfile -#undef __funlockfile -#define __funlockfile funlockfile -#undef __mempcpy -#define __mempcpy mempcpy -#undef __sleep -#define __sleep sleep -#undef __strcasecmp -#define __strcasecmp strcasecmp -#undef __strchrnul -#define __strchrnul strchrnul -#undef __strerror_r -#define __strerror_r strerror_r -#undef __strndup -#define __strndup strndup -#undef __vsnprintf -#define __vsnprintf vsnprintf - -#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED -# define clearerr_unlocked(x) clearerr (x) -#endif -#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED -# define feof_unlocked(x) feof (x) -# endif -#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED -# define ferror_unlocked(x) ferror (x) -# endif -#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED -# define fflush_unlocked(x) fflush (x) -# endif -#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED -# define fgets_unlocked(x,y,z) fgets (x,y,z) -# endif -#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED -# define fputc_unlocked(x,y) fputc (x,y) -# endif -#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED -# define fputs_unlocked(x,y) fputs (x,y) -# endif -#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED -# define fread_unlocked(w,x,y,z) fread (w,x,y,z) -# endif -#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED -# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) -# endif -#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED -# define getc_unlocked(x) getc (x) -# endif -#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED -# define getchar_unlocked() getchar () -# endif -#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED -# define putc_unlocked(x,y) putc (x,y) -# endif -#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED -# define putchar_unlocked(x) putchar (x) -# endif - -#endif /* !_LIBC */ - -#ifndef __set_errno -#define __set_errno(e) (errno = (e)) -#endif - -#if defined GNULIB_ARGP_DISABLE_DIRNAME -# define __argp_base_name(arg) arg -#elif defined GNULIB_ARGP_EXTERN_BASENAME -extern char *__argp_base_name(const char *arg); -#else -# include "dirname.h" -# define __argp_base_name base_name -#endif - -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME -# define __argp_short_program_name() (program_invocation_short_name) -#else -extern char *__argp_short_program_name (void); -#endif diff --git a/src/bin/tar/lib/argp-parse.c b/src/bin/tar/lib/argp-parse.c deleted file mode 100644 index a7de72902a..0000000000 --- a/src/bin/tar/lib/argp-parse.c +++ /dev/null @@ -1,953 +0,0 @@ -/* Hierarchial argument parsing, layered over getopt - Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _LIBC -# include -# undef dgettext -# define dgettext(domain, msgid) \ - INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) -#else -# include "gettext.h" -#endif -#define N_(msgid) msgid - -#include "argp.h" -#include "argp-namefrob.h" - -#define alignof(type) offsetof (struct { char c; type x; }, x) -#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d)) - -/* Getopt return values. */ -#define KEY_END (-1) /* The end of the options. */ -#define KEY_ARG 1 /* A non-option argument. */ -#define KEY_ERR '?' /* An error parsing the options. */ - -/* The meta-argument used to prevent any further arguments being interpreted - as options. */ -#define QUOTE "--" - -/* The number of bits we steal in a long-option value for our own use. */ -#define GROUP_BITS CHAR_BIT - -/* The number of bits available for the user value. */ -#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS) -#define USER_MASK ((1 << USER_BITS) - 1) - -/* EZ alias for ARGP_ERR_UNKNOWN. */ -#define EBADKEY ARGP_ERR_UNKNOWN - -/* Default options. */ - -/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep - for one second intervals, decrementing _ARGP_HANG until it's zero. Thus - you can force the program to continue by attaching a debugger and setting - it to 0 yourself. */ -static volatile int _argp_hang; - -#define OPT_PROGNAME -2 -#define OPT_USAGE -3 -#define OPT_HANG -4 - -static const struct argp_option argp_default_options[] = -{ - {"help", '?', 0, 0, N_("give this help list"), -1}, - {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0}, - {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0}, - {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, - N_("hang for SECS seconds (default 3600)"), 0}, - {NULL, 0, 0, 0, NULL, 0} -}; - -static error_t -argp_default_parser (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case '?': - __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); - break; - case OPT_USAGE: - __argp_state_help (state, state->out_stream, - ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); - break; - - case OPT_PROGNAME: /* Set the program name. */ -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME - program_invocation_name = arg; -#endif - /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka - __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined - to be that, so we have to be a bit careful here.] */ - - /* Update what we use for messages. */ - state->name = __argp_base_name (arg); - -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - program_invocation_short_name = state->name; -#endif - - if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) - == ARGP_PARSE_ARGV0) - /* Update what getopt uses too. */ - state->argv[0] = arg; - - break; - - case OPT_HANG: - _argp_hang = atoi (arg ? arg : "3600"); - while (_argp_hang-- > 0) - __sleep (1); - break; - - default: - return EBADKEY; - } - return 0; -} - -static const struct argp argp_default_argp = - {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; - - -static const struct argp_option argp_version_options[] = -{ - {"version", 'V', 0, 0, N_("print program version"), -1}, - {NULL, 0, 0, 0, NULL, 0} -}; - -static error_t -argp_version_parser (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 'V': - if (argp_program_version_hook) - (*argp_program_version_hook) (state->out_stream, state); - else if (argp_program_version) - fprintf (state->out_stream, "%s\n", argp_program_version); - else - __argp_error (state, dgettext (state->root_argp->argp_domain, - "(PROGRAM ERROR) No version known!?")); - if (! (state->flags & ARGP_NO_EXIT)) - exit (0); - break; - default: - return EBADKEY; - } - return 0; -} - -static const struct argp argp_version_argp = - {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; - -/* Returns the offset into the getopt long options array LONG_OPTIONS of a - long option with called NAME, or -1 if none is found. Passing NULL as - NAME will return the number of options. */ -static int -find_long_option (struct option *long_options, const char *name) -{ - struct option *l = long_options; - while (l->name != NULL) - if (name != NULL && strcmp (l->name, name) == 0) - return l - long_options; - else - l++; - if (name == NULL) - return l - long_options; - else - return -1; -} - - -/* The state of a `group' during parsing. Each group corresponds to a - particular argp structure from the tree of such descending from the top - level argp passed to argp_parse. */ -struct group -{ - /* This group's parsing function. */ - argp_parser_t parser; - - /* Which argp this group is from. */ - const struct argp *argp; - - /* Points to the point in SHORT_OPTS corresponding to the end of the short - options for this group. We use it to determine from which group a - particular short options is from. */ - char *short_end; - - /* The number of non-option args sucessfully handled by this parser. */ - unsigned args_processed; - - /* This group's parser's parent's group. */ - struct group *parent; - unsigned parent_index; /* And the our position in the parent. */ - - /* These fields are swapped into and out of the state structure when - calling this group's parser. */ - void *input, **child_inputs; - void *hook; -}; - -/* Call GROUP's parser with KEY and ARG, swapping any group-specific info - from STATE before calling, and back into state afterwards. If GROUP has - no parser, EBADKEY is returned. */ -static error_t -group_parse (struct group *group, struct argp_state *state, int key, char *arg) -{ - if (group->parser) - { - error_t err; - state->hook = group->hook; - state->input = group->input; - state->child_inputs = group->child_inputs; - state->arg_num = group->args_processed; - err = (*group->parser)(key, arg, state); - group->hook = state->hook; - return err; - } - else - return EBADKEY; -} - -struct parser -{ - const struct argp *argp; - - /* SHORT_OPTS is the getopt short options string for the union of all the - groups of options. */ - char *short_opts; - /* LONG_OPTS is the array of getop long option structures for the union of - all the groups of options. */ - struct option *long_opts; - /* OPT_DATA is the getopt data used for the re-entrant getopt. */ - struct _getopt_data opt_data; - - /* States of the various parsing groups. */ - struct group *groups; - /* The end of the GROUPS array. */ - struct group *egroup; - /* An vector containing storage for the CHILD_INPUTS field in all groups. */ - void **child_inputs; - - /* True if we think using getopt is still useful; if false, then - remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is - cleared whenever getopt returns KEY_END, but may be set again if the user - moves the next argument pointer backwards. */ - int try_getopt; - - /* State block supplied to parsing routines. */ - struct argp_state state; - - /* Memory used by this parser. */ - void *storage; -}; - -/* The next usable entries in the various parser tables being filled in by - convert_options. */ -struct parser_convert_state -{ - struct parser *parser; - char *short_end; - struct option *long_end; - void **child_inputs_end; -}; - -/* Converts all options in ARGP (which is put in GROUP) and ancestors - into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and - CVT->LONG_END are the points at which new options are added. Returns the - next unused group entry. CVT holds state used during the conversion. */ -static struct group * -convert_options (const struct argp *argp, - struct group *parent, unsigned parent_index, - struct group *group, struct parser_convert_state *cvt) -{ - /* REAL is the most recent non-alias value of OPT. */ - const struct argp_option *real = argp->options; - const struct argp_child *children = argp->children; - - if (real || argp->parser) - { - const struct argp_option *opt; - - if (real) - for (opt = real; !__option_is_end (opt); opt++) - { - if (! (opt->flags & OPTION_ALIAS)) - /* OPT isn't an alias, so we can use values from it. */ - real = opt; - - if (! (real->flags & OPTION_DOC)) - /* A real option (not just documentation). */ - { - if (__option_is_short (opt)) - /* OPT can be used as a short option. */ - { - *cvt->short_end++ = opt->key; - if (real->arg) - { - *cvt->short_end++ = ':'; - if (real->flags & OPTION_ARG_OPTIONAL) - *cvt->short_end++ = ':'; - } - *cvt->short_end = '\0'; /* keep 0 terminated */ - } - - if (opt->name - && find_long_option (cvt->parser->long_opts, opt->name) < 0) - /* OPT can be used as a long option. */ - { - cvt->long_end->name = opt->name; - cvt->long_end->has_arg = - (real->arg - ? (real->flags & OPTION_ARG_OPTIONAL - ? optional_argument - : required_argument) - : no_argument); - cvt->long_end->flag = 0; - /* we add a disambiguating code to all the user's - values (which is removed before we actually call - the function to parse the value); this means that - the user loses use of the high 8 bits in all his - values (the sign of the lower bits is preserved - however)... */ - cvt->long_end->val = - ((opt->key | real->key) & USER_MASK) - + (((group - cvt->parser->groups) + 1) << USER_BITS); - - /* Keep the LONG_OPTS list terminated. */ - (++cvt->long_end)->name = NULL; - } - } - } - - group->parser = argp->parser; - group->argp = argp; - group->short_end = cvt->short_end; - group->args_processed = 0; - group->parent = parent; - group->parent_index = parent_index; - group->input = 0; - group->hook = 0; - group->child_inputs = 0; - - if (children) - /* Assign GROUP's CHILD_INPUTS field some space from - CVT->child_inputs_end.*/ - { - unsigned num_children = 0; - while (children[num_children].argp) - num_children++; - group->child_inputs = cvt->child_inputs_end; - cvt->child_inputs_end += num_children; - } - - parent = group++; - } - else - parent = 0; - - if (children) - { - unsigned index = 0; - while (children->argp) - group = - convert_options (children++->argp, parent, index++, group, cvt); - } - - return group; -} - -/* Find the merged set of getopt options, with keys appropiately prefixed. */ -static void -parser_convert (struct parser *parser, const struct argp *argp, int flags) -{ - struct parser_convert_state cvt; - - cvt.parser = parser; - cvt.short_end = parser->short_opts; - cvt.long_end = parser->long_opts; - cvt.child_inputs_end = parser->child_inputs; - - if (flags & ARGP_IN_ORDER) - *cvt.short_end++ = '-'; - else if (flags & ARGP_NO_ARGS) - *cvt.short_end++ = '+'; - *cvt.short_end = '\0'; - - cvt.long_end->name = NULL; - - parser->argp = argp; - - if (argp) - parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); - else - parser->egroup = parser->groups; /* No parsers at all! */ -} - -/* Lengths of various parser fields which we will allocated. */ -struct parser_sizes -{ - size_t short_len; /* Getopt short options string. */ - size_t long_len; /* Getopt long options vector. */ - size_t num_groups; /* Group structures we allocate. */ - size_t num_child_inputs; /* Child input slots. */ -}; - -/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of - argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by - the maximum lengths of the resulting merged getopt short options string and - long-options array, respectively. */ -static void -calc_sizes (const struct argp *argp, struct parser_sizes *szs) -{ - const struct argp_child *child = argp->children; - const struct argp_option *opt = argp->options; - - if (opt || argp->parser) - { - szs->num_groups++; - if (opt) - { - int num_opts = 0; - while (!__option_is_end (opt++)) - num_opts++; - szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */ - szs->long_len += num_opts; - } - } - - if (child) - while (child->argp) - { - calc_sizes ((child++)->argp, szs); - szs->num_child_inputs++; - } -} - -/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ -static error_t -parser_init (struct parser *parser, const struct argp *argp, - int argc, char **argv, int flags, void *input) -{ - error_t err = 0; - struct group *group; - struct parser_sizes szs; - struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER; - char *storage; - size_t glen, gsum; - size_t clen, csum; - size_t llen, lsum; - size_t slen, ssum; - - szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; - szs.long_len = 0; - szs.num_groups = 0; - szs.num_child_inputs = 0; - - if (argp) - calc_sizes (argp, &szs); - - /* Lengths of the various bits of storage used by PARSER. */ - glen = (szs.num_groups + 1) * sizeof (struct group); - clen = szs.num_child_inputs * sizeof (void *); - llen = (szs.long_len + 1) * sizeof (struct option); - slen = szs.short_len + 1; - - /* Sums of previous lengths, properly aligned. There's no need to - align gsum, since struct group is aligned at least as strictly as - void * (since it contains a void * member). And there's no need - to align lsum, since struct option is aligned at least as - strictly as char. */ - gsum = glen; - csum = alignto (gsum + clen, alignof (struct option)); - lsum = csum + llen; - ssum = lsum + slen; - - parser->storage = malloc (ssum); - if (! parser->storage) - return ENOMEM; - - storage = parser->storage; - parser->groups = parser->storage; - parser->child_inputs = (void **) (storage + gsum); - parser->long_opts = (struct option *) (storage + csum); - parser->short_opts = storage + lsum; - parser->opt_data = opt_data; - - memset (parser->child_inputs, 0, clen); - parser_convert (parser, argp, flags); - - memset (&parser->state, 0, sizeof (struct argp_state)); - parser->state.root_argp = parser->argp; - parser->state.argc = argc; - parser->state.argv = argv; - parser->state.flags = flags; - parser->state.err_stream = stderr; - parser->state.out_stream = stdout; - parser->state.next = 0; /* Tell getopt to initialize. */ - parser->state.pstate = parser; - - parser->try_getopt = 1; - - /* Call each parser for the first time, giving it a chance to propagate - values to child parsers. */ - if (parser->groups < parser->egroup) - parser->groups->input = input; - for (group = parser->groups; - group < parser->egroup && (!err || err == EBADKEY); - group++) - { - if (group->parent) - /* If a child parser, get the initial input value from the parent. */ - group->input = group->parent->child_inputs[group->parent_index]; - - if (!group->parser - && group->argp->children && group->argp->children->argp) - /* For the special case where no parsing function is supplied for an - argp, propagate its input to its first child, if any (this just - makes very simple wrapper argps more convenient). */ - group->child_inputs[0] = group->input; - - err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); - } - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - - if (err) - return err; - - if (parser->state.flags & ARGP_NO_ERRS) - { - parser->opt_data.opterr = 0; - if (parser->state.flags & ARGP_PARSE_ARGV0) - /* getopt always skips ARGV[0], so we have to fake it out. As long - as OPTERR is 0, then it shouldn't actually try to access it. */ - parser->state.argv--, parser->state.argc++; - } - else - parser->opt_data.opterr = 1; /* Print error messages. */ - - if (parser->state.argv == argv && argv[0]) - /* There's an argv[0]; use it for messages. */ - parser->state.name = __argp_base_name (argv[0]); - else - parser->state.name = __argp_short_program_name (); - - return 0; -} - -/* Free any storage consumed by PARSER (but not PARSER itself). */ -static error_t -parser_finalize (struct parser *parser, - error_t err, int arg_ebadkey, int *end_index) -{ - struct group *group; - - if (err == EBADKEY && arg_ebadkey) - /* Suppress errors generated by unparsed arguments. */ - err = 0; - - if (! err) - { - if (parser->state.next == parser->state.argc) - /* We successfully parsed all arguments! Call all the parsers again, - just a few more times... */ - { - for (group = parser->groups; - group < parser->egroup && (!err || err==EBADKEY); - group++) - if (group->args_processed == 0) - err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); - for (group = parser->egroup - 1; - group >= parser->groups && (!err || err==EBADKEY); - group--) - err = group_parse (group, &parser->state, ARGP_KEY_END, 0); - - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - - /* Tell the user that all arguments are parsed. */ - if (end_index) - *end_index = parser->state.next; - } - else if (end_index) - /* Return any remaining arguments to the user. */ - *end_index = parser->state.next; - else - /* No way to return the remaining arguments, they must be bogus. */ - { - if (!(parser->state.flags & ARGP_NO_ERRS) - && parser->state.err_stream) - fprintf (parser->state.err_stream, - dgettext (parser->argp->argp_domain, - "%s: Too many arguments\n"), - parser->state.name); - err = EBADKEY; - } - } - - /* Okay, we're all done, with either an error or success; call the parsers - to indicate which one. */ - - if (err) - { - /* Maybe print an error message. */ - if (err == EBADKEY) - /* An appropriate message describing what the error was should have - been printed earlier. */ - __argp_state_help (&parser->state, parser->state.err_stream, - ARGP_HELP_STD_ERR); - - /* Since we didn't exit, give each parser an error indication. */ - for (group = parser->groups; group < parser->egroup; group++) - group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); - } - else - /* Notify parsers of success, and propagate back values from parsers. */ - { - /* We pass over the groups in reverse order so that child groups are - given a chance to do there processing before passing back a value to - the parent. */ - for (group = parser->egroup - 1 - ; group >= parser->groups && (!err || err == EBADKEY) - ; group--) - err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - } - - /* Call parsers once more, to do any final cleanup. Errors are ignored. */ - for (group = parser->egroup - 1; group >= parser->groups; group--) - group_parse (group, &parser->state, ARGP_KEY_FINI, 0); - - if (err == EBADKEY) - err = EINVAL; - - free (parser->storage); - - return err; -} - -/* Call the user parsers to parse the non-option argument VAL, at the current - position, returning any error. The state NEXT pointer is assumed to have - been adjusted (by getopt) to point after this argument; this function will - adjust it correctly to reflect however many args actually end up being - consumed. */ -static error_t -parser_parse_arg (struct parser *parser, char *val) -{ - /* Save the starting value of NEXT, first adjusting it so that the arg - we're parsing is again the front of the arg vector. */ - int index = --parser->state.next; - error_t err = EBADKEY; - struct group *group; - int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ - - /* Try to parse the argument in each parser. */ - for (group = parser->groups - ; group < parser->egroup && err == EBADKEY - ; group++) - { - parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ - key = ARGP_KEY_ARG; - err = group_parse (group, &parser->state, key, val); - - if (err == EBADKEY) - /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ - { - parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ - key = ARGP_KEY_ARGS; - err = group_parse (group, &parser->state, key, 0); - } - } - - if (! err) - { - if (key == ARGP_KEY_ARGS) - /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't - changed by the user, *all* arguments should be considered - consumed. */ - parser->state.next = parser->state.argc; - - if (parser->state.next > index) - /* Remember that we successfully processed a non-option - argument -- but only if the user hasn't gotten tricky and set - the clock back. */ - (--group)->args_processed += (parser->state.next - index); - else - /* The user wants to reparse some args, give getopt another try. */ - parser->try_getopt = 1; - } - - return err; -} - -/* Call the user parsers to parse the option OPT, with argument VAL, at the - current position, returning any error. */ -static error_t -parser_parse_opt (struct parser *parser, int opt, char *val) -{ - /* The group key encoded in the high bits; 0 for short opts or - group_number + 1 for long opts. */ - int group_key = opt >> USER_BITS; - error_t err = EBADKEY; - - if (group_key == 0) - /* A short option. By comparing OPT's position in SHORT_OPTS to the - various starting positions in each group's SHORT_END field, we can - determine which group OPT came from. */ - { - struct group *group; - char *short_index = strchr (parser->short_opts, opt); - - if (short_index) - for (group = parser->groups; group < parser->egroup; group++) - if (group->short_end > short_index) - { - err = group_parse (group, &parser->state, opt, - parser->opt_data.optarg); - break; - } - } - else - /* A long option. We use shifts instead of masking for extracting - the user value in order to preserve the sign. */ - err = - group_parse (&parser->groups[group_key - 1], &parser->state, - (opt << GROUP_BITS) >> GROUP_BITS, - parser->opt_data.optarg); - - if (err == EBADKEY) - /* At least currently, an option not recognized is an error in the - parser, because we pre-compute which parser is supposed to deal - with each option. */ - { - static const char bad_key_err[] = - N_("(PROGRAM ERROR) Option should have been recognized!?"); - if (group_key == 0) - __argp_error (&parser->state, "-%c: %s", opt, - dgettext (parser->argp->argp_domain, bad_key_err)); - else - { - struct option *long_opt = parser->long_opts; - while (long_opt->val != opt && long_opt->name) - long_opt++; - __argp_error (&parser->state, "--%s: %s", - long_opt->name ? long_opt->name : "???", - dgettext (parser->argp->argp_domain, bad_key_err)); - } - } - - return err; -} - -/* Parse the next argument in PARSER (as indicated by PARSER->state.next). - Any error from the parsers is returned, and *ARGP_EBADKEY indicates - whether a value of EBADKEY is due to an unrecognized argument (which is - generally not fatal). */ -static error_t -parser_parse_next (struct parser *parser, int *arg_ebadkey) -{ - int opt; - error_t err = 0; - - if (parser->state.quoted && parser->state.next < parser->state.quoted) - /* The next argument pointer has been moved to before the quoted - region, so pretend we never saw the quoting `--', and give getopt - another chance. If the user hasn't removed it, getopt will just - process it again. */ - parser->state.quoted = 0; - - if (parser->try_getopt && !parser->state.quoted) - /* Give getopt a chance to parse this. */ - { - /* Put it back in OPTIND for getopt. */ - parser->opt_data.optind = parser->state.next; - /* Distinguish KEY_ERR from a real option. */ - parser->opt_data.optopt = KEY_END; - if (parser->state.flags & ARGP_LONG_ONLY) - opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); - else - opt = _getopt_long_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); - /* And see what getopt did. */ - parser->state.next = parser->opt_data.optind; - - if (opt == KEY_END) - /* Getopt says there are no more options, so stop using - getopt; we'll continue if necessary on our own. */ - { - parser->try_getopt = 0; - if (parser->state.next > 1 - && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) - == 0) - /* Not only is this the end of the options, but it's a - `quoted' region, which may have args that *look* like - options, so we definitely shouldn't try to use getopt past - here, whatever happens. */ - parser->state.quoted = parser->state.next; - } - else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END) - /* KEY_ERR can have the same value as a valid user short - option, but in the case of a real error, getopt sets OPTOPT - to the offending character, which can never be KEY_END. */ - { - *arg_ebadkey = 0; - return EBADKEY; - } - } - else - opt = KEY_END; - - if (opt == KEY_END) - { - /* We're past what getopt considers the options. */ - if (parser->state.next >= parser->state.argc - || (parser->state.flags & ARGP_NO_ARGS)) - /* Indicate that we're done. */ - { - *arg_ebadkey = 1; - return EBADKEY; - } - else - /* A non-option arg; simulate what getopt might have done. */ - { - opt = KEY_ARG; - parser->opt_data.optarg = parser->state.argv[parser->state.next++]; - } - } - - if (opt == KEY_ARG) - /* A non-option argument; try each parser in turn. */ - err = parser_parse_arg (parser, parser->opt_data.optarg); - else - err = parser_parse_opt (parser, opt, parser->opt_data.optarg); - - if (err == EBADKEY) - *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); - - return err; -} - -/* Parse the options strings in ARGC & ARGV according to the argp in ARGP. - FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the - index in ARGV of the first unparsed option is returned in it. If an - unknown option is present, EINVAL is returned; if some parser routine - returned a non-zero value, it is returned; otherwise 0 is returned. */ -error_t -__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, - int *end_index, void *input) -{ - error_t err; - struct parser parser; - - /* If true, then err == EBADKEY is a result of a non-option argument failing - to be parsed (which in some cases isn't actually an error). */ - int arg_ebadkey = 0; - -#ifndef _LIBC - if (!(flags & ARGP_PARSE_ARGV0)) - { -#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME - if (!program_invocation_name) - program_invocation_name = argv[0]; -#endif -#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - if (!program_invocation_short_name) - program_invocation_short_name = __argp_base_name (argv[0]); -#endif - } -#endif - - if (! (flags & ARGP_NO_HELP)) - /* Add our own options. */ - { - struct argp_child *child = alloca (4 * sizeof (struct argp_child)); - struct argp *top_argp = alloca (sizeof (struct argp)); - - /* TOP_ARGP has no options, it just serves to group the user & default - argps. */ - memset (top_argp, 0, sizeof (*top_argp)); - top_argp->children = child; - - memset (child, 0, 4 * sizeof (struct argp_child)); - - if (argp) - (child++)->argp = argp; - (child++)->argp = &argp_default_argp; - if (argp_program_version || argp_program_version_hook) - (child++)->argp = &argp_version_argp; - child->argp = 0; - - argp = top_argp; - } - - /* Construct a parser for these arguments. */ - err = parser_init (&parser, argp, argc, argv, flags, input); - - if (! err) - /* Parse! */ - { - while (! err) - err = parser_parse_next (&parser, &arg_ebadkey); - err = parser_finalize (&parser, err, arg_ebadkey, end_index); - } - - return err; -} -#ifdef weak_alias -weak_alias (__argp_parse, argp_parse) -#endif - -/* Return the input field for ARGP in the parser corresponding to STATE; used - by the help routines. */ -void * -__argp_input (const struct argp *argp, const struct argp_state *state) -{ - if (state) - { - struct group *group; - struct parser *parser = state->pstate; - - for (group = parser->groups; group < parser->egroup; group++) - if (group->argp == argp) - return group->input; - } - - return 0; -} -#ifdef weak_alias -weak_alias (__argp_input, _argp_input) -#endif diff --git a/src/bin/tar/lib/argp-pin.c b/src/bin/tar/lib/argp-pin.c deleted file mode 100644 index 852c6d6d93..0000000000 --- a/src/bin/tar/lib/argp-pin.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Full and short program names for argp module - Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME -char *program_invocation_short_name = 0; -#endif -#ifndef HAVE_PROGRAM_INVOCATION_NAME -char *program_invocation_name = 0; -#endif - diff --git a/src/bin/tar/lib/argp-pv.c b/src/bin/tar/lib/argp-pv.c deleted file mode 100644 index a11298bfab..0000000000 --- a/src/bin/tar/lib/argp-pv.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Default definition for ARGP_PROGRAM_VERSION. - Copyright (C) 1996, 1997, 1999, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* If set by the user program to a non-zero value, then a default option - --version is added (unless the ARGP_NO_HELP flag is used), which will - print this string followed by a newline and exit (unless the - ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ -const char *argp_program_version; diff --git a/src/bin/tar/lib/argp-pvh.c b/src/bin/tar/lib/argp-pvh.c deleted file mode 100644 index 6bf7c49b81..0000000000 --- a/src/bin/tar/lib/argp-pvh.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Default definition for ARGP_PROGRAM_VERSION_HOOK. - Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "argp.h" - -/* If set by the user program to a non-zero value, then a default option - --version is added (unless the ARGP_NO_HELP flag is used), which calls - this function with a stream to print the version to and a pointer to the - current parsing state, and then exits (unless the ARGP_NO_EXIT flag is - used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ -void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL; diff --git a/src/bin/tar/lib/argp-xinl.c b/src/bin/tar/lib/argp-xinl.c deleted file mode 100644 index a6afb1f739..0000000000 --- a/src/bin/tar/lib/argp-xinl.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Real definitions for extern inline functions in argp.h - Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if defined _LIBC || defined HAVE_FEATURES_H -# include -#endif - -#ifndef __USE_EXTERN_INLINES -# define __USE_EXTERN_INLINES 1 -#endif -#define ARGP_EI -#undef __OPTIMIZE__ -#define __OPTIMIZE__ 1 -#include "argp.h" - -/* Add weak aliases. */ -#if _LIBC - 0 && defined (weak_alias) - -weak_alias (__argp_usage, argp_usage) -weak_alias (__option_is_short, _option_is_short) -weak_alias (__option_is_end, _option_is_end) - -#endif diff --git a/src/bin/tar/lib/argp.h b/src/bin/tar/lib/argp.h deleted file mode 100644 index 1c4e06f8fe..0000000000 --- a/src/bin/tar/lib/argp.h +++ /dev/null @@ -1,622 +0,0 @@ -/* Hierarchial argument parsing, layered over getopt. - Copyright (C) 1995-1999,2003-2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _ARGP_H -#define _ARGP_H - -#include -#include -#include -#include - -#define __need_error_t -#include - -#ifndef __THROW -# define __THROW -#endif -#ifndef __NTH -# define __NTH(fct) fct __THROW -#endif - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || __STRICT_ANSI__ -# define __format__ format -# define __printf__ printf -# endif -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". - Other compilers use __restrict, __restrict__, and _Restrict, and - 'configure' might #define 'restrict' to those words. */ -#ifndef __restrict -# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) -# if 199901L <= __STDC_VERSION__ -# define __restrict restrict -# else -# define __restrict -# endif -# endif -#endif - -#ifndef __error_t_defined -typedef int error_t; -# define __error_t_defined -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* A description of a particular option. A pointer to an array of - these is passed in the OPTIONS field of an argp structure. Each option - entry can correspond to one long option and/or one short option; more - names for the same option can be added by following an entry in an option - array with options having the OPTION_ALIAS flag set. */ -struct argp_option -{ - /* The long option name. For more than one name for the same option, you - can use following options with the OPTION_ALIAS flag set. */ - const char *name; - - /* What key is returned for this option. If > 0 and printable, then it's - also accepted as a short option. */ - int key; - - /* If non-NULL, this is the name of the argument associated with this - option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ - const char *arg; - - /* OPTION_ flags. */ - int flags; - - /* The doc string for this option. If both NAME and KEY are 0, This string - will be printed outdented from the normal option column, making it - useful as a group header (it will be the first thing printed in its - group); in this usage, it's conventional to end the string with a `:'. - - Write the initial value as N_("TEXT") if you want xgettext to collect - it into a POT file. */ - const char *doc; - - /* The group this option is in. In a long help message, options are sorted - alphabetically within each group, and the groups presented in the order - 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with - if this field 0 will inherit the group number of the previous entry, or - zero if it's the first one, unless its a group header (NAME and KEY both - 0), in which case, the previous entry + 1 is the default. Automagic - options such as --help are put into group -1. */ - int group; -}; - -/* The argument associated with this option is optional. */ -#define OPTION_ARG_OPTIONAL 0x1 - -/* This option isn't displayed in any help messages. */ -#define OPTION_HIDDEN 0x2 - -/* This option is an alias for the closest previous non-alias option. This - means that it will be displayed in the same help entry, and will inherit - fields other than NAME and KEY from the aliased option. */ -#define OPTION_ALIAS 0x4 - -/* This option isn't actually an option (and so should be ignored by the - actual option parser), but rather an arbitrary piece of documentation that - should be displayed in much the same manner as the options. If this flag - is set, then the option NAME field is displayed unmodified (e.g., no `--' - prefix is added) at the left-margin (where a *short* option would normally - be displayed), and the documentation string in the normal place. The NAME - field will be translated using gettext, unless OPTION_NO_TRANS is set (see - below). For purposes of sorting, any leading whitespace and punctuation is - ignored, except that if the first non-whitespace character is not `-', this - entry is displayed after all options (and OPTION_DOC entries with a leading - `-') in the same group. */ -#define OPTION_DOC 0x8 - -/* This option shouldn't be included in `long' usage messages (but is still - included in help messages). This is mainly intended for options that are - completely documented in an argp's ARGS_DOC field, in which case including - the option in the generic usage list would be redundant. For instance, - if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to - distinguish these two cases, -x should probably be marked - OPTION_NO_USAGE. */ -#define OPTION_NO_USAGE 0x10 - -/* Valid only in conjunction with OPTION_DOC. This option disables translation - of option name. */ -#define OPTION_NO_TRANS 0x20 - - -struct argp; /* fwd declare this type */ -struct argp_state; /* " */ -struct argp_child; /* " */ - -/* The type of a pointer to an argp parsing function. */ -typedef error_t (*argp_parser_t) (int key, char *arg, - struct argp_state *state); - -/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such - returns will simply be ignored. For user keys, this error will be turned - into EINVAL (if the call to argp_parse is such that errors are propagated - back to the user instead of exiting); returning EINVAL itself would result - in an immediate stop to parsing in *all* cases. */ -#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ - -/* Special values for the KEY argument to an argument parsing function. - ARGP_ERR_UNKNOWN should be returned if they aren't understood. - - The sequence of keys to a parsing function is either (where each - uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key): - - INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all - or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed - or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized - - The third case is where every parser returned ARGP_KEY_UNKNOWN for an - argument, in which case parsing stops at that argument (returning the - unparsed arguments to the caller of argp_parse if requested, or stopping - with an error message if not). - - If an error occurs (either detected by argp, or because the parsing - function returned an error value), then the parser is called with - ARGP_KEY_ERROR, and no further calls are made. */ - -/* This is not an option at all, but rather a command line argument. If a - parser receiving this key returns success, the fact is recorded, and the - ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the - argument, a parser function decrements the NEXT field of the state it's - passed, the option won't be considered processed; this is to allow you to - actually modify the argument (perhaps into an option), and have it - processed again. */ -#define ARGP_KEY_ARG 0 -/* There are remaining arguments not parsed by any parser, which may be found - starting at (STATE->argv + STATE->next). If success is returned, but - STATE->next left untouched, it's assumed that all arguments were consume, - otherwise, the parser should adjust STATE->next to reflect any arguments - consumed. */ -#define ARGP_KEY_ARGS 0x1000006 -/* There are no more command line arguments at all. */ -#define ARGP_KEY_END 0x1000001 -/* Because it's common to want to do some special processing if there aren't - any non-option args, user parsers are called with this key if they didn't - successfully process any non-option arguments. Called just before - ARGP_KEY_END (where more general validity checks on previously parsed - arguments can take place). */ -#define ARGP_KEY_NO_ARGS 0x1000002 -/* Passed in before any parsing is done. Afterwards, the values of each - element of the CHILD_INPUT field, if any, in the state structure is - copied to each child's state to be the initial value of the INPUT field. */ -#define ARGP_KEY_INIT 0x1000003 -/* Use after all other keys, including SUCCESS & END. */ -#define ARGP_KEY_FINI 0x1000007 -/* Passed in when parsing has successfully been completed (even if there are - still arguments remaining). */ -#define ARGP_KEY_SUCCESS 0x1000004 -/* Passed in if an error occurs. */ -#define ARGP_KEY_ERROR 0x1000005 - -/* An argp structure contains a set of options declarations, a function to - deal with parsing one, documentation string, a possible vector of child - argp's, and perhaps a function to filter help output. When actually - parsing options, getopt is called with the union of all the argp - structures chained together through their CHILD pointers, with conflicts - being resolved in favor of the first occurrence in the chain. */ -struct argp -{ - /* An array of argp_option structures, terminated by an entry with both - NAME and KEY having a value of 0. */ - const struct argp_option *options; - - /* What to do with an option from this structure. KEY is the key - associated with the option, and ARG is any associated argument (NULL if - none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be - returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then - parsing is stopped immediately, and that value is returned from - argp_parse(). For special (non-user-supplied) values of KEY, see the - ARGP_KEY_ definitions below. */ - argp_parser_t parser; - - /* A string describing what other arguments are wanted by this program. It - is only used by argp_usage to print the `Usage:' message. If it - contains newlines, the strings separated by them are considered - alternative usage patterns, and printed on separate lines (lines after - the first are prefix by ` or: ' instead of `Usage:'). */ - const char *args_doc; - - /* If non-NULL, a string containing extra text to be printed before and - after the options in a long help message (separated by a vertical tab - `\v' character). - Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if - you want xgettext to collect the two pieces of text into a POT file. */ - const char *doc; - - /* A vector of argp_children structures, terminated by a member with a 0 - argp field, pointing to child argps should be parsed with this one. Any - conflicts are resolved in favor of this argp, or early argps in the - CHILDREN list. This field is useful if you use libraries that supply - their own argp structure, which you want to use in conjunction with your - own. */ - const struct argp_child *children; - - /* If non-zero, this should be a function to filter the output of help - messages. KEY is either a key from an option, in which case TEXT is - that option's help text, or a special key from the ARGP_KEY_HELP_ - defines, below, describing which other help text TEXT is. The function - should return either TEXT, if it should be used as-is, a replacement - string, which should be malloced, and will be freed by argp, or NULL, - meaning `print nothing'. The value for TEXT is *after* any translation - has been done, so if any of the replacement text also needs translation, - that should be done by the filter function. INPUT is either the input - supplied to argp_parse, or NULL, if argp_help was called directly. */ - char *(*help_filter) (int __key, const char *__text, void *__input); - - /* If non-zero the strings used in the argp library are translated using - the domain described by this string. Otherwise the currently installed - default domain is used. */ - const char *argp_domain; -}; - -/* Possible KEY arguments to a help filter function. */ -#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */ -#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ -#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ -#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; - TEXT is NULL for this key. */ -/* Explanatory note emitted when duplicate option arguments have been - suppressed. */ -#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 -#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ - -/* When an argp has a non-zero CHILDREN field, it should point to a vector of - argp_child structures, each of which describes a subsidiary argp. */ -struct argp_child -{ - /* The child parser. */ - const struct argp *argp; - - /* Flags for this child. */ - int flags; - - /* If non-zero, an optional header to be printed in help output before the - child options. As a side-effect, a non-zero value forces the child - options to be grouped together; to achieve this effect without actually - printing a header string, use a value of "". */ - const char *header; - - /* Where to group the child options relative to the other (`consolidated') - options in the parent argp; the values are the same as the GROUP field - in argp_option structs, but all child-groupings follow parent options at - a particular group level. If both this field and HEADER are zero, then - they aren't grouped at all, but rather merged with the parent options - (merging the child's grouping levels with the parents). */ - int group; -}; - -/* Parsing state. This is provided to parsing functions called by argp, - which may examine and, as noted, modify fields. */ -struct argp_state -{ - /* The top level ARGP being parsed. */ - const struct argp *root_argp; - - /* The argument vector being parsed. May be modified. */ - int argc; - char **argv; - - /* The index in ARGV of the next arg that to be parsed. May be modified. */ - int next; - - /* The flags supplied to argp_parse. May be modified. */ - unsigned flags; - - /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the - number of the current arg, starting at zero, and incremented after each - such call returns. At all other times, this is the number of such - arguments that have been processed. */ - unsigned arg_num; - - /* If non-zero, the index in ARGV of the first argument following a special - `--' argument (which prevents anything following being interpreted as an - option). Only set once argument parsing has proceeded past this point. */ - int quoted; - - /* An arbitrary pointer passed in from the user. */ - void *input; - /* Values to pass to child parsers. This vector will be the same length as - the number of children for the current parser. */ - void **child_inputs; - - /* For the parser's use. Initialized to 0. */ - void *hook; - - /* The name used when printing messages. This is initialized to ARGV[0], - or PROGRAM_INVOCATION_NAME if that is unavailable. */ - char *name; - - /* Streams used when argp prints something. */ - FILE *err_stream; /* For errors; initialized to stderr. */ - FILE *out_stream; /* For information; initialized to stdout. */ - - void *pstate; /* Private, for use by argp. */ -}; - -/* Flags for argp_parse (note that the defaults are those that are - convenient for program command line parsing): */ - -/* Don't ignore the first element of ARGV. Normally (and always unless - ARGP_NO_ERRS is set) the first element of the argument vector is - skipped for option parsing purposes, as it corresponds to the program name - in a command line. */ -#define ARGP_PARSE_ARGV0 0x01 - -/* Don't print error messages for unknown options to stderr; unless this flag - is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program - name in the error messages. This flag implies ARGP_NO_EXIT (on the - assumption that silent exiting upon errors is bad behaviour). */ -#define ARGP_NO_ERRS 0x02 - -/* Don't parse any non-option args. Normally non-option args are parsed by - calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg - as the value. Since it's impossible to know which parse function wants to - handle it, each one is called in turn, until one returns 0 or an error - other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the - argp_parse returns prematurely (but with a return value of 0). If all - args have been parsed without error, all parsing functions are called one - last time with a key of ARGP_KEY_END. This flag needn't normally be set, - as the normal behavior is to stop parsing as soon as some argument can't - be handled. */ -#define ARGP_NO_ARGS 0x04 - -/* Parse options and arguments in the same order they occur on the command - line -- normally they're rearranged so that all options come first. */ -#define ARGP_IN_ORDER 0x08 - -/* Don't provide the standard long option --help, which causes usage and - option help information to be output to stdout, and exit (0) called. */ -#define ARGP_NO_HELP 0x10 - -/* Don't exit on errors (they may still result in error messages). */ -#define ARGP_NO_EXIT 0x20 - -/* Use the gnu getopt `long-only' rules for parsing arguments. */ -#define ARGP_LONG_ONLY 0x40 - -/* Turns off any message-printing/exiting options. */ -#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) - -/* Parse the options strings in ARGC & ARGV according to the options in ARGP. - FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the - index in ARGV of the first unparsed option is returned in it. If an - unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser - routine returned a non-zero value, it is returned; otherwise 0 is - returned. This function may also call exit unless the ARGP_NO_HELP flag - is set. INPUT is a pointer to a value to be passed in to the parser. */ -extern error_t argp_parse (const struct argp *__restrict __argp, - int /*argc*/, char **__restrict /*argv*/, - unsigned __flags, int *__restrict __arg_index, - void *__restrict __input); -extern error_t __argp_parse (const struct argp *__restrict __argp, - int /*argc*/, char **__restrict /*argv*/, - unsigned __flags, int *__restrict __arg_index, - void *__restrict __input); - -/* Global variables. */ - -/* GNULIB makes sure both program_invocation_name and - program_invocation_short_name are available */ -#ifdef GNULIB_PROGRAM_INVOCATION_NAME -extern char *program_invocation_name; -# undef HAVE_DECL_PROGRAM_INVOCATION_NAME -# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 -#endif - -#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME -extern char *program_invocation_short_name; -# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME -# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 -#endif - -/* If defined or set by the user program to a non-zero value, then a default - option --version is added (unless the ARGP_NO_HELP flag is used), which - will print this string followed by a newline and exit (unless the - ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ -extern const char *argp_program_version; - -/* If defined or set by the user program to a non-zero value, then a default - option --version is added (unless the ARGP_NO_HELP flag is used), which - calls this function with a stream to print the version to and a pointer to - the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is - used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ -extern void (*argp_program_version_hook) (FILE *__restrict __stream, - struct argp_state *__restrict - __state); - -/* If defined or set by the user program, it should point to string that is - the bug-reporting address for the program. It will be printed by - argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various - standard help messages), embedded in a sentence that says something like - `Report bugs to ADDR.'. */ -extern const char *argp_program_bug_address; - -/* The exit status that argp will use when exiting due to a parsing error. - If not defined or set by the user program, this defaults to EX_USAGE from - . */ -extern error_t argp_err_exit_status; - -/* Flags for argp_help. */ -#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ -#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ -#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */ -#define ARGP_HELP_LONG 0x08 /* a long help message. */ -#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ -#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ -#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) -#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ -#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to - reflect ARGP_LONG_ONLY mode. */ - -/* These ARGP_HELP flags are only understood by argp_state_help. */ -#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ -#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ - -/* The standard thing to do after a program command line parsing error, if an - error message has already been printed. */ -#define ARGP_HELP_STD_ERR \ - (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) -/* The standard thing to do after a program command line parsing error, if no - more specific error message has been printed. */ -#define ARGP_HELP_STD_USAGE \ - (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) -/* The standard thing to do in response to a --help option. */ -#define ARGP_HELP_STD_HELP \ - (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ - | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) - -/* Output a usage message for ARGP to STREAM. FLAGS are from the set - ARGP_HELP_*. */ -extern void argp_help (const struct argp *__restrict __argp, - FILE *__restrict __stream, - unsigned __flags, char *__restrict __name); -extern void __argp_help (const struct argp *__restrict __argp, - FILE *__restrict __stream, unsigned __flags, - char *__name); - -/* The following routines are intended to be called from within an argp - parsing routine (thus taking an argp_state structure as the first - argument). They may or may not print an error message and exit, depending - on the flags in STATE -- in any case, the caller should be prepared for - them *not* to exit, and should return an appropiate error after calling - them. [argp_usage & argp_error should probably be called argp_state_..., - but they're used often enough that they should be short] */ - -/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are - from the set ARGP_HELP_*. */ -extern void argp_state_help (const struct argp_state *__restrict __state, - FILE *__restrict __stream, - unsigned int __flags); -extern void __argp_state_help (const struct argp_state *__restrict __state, - FILE *__restrict __stream, - unsigned int __flags); - -/* Possibly output the standard usage message for ARGP to stderr and exit. */ -extern void argp_usage (const struct argp_state *__state); -extern void __argp_usage (const struct argp_state *__state); - -/* If appropriate, print the printf string FMT and following args, preceded - by the program name and `:', to stderr, and followed by a `Try ... --help' - message, then exit (1). */ -extern void argp_error (const struct argp_state *__restrict __state, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); -extern void __argp_error (const struct argp_state *__restrict __state, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -/* Similar to the standard gnu error-reporting function error(), but will - respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print - to STATE->err_stream. This is useful for argument parsing code that is - shared between program startup (when exiting is desired) and runtime - option parsing (when typically an error code is returned instead). The - difference between this function and argp_error is that the latter is for - *parsing errors*, and the former is for other problems that occur during - parsing but don't reflect a (syntactic) problem with the input. */ -extern void argp_failure (const struct argp_state *__restrict __state, - int __status, int __errnum, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); -extern void __argp_failure (const struct argp_state *__restrict __state, - int __status, int __errnum, - const char *__restrict __fmt, ...) - __attribute__ ((__format__ (__printf__, 4, 5))); - -/* Returns true if the option OPT is a valid short option. */ -extern int _option_is_short (const struct argp_option *__opt) __THROW; -extern int __option_is_short (const struct argp_option *__opt) __THROW; - -/* Returns true if the option OPT is in fact the last (unused) entry in an - options array. */ -extern int _option_is_end (const struct argp_option *__opt) __THROW; -extern int __option_is_end (const struct argp_option *__opt) __THROW; - -/* Return the input field for ARGP in the parser corresponding to STATE; used - by the help routines. */ -extern void *_argp_input (const struct argp *__restrict __argp, - const struct argp_state *__restrict __state) - __THROW; -extern void *__argp_input (const struct argp *__restrict __argp, - const struct argp_state *__restrict __state) - __THROW; - -#ifdef __USE_EXTERN_INLINES - -# if !_LIBC -# define __argp_usage argp_usage -# define __argp_state_help argp_state_help -# define __option_is_short _option_is_short -# define __option_is_end _option_is_end -# endif - -# ifndef ARGP_EI -# define ARGP_EI extern __inline__ -# endif - -ARGP_EI void -__argp_usage (const struct argp_state *__state) -{ - __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); -} - -ARGP_EI int -__NTH (__option_is_short (const struct argp_option *__opt)) -{ - if (__opt->flags & OPTION_DOC) - return 0; - else - { - int __key = __opt->key; - return __key > 0 && __key <= UCHAR_MAX && isprint (__key); - } -} - -ARGP_EI int -__NTH (__option_is_end (const struct argp_option *__opt)) -{ - return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; -} - -# if !_LIBC -# undef __argp_usage -# undef __argp_state_help -# undef __option_is_short -# undef __option_is_end -# endif -#endif /* Use extern inlines. */ - -#ifdef __cplusplus -} -#endif - -#endif /* argp.h */ diff --git a/src/bin/tar/lib/asnprintf.c b/src/bin/tar/lib/asnprintf.c deleted file mode 100644 index 26c3988b01..0000000000 --- a/src/bin/tar/lib/asnprintf.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Formatted output to strings. - Copyright (C) 1999, 2002, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include "vasnprintf.h" - -#include - -char * -asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) -{ - va_list args; - char *result; - - va_start (args, format); - result = vasnprintf (resultbuf, lengthp, format, args); - va_end (args); - return result; -} diff --git a/src/bin/tar/lib/at-func.c b/src/bin/tar/lib/at-func.c deleted file mode 100644 index f98c207e72..0000000000 --- a/src/bin/tar/lib/at-func.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Define an at-style functions like fstatat, unlinkat, fchownat, etc. - Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#define CALL_FUNC(F) \ - (AT_FUNC_USE_F1_COND \ - ? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \ - : AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS)) - -/* Call AT_FUNC_F1 or AT_FUNC_F2 (testing AT_FUNC_USE_F1_COND to - determine which) to operate on FILE, which is in the directory - open on descriptor FD. If possible, do it without changing the - working directory. Otherwise, resort to using save_cwd/fchdir, - then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd - fails, then give a diagnostic and exit nonzero. */ -int -AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) -{ - struct saved_cwd saved_cwd; - int saved_errno; - int err; - - if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) - return CALL_FUNC (file); - - { - char buf[OPENAT_BUFFER_SIZE]; - char *proc_file = openat_proc_name (buf, fd, file); - if (proc_file) - { - int proc_result = CALL_FUNC (proc_file); - int proc_errno = errno; - if (proc_file != buf) - free (proc_file); - /* If the syscall succeeds, or if it fails with an unexpected - errno value, then return right away. Otherwise, fall through - and resort to using save_cwd/restore_cwd. */ - if (0 <= proc_result) - return proc_result; - if (! EXPECTED_ERRNO (proc_errno)) - { - errno = proc_errno; - return proc_result; - } - } - } - - if (save_cwd (&saved_cwd) != 0) - openat_save_fail (errno); - - if (fchdir (fd) != 0) - { - saved_errno = errno; - free_cwd (&saved_cwd); - errno = saved_errno; - return -1; - } - - err = CALL_FUNC (file); - saved_errno = (err < 0 ? errno : 0); - - if (restore_cwd (&saved_cwd) != 0) - openat_restore_fail (errno); - - free_cwd (&saved_cwd); - - if (saved_errno) - errno = saved_errno; - return err; -} -#undef CALL_FUNC diff --git a/src/bin/tar/lib/backupfile.c b/src/bin/tar/lib/backupfile.c deleted file mode 100644 index adfc0e5411..0000000000 --- a/src/bin/tar/lib/backupfile.c +++ /dev/null @@ -1,364 +0,0 @@ -/* backupfile.c -- make Emacs style backup file names - - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert and David MacKenzie. - Some algorithms adapted from GNU Emacs. */ - -#include - -#include "backupfile.h" - -#include "argmatch.h" -#include "dirname.h" -#include "xalloc.h" - -#include -#include -#include -#include - -#include - -#include - -#include -#ifndef _D_EXACT_NAMLEN -# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name) -#endif -#if D_INO_IN_DIRENT -# define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0) -#else -# define REAL_DIR_ENTRY(dp) 1 -#endif - -#if ! (HAVE_PATHCONF && defined _PC_NAME_MAX) -# define pathconf(file, option) (errno = -1) -#endif - -#ifndef _POSIX_NAME_MAX -# define _POSIX_NAME_MAX 14 -#endif -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -#if defined _XOPEN_NAME_MAX -# define NAME_MAX_MINIMUM _XOPEN_NAME_MAX -#else -# define NAME_MAX_MINIMUM _POSIX_NAME_MAX -#endif - -#ifndef HAVE_DOS_FILE_NAMES -# define HAVE_DOS_FILE_NAMES 0 -#endif -#ifndef HAVE_LONG_FILE_NAMES -# define HAVE_LONG_FILE_NAMES 0 -#endif - -/* ISDIGIT differs from isdigit, as follows: - - Its arg may be any int or unsigned int; it need not be an unsigned char - or EOF. - - It's typically faster. - POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to - ISDIGIT unless it's important to use the locale's definition - of `digit' even when the host does not conform to POSIX. */ -#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) - -/* The results of opendir() in this file are not used with dirfd and fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef opendir -#undef closedir - -/* The extension added to file names to produce a simple (as opposed - to numbered) backup file name. */ -char const *simple_backup_suffix = "~"; - - -/* If FILE (which was of length FILELEN before an extension was - appended to it) is too long, replace the extension with the single - char E. If the result is still too long, remove the char just - before E. */ - -static void -check_extension (char *file, size_t filelen, char e) -{ - char *base = last_component (file); - size_t baselen = base_len (base); - size_t baselen_max = HAVE_LONG_FILE_NAMES ? 255 : NAME_MAX_MINIMUM; - - if (HAVE_DOS_FILE_NAMES || NAME_MAX_MINIMUM < baselen) - { - /* The new base name is long enough to require a pathconf check. */ - long name_max; - - /* Temporarily modify the buffer into its parent directory name, - invoke pathconf on the directory, and then restore the buffer. */ - char tmp[sizeof "."]; - memcpy (tmp, base, sizeof "."); - strcpy (base, "."); - errno = 0; - name_max = pathconf (file, _PC_NAME_MAX); - if (0 <= name_max || errno == 0) - { - long size = baselen_max = name_max; - if (name_max != size) - baselen_max = SIZE_MAX; - } - memcpy (base, tmp, sizeof "."); - } - - if (HAVE_DOS_FILE_NAMES && baselen_max <= 12) - { - /* Live within DOS's 8.3 limit. */ - char *dot = strchr (base, '.'); - if (!dot) - baselen_max = 8; - else - { - char const *second_dot = strchr (dot + 1, '.'); - baselen_max = (second_dot - ? second_dot - base - : dot + 1 - base + 3); - } - } - - if (baselen_max < baselen) - { - baselen = file + filelen - base; - if (baselen_max <= baselen) - baselen = baselen_max - 1; - base[baselen] = e; - base[baselen + 1] = '\0'; - } -} - -/* Returned values for NUMBERED_BACKUP. */ - -enum numbered_backup_result - { - /* The new backup name is the same length as an existing backup - name, so it's valid for that directory. */ - BACKUP_IS_SAME_LENGTH, - - /* Some backup names already exist, but the returned name is longer - than any of them, and its length should be checked. */ - BACKUP_IS_LONGER, - - /* There are no existing backup names. The new name's length - should be checked. */ - BACKUP_IS_NEW - }; - -/* *BUFFER contains a file name. Store into *BUFFER the next backup - name for the named file, with a version number greater than all the - existing numbered backups. Reallocate *BUFFER as necessary; its - initial allocated size is BUFFER_SIZE, which must be at least 4 - bytes longer than the file name to make room for the initially - appended ".~1". FILELEN is the length of the original file name. - The returned value indicates what kind of backup was found. If an - I/O or other read error occurs, use the highest backup number that - was found. */ - -static enum numbered_backup_result -numbered_backup (char **buffer, size_t buffer_size, size_t filelen) -{ - enum numbered_backup_result result = BACKUP_IS_NEW; - DIR *dirp; - struct dirent *dp; - char *buf = *buffer; - size_t versionlenmax = 1; - char *base = last_component (buf); - size_t base_offset = base - buf; - size_t baselen = base_len (base); - - /* Temporarily modify the buffer into its parent directory name, - open the directory, and then restore the buffer. */ - char tmp[sizeof "."]; - memcpy (tmp, base, sizeof "."); - strcpy (base, "."); - dirp = opendir (buf); - memcpy (base, tmp, sizeof "."); - strcpy (base + baselen, ".~1~"); - - if (!dirp) - return result; - - while ((dp = readdir (dirp)) != NULL) - { - char const *p; - char *q; - bool all_9s; - size_t versionlen; - size_t new_buflen; - - if (! REAL_DIR_ENTRY (dp) || _D_EXACT_NAMLEN (dp) < baselen + 4) - continue; - - if (memcmp (buf + base_offset, dp->d_name, baselen + 2) != 0) - continue; - - p = dp->d_name + baselen + 2; - - /* Check whether this file has a version number and if so, - whether it is larger. Use string operations rather than - integer arithmetic, to avoid problems with integer overflow. */ - - if (! ('1' <= *p && *p <= '9')) - continue; - all_9s = (*p == '9'); - for (versionlen = 1; ISDIGIT (p[versionlen]); versionlen++) - all_9s &= (p[versionlen] == '9'); - - if (! (p[versionlen] == '~' && !p[versionlen + 1] - && (versionlenmax < versionlen - || (versionlenmax == versionlen - && memcmp (buf + filelen + 2, p, versionlen) <= 0)))) - continue; - - /* This directory has the largest version number seen so far. - Append this highest numbered extension to the file name, - prepending '0' to the number if it is all 9s. */ - - versionlenmax = all_9s + versionlen; - result = (all_9s ? BACKUP_IS_LONGER : BACKUP_IS_SAME_LENGTH); - new_buflen = filelen + 2 + versionlenmax + 1; - if (buffer_size <= new_buflen) - { - buf = xnrealloc (buf, 2, new_buflen); - buffer_size = new_buflen * 2; - } - q = buf + filelen; - *q++ = '.'; - *q++ = '~'; - *q = '0'; - q += all_9s; - memcpy (q, p, versionlen + 2); - - /* Add 1 to the version number. */ - - q += versionlen; - while (*--q == '9') - *q = '0'; - ++*q; - } - - closedir (dirp); - *buffer = buf; - return result; -} - -/* Return the name of the new backup file for the existing file FILE, - allocated with malloc. Report an error and fail if out of memory. - Do not call this function if backup_type == no_backups. */ - -char * -find_backup_file_name (char const *file, enum backup_type backup_type) -{ - size_t filelen = strlen (file); - char *s; - size_t ssize; - bool simple = true; - - /* Allow room for simple or ".~N~" backups. The guess must be at - least sizeof ".~1~", but otherwise will be adjusted as needed. */ - size_t simple_backup_suffix_size = strlen (simple_backup_suffix) + 1; - size_t backup_suffix_size_guess = simple_backup_suffix_size; - enum { GUESS = sizeof ".~12345~" }; - if (backup_suffix_size_guess < GUESS) - backup_suffix_size_guess = GUESS; - - ssize = filelen + backup_suffix_size_guess + 1; - s = xmalloc (ssize); - memcpy (s, file, filelen + 1); - - if (backup_type != simple_backups) - switch (numbered_backup (&s, ssize, filelen)) - { - case BACKUP_IS_SAME_LENGTH: - return s; - - case BACKUP_IS_LONGER: - simple = false; - break; - - case BACKUP_IS_NEW: - simple = (backup_type == numbered_existing_backups); - break; - } - - if (simple) - memcpy (s + filelen, simple_backup_suffix, simple_backup_suffix_size); - check_extension (s, filelen, '~'); - return s; -} - -static char const * const backup_args[] = -{ - /* In a series of synonyms, present the most meaningful first, so - that argmatch_valid be more readable. */ - "none", "off", - "simple", "never", - "existing", "nil", - "numbered", "t", - NULL -}; - -static const enum backup_type backup_types[] = -{ - no_backups, no_backups, - simple_backups, simple_backups, - numbered_existing_backups, numbered_existing_backups, - numbered_backups, numbered_backups -}; - -/* Ensure that these two vectors have the same number of elements, - not counting the final NULL in the first one. */ -ARGMATCH_VERIFY (backup_args, backup_types); - -/* Return the type of backup specified by VERSION. - If VERSION is NULL or the empty string, return numbered_existing_backups. - If VERSION is invalid or ambiguous, fail with a diagnostic appropriate - for the specified CONTEXT. Unambiguous abbreviations are accepted. */ - -enum backup_type -get_version (char const *context, char const *version) -{ - if (version == 0 || *version == 0) - return numbered_existing_backups; - else - return XARGMATCH (context, version, backup_args, backup_types); -} - - -/* Return the type of backup specified by VERSION. - If VERSION is NULL, use the value of the envvar VERSION_CONTROL. - If the specified string is invalid or ambiguous, fail with a diagnostic - appropriate for the specified CONTEXT. - Unambiguous abbreviations are accepted. */ - -enum backup_type -xget_version (char const *context, char const *version) -{ - if (version && *version) - return get_version (context, version); - else - return get_version ("$VERSION_CONTROL", getenv ("VERSION_CONTROL")); -} diff --git a/src/bin/tar/lib/backupfile.h b/src/bin/tar/lib/backupfile.h deleted file mode 100644 index 7b44e58063..0000000000 --- a/src/bin/tar/lib/backupfile.h +++ /dev/null @@ -1,61 +0,0 @@ -/* backupfile.h -- declarations for making Emacs style backup file names - - Copyright (C) 1990, 1991, 1992, 1997, 1998, 1999, 2003, 2004 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef BACKUPFILE_H_ -# define BACKUPFILE_H_ - -# ifdef __cplusplus -extern "C" { -# endif - - -/* When to make backup files. */ -enum backup_type -{ - /* Never make backups. */ - no_backups, - - /* Make simple backups of every file. */ - simple_backups, - - /* Make numbered backups of files that already have numbered backups, - and simple backups of the others. */ - numbered_existing_backups, - - /* Make numbered backups of every file. */ - numbered_backups -}; - -# define VALID_BACKUP_TYPE(Type) \ - ((unsigned int) (Type) <= numbered_backups) - -extern char const *simple_backup_suffix; - -char *find_backup_file_name (char const *, enum backup_type); -enum backup_type get_version (char const *context, char const *arg); -enum backup_type xget_version (char const *context, char const *arg); -void addext (char *, char const *, int); - - -# ifdef __cplusplus -} -# endif - -#endif /* ! BACKUPFILE_H_ */ diff --git a/src/bin/tar/lib/basename.c b/src/bin/tar/lib/basename.c deleted file mode 100644 index fbe17ff910..0000000000 --- a/src/bin/tar/lib/basename.c +++ /dev/null @@ -1,129 +0,0 @@ -/* basename.c -- return the last element in a file name - - Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "dirname.h" - -#include -#include "xalloc.h" -#include "xstrndup.h" - -/* Return the address of the last file name component of NAME. If - NAME has no relative file name components because it is a file - system root, return the empty string. */ - -char * -last_component (char const *name) -{ - char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); - char const *p; - bool saw_slash = false; - - while (ISSLASH (*base)) - base++; - - for (p = base; *p; p++) - { - if (ISSLASH (*p)) - saw_slash = true; - else if (saw_slash) - { - base = p; - saw_slash = false; - } - } - - return (char *) base; -} - - -/* In general, we can't use the builtin `basename' function if available, - since it has different meanings in different environments. - In some environments the builtin `basename' modifies its argument. - - Return the last file name component of NAME, allocated with - xmalloc. On systems with drive letters, a leading "./" - distinguishes relative names that would otherwise look like a drive - letter. Unlike POSIX basename(), NAME cannot be NULL, - base_name("") returns "", and the first trailing slash is not - stripped. - - If lstat (NAME) would succeed, then { chdir (dir_name (NAME)); - lstat (base_name (NAME)); } will access the same file. Likewise, - if the sequence { chdir (dir_name (NAME)); - rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME - to "foo" in the same directory NAME was in. */ - -char * -base_name (char const *name) -{ - char const *base = last_component (name); - size_t length; - - /* If there is no last component, then name is a file system root or the - empty string. */ - if (! *base) - return xstrndup (name, base_len (name)); - - /* Collapse a sequence of trailing slashes into one. */ - length = base_len (base); - if (ISSLASH (base[length])) - length++; - - /* On systems with drive letters, `a/b:c' must return `./b:c' rather - than `b:c' to avoid confusion with a drive letter. On systems - with pure POSIX semantics, this is not an issue. */ - if (FILE_SYSTEM_PREFIX_LEN (base)) - { - char *p = xmalloc (length + 3); - p[0] = '.'; - p[1] = '/'; - memcpy (p + 2, base, length); - p[length + 2] = '\0'; - return p; - } - - /* Finally, copy the basename. */ - return xstrndup (base, length); -} - -/* Return the length of the basename NAME. Typically NAME is the - value returned by base_name or last_component. Act like strlen - (NAME), except omit all trailing slashes. */ - -size_t -base_len (char const *name) -{ - size_t len; - size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); - - for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--) - continue; - - if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1 - && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2]) - return 2; - - if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len - && len == prefix_len && ISSLASH (name[prefix_len])) - return prefix_len + 1; - - return len; -} diff --git a/src/bin/tar/lib/canonicalize-lgpl.c b/src/bin/tar/lib/canonicalize-lgpl.c deleted file mode 100644 index 2ed149bcb0..0000000000 --- a/src/bin/tar/lib/canonicalize-lgpl.c +++ /dev/null @@ -1,363 +0,0 @@ -/* Return the canonical absolute name of a given file. - Copyright (C) 1996-2003, 2005-2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Avoid a clash of our rpl_realpath() function with the prototype in - on Solaris 2.5.1. */ -#undef realpath - -#if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC - -#include - -/* Specification. */ -#include "canonicalize.h" - -#include -#include -#include - -#if HAVE_UNISTD_H || defined _LIBC -# include -#endif - -#include - -#if HAVE_SYS_PARAM_H || defined _LIBC -# include -#endif -#ifndef MAXSYMLINKS -# define MAXSYMLINKS 20 -#endif - -#include - -#include -#ifndef _LIBC -# define __set_errno(e) errno = (e) -# ifndef ENAMETOOLONG -# define ENAMETOOLONG EINVAL -# endif -#endif - -#ifdef _LIBC -# include -#else -# define SHLIB_COMPAT(lib, introduced, obsoleted) 0 -# define versioned_symbol(lib, local, symbol, version) -# define compat_symbol(lib, local, symbol, version) -# define weak_alias(local, symbol) -# define __canonicalize_file_name canonicalize_file_name -# define __realpath rpl_realpath -# include "pathmax.h" -# include "malloca.h" -# if HAVE_GETCWD -# ifdef VMS - /* We want the directory in Unix syntax, not in VMS syntax. */ -# define __getcwd(buf, max) getcwd (buf, max, 0) -# else -# define __getcwd getcwd -# endif -# else -# define __getcwd(buf, max) getwd (buf) -# endif -# define __readlink readlink - /* On systems without symbolic links, call stat() instead of lstat(). */ -# if !defined S_ISNLK && !HAVE_READLINK -# define lstat stat -# endif -#endif - -/* Return the canonical absolute name of file NAME. A canonical name - does not contain any `.', `..' components nor any repeated path - separators ('/') or symlinks. All path components must exist. If - RESOLVED is null, the result is malloc'd; otherwise, if the - canonical name is PATH_MAX chars or more, returns null with `errno' - set to ENAMETOOLONG; if the name fits in fewer than PATH_MAX chars, - returns the name in RESOLVED. If the name cannot be resolved and - RESOLVED is non-NULL, it contains the path of the first component - that cannot be resolved. If the path can be resolved, RESOLVED - holds the same value as the value returned. */ - -char * -__realpath (const char *name, char *resolved) -{ - char *rpath, *dest, *extra_buf = NULL; - const char *start, *end, *rpath_limit; - long int path_max; -#if HAVE_READLINK - int num_links = 0; -#endif - - if (name == NULL) - { - /* As per Single Unix Specification V2 we must return an error if - either parameter is a null pointer. We extend this to allow - the RESOLVED parameter to be NULL in case the we are expected to - allocate the room for the return value. */ - __set_errno (EINVAL); - return NULL; - } - - if (name[0] == '\0') - { - /* As per Single Unix Specification V2 we must return an error if - the name argument points to an empty string. */ - __set_errno (ENOENT); - return NULL; - } - -#ifdef PATH_MAX - path_max = PATH_MAX; -#else - path_max = pathconf (name, _PC_PATH_MAX); - if (path_max <= 0) - path_max = 1024; -#endif - - if (resolved == NULL) - { - rpath = malloc (path_max); - if (rpath == NULL) - { - /* It's easier to set errno to ENOMEM than to rely on the - 'malloc-posix' gnulib module. */ - errno = ENOMEM; - return NULL; - } - } - else - rpath = resolved; - rpath_limit = rpath + path_max; - - if (name[0] != '/') - { - if (!__getcwd (rpath, path_max)) - { - rpath[0] = '\0'; - goto error; - } - dest = strchr (rpath, '\0'); - } - else - { - rpath[0] = '/'; - dest = rpath + 1; - } - - for (start = end = name; *start; start = end) - { -#ifdef _LIBC - struct stat64 st; -#else - struct stat st; -#endif - - /* Skip sequence of multiple path-separators. */ - while (*start == '/') - ++start; - - /* Find end of path component. */ - for (end = start; *end && *end != '/'; ++end) - /* Nothing. */; - - if (end - start == 0) - break; - else if (end - start == 1 && start[0] == '.') - /* nothing */; - else if (end - start == 2 && start[0] == '.' && start[1] == '.') - { - /* Back up to previous component, ignore if at root already. */ - if (dest > rpath + 1) - while ((--dest)[-1] != '/'); - } - else - { - size_t new_size; - - if (dest[-1] != '/') - *dest++ = '/'; - - if (dest + (end - start) >= rpath_limit) - { - ptrdiff_t dest_offset = dest - rpath; - char *new_rpath; - - if (resolved) - { - __set_errno (ENAMETOOLONG); - if (dest > rpath + 1) - dest--; - *dest = '\0'; - goto error; - } - new_size = rpath_limit - rpath; - if (end - start + 1 > path_max) - new_size += end - start + 1; - else - new_size += path_max; - new_rpath = (char *) realloc (rpath, new_size); - if (new_rpath == NULL) - { - /* It's easier to set errno to ENOMEM than to rely on the - 'realloc-posix' gnulib module. */ - errno = ENOMEM; - goto error; - } - rpath = new_rpath; - rpath_limit = rpath + new_size; - - dest = rpath + dest_offset; - } - -#ifdef _LIBC - dest = __mempcpy (dest, start, end - start); -#else - memcpy (dest, start, end - start); - dest += end - start; -#endif - *dest = '\0'; - -#ifdef _LIBC - if (__lxstat64 (_STAT_VER, rpath, &st) < 0) -#else - if (lstat (rpath, &st) < 0) -#endif - goto error; - -#if HAVE_READLINK - if (S_ISLNK (st.st_mode)) - { - char *buf; - size_t len; - int n; - - if (++num_links > MAXSYMLINKS) - { - __set_errno (ELOOP); - goto error; - } - - buf = malloca (path_max); - if (!buf) - { - errno = ENOMEM; - goto error; - } - - n = __readlink (rpath, buf, path_max); - if (n < 0) - { - int saved_errno = errno; - freea (buf); - errno = saved_errno; - goto error; - } - buf[n] = '\0'; - - if (!extra_buf) - { - extra_buf = malloca (path_max); - if (!extra_buf) - { - freea (buf); - errno = ENOMEM; - goto error; - } - } - - len = strlen (end); - if ((long int) (n + len) >= path_max) - { - freea (buf); - __set_errno (ENAMETOOLONG); - goto error; - } - - /* Careful here, end may be a pointer into extra_buf... */ - memmove (&extra_buf[n], end, len + 1); - name = end = memcpy (extra_buf, buf, n); - - if (buf[0] == '/') - dest = rpath + 1; /* It's an absolute symlink */ - else - /* Back up to previous component, ignore if at root already: */ - if (dest > rpath + 1) - while ((--dest)[-1] != '/'); - } -#endif - } - } - if (dest > rpath + 1 && dest[-1] == '/') - --dest; - *dest = '\0'; - - if (extra_buf) - freea (extra_buf); - - return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath; - -error: - { - int saved_errno = errno; - if (extra_buf) - freea (extra_buf); - if (resolved) - strcpy (resolved, rpath); - else - free (rpath); - errno = saved_errno; - } - return NULL; -} -#ifdef _LIBC -versioned_symbol (libc, __realpath, realpath, GLIBC_2_3); -#endif - - -#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) -char * -__old_realpath (const char *name, char *resolved) -{ - if (resolved == NULL) - { - __set_errno (EINVAL); - return NULL; - } - - return __realpath (name, resolved); -} -compat_symbol (libc, __old_realpath, realpath, GLIBC_2_0); -#endif - - -char * -__canonicalize_file_name (const char *name) -{ - return __realpath (name, NULL); -} -weak_alias (__canonicalize_file_name, canonicalize_file_name) - -#else - -/* This declaration is solely to ensure that after preprocessing - this file is never empty. */ -typedef int dummy; - -#endif diff --git a/src/bin/tar/lib/canonicalize.h b/src/bin/tar/lib/canonicalize.h deleted file mode 100644 index 5c4d3f1a5e..0000000000 --- a/src/bin/tar/lib/canonicalize.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Return the canonical absolute name of a given file. - Copyright (C) 1996-2007 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef CANONICALIZE_H_ -# define CANONICALIZE_H_ - -# if GNULIB_CANONICALIZE -enum canonicalize_mode_t - { - /* All components must exist. */ - CAN_EXISTING = 0, - - /* All components excluding last one must exist. */ - CAN_ALL_BUT_LAST = 1, - - /* No requirements on components existence. */ - CAN_MISSING = 2 - }; -typedef enum canonicalize_mode_t canonicalize_mode_t; - -/* Return a malloc'd string containing the canonical absolute name of - the named file. This acts like canonicalize_file_name, except that - whether components must exist depends on the canonicalize_mode_t - argument. */ -char *canonicalize_filename_mode (const char *, canonicalize_mode_t); -# endif - -# if HAVE_DECL_CANONICALIZE_FILE_NAME -# include -# else -/* Return a malloc'd string containing the canonical absolute name of - the named file. If any file name component does not exist or is a - symlink to a nonexistent file, return NULL. A canonical name does - not contain any `.', `..' components nor any repeated file name - separators ('/') or symlinks. */ -char *canonicalize_file_name (const char *); -# endif - -#endif /* !CANONICALIZE_H_ */ diff --git a/src/bin/tar/lib/chdir-long.c b/src/bin/tar/lib/chdir-long.c deleted file mode 100644 index 9d20e20747..0000000000 --- a/src/bin/tar/lib/chdir-long.c +++ /dev/null @@ -1,266 +0,0 @@ -/* provide a chdir function that tries not to fail due to ENAMETOOLONG - Copyright (C) 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -#include "chdir-long.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "openat.h" -#include "system.h" - -#ifndef PATH_MAX -# error "compile this file only if your system defines PATH_MAX" -#endif - -struct cd_buf -{ - int fd; -}; - -static inline void -cdb_init (struct cd_buf *cdb) -{ - cdb->fd = AT_FDCWD; -} - -static inline int -cdb_fchdir (struct cd_buf const *cdb) -{ - return fchdir (cdb->fd); -} - -static inline void -cdb_free (struct cd_buf const *cdb) -{ - if (0 <= cdb->fd) - { - bool close_fail = close (cdb->fd); - assert (! close_fail); - } -} - -/* Given a file descriptor of an open directory (or AT_FDCWD), CDB->fd, - try to open the CDB->fd-relative directory, DIR. If the open succeeds, - update CDB->fd with the resulting descriptor, close the incoming file - descriptor, and return zero. Upon failure, return -1 and set errno. */ -static int -cdb_advance_fd (struct cd_buf *cdb, char const *dir) -{ - int new_fd = openat (cdb->fd, dir, - O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK); - if (new_fd < 0) - return -1; - - cdb_free (cdb); - cdb->fd = new_fd; - - return 0; -} - -/* Return a pointer to the first non-slash in S. */ -static inline char * -find_non_slash (char const *s) -{ - size_t n_slash = strspn (s, "/"); - return (char *) s + n_slash; -} - -/* This is a function much like chdir, but without the PATH_MAX limitation - on the length of the directory name. A significant difference is that - it must be able to modify (albeit only temporarily) the directory - name. It handles an arbitrarily long directory name by operating - on manageable portions of the name. On systems without the openat - syscall, this means changing the working directory to more and more - `distant' points along the long directory name and then restoring - the working directory. If any of those attempts to save or restore - the working directory fails, this function exits nonzero. - - Note that this function may still fail with errno == ENAMETOOLONG, but - only if the specified directory name contains a component that is long - enough to provoke such a failure all by itself (e.g. if the component - has length PATH_MAX or greater on systems that define PATH_MAX). */ - -int -chdir_long (char *dir) -{ - int e = chdir (dir); - if (e == 0 || errno != ENAMETOOLONG) - return e; - - { - size_t len = strlen (dir); - char *dir_end = dir + len; - struct cd_buf cdb; - size_t n_leading_slash; - - cdb_init (&cdb); - - /* If DIR is the empty string, then the chdir above - must have failed and set errno to ENOENT. */ - assert (0 < len); - assert (PATH_MAX <= len); - - /* Count leading slashes. */ - n_leading_slash = strspn (dir, "/"); - - /* Handle any leading slashes as well as any name that matches - the regular expression, m!^//hostname[/]*! . Handling this - prefix separately usually results in a single additional - cdb_advance_fd call, but it's worthwhile, since it makes the - code in the following loop cleaner. */ - if (n_leading_slash == 2) - { - int err; - /* Find next slash. - We already know that dir[2] is neither a slash nor '\0'. */ - char *slash = memchr (dir + 3, '/', dir_end - (dir + 3)); - if (slash == NULL) - { - errno = ENAMETOOLONG; - return -1; - } - *slash = '\0'; - err = cdb_advance_fd (&cdb, dir); - *slash = '/'; - if (err != 0) - goto Fail; - dir = find_non_slash (slash + 1); - } - else if (n_leading_slash) - { - if (cdb_advance_fd (&cdb, "/") != 0) - goto Fail; - dir += n_leading_slash; - } - - assert (*dir != '/'); - assert (dir <= dir_end); - - while (PATH_MAX <= dir_end - dir) - { - int err; - /* Find a slash that is PATH_MAX or fewer bytes away from dir. - I.e. see if there is a slash that will give us a name of - length PATH_MAX-1 or less. */ - char *slash = memrchr (dir, '/', PATH_MAX); - if (slash == NULL) - { - errno = ENAMETOOLONG; - return -1; - } - - *slash = '\0'; - assert (slash - dir < PATH_MAX); - err = cdb_advance_fd (&cdb, dir); - *slash = '/'; - if (err != 0) - goto Fail; - - dir = find_non_slash (slash + 1); - } - - if (dir < dir_end) - { - if (cdb_advance_fd (&cdb, dir) != 0) - goto Fail; - } - - if (cdb_fchdir (&cdb) != 0) - goto Fail; - - cdb_free (&cdb); - return 0; - - Fail: - { - int saved_errno = errno; - cdb_free (&cdb); - errno = saved_errno; - return -1; - } - } -} - -#if TEST_CHDIR - -# include -# include "closeout.h" -# include "error.h" - -char *program_name; - -int -main (int argc, char *argv[]) -{ - char *line = NULL; - size_t n = 0; - int len; - - program_name = argv[0]; - atexit (close_stdout); - - len = getline (&line, &n, stdin); - if (len < 0) - { - int saved_errno = errno; - if (feof (stdin)) - exit (0); - - error (EXIT_FAILURE, saved_errno, - "reading standard input"); - } - else if (len == 0) - exit (0); - - if (line[len-1] == '\n') - line[len-1] = '\0'; - - if (chdir_long (line) != 0) - error (EXIT_FAILURE, errno, - "chdir_long failed: %s", line); - - if (argc <= 1) - { - /* Using `pwd' here makes sense only if it is a robust implementation, - like the one in coreutils after the 2004-04-19 changes. */ - char const *cmd = "pwd"; - execlp (cmd, (char *) NULL); - error (EXIT_FAILURE, errno, "%s", cmd); - } - - fclose (stdin); - fclose (stderr); - - exit (EXIT_SUCCESS); -} -#endif - -/* -Local Variables: -compile-command: "gcc -DTEST_CHDIR=1 -g -O -W -Wall chdir-long.c libcoreutils.a" -End: -*/ diff --git a/src/bin/tar/lib/chdir-long.h b/src/bin/tar/lib/chdir-long.h deleted file mode 100644 index 4852b40d16..0000000000 --- a/src/bin/tar/lib/chdir-long.h +++ /dev/null @@ -1,35 +0,0 @@ -/* provide a chdir function that tries not to fail due to ENAMETOOLONG - Copyright (C) 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include -#include - -#ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# endif -#endif - -/* On systems without PATH_MAX, presume that chdir accepts - arbitrarily long directory names. */ -#ifndef PATH_MAX -# define chdir_long(Dir) chdir (Dir) -#else -int chdir_long (char *dir); -#endif diff --git a/src/bin/tar/lib/chown.c b/src/bin/tar/lib/chown.c deleted file mode 100644 index b7786f6205..0000000000 --- a/src/bin/tar/lib/chown.c +++ /dev/null @@ -1,104 +0,0 @@ -/* provide consistent interface to chown for systems that don't interpret - an ID of -1 as meaning `don't change the corresponding ID'. - - Copyright (C) 1997, 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -/* Specification. */ -#include - -#include -#include -#include -#include -#include - -/* Below we refer to the system's chown(). */ -#undef chown - -/* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef open -#undef close - -/* Provide a more-closely POSIX-conforming version of chown on - systems with one or both of the following problems: - - chown doesn't treat an ID of -1 as meaning - `don't change the corresponding ID'. - - chown doesn't dereference symlinks. */ - -int -rpl_chown (const char *file, uid_t uid, gid_t gid) -{ -#if CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE - if (gid == (gid_t) -1 || uid == (uid_t) -1) - { - struct stat file_stats; - - /* Stat file to get id(s) that should remain unchanged. */ - if (stat (file, &file_stats)) - return -1; - - if (gid == (gid_t) -1) - gid = file_stats.st_gid; - - if (uid == (uid_t) -1) - uid = file_stats.st_uid; - } -#endif - -#if CHOWN_MODIFIES_SYMLINK - { - /* Handle the case in which the system-supplied chown function - does *not* follow symlinks. Instead, it changes permissions - on the symlink itself. To work around that, we open the - file (but this can fail due to lack of read or write permission) and - use fchown on the resulting descriptor. */ - int open_flags = O_NONBLOCK | O_NOCTTY; - int fd = open (file, O_RDONLY | open_flags); - if (0 <= fd - || (errno == EACCES - && 0 <= (fd = open (file, O_WRONLY | open_flags)))) - { - int result = fchown (fd, uid, gid); - int saved_errno = errno; - - /* POSIX says fchown can fail with errno == EINVAL on sockets, - so fall back on chown in that case. */ - struct stat sb; - bool fchown_socket_failure = - (result != 0 && saved_errno == EINVAL - && fstat (fd, &sb) == 0 && S_ISFIFO (sb.st_mode)); - - close (fd); - - if (! fchown_socket_failure) - { - errno = saved_errno; - return result; - } - } - else if (errno != EACCES) - return -1; - } -#endif - - return chown (file, uid, gid); -} diff --git a/src/bin/tar/lib/close-stream.c b/src/bin/tar/lib/close-stream.c deleted file mode 100644 index 2a1f8a4a0b..0000000000 --- a/src/bin/tar/lib/close-stream.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Close a stream, with nicer error checking than fclose's. - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "close-stream.h" - -#include -#include - -#include "fpending.h" - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -/* Close STREAM. Return 0 if successful, EOF (setting errno) - otherwise. A failure might set errno to 0 if the error number - cannot be determined. - - If a program writes *anything* to STREAM, that program should close - STREAM and make sure that it succeeds before exiting. Otherwise, - suppose that you go to the extreme of checking the return status - of every function that does an explicit write to STREAM. The last - printf can succeed in writing to the internal stream buffer, and yet - the fclose(STREAM) could still fail (due e.g., to a disk full error) - when it tries to write out that buffered data. Thus, you would be - left with an incomplete output file and the offending program would - exit successfully. Even calling fflush is not always sufficient, - since some file systems (NFS and CODA) buffer written/flushed data - until an actual close call. - - Besides, it's wasteful to check the return value from every call - that writes to STREAM -- just let the internal stream state record - the failure. That's what the ferror test is checking below. */ - -int -close_stream (FILE *stream) -{ - bool some_pending = (__fpending (stream) != 0); - bool prev_fail = (ferror (stream) != 0); - bool fclose_fail = (fclose (stream) != 0); - - /* Return an error indication if there was a previous failure or if - fclose failed, with one exception: ignore an fclose failure if - there was no previous error, no data remains to be flushed, and - fclose failed with EBADF. That can happen when a program like cp - is invoked like this `cp a b >&-' (i.e., with standard output - closed) and doesn't generate any output (hence no previous error - and nothing to be flushed). */ - - if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) - { - if (! fclose_fail) - errno = 0; - return EOF; - } - - return 0; -} diff --git a/src/bin/tar/lib/close-stream.h b/src/bin/tar/lib/close-stream.h deleted file mode 100644 index be3d4196b0..0000000000 --- a/src/bin/tar/lib/close-stream.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -int close_stream (FILE *stream); diff --git a/src/bin/tar/lib/closeout.c b/src/bin/tar/lib/closeout.c deleted file mode 100644 index 830f16f8ae..0000000000 --- a/src/bin/tar/lib/closeout.c +++ /dev/null @@ -1,86 +0,0 @@ -/* Close standard output and standard error, exiting with a diagnostic on error. - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "closeout.h" - -#include -#include -#include - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -#include "close-stream.h" -#include "error.h" -#include "exitfail.h" -#include "quotearg.h" - -static const char *file_name; - -/* Set the file name to be reported in the event an error is detected - by close_stdout. */ -void -close_stdout_set_file_name (const char *file) -{ - file_name = file; -} - -/* Close standard output. On error, issue a diagnostic and _exit - with status 'exit_failure'. - - Also close standard error. On error, _exit with status 'exit_failure'. - - Since close_stdout is commonly registered via 'atexit', POSIX - and the C standard both say that it should not call 'exit', - because the behavior is undefined if 'exit' is called more than - once. So it calls '_exit' instead of 'exit'. If close_stdout - is registered via atexit before other functions are registered, - the other functions can act before this _exit is invoked. - - Applications that use close_stdout should flush any streams - other than stdout and stderr before exiting, since the call to - _exit will bypass other buffer flushing. Applications should - be flushing and closing other streams anyway, to check for I/O - errors. Also, applications should not use tmpfile, since _exit - can bypass the removal of these files. - - It's important to detect such failures and exit nonzero because many - tools (most notably `make' and other build-management systems) depend - on being able to detect failure in other tools via their exit status. */ - -void -close_stdout (void) -{ - if (close_stream (stdout) != 0) - { - char const *write_error = _("write error"); - if (file_name) - error (0, errno, "%s: %s", quotearg_colon (file_name), - write_error); - else - error (0, errno, "%s", write_error); - - _exit (exit_failure); - } - - if (close_stream (stderr) != 0) - _exit (exit_failure); -} diff --git a/src/bin/tar/lib/closeout.h b/src/bin/tar/lib/closeout.h deleted file mode 100644 index 8bed23b5f1..0000000000 --- a/src/bin/tar/lib/closeout.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Close standard output and standard error. - - Copyright (C) 1998, 2000, 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef CLOSEOUT_H -# define CLOSEOUT_H 1 - -# ifdef __cplusplus -extern "C" { -# endif - -void close_stdout_set_file_name (const char *file); -void close_stdout (void); - -# ifdef __cplusplus -} -# endif - -#endif diff --git a/src/bin/tar/lib/config.charset b/src/bin/tar/lib/config.charset deleted file mode 100755 index 148ea441fa..0000000000 --- a/src/bin/tar/lib/config.charset +++ /dev/null @@ -1,639 +0,0 @@ -#! /bin/sh -# Output a system dependent table of character encoding aliases. -# -# Copyright (C) 2000-2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The table consists of lines of the form -# ALIAS CANONICAL -# -# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". -# ALIAS is compared in a case sensitive way. -# -# CANONICAL is the GNU canonical name for this character encoding. -# It must be an encoding supported by libiconv. Support by GNU libc is -# also desirable. CANONICAL is case insensitive. Usually an upper case -# MIME charset name is preferred. -# The current list of GNU canonical charset names is as follows. -# -# name MIME? used by which systems -# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin -# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd darwin -# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd darwin -# ISO-8859-3 Y glibc solaris -# ISO-8859-4 Y osf solaris freebsd netbsd darwin -# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd darwin -# ISO-8859-6 Y glibc aix hpux solaris -# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd darwin -# ISO-8859-8 Y glibc aix hpux osf solaris -# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin -# ISO-8859-13 glibc netbsd darwin -# ISO-8859-14 glibc -# ISO-8859-15 glibc aix osf solaris freebsd darwin -# KOI8-R Y glibc solaris freebsd netbsd darwin -# KOI8-U Y glibc freebsd netbsd darwin -# KOI8-T glibc -# CP437 dos -# CP775 dos -# CP850 aix osf dos -# CP852 dos -# CP855 dos -# CP856 aix -# CP857 dos -# CP861 dos -# CP862 dos -# CP864 dos -# CP865 dos -# CP866 freebsd netbsd darwin dos -# CP869 dos -# CP874 woe32 dos -# CP922 aix -# CP932 aix woe32 dos -# CP943 aix -# CP949 osf woe32 dos -# CP950 woe32 dos -# CP1046 aix -# CP1124 aix -# CP1125 dos -# CP1129 aix -# CP1250 woe32 -# CP1251 glibc solaris netbsd darwin woe32 -# CP1252 aix woe32 -# CP1253 woe32 -# CP1254 woe32 -# CP1255 glibc woe32 -# CP1256 woe32 -# CP1257 woe32 -# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin -# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin -# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin -# EUC-TW glibc aix hpux irix osf solaris netbsd -# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin -# BIG5-HKSCS glibc solaris -# GBK glibc aix osf solaris woe32 dos -# GB18030 glibc solaris netbsd -# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin -# JOHAB glibc solaris woe32 -# TIS-620 glibc aix hpux osf solaris -# VISCII Y glibc -# TCVN5712-1 glibc -# GEORGIAN-PS glibc -# HP-ROMAN8 hpux -# HP-ARABIC8 hpux -# HP-GREEK8 hpux -# HP-HEBREW8 hpux -# HP-TURKISH8 hpux -# HP-KANA8 hpux -# DEC-KANJI osf -# DEC-HANYU osf -# UTF-8 Y glibc aix hpux osf solaris netbsd darwin -# -# Note: Names which are not marked as being a MIME name should not be used in -# Internet protocols for information interchange (mail, news, etc.). -# -# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications -# must understand both names and treat them as equivalent. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM - -host="$1" -os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` -echo "# This file contains a table of character encoding aliases," -echo "# suitable for operating system '${os}'." -echo "# It was automatically generated from config.charset." -# List of references, updated during installation: -echo "# Packages using this file: " -case "$os" in - linux-gnulibc1*) - # Linux libc5 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "C ASCII" - echo "POSIX ASCII" - for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \ - en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \ - en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \ - es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \ - et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \ - fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \ - it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \ - sv_FI sv_SE; do - echo "$l ISO-8859-1" - echo "$l.iso-8859-1 ISO-8859-1" - echo "$l.iso-8859-15 ISO-8859-15" - echo "$l.iso-8859-15@euro ISO-8859-15" - echo "$l@euro ISO-8859-15" - echo "$l.cp-437 CP437" - echo "$l.cp-850 CP850" - echo "$l.cp-1252 CP1252" - echo "$l.cp-1252@euro CP1252" - #echo "$l.atari-st ATARI-ST" # not a commonly used encoding - echo "$l.utf-8 UTF-8" - echo "$l.utf-8@euro UTF-8" - done - for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \ - sl_SI sr sr_CS sr_YU; do - echo "$l ISO-8859-2" - echo "$l.iso-8859-2 ISO-8859-2" - echo "$l.cp-852 CP852" - echo "$l.cp-1250 CP1250" - echo "$l.utf-8 UTF-8" - done - for l in mk mk_MK ru ru_RU; do - echo "$l ISO-8859-5" - echo "$l.iso-8859-5 ISO-8859-5" - echo "$l.koi8-r KOI8-R" - echo "$l.cp-866 CP866" - echo "$l.cp-1251 CP1251" - echo "$l.utf-8 UTF-8" - done - for l in ar ar_SA; do - echo "$l ISO-8859-6" - echo "$l.iso-8859-6 ISO-8859-6" - echo "$l.cp-864 CP864" - #echo "$l.cp-868 CP868" # not a commonly used encoding - echo "$l.cp-1256 CP1256" - echo "$l.utf-8 UTF-8" - done - for l in el el_GR gr gr_GR; do - echo "$l ISO-8859-7" - echo "$l.iso-8859-7 ISO-8859-7" - echo "$l.cp-869 CP869" - echo "$l.cp-1253 CP1253" - echo "$l.cp-1253@euro CP1253" - echo "$l.utf-8 UTF-8" - echo "$l.utf-8@euro UTF-8" - done - for l in he he_IL iw iw_IL; do - echo "$l ISO-8859-8" - echo "$l.iso-8859-8 ISO-8859-8" - echo "$l.cp-862 CP862" - echo "$l.cp-1255 CP1255" - echo "$l.utf-8 UTF-8" - done - for l in tr tr_TR; do - echo "$l ISO-8859-9" - echo "$l.iso-8859-9 ISO-8859-9" - echo "$l.cp-857 CP857" - echo "$l.cp-1254 CP1254" - echo "$l.utf-8 UTF-8" - done - for l in lt lt_LT lv lv_LV; do - #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name - echo "$l ISO-8859-13" - done - for l in ru_UA uk uk_UA; do - echo "$l KOI8-U" - done - for l in zh zh_CN; do - #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name - echo "$l GB2312" - done - for l in ja ja_JP ja_JP.EUC; do - echo "$l EUC-JP" - done - for l in ko ko_KR; do - echo "$l EUC-KR" - done - for l in th th_TH; do - echo "$l TIS-620" - done - for l in fa fa_IR; do - #echo "$l ISIRI-3342" # a broken encoding - echo "$l.utf-8 UTF-8" - done - ;; - linux* | *-gnu*) - # With glibc-2.1 or newer, we don't need any canonicalization, - # because glibc has iconv and both glibc and libiconv support all - # GNU canonical names directly. Therefore, the Makefile does not - # need to install the alias file at all. - # The following applies only to glibc-2.0.x and older libcs. - echo "ISO_646.IRV:1983 ASCII" - ;; - aix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "IBM-850 CP850" - echo "IBM-856 CP856" - echo "IBM-921 ISO-8859-13" - echo "IBM-922 CP922" - echo "IBM-932 CP932" - echo "IBM-943 CP943" - echo "IBM-1046 CP1046" - echo "IBM-1124 CP1124" - echo "IBM-1129 CP1129" - echo "IBM-1252 CP1252" - echo "IBM-eucCN GB2312" - echo "IBM-eucJP EUC-JP" - echo "IBM-eucKR EUC-KR" - echo "IBM-eucTW EUC-TW" - echo "big5 BIG5" - echo "GBK GBK" - echo "TIS-620 TIS-620" - echo "UTF-8 UTF-8" - ;; - hpux*) - echo "iso88591 ISO-8859-1" - echo "iso88592 ISO-8859-2" - echo "iso88595 ISO-8859-5" - echo "iso88596 ISO-8859-6" - echo "iso88597 ISO-8859-7" - echo "iso88598 ISO-8859-8" - echo "iso88599 ISO-8859-9" - echo "iso885915 ISO-8859-15" - echo "roman8 HP-ROMAN8" - echo "arabic8 HP-ARABIC8" - echo "greek8 HP-GREEK8" - echo "hebrew8 HP-HEBREW8" - echo "turkish8 HP-TURKISH8" - echo "kana8 HP-KANA8" - echo "tis620 TIS-620" - echo "big5 BIG5" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "hp15CN GB2312" - #echo "ccdc ?" # what is this? - echo "SJIS SHIFT_JIS" - echo "utf8 UTF-8" - ;; - irix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-9 ISO-8859-9" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - ;; - osf*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "cp850 CP850" - echo "big5 BIG5" - echo "dechanyu DEC-HANYU" - echo "dechanzi GB2312" - echo "deckanji DEC-KANJI" - echo "deckorean EUC-KR" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "GBK GBK" - echo "KSC5601 CP949" - echo "sdeckanji EUC-JP" - echo "SJIS SHIFT_JIS" - echo "TACTIS TIS-620" - echo "UTF-8 UTF-8" - ;; - solaris*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-3 ISO-8859-3" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "koi8-r KOI8-R" - echo "ansi-1251 CP1251" - echo "BIG5 BIG5" - echo "Big5-HKSCS BIG5-HKSCS" - echo "gb2312 GB2312" - echo "GBK GBK" - echo "GB18030 GB18030" - echo "cns11643 EUC-TW" - echo "5601 EUC-KR" - echo "ko_KR.johap92 JOHAB" - echo "eucJP EUC-JP" - echo "PCK SHIFT_JIS" - echo "TIS620.2533 TIS-620" - #echo "sun_eu_greek ?" # what is this? - echo "UTF-8 UTF-8" - ;; - freebsd* | os2*) - # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just - # reuse FreeBSD's locale data for OS/2. - echo "C ASCII" - echo "US-ASCII ASCII" - for l in la_LN lt_LN; do - echo "$l.ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ - lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do - echo "$l.ISO_8859-1 ISO-8859-1" - echo "$l.DIS_8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do - echo "$l.ISO_8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO_8859-4 ISO-8859-4" - done - for l in ru_RU ru_SU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO_8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ja_JP.Shift_JIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - netbsd*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-13 ISO-8859-13" - echo "ISO8859-15 ISO-8859-15" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "BIG5 BIG5" - echo "SJIS SHIFT_JIS" - ;; - darwin[56]*) - # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "C ASCII" - for l in en_AU en_CA en_GB en_US la_LN; do - echo "$l.US-ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \ - nl_NL no_NO pt_PT sv_SE; do - echo "$l ISO-8859-1" - echo "$l.ISO8859-1 ISO-8859-1" - echo "$l.ISO8859-15 ISO-8859-15" - done - for l in la_LN; do - echo "$l.ISO8859-1 ISO-8859-1" - echo "$l.ISO8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do - echo "$l.ISO8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO8859-4 ISO-8859-4" - done - for l in ru_RU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - for l in bg_BG; do - echo "$l.CP1251 CP1251" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - darwin*) - # Darwin 7.5 has nl_langinfo(CODESET), but it is useless: - # - It returns the empty string when LANG is set to a locale of the - # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 - # LC_CTYPE file. - # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by - # the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. - # - The documentation says: - # "... all code that calls BSD system routines should ensure - # that the const *char parameters of these routines are in UTF-8 - # encoding. All BSD system functions expect their string - # parameters to be in UTF-8 encoding and nothing else." - # It also says - # "An additional caveat is that string parameters for files, - # paths, and other file-system entities must be in canonical - # UTF-8. In a canonical UTF-8 Unicode string, all decomposable - # characters are decomposed ..." - # but this is not true: You can pass non-decomposed UTF-8 strings - # to file system functions, and it is the OS which will convert - # them to decomposed UTF-8 before accessing the file system. - # - The Apple Terminal application displays UTF-8 by default. - # - However, other applications are free to use different encodings: - # - xterm uses ISO-8859-1 by default. - # - TextEdit uses MacRoman by default. - # We prefer UTF-8 over decomposed UTF-8-MAC because one should - # minimize the use of decomposed Unicode. Unfortunately, through the - # Darwin file system, decomposed UTF-8 strings are leaked into user - # space nevertheless. - echo "* UTF-8" - ;; - beos*) - # BeOS has a single locale, and it has UTF-8 encoding. - echo "* UTF-8" - ;; - msdosdjgpp*) - # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "#" - echo "# The encodings given here may not all be correct." - echo "# If you find that the encoding given for your language and" - echo "# country is not the one your DOS machine actually uses, just" - echo "# correct it in this file, and send a mail to" - echo "# Juan Manuel Guerrero " - echo "# and Bruno Haible ." - echo "#" - echo "C ASCII" - # ISO-8859-1 languages - echo "ca CP850" - echo "ca_ES CP850" - echo "da CP865" # not CP850 ?? - echo "da_DK CP865" # not CP850 ?? - echo "de CP850" - echo "de_AT CP850" - echo "de_CH CP850" - echo "de_DE CP850" - echo "en CP850" - echo "en_AU CP850" # not CP437 ?? - echo "en_CA CP850" - echo "en_GB CP850" - echo "en_NZ CP437" - echo "en_US CP437" - echo "en_ZA CP850" # not CP437 ?? - echo "es CP850" - echo "es_AR CP850" - echo "es_BO CP850" - echo "es_CL CP850" - echo "es_CO CP850" - echo "es_CR CP850" - echo "es_CU CP850" - echo "es_DO CP850" - echo "es_EC CP850" - echo "es_ES CP850" - echo "es_GT CP850" - echo "es_HN CP850" - echo "es_MX CP850" - echo "es_NI CP850" - echo "es_PA CP850" - echo "es_PY CP850" - echo "es_PE CP850" - echo "es_SV CP850" - echo "es_UY CP850" - echo "es_VE CP850" - echo "et CP850" - echo "et_EE CP850" - echo "eu CP850" - echo "eu_ES CP850" - echo "fi CP850" - echo "fi_FI CP850" - echo "fr CP850" - echo "fr_BE CP850" - echo "fr_CA CP850" - echo "fr_CH CP850" - echo "fr_FR CP850" - echo "ga CP850" - echo "ga_IE CP850" - echo "gd CP850" - echo "gd_GB CP850" - echo "gl CP850" - echo "gl_ES CP850" - echo "id CP850" # not CP437 ?? - echo "id_ID CP850" # not CP437 ?? - echo "is CP861" # not CP850 ?? - echo "is_IS CP861" # not CP850 ?? - echo "it CP850" - echo "it_CH CP850" - echo "it_IT CP850" - echo "lt CP775" - echo "lt_LT CP775" - echo "lv CP775" - echo "lv_LV CP775" - echo "nb CP865" # not CP850 ?? - echo "nb_NO CP865" # not CP850 ?? - echo "nl CP850" - echo "nl_BE CP850" - echo "nl_NL CP850" - echo "nn CP865" # not CP850 ?? - echo "nn_NO CP865" # not CP850 ?? - echo "no CP865" # not CP850 ?? - echo "no_NO CP865" # not CP850 ?? - echo "pt CP850" - echo "pt_BR CP850" - echo "pt_PT CP850" - echo "sv CP850" - echo "sv_SE CP850" - # ISO-8859-2 languages - echo "cs CP852" - echo "cs_CZ CP852" - echo "hr CP852" - echo "hr_HR CP852" - echo "hu CP852" - echo "hu_HU CP852" - echo "pl CP852" - echo "pl_PL CP852" - echo "ro CP852" - echo "ro_RO CP852" - echo "sk CP852" - echo "sk_SK CP852" - echo "sl CP852" - echo "sl_SI CP852" - echo "sq CP852" - echo "sq_AL CP852" - echo "sr CP852" # CP852 or CP866 or CP855 ?? - echo "sr_CS CP852" # CP852 or CP866 or CP855 ?? - echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? - # ISO-8859-3 languages - echo "mt CP850" - echo "mt_MT CP850" - # ISO-8859-5 languages - echo "be CP866" - echo "be_BE CP866" - echo "bg CP866" # not CP855 ?? - echo "bg_BG CP866" # not CP855 ?? - echo "mk CP866" # not CP855 ?? - echo "mk_MK CP866" # not CP855 ?? - echo "ru CP866" - echo "ru_RU CP866" - echo "uk CP1125" - echo "uk_UA CP1125" - # ISO-8859-6 languages - echo "ar CP864" - echo "ar_AE CP864" - echo "ar_DZ CP864" - echo "ar_EG CP864" - echo "ar_IQ CP864" - echo "ar_IR CP864" - echo "ar_JO CP864" - echo "ar_KW CP864" - echo "ar_MA CP864" - echo "ar_OM CP864" - echo "ar_QA CP864" - echo "ar_SA CP864" - echo "ar_SY CP864" - # ISO-8859-7 languages - echo "el CP869" - echo "el_GR CP869" - # ISO-8859-8 languages - echo "he CP862" - echo "he_IL CP862" - # ISO-8859-9 languages - echo "tr CP857" - echo "tr_TR CP857" - # Japanese - echo "ja CP932" - echo "ja_JP CP932" - # Chinese - echo "zh_CN GBK" - echo "zh_TW CP950" # not CP938 ?? - # Korean - echo "kr CP949" # not CP934 ?? - echo "kr_KR CP949" # not CP934 ?? - # Thai - echo "th CP874" - echo "th_TH CP874" - # Other - echo "eo CP850" - echo "eo_EO CP850" - ;; -esac diff --git a/src/bin/tar/lib/configmake.h b/src/bin/tar/lib/configmake.h deleted file mode 100644 index 1e7d13cca5..0000000000 --- a/src/bin/tar/lib/configmake.h +++ /dev/null @@ -1,25 +0,0 @@ -/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ -#define PREFIX "/usr/local" -#define EXEC_PREFIX "/usr/local" -#define BINDIR "/usr/local/bin" -#define SBINDIR "/usr/local/sbin" -#define LIBEXECDIR "/usr/local/libexec" -#define DATAROOTDIR "/usr/local/share" -#define DATADIR "/usr/local/share" -#define SYSCONFDIR "/usr/local/etc" -#define SHAREDSTATEDIR "/usr/local/com" -#define LOCALSTATEDIR "/usr/local/var" -#define INCLUDEDIR "/usr/local/include" -#define OLDINCLUDEDIR "/usr/include" -#define DOCDIR "/usr/local/share/doc/coreutils" -#define INFODIR "/usr/local/share/info" -#define HTMLDIR "/usr/local/share/doc/coreutils" -#define DVIDIR "/usr/local/share/doc/coreutils" -#define PDFDIR "/usr/local/share/doc/coreutils" -#define PSDIR "/usr/local/share/doc/coreutils" -#define LIBDIR "/usr/local/lib" -#define LOCALEDIR "/usr/local/share/locale" -#define MANDIR "/usr/local/share/man" -#define PKGDATADIR "/usr/local/share/coreutils" -#define PKGINCLUDEDIR "/usr/local/include/coreutils" -#define PKGLIBDIR "/usr/local/lib/coreutils" diff --git a/src/bin/tar/lib/creat-safer.c b/src/bin/tar/lib/creat-safer.c deleted file mode 100644 index f4a2e59db1..0000000000 --- a/src/bin/tar/lib/creat-safer.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Invoke creat, but avoid some glitches. - - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -#include "fcntl-safer.h" - -#include -#include "unistd-safer.h" - -int -creat_safer (char const *file, mode_t mode) -{ - return fd_safer (creat (file, mode)); -} diff --git a/src/bin/tar/lib/dirent.in.h b/src/bin/tar/lib/dirent.in.h deleted file mode 100644 index cd80bac9cb..0000000000 --- a/src/bin/tar/lib/dirent.in.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Wrapper around . - Copyright (C) 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GL_DIRENT_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_DIRENT_H@ - -#ifndef _GL_DIRENT_H -#define _GL_DIRENT_H - - -/* Declare overridden functions. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if @REPLACE_FCHDIR@ -# define opendir rpl_opendir -extern DIR * opendir (const char *); -# define closedir rpl_closedir -extern int closedir (DIR *); -#endif - -#ifdef __cplusplus -} -#endif - - -#endif /* _GL_DIRENT_H */ -#endif /* _GL_DIRENT_H */ diff --git a/src/bin/tar/lib/dirfd.c b/src/bin/tar/lib/dirfd.c deleted file mode 100644 index 06cb3c46f8..0000000000 --- a/src/bin/tar/lib/dirfd.c +++ /dev/null @@ -1,29 +0,0 @@ -/* dirfd.c -- return the file descriptor associated with an open DIR* - - Copyright (C) 2001, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -#include "dirfd.h" - -int -dirfd (DIR const *dir_p) -{ - return DIR_TO_FD (dir_p); -} diff --git a/src/bin/tar/lib/dirfd.h b/src/bin/tar/lib/dirfd.h deleted file mode 100644 index 05b77774f6..0000000000 --- a/src/bin/tar/lib/dirfd.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Declare dirfd, if necessary. - Copyright (C) 2001, 2002, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - Written by Jim Meyering. */ - -#include - -#include - -#ifndef HAVE_DECL_DIRFD -"this configure-time declaration test was not run" -#endif -#if !HAVE_DECL_DIRFD && !defined dirfd -int dirfd (DIR const *); -#endif diff --git a/src/bin/tar/lib/dirname.c b/src/bin/tar/lib/dirname.c deleted file mode 100644 index 16552c64d2..0000000000 --- a/src/bin/tar/lib/dirname.c +++ /dev/null @@ -1,85 +0,0 @@ -/* dirname.c -- return all but the last element in a file name - - Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "dirname.h" - -#include -#include "xalloc.h" - -/* Return the length of the prefix of FILE that will be used by - dir_name. If FILE is in the working directory, this returns zero - even though `dir_name (FILE)' will return ".". Works properly even - if there are trailing slashes (by effectively ignoring them). */ - -size_t -dir_len (char const *file) -{ - size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file); - size_t length; - - /* Advance prefix_length beyond important leading slashes. */ - prefix_length += (prefix_length != 0 - ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE - && ISSLASH (file[prefix_length])) - : (ISSLASH (file[0]) - ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT - && ISSLASH (file[1]) && ! ISSLASH (file[2]) - ? 2 : 1)) - : 0)); - - /* Strip the basename and any redundant slashes before it. */ - for (length = last_component (file) - file; - prefix_length < length; length--) - if (! ISSLASH (file[length - 1])) - break; - return length; -} - - -/* In general, we can't use the builtin `dirname' function if available, - since it has different meanings in different environments. - In some environments the builtin `dirname' modifies its argument. - - Return the leading directories part of FILE, allocated with xmalloc. - Works properly even if there are trailing slashes (by effectively - ignoring them). Unlike POSIX dirname(), FILE cannot be NULL. - - If lstat (FILE) would succeed, then { chdir (dir_name (FILE)); - lstat (base_name (FILE)); } will access the same file. Likewise, - if the sequence { chdir (dir_name (FILE)); - rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE - to "foo" in the same directory FILE was in. */ - -char * -dir_name (char const *file) -{ - size_t length = dir_len (file); - bool append_dot = (length == 0 - || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE - && length == FILE_SYSTEM_PREFIX_LEN (file) - && file[2] != '\0' && ! ISSLASH (file[2]))); - char *dir = xmalloc (length + append_dot + 1); - memcpy (dir, file, length); - if (append_dot) - dir[length++] = '.'; - dir[length] = '\0'; - return dir; -} diff --git a/src/bin/tar/lib/dirname.h b/src/bin/tar/lib/dirname.h deleted file mode 100644 index 91e7ed3366..0000000000 --- a/src/bin/tar/lib/dirname.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Take file names apart into directory and base names. - - Copyright (C) 1998, 2001, 2003-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef DIRNAME_H_ -# define DIRNAME_H_ 1 - -# include -# include - -# ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -# endif - -# ifndef ISSLASH -# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) -# endif - -# ifndef FILE_SYSTEM_PREFIX_LEN -# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX - /* This internal macro assumes ASCII, but all hosts that support drive - letters use ASCII. */ -# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \ - <= 'z' - 'a') -# define FILE_SYSTEM_PREFIX_LEN(Filename) \ - (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) -# else -# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 -# endif -# endif - -# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 -# endif - -# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT -# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 -# endif - -# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) -# else -# define IS_ABSOLUTE_FILE_NAME(F) \ - (ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F)) -# endif -# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) - -char *base_name (char const *file); -char *dir_name (char const *file); -size_t base_len (char const *file); -size_t dir_len (char const *file); -char *last_component (char const *file); - -bool strip_trailing_slashes (char *file); - -#endif /* not DIRNAME_H_ */ diff --git a/src/bin/tar/lib/dup-safer.c b/src/bin/tar/lib/dup-safer.c deleted file mode 100644 index 7b12b615ca..0000000000 --- a/src/bin/tar/lib/dup-safer.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Invoke dup, but avoid some glitches. - - Copyright (C) 2001, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -#include "unistd-safer.h" - -#include - -#include -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif - -/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or - STDERR_FILENO. */ - -int -dup_safer (int fd) -{ -#if defined F_DUPFD && !defined FCHDIR_REPLACEMENT - return fcntl (fd, F_DUPFD, STDERR_FILENO + 1); -#else - /* fd_safer calls us back, but eventually the recursion unwinds and - does the right thing. */ - return fd_safer (dup (fd)); -#endif -} diff --git a/src/bin/tar/lib/dup2.c b/src/bin/tar/lib/dup2.c deleted file mode 100644 index 88944817cf..0000000000 --- a/src/bin/tar/lib/dup2.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Duplicate an open file descriptor to a specified file descriptor. - - Copyright (C) 1999, 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Paul Eggert */ - -#include - -/* Specification. */ -#include - -#include -#include - -#ifndef F_DUPFD -static int -dupfd (int fd, int desired_fd) -{ - int duplicated_fd = dup (fd); - if (duplicated_fd < 0 || duplicated_fd == desired_fd) - return duplicated_fd; - else - { - int r = dupfd (fd, desired_fd); - int e = errno; - close (duplicated_fd); - errno = e; - return r; - } -} -#endif - -int -dup2 (int fd, int desired_fd) -{ - if (fd == desired_fd) - return fd; - close (desired_fd); -#ifdef F_DUPFD - return fcntl (fd, F_DUPFD, desired_fd); -#else - return dupfd (fd, desired_fd); -#endif -} diff --git a/src/bin/tar/lib/error.c b/src/bin/tar/lib/error.c deleted file mode 100644 index 9cf67ff904..0000000000 --- a/src/bin/tar/lib/error.c +++ /dev/null @@ -1,339 +0,0 @@ -/* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000-2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie . */ - -#if !_LIBC -# include -#endif - -#include "error.h" - -#include -#include -#include -#include - -#if !_LIBC && ENABLE_NLS -# include "gettext.h" -# define _(msgid) gettext (msgid) -#endif - -#ifdef _LIBC -# include -# include -# include -# include -# define mbsrtowcs __mbsrtowcs -#endif - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -#ifndef _ -# define _(String) String -#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) (void); - -/* This variable is incremented each time `error' is called. */ -unsigned int error_message_count; - -#ifdef _LIBC -/* In the GNU C library, there is a predefined variable for this. */ - -# define program_name program_invocation_name -# include -# include -# include - -/* In GNU libc we want do not want to use the common name `error' directly. - Instead make it a weak alias. */ -extern void __error (int status, int errnum, const char *message, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -extern void __error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, - ...) - __attribute__ ((__format__ (__printf__, 5, 6)));; -# define error __error -# define error_at_line __error_at_line - -# include -# define fflush(s) INTUSE(_IO_fflush) (s) -# undef putc -# define putc(c, fp) INTUSE(_IO_putc) (c, fp) - -# include - -#else /* not _LIBC */ - -# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P -# ifndef HAVE_DECL_STRERROR_R -"this configure-time declaration test was not run" -# endif -char *strerror_r (); -# endif - -/* The calling program should define program_name and set it to the - name of the executing program. */ -extern char *program_name; - -# if HAVE_STRERROR_R || defined strerror_r -# define __strerror_r strerror_r -# endif /* HAVE_STRERROR_R || defined strerror_r */ -#endif /* not _LIBC */ - -static void -print_errno_message (int errnum) -{ - char const *s; - -#if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; -# if STRERROR_R_CHAR_P || _LIBC - s = __strerror_r (errnum, errbuf, sizeof errbuf); -# else - if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) - s = errbuf; - else - s = 0; -# endif -#else - s = strerror (errnum); -#endif - -#if !_LIBC - if (! s) - s = _("Unknown system error"); -#endif - -#if _LIBC - __fxprintf (NULL, ": %s", s); -#else - fprintf (stderr, ": %s", s); -#endif -} - -static void -error_tail (int status, int errnum, const char *message, va_list args) -{ -#if _LIBC - if (_IO_fwide (stderr, 0) > 0) - { -# define ALLOCA_LIMIT 2000 - size_t len = strlen (message) + 1; - wchar_t *wmessage = NULL; - mbstate_t st; - size_t res; - const char *tmp; - bool use_malloc = false; - - while (1) - { - if (__libc_use_alloca (len * sizeof (wchar_t))) - wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); - else - { - if (!use_malloc) - wmessage = NULL; - - wchar_t *p = (wchar_t *) realloc (wmessage, - len * sizeof (wchar_t)); - if (p == NULL) - { - free (wmessage); - fputws_unlocked (L"out of memory\n", stderr); - return; - } - wmessage = p; - use_malloc = true; - } - - memset (&st, '\0', sizeof (st)); - tmp = message; - - res = mbsrtowcs (wmessage, &tmp, len, &st); - if (res != len) - break; - - if (__builtin_expect (len >= SIZE_MAX / 2, 0)) - { - /* This really should not happen if everything is fine. */ - res = (size_t) -1; - break; - } - - len *= 2; - } - - if (res == (size_t) -1) - { - /* The string cannot be converted. */ - if (use_malloc) - { - free (wmessage); - use_malloc = false; - } - wmessage = (wchar_t *) L"???"; - } - - __vfwprintf (stderr, wmessage, args); - - if (use_malloc) - free (wmessage); - } - else -#endif - vfprintf (stderr, message, args); - va_end (args); - - ++error_message_count; - if (errnum) - print_errno_message (errnum); -#if _LIBC - __fxprintf (NULL, "\n"); -#else - putc ('\n', stderr); -#endif - fflush (stderr); - if (status) - exit (status); -} - - -/* 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. */ -void -error (int status, int errnum, const char *message, ...) -{ - va_list args; - -#if defined _LIBC && defined __libc_ptf_call - /* We do not want this call to be cut short by a thread - cancellation. Therefore disable cancellation for now. */ - int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); -#endif - - fflush (stdout); -#ifdef _LIBC - _IO_flockfile (stderr); -#endif - if (error_print_progname) - (*error_print_progname) (); - else - { -#if _LIBC - __fxprintf (NULL, "%s: ", program_name); -#else - fprintf (stderr, "%s: ", program_name); -#endif - } - - va_start (args, message); - error_tail (status, errnum, message, args); - -#ifdef _LIBC - _IO_funlockfile (stderr); -# ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); -# endif -#endif -} - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -int error_one_per_line; - -void -error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, ...) -{ - va_list args; - - if (error_one_per_line) - { - static const char *old_file_name; - static unsigned int old_line_number; - - if (old_line_number == line_number - && (file_name == old_file_name - || strcmp (old_file_name, file_name) == 0)) - /* Simply return and print nothing. */ - return; - - old_file_name = file_name; - old_line_number = line_number; - } - -#if defined _LIBC && defined __libc_ptf_call - /* We do not want this call to be cut short by a thread - cancellation. Therefore disable cancellation for now. */ - int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); -#endif - - fflush (stdout); -#ifdef _LIBC - _IO_flockfile (stderr); -#endif - if (error_print_progname) - (*error_print_progname) (); - else - { -#if _LIBC - __fxprintf (NULL, "%s:", program_name); -#else - fprintf (stderr, "%s:", program_name); -#endif - } - -#if _LIBC - __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); -#else - fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); -#endif - - va_start (args, message); - error_tail (status, errnum, message, args); - -#ifdef _LIBC - _IO_funlockfile (stderr); -# ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); -# endif -#endif -} - -#ifdef _LIBC -/* Make the weak alias. */ -# undef error -# undef error_at_line -weak_alias (__error, error) -weak_alias (__error_at_line, error_at_line) -#endif diff --git a/src/bin/tar/lib/error.h b/src/bin/tar/lib/error.h deleted file mode 100644 index 5a5f247658..0000000000 --- a/src/bin/tar/lib/error.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Declaration for error-reporting function - Copyright (C) 1995, 1996, 1997, 2003, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Print a message with `fprintf (stderr, FORMAT, ...)'; - if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). - If STATUS is nonzero, terminate the program with `exit (STATUS)'. */ - -extern void error (int __status, int __errnum, const char *__format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -extern void error_at_line (int __status, int __errnum, const char *__fname, - unsigned int __lineno, const char *__format, ...) - __attribute__ ((__format__ (__printf__, 5, 6))); - -/* 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. */ -extern void (*error_print_progname) (void); - -/* This variable is incremented each time `error' is called. */ -extern unsigned int error_message_count; - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -extern int error_one_per_line; - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ diff --git a/src/bin/tar/lib/exclude.c b/src/bin/tar/lib/exclude.c deleted file mode 100644 index ed34d0f1f7..0000000000 --- a/src/bin/tar/lib/exclude.c +++ /dev/null @@ -1,275 +0,0 @@ -/* exclude.c -- exclude file names - - Copyright (C) 1992, 1993, 1994, 1997, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "exclude.h" -#include "fnmatch.h" -#include "xalloc.h" -#include "verify.h" - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -/* Non-GNU systems lack these options, so we don't need to check them. */ -#ifndef FNM_CASEFOLD -# define FNM_CASEFOLD 0 -#endif -#ifndef FNM_EXTMATCH -# define FNM_EXTMATCH 0 -#endif -#ifndef FNM_LEADING_DIR -# define FNM_LEADING_DIR 0 -#endif - -verify (((EXCLUDE_ANCHORED | EXCLUDE_INCLUDE | EXCLUDE_WILDCARDS) - & (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD | FNM_LEADING_DIR - | FNM_CASEFOLD | FNM_EXTMATCH)) - == 0); - -/* An exclude pattern-options pair. The options are fnmatch options - ORed with EXCLUDE_* options. */ - -struct patopts - { - char const *pattern; - int options; - }; - -/* An exclude list, of pattern-options pairs. */ - -struct exclude - { - struct patopts *exclude; - size_t exclude_alloc; - size_t exclude_count; - }; - -/* Return a newly allocated and empty exclude list. */ - -struct exclude * -new_exclude (void) -{ - return xzalloc (sizeof *new_exclude ()); -} - -/* Free the storage associated with an exclude list. */ - -void -free_exclude (struct exclude *ex) -{ - free (ex->exclude); - free (ex); -} - -/* Return zero if PATTERN matches F, obeying OPTIONS, except that - (unlike fnmatch) wildcards are disabled in PATTERN. */ - -static int -fnmatch_no_wildcards (char const *pattern, char const *f, int options) -{ - if (! (options & FNM_LEADING_DIR)) - return ((options & FNM_CASEFOLD) - ? mbscasecmp (pattern, f) - : strcmp (pattern, f)); - else if (! (options & FNM_CASEFOLD)) - { - size_t patlen = strlen (pattern); - int r = strncmp (pattern, f, patlen); - if (! r) - { - r = f[patlen]; - if (r == '/') - r = 0; - } - return r; - } - else - { - /* Walk through a copy of F, seeing whether P matches any prefix - of F. - - FIXME: This is an O(N**2) algorithm; it should be O(N). - Also, the copy should not be necessary. However, fixing this - will probably involve a change to the mbs* API. */ - - char *fcopy = xstrdup (f); - char *p; - int r; - for (p = fcopy; ; *p++ = '/') - { - p = strchr (p, '/'); - if (p) - *p = '\0'; - r = mbscasecmp (pattern, fcopy); - if (!p || r <= 0) - break; - } - free (fcopy); - return r; - } -} - -bool -exclude_fnmatch (char const *pattern, char const *f, int options) -{ - int (*matcher) (char const *, char const *, int) = - (options & EXCLUDE_WILDCARDS - ? fnmatch - : fnmatch_no_wildcards); - bool matched = ((*matcher) (pattern, f, options) == 0); - char const *p; - - if (! (options & EXCLUDE_ANCHORED)) - for (p = f; *p && ! matched; p++) - if (*p == '/' && p[1] != '/') - matched = ((*matcher) (pattern, p + 1, options) == 0); - - return matched; -} - -/* Return true if EX excludes F. */ - -bool -excluded_file_name (struct exclude const *ex, char const *f) -{ - size_t exclude_count = ex->exclude_count; - - /* If no options are given, the default is to include. */ - if (exclude_count == 0) - return false; - else - { - struct patopts const *exclude = ex->exclude; - size_t i; - - /* Otherwise, the default is the opposite of the first option. */ - bool excluded = !! (exclude[0].options & EXCLUDE_INCLUDE); - - /* Scan through the options, seeing whether they change F from - excluded to included or vice versa. */ - for (i = 0; i < exclude_count; i++) - { - char const *pattern = exclude[i].pattern; - int options = exclude[i].options; - if (excluded == !! (options & EXCLUDE_INCLUDE)) - excluded ^= exclude_fnmatch (pattern, f, options); - } - - return excluded; - } -} - -/* Append to EX the exclusion PATTERN with OPTIONS. */ - -void -add_exclude (struct exclude *ex, char const *pattern, int options) -{ - struct patopts *patopts; - - if (ex->exclude_count == ex->exclude_alloc) - ex->exclude = x2nrealloc (ex->exclude, &ex->exclude_alloc, - sizeof *ex->exclude); - - patopts = &ex->exclude[ex->exclude_count++]; - patopts->pattern = pattern; - patopts->options = options; -} - -/* Use ADD_FUNC to append to EX the patterns in FILE_NAME, each with - OPTIONS. LINE_END terminates each pattern in the file. If - LINE_END is a space character, ignore trailing spaces and empty - lines in FILE. Return -1 on failure, 0 on success. */ - -int -add_exclude_file (void (*add_func) (struct exclude *, char const *, int), - struct exclude *ex, char const *file_name, int options, - char line_end) -{ - bool use_stdin = file_name[0] == '-' && !file_name[1]; - FILE *in; - char *buf = NULL; - char *p; - char const *pattern; - char const *lim; - size_t buf_alloc = 0; - size_t buf_count = 0; - int c; - int e = 0; - - if (use_stdin) - in = stdin; - else if (! (in = fopen (file_name, "r"))) - return -1; - - while ((c = getc (in)) != EOF) - { - if (buf_count == buf_alloc) - buf = x2realloc (buf, &buf_alloc); - buf[buf_count++] = c; - } - - if (ferror (in)) - e = errno; - - if (!use_stdin && fclose (in) != 0) - e = errno; - - buf = xrealloc (buf, buf_count + 1); - buf[buf_count] = line_end; - lim = buf + buf_count + ! (buf_count == 0 || buf[buf_count - 1] == line_end); - pattern = buf; - - for (p = buf; p < lim; p++) - if (*p == line_end) - { - char *pattern_end = p; - - if (isspace ((unsigned char) line_end)) - { - for (; ; pattern_end--) - if (pattern_end == pattern) - goto next_pattern; - else if (! isspace ((unsigned char) pattern_end[-1])) - break; - } - - *pattern_end = '\0'; - (*add_func) (ex, pattern, options); - - next_pattern: - pattern = p + 1; - } - - errno = e; - return e ? -1 : 0; -} diff --git a/src/bin/tar/lib/exclude.h b/src/bin/tar/lib/exclude.h deleted file mode 100644 index 203e38485d..0000000000 --- a/src/bin/tar/lib/exclude.h +++ /dev/null @@ -1,44 +0,0 @@ -/* exclude.h -- declarations for excluding file names - - Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001, 2002, 2003, 2005, - 2006 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -/* Exclude options, which can be ORed with fnmatch options. */ - -/* Patterns must match the start of file names, instead of matching - anywhere after a '/'. */ -#define EXCLUDE_ANCHORED (1 << 30) - -/* Include instead of exclude. */ -#define EXCLUDE_INCLUDE (1 << 29) - -/* '?', '*', '[', and '\\' are special in patterns. Without this - option, these characters are ordinary and fnmatch is not used. */ -#define EXCLUDE_WILDCARDS (1 << 28) - -struct exclude; - -struct exclude *new_exclude (void); -void free_exclude (struct exclude *); -void add_exclude (struct exclude *, char const *, int); -int add_exclude_file (void (*) (struct exclude *, char const *, int), - struct exclude *, char const *, int, char); -bool excluded_file_name (struct exclude const *, char const *); -bool exclude_fnmatch (char const *pattern, char const *f, int options); diff --git a/src/bin/tar/lib/exitfail.c b/src/bin/tar/lib/exitfail.c deleted file mode 100644 index 373d325c5a..0000000000 --- a/src/bin/tar/lib/exitfail.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Failure exit status - - Copyright (C) 2002, 2003, 2005, 2006, 2007 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "exitfail.h" - -#include - -int volatile exit_failure = EXIT_FAILURE; diff --git a/src/bin/tar/lib/exitfail.h b/src/bin/tar/lib/exitfail.h deleted file mode 100644 index e46cf9c166..0000000000 --- a/src/bin/tar/lib/exitfail.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Failure exit status - - Copyright (C) 2002 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -extern int volatile exit_failure; diff --git a/src/bin/tar/lib/fchdir.c b/src/bin/tar/lib/fchdir.c deleted file mode 100644 index e3ec2fcf6d..0000000000 --- a/src/bin/tar/lib/fchdir.c +++ /dev/null @@ -1,279 +0,0 @@ -/* fchdir replacement. - Copyright (C) 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "canonicalize.h" -#include "dirfd.h" - -/* This replacement assumes that a directory is not renamed while opened - through a file descriptor. */ - -/* Array of file descriptors opened. If it points to a directory, it stores - info about this directory; otherwise it stores an errno value of ENOTDIR. */ -typedef struct -{ - char *name; /* Absolute name of the directory, or NULL. */ - int saved_errno; /* If name == NULL: The error code describing the failure - reason. */ -} dir_info_t; -static dir_info_t *dirs; -static size_t dirs_allocated; - -/* Try to ensure dirs has enough room for a slot at index fd. */ -static void -ensure_dirs_slot (size_t fd) -{ - if (fd >= dirs_allocated) - { - size_t new_allocated; - dir_info_t *new_dirs; - size_t i; - - new_allocated = 2 * dirs_allocated + 1; - if (new_allocated <= fd) - new_allocated = fd + 1; - new_dirs = - (dirs != NULL - ? (dir_info_t *) realloc (dirs, new_allocated * sizeof (dir_info_t)) - : (dir_info_t *) malloc (new_allocated * sizeof (dir_info_t))); - if (new_dirs != NULL) - { - for (i = dirs_allocated; i < new_allocated; i++) - { - new_dirs[i].name = NULL; - new_dirs[i].saved_errno = ENOTDIR; - } - dirs = new_dirs; - dirs_allocated = new_allocated; - } - } -} - -/* Override open() and close(), to keep track of the open file descriptors. */ - -int -close (int fd) -#undef close -{ - int retval = close (fd); - - if (retval >= 0 && fd >= 0 && fd < dirs_allocated) - { - if (dirs[fd].name != NULL) - free (dirs[fd].name); - dirs[fd].name = NULL; - dirs[fd].saved_errno = ENOTDIR; - } - return retval; -} - -int -open (const char *filename, int flags, ...) -#undef open -{ - mode_t mode; - int fd; - struct stat statbuf; - - mode = 0; - if (flags & O_CREAT) - { - va_list arg; - va_start (arg, flags); - - /* If mode_t is narrower than int, use the promoted type (int), - not mode_t. Use sizeof to guess whether mode_t is narrower; - we don't know of any practical counterexamples. */ - mode = (sizeof (mode_t) < sizeof (int) - ? va_arg (arg, int) - : va_arg (arg, mode_t)); - - va_end (arg); - } - fd = open (filename, flags, mode); - if (fd >= 0) - { - ensure_dirs_slot (fd); - if (fd < dirs_allocated - && fstat (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) - { - dirs[fd].name = canonicalize_file_name (filename); - if (dirs[fd].name == NULL) - dirs[fd].saved_errno = errno; - } - } - return fd; -} - -/* Override opendir() and closedir(), to keep track of the open file - descriptors. Needed because there is a function dirfd(). */ - -int -closedir (DIR *dp) -#undef closedir -{ - int fd = dirfd (dp); - int retval = closedir (dp); - - if (retval >= 0 && fd >= 0 && fd < dirs_allocated) - { - if (dirs[fd].name != NULL) - free (dirs[fd].name); - dirs[fd].name = NULL; - dirs[fd].saved_errno = ENOTDIR; - } - return retval; -} - -DIR * -opendir (const char *filename) -#undef opendir -{ - DIR *dp; - - dp = opendir (filename); - if (dp != NULL) - { - int fd = dirfd (dp); - if (fd >= 0) - { - ensure_dirs_slot (fd); - if (fd < dirs_allocated) - { - dirs[fd].name = canonicalize_file_name (filename); - if (dirs[fd].name == NULL) - dirs[fd].saved_errno = errno; - } - } - } - return dp; -} - -/* Override dup() and dup2(), to keep track of open file descriptors. */ - -int -dup (int oldfd) -#undef dup -{ - int newfd = dup (oldfd); - - if (oldfd >= 0 && newfd >= 0) - { - ensure_dirs_slot (newfd); - if (newfd < dirs_allocated) - { - if (oldfd < dirs_allocated) - { - if (dirs[oldfd].name != NULL) - { - dirs[newfd].name = strdup (dirs[oldfd].name); - if (dirs[newfd].name == NULL) - dirs[newfd].saved_errno = ENOMEM; - } - else - { - dirs[newfd].name = NULL; - dirs[newfd].saved_errno = dirs[oldfd].saved_errno; - } - } - else - { - dirs[newfd].name = NULL; - dirs[newfd].saved_errno = ENOMEM; - } - } - } - return newfd; -} - -int -dup2 (int oldfd, int newfd) -#undef dup2 -{ - int retval = dup2 (oldfd, newfd); - - if (retval >= 0 && oldfd >= 0 && newfd >= 0 && newfd != oldfd) - { - ensure_dirs_slot (newfd); - if (newfd < dirs_allocated) - { - if (oldfd < dirs_allocated) - { - if (dirs[oldfd].name != NULL) - { - dirs[newfd].name = strdup (dirs[oldfd].name); - if (dirs[newfd].name == NULL) - dirs[newfd].saved_errno = ENOMEM; - } - else - { - dirs[newfd].name = NULL; - dirs[newfd].saved_errno = dirs[oldfd].saved_errno; - } - } - else - { - dirs[newfd].name = NULL; - dirs[newfd].saved_errno = ENOMEM; - } - } - } - return retval; -} - -/* Implement fchdir() in terms of chdir(). */ - -int -fchdir (int fd) -{ - if (fd >= 0) - { - if (fd < dirs_allocated) - { - if (dirs[fd].name != NULL) - return chdir (dirs[fd].name); - else - { - errno = dirs[fd].saved_errno; - return -1; - } - } - else - { - errno = ENOMEM; - return -1; - } - } - else - { - errno = EBADF; - return -1; - } -} diff --git a/src/bin/tar/lib/fchmodat.c b/src/bin/tar/lib/fchmodat.c deleted file mode 100644 index 2598b7015f..0000000000 --- a/src/bin/tar/lib/fchmodat.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Change the protections of file relative to an open directory. - Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -#include "openat.h" -#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ -#include "save-cwd.h" -#include "openat-priv.h" - -#ifndef HAVE_LCHMOD -/* Use a different name, to avoid conflicting with any - system-supplied declaration. */ -# undef lchmod -# define lchmod lchmod_rpl -static int lchmod (char const *f, mode_t m) { errno = ENOSYS; return -1; } -#endif - -/* Solaris 10 has no function like this. - Invoke chmod or lchmod on file, FILE, using mode MODE, in the directory - open on descriptor FD. If possible, do it without changing the - working directory. Otherwise, resort to using save_cwd/fchdir, - then mkdir/restore_cwd. If either the save_cwd or the restore_cwd - fails, then give a diagnostic and exit nonzero. - Note that an attempt to use a FLAG value of AT_SYMLINK_NOFOLLOW - on a system without lchmod support causes this function to fail. */ - -#define AT_FUNC_NAME fchmodat -#define AT_FUNC_F1 lchmod -#define AT_FUNC_F2 chmod -#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW -#define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode, int flag -#define AT_FUNC_POST_FILE_ARGS , mode -#include "at-func.c" diff --git a/src/bin/tar/lib/fchown-stub.c b/src/bin/tar/lib/fchown-stub.c deleted file mode 100644 index 6be750b829..0000000000 --- a/src/bin/tar/lib/fchown-stub.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include -#include - -/* A trivial substitute for `fchown'. - - DJGPP 2.03 and earlier (and perhaps later) don't have `fchown', - so we pretend no-one has permission for this operation. */ - -int -fchown (int fd, uid_t uid, gid_t gid) -{ - errno = EPERM; - return -1; -} diff --git a/src/bin/tar/lib/fchownat.c b/src/bin/tar/lib/fchownat.c deleted file mode 100644 index 6a6fe0f99b..0000000000 --- a/src/bin/tar/lib/fchownat.c +++ /dev/null @@ -1,49 +0,0 @@ -/* This function serves as replacement for a missing fchownat function, - as well as a work around for the fchownat bug in glibc-2.4: - - when the buggy fchownat-with-AT_SYMLINK_NOFOLLOW operates on a symlink, it - mistakenly affects the symlink referent, rather than the symlink itself. - - Copyright (C) 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -#include "openat.h" - -#include - -#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ -#include "save-cwd.h" -#include "openat-priv.h" - -/* Replacement for Solaris' function by the same name. - Invoke chown or lchown on file, FILE, using OWNER and GROUP, in the - directory open on descriptor FD. If FLAG is AT_SYMLINK_NOFOLLOW, then - use lchown, otherwise, use chown. If possible, do it without changing - the working directory. Otherwise, resort to using save_cwd/fchdir, - then mkdir/restore_cwd. If either the save_cwd or the restore_cwd - fails, then give a diagnostic and exit nonzero. */ - -#define AT_FUNC_NAME fchownat -#define AT_FUNC_F1 lchown -#define AT_FUNC_F2 chown -#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW -#define AT_FUNC_POST_FILE_PARAM_DECLS , uid_t owner, gid_t group, int flag -#define AT_FUNC_POST_FILE_ARGS , owner, group -#include "at-func.c" diff --git a/src/bin/tar/lib/fcntl--.h b/src/bin/tar/lib/fcntl--.h deleted file mode 100644 index 51b869e687..0000000000 --- a/src/bin/tar/lib/fcntl--.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Like fcntl.h, but redefine some names to avoid glitches. - - Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include -#include "fcntl-safer.h" - -#undef open -#define open open_safer - -#undef creat -#define creat creat_safer diff --git a/src/bin/tar/lib/fcntl-safer.h b/src/bin/tar/lib/fcntl-safer.h deleted file mode 100644 index cab6aab1ad..0000000000 --- a/src/bin/tar/lib/fcntl-safer.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Invoke fcntl-like functions, but avoid some glitches. - - Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -int open_safer (char const *, int, ...); -int creat_safer (char const *, mode_t); diff --git a/src/bin/tar/lib/fcntl.in.h b/src/bin/tar/lib/fcntl.in.h deleted file mode 100644 index 49a7915f60..0000000000 --- a/src/bin/tar/lib/fcntl.in.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Like , but with non-working flags defined to 0. - - Copyright (C) 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Paul Eggert */ - -#ifndef _GL_FCNTL_H - -#include -#include -#include -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_FCNTL_H@ - -#ifndef _GL_FCNTL_H -#define _GL_FCNTL_H - - -/* Declare overridden functions. */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef FCHDIR_REPLACEMENT -# define open rpl_open -extern int open (const char *, int, ...); -#endif - -#ifdef __cplusplus -} -#endif - - -/* Fix up the O_* macros. */ - -#if !defined O_DIRECT && defined O_DIRECTIO -/* Tru64 spells it `O_DIRECTIO'. */ -# define O_DIRECT O_DIRECTIO -#endif - -#ifndef O_DIRECT -# define O_DIRECT 0 -#endif - -#ifndef O_DIRECTORY -# define O_DIRECTORY 0 -#endif - -#ifndef O_DSYNC -# define O_DSYNC 0 -#endif - -#ifndef O_NDELAY -# define O_NDELAY 0 -#endif - -#ifndef O_NOATIME -# define O_NOATIME 0 -#endif - -#ifndef O_NONBLOCK -# define O_NONBLOCK O_NDELAY -#endif - -#ifndef O_NOCTTY -# define O_NOCTTY 0 -#endif - -#ifndef O_NOFOLLOW -# define O_NOFOLLOW 0 -#endif - -#ifndef O_NOLINKS -# define O_NOLINKS 0 -#endif - -#ifndef O_RSYNC -# define O_RSYNC 0 -#endif - -#ifndef O_SYNC -# define O_SYNC 0 -#endif - -/* For systems that distinguish between text and binary I/O. - O_BINARY is usually declared in fcntl.h */ -#if !defined O_BINARY && defined _O_BINARY - /* For MSC-compatible compilers. */ -# define O_BINARY _O_BINARY -# define O_TEXT _O_TEXT -#endif - -#if (defined(__BEOS__) || defined(__HAIKU__)) - /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */ -# undef O_BINARY -# undef O_TEXT -#endif - -#ifndef O_BINARY -# define O_BINARY 0 -# define O_TEXT 0 -#endif - - -#endif /* _GL_FCNTL_H */ -#endif /* _GL_FCNTL_H */ diff --git a/src/bin/tar/lib/fd-safer.c b/src/bin/tar/lib/fd-safer.c deleted file mode 100644 index 256bfa4a0e..0000000000 --- a/src/bin/tar/lib/fd-safer.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Return a safer copy of a file descriptor. - - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -#include "unistd-safer.h" - -#include - -#include -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif - -/* Return FD, unless FD would be a copy of standard input, output, or - error; in that case, return a duplicate of FD, closing FD. On - failure to duplicate, close FD, set errno, and return -1. Preserve - errno if FD is negative, so that the caller can always inspect - errno when the returned value is negative. - - This function is usefully wrapped around functions that return file - descriptors, e.g., fd_safer (open ("file", O_RDONLY)). */ - -int -fd_safer (int fd) -{ - if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) - { - int f = dup_safer (fd); - int e = errno; - close (fd); - errno = e; - fd = f; - } - - return fd; -} diff --git a/src/bin/tar/lib/fileblocks.c b/src/bin/tar/lib/fileblocks.c deleted file mode 100644 index 4024d1ef24..0000000000 --- a/src/bin/tar/lib/fileblocks.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Convert file size to number of blocks on System V-like machines. - - Copyright (C) 1990, 1997, 1998, 1999, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Brian L. Matthews, blm@6sceng.UUCP. */ - -#include - -#include - -#if HAVE_SYS_PARAM_H -# include -#endif - -#if !HAVE_STRUCT_STAT_ST_BLOCKS && !defined _POSIX_SOURCE && defined BSIZE - -# include - -# ifndef NINDIR - -# if defined __DJGPP__ -typedef long daddr_t; /* for disk address */ -# endif - -/* Some SysV's, like Irix, seem to lack this. Hope it's correct. */ -/* 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. */ - -off_t -st_blocks (off_t size) -{ - off_t datablks = size / 512 + (size % 512 != 0); - off_t 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; -} -#else -/* This declaration is solely to ensure that after preprocessing - this file is never empty. */ -typedef int textutils_fileblocks_unused; -#endif diff --git a/src/bin/tar/lib/float+.h b/src/bin/tar/lib/float+.h deleted file mode 100644 index 4de25a941e..0000000000 --- a/src/bin/tar/lib/float+.h +++ /dev/null @@ -1,148 +0,0 @@ -/* Supplemental information about the floating-point formats. - Copyright (C) 2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2007. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _FLOATPLUS_H -#define _FLOATPLUS_H - -#include -#include - -/* Number of bits in the mantissa of a floating-point number, including the - "hidden bit". */ -#if FLT_RADIX == 2 -# define FLT_MANT_BIT FLT_MANT_DIG -# define DBL_MANT_BIT DBL_MANT_DIG -# define LDBL_MANT_BIT LDBL_MANT_DIG -#elif FLT_RADIX == 4 -# define FLT_MANT_BIT (FLT_MANT_DIG * 2) -# define DBL_MANT_BIT (DBL_MANT_DIG * 2) -# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2) -#elif FLT_RADIX == 16 -# define FLT_MANT_BIT (FLT_MANT_DIG * 4) -# define DBL_MANT_BIT (DBL_MANT_DIG * 4) -# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4) -#endif - -/* Bit mask that can be used to mask the exponent, as an unsigned number. */ -#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7) -#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) -#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7) - -/* Number of bits used for the exponent of a floating-point number, including - the exponent's sign. */ -#define FLT_EXP_BIT \ - (FLT_EXP_MASK < 0x100 ? 8 : \ - FLT_EXP_MASK < 0x200 ? 9 : \ - FLT_EXP_MASK < 0x400 ? 10 : \ - FLT_EXP_MASK < 0x800 ? 11 : \ - FLT_EXP_MASK < 0x1000 ? 12 : \ - FLT_EXP_MASK < 0x2000 ? 13 : \ - FLT_EXP_MASK < 0x4000 ? 14 : \ - FLT_EXP_MASK < 0x8000 ? 15 : \ - FLT_EXP_MASK < 0x10000 ? 16 : \ - FLT_EXP_MASK < 0x20000 ? 17 : \ - FLT_EXP_MASK < 0x40000 ? 18 : \ - FLT_EXP_MASK < 0x80000 ? 19 : \ - FLT_EXP_MASK < 0x100000 ? 20 : \ - FLT_EXP_MASK < 0x200000 ? 21 : \ - FLT_EXP_MASK < 0x400000 ? 22 : \ - FLT_EXP_MASK < 0x800000 ? 23 : \ - FLT_EXP_MASK < 0x1000000 ? 24 : \ - FLT_EXP_MASK < 0x2000000 ? 25 : \ - FLT_EXP_MASK < 0x4000000 ? 26 : \ - FLT_EXP_MASK < 0x8000000 ? 27 : \ - FLT_EXP_MASK < 0x10000000 ? 28 : \ - FLT_EXP_MASK < 0x20000000 ? 29 : \ - FLT_EXP_MASK < 0x40000000 ? 30 : \ - FLT_EXP_MASK <= 0x7fffffff ? 31 : \ - 32) -#define DBL_EXP_BIT \ - (DBL_EXP_MASK < 0x100 ? 8 : \ - DBL_EXP_MASK < 0x200 ? 9 : \ - DBL_EXP_MASK < 0x400 ? 10 : \ - DBL_EXP_MASK < 0x800 ? 11 : \ - DBL_EXP_MASK < 0x1000 ? 12 : \ - DBL_EXP_MASK < 0x2000 ? 13 : \ - DBL_EXP_MASK < 0x4000 ? 14 : \ - DBL_EXP_MASK < 0x8000 ? 15 : \ - DBL_EXP_MASK < 0x10000 ? 16 : \ - DBL_EXP_MASK < 0x20000 ? 17 : \ - DBL_EXP_MASK < 0x40000 ? 18 : \ - DBL_EXP_MASK < 0x80000 ? 19 : \ - DBL_EXP_MASK < 0x100000 ? 20 : \ - DBL_EXP_MASK < 0x200000 ? 21 : \ - DBL_EXP_MASK < 0x400000 ? 22 : \ - DBL_EXP_MASK < 0x800000 ? 23 : \ - DBL_EXP_MASK < 0x1000000 ? 24 : \ - DBL_EXP_MASK < 0x2000000 ? 25 : \ - DBL_EXP_MASK < 0x4000000 ? 26 : \ - DBL_EXP_MASK < 0x8000000 ? 27 : \ - DBL_EXP_MASK < 0x10000000 ? 28 : \ - DBL_EXP_MASK < 0x20000000 ? 29 : \ - DBL_EXP_MASK < 0x40000000 ? 30 : \ - DBL_EXP_MASK <= 0x7fffffff ? 31 : \ - 32) -#define LDBL_EXP_BIT \ - (LDBL_EXP_MASK < 0x100 ? 8 : \ - LDBL_EXP_MASK < 0x200 ? 9 : \ - LDBL_EXP_MASK < 0x400 ? 10 : \ - LDBL_EXP_MASK < 0x800 ? 11 : \ - LDBL_EXP_MASK < 0x1000 ? 12 : \ - LDBL_EXP_MASK < 0x2000 ? 13 : \ - LDBL_EXP_MASK < 0x4000 ? 14 : \ - LDBL_EXP_MASK < 0x8000 ? 15 : \ - LDBL_EXP_MASK < 0x10000 ? 16 : \ - LDBL_EXP_MASK < 0x20000 ? 17 : \ - LDBL_EXP_MASK < 0x40000 ? 18 : \ - LDBL_EXP_MASK < 0x80000 ? 19 : \ - LDBL_EXP_MASK < 0x100000 ? 20 : \ - LDBL_EXP_MASK < 0x200000 ? 21 : \ - LDBL_EXP_MASK < 0x400000 ? 22 : \ - LDBL_EXP_MASK < 0x800000 ? 23 : \ - LDBL_EXP_MASK < 0x1000000 ? 24 : \ - LDBL_EXP_MASK < 0x2000000 ? 25 : \ - LDBL_EXP_MASK < 0x4000000 ? 26 : \ - LDBL_EXP_MASK < 0x8000000 ? 27 : \ - LDBL_EXP_MASK < 0x10000000 ? 28 : \ - LDBL_EXP_MASK < 0x20000000 ? 29 : \ - LDBL_EXP_MASK < 0x40000000 ? 30 : \ - LDBL_EXP_MASK <= 0x7fffffff ? 31 : \ - 32) - -/* Number of bits used for a floating-point number: the mantissa (not - counting the "hidden bit", since it may or may not be explicit), the - exponent, and the sign. */ -#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1) -#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1) -#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1) - -/* Number of bytes used for a floating-point number. - This can be smaller than the 'sizeof'. For example, on i386 systems, - 'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence - LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but - sizeof (long double) = 12 or = 16. */ -#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) -#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) -#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) - -/* Verify that SIZEOF_FLT <= sizeof (float) etc. */ -typedef int verify_sizeof_flt[2 * (SIZEOF_FLT <= sizeof (float)) - 1]; -typedef int verify_sizeof_dbl[2 * (SIZEOF_DBL <= sizeof (double)) - 1]; -typedef int verify_sizeof_ldbl[2 * (SIZEOF_LDBL <= sizeof (long double)) - 1]; - -#endif /* _FLOATPLUS_H */ diff --git a/src/bin/tar/lib/float.in.h b/src/bin/tar/lib/float.in.h deleted file mode 100644 index d3e94023e9..0000000000 --- a/src/bin/tar/lib/float.in.h +++ /dev/null @@ -1,59 +0,0 @@ -/* A correct . - - Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GL_FLOAT_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_FLOAT_H@ - -#ifndef _GL_FLOAT_H -#define _GL_FLOAT_H - -/* 'long double' properties. */ -#if defined __i386__ && (defined(__BEOS__) || defined(__HAIKU__)) -/* Number of mantissa units, in base FLT_RADIX. */ -# undef LDBL_MANT_DIG -# define LDBL_MANT_DIG 64 -/* Number of decimal digits that is sufficient for representing a number. */ -# undef LDBL_DIG -# define LDBL_DIG 18 -/* x-1 where x is the smallest representable number > 1. */ -# undef LDBL_EPSILON -# define LDBL_EPSILON 1.0842021724855044340E-19L -/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ -# undef LDBL_MIN_EXP -# define LDBL_MIN_EXP (-16381) -/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ -# undef LDBL_MAX_EXP -# define LDBL_MAX_EXP 16384 -/* Minimum positive normalized number. */ -# undef LDBL_MIN -# define LDBL_MIN 3.3621031431120935063E-4932L -/* Maximum representable finite number. */ -# undef LDBL_MAX -# define LDBL_MAX 1.1897314953572317650E+4932L -/* Minimum e such that 10^e is in the range of normalized numbers. */ -# undef LDBL_MIN_10_EXP -# define LDBL_MIN_10_EXP (-4931) -/* Maximum e such that 10^e is in the range of representable finite numbers. */ -# undef LDBL_MAX_10_EXP -# define LDBL_MAX_10_EXP 4932 -#endif - -#endif /* _GL_FLOAT_H */ -#endif /* _GL_FLOAT_H */ diff --git a/src/bin/tar/lib/fnmatch.c b/src/bin/tar/lib/fnmatch.c deleted file mode 100644 index 48bc8b5d2a..0000000000 --- a/src/bin/tar/lib/fnmatch.c +++ /dev/null @@ -1,354 +0,0 @@ -/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LIBC -# include -#endif - -/* Enable GNU extensions in fnmatch.h. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#if ! defined __builtin_expect && __GNUC__ < 3 -# define __builtin_expect(expr, expected) (expr) -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define WIDE_CHAR_SUPPORT \ - (HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \ - && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY)) - -/* For platform which support the ISO C amendement 1 functionality we - support user defined character classes. */ -#if defined _LIBC || WIDE_CHAR_SUPPORT -# include -# include -#endif - -/* We need some of the locale data (the collation sequence information) - but there is no interface to get this information in general. Therefore - we support a correct implementation only in glibc. */ -#ifdef _LIBC -# include "../locale/localeinfo.h" -# include "../locale/elem-hash.h" -# include "../locale/coll-lookup.h" -# include - -# define CONCAT(a,b) __CONCAT(a,b) -# define mbsrtowcs __mbsrtowcs -# define fnmatch __fnmatch -extern int fnmatch (const char *pattern, const char *string, int flags); -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ -#define NO_LEADING_PERIOD(flags) \ - ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD)) - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself, and have not detected a bug - in the library. 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__ || !HAVE_FNMATCH_GNU - - -# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) -# define isblank(c) ((c) == ' ' || (c) == '\t') -# endif - -# define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) - -# if defined _LIBC || WIDE_CHAR_SUPPORT -/* The GNU C library provides support for user-defined character classes - and the functions from ISO C amendement 1. */ -# ifdef CHARCLASS_NAME_MAX -# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX -# else -/* This shouldn't happen but some implementation might still have this - problem. Use a reasonable default value. */ -# define CHAR_CLASS_MAX_LENGTH 256 -# endif - -# ifdef _LIBC -# define IS_CHAR_CLASS(string) __wctype (string) -# else -# define IS_CHAR_CLASS(string) wctype (string) -# endif - -# ifdef _LIBC -# define ISWCTYPE(WC, WT) __iswctype (WC, WT) -# else -# define ISWCTYPE(WC, WT) iswctype (WC, WT) -# endif - -# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC -/* In this case we are implementing the multibyte character handling. */ -# define HANDLE_MULTIBYTE 1 -# endif - -# else -# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ - -# define IS_CHAR_CLASS(string) \ - (STREQ (string, "alpha") || STREQ (string, "upper") \ - || STREQ (string, "lower") || STREQ (string, "digit") \ - || STREQ (string, "alnum") || STREQ (string, "xdigit") \ - || STREQ (string, "space") || STREQ (string, "print") \ - || STREQ (string, "punct") || STREQ (string, "graph") \ - || STREQ (string, "cntrl") || STREQ (string, "blank")) -# endif - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -/* Global variable. */ -static int posixly_correct; - -# ifndef internal_function -/* Inside GNU libc we mark some function in a special way. In other - environments simply ignore the marking. */ -# define internal_function -# endif - -/* Note that this evaluates C many times. */ -# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) -# define CHAR char -# define UCHAR unsigned char -# define INT int -# define FCT internal_fnmatch -# define EXT ext_match -# define END end_pattern -# define L_(CS) CS -# ifdef _LIBC -# define BTOWC(C) __btowc (C) -# else -# define BTOWC(C) btowc (C) -# endif -# define STRLEN(S) strlen (S) -# define STRCAT(D, S) strcat (D, S) -# ifdef _LIBC -# define MEMPCPY(D, S, N) __mempcpy (D, S, N) -# else -# if HAVE_MEMPCPY -# define MEMPCPY(D, S, N) mempcpy (D, S, N) -# else -# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) -# endif -# endif -# define MEMCHR(S, C, N) memchr (S, C, N) -# define STRCOLL(S1, S2) strcoll (S1, S2) -# include "fnmatch_loop.c" - - -# if HANDLE_MULTIBYTE -# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c)) -# define CHAR wchar_t -# define UCHAR wint_t -# define INT wint_t -# define FCT internal_fnwmatch -# define EXT ext_wmatch -# define END end_wpattern -# define L_(CS) L##CS -# define BTOWC(C) (C) -# ifdef _LIBC -# define STRLEN(S) __wcslen (S) -# define STRCAT(D, S) __wcscat (D, S) -# define MEMPCPY(D, S, N) __wmempcpy (D, S, N) -# else -# define STRLEN(S) wcslen (S) -# define STRCAT(D, S) wcscat (D, S) -# if HAVE_WMEMPCPY -# define MEMPCPY(D, S, N) wmempcpy (D, S, N) -# else -# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N)) -# endif -# endif -# define MEMCHR(S, C, N) wmemchr (S, C, N) -# define STRCOLL(S1, S2) wcscoll (S1, S2) -# define WIDE_CHAR_VERSION 1 - -# undef IS_CHAR_CLASS -/* We have to convert the wide character string in a multibyte string. But - we know that the character class names consist of alphanumeric characters - from the portable character set, and since the wide character encoding - for a member of the portable character set is the same code point as - its single-byte encoding, we can use a simplified method to convert the - string to a multibyte character string. */ -static wctype_t -is_char_class (const wchar_t *wcs) -{ - char s[CHAR_CLASS_MAX_LENGTH + 1]; - char *cp = s; - - do - { - /* Test for a printable character from the portable character set. */ -# ifdef _LIBC - if (*wcs < 0x20 || *wcs > 0x7e - || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) - return (wctype_t) 0; -# else - switch (*wcs) - { - case L' ': case L'!': case L'"': case L'#': case L'%': - case L'&': case L'\'': case L'(': case L')': case L'*': - case L'+': case L',': case L'-': case L'.': case L'/': - case L'0': case L'1': case L'2': case L'3': case L'4': - case L'5': case L'6': case L'7': case L'8': case L'9': - case L':': case L';': case L'<': case L'=': case L'>': - case L'?': - case L'A': case L'B': case L'C': case L'D': case L'E': - case L'F': case L'G': case L'H': case L'I': case L'J': - case L'K': case L'L': case L'M': case L'N': case L'O': - case L'P': case L'Q': case L'R': case L'S': case L'T': - case L'U': case L'V': case L'W': case L'X': case L'Y': - case L'Z': - case L'[': case L'\\': case L']': case L'^': case L'_': - case L'a': case L'b': case L'c': case L'd': case L'e': - case L'f': case L'g': case L'h': case L'i': case L'j': - case L'k': case L'l': case L'm': case L'n': case L'o': - case L'p': case L'q': case L'r': case L's': case L't': - case L'u': case L'v': case L'w': case L'x': case L'y': - case L'z': case L'{': case L'|': case L'}': case L'~': - break; - default: - return (wctype_t) 0; - } -# endif - - /* Avoid overrunning the buffer. */ - if (cp == s + CHAR_CLASS_MAX_LENGTH) - return (wctype_t) 0; - - *cp++ = (char) *wcs++; - } - while (*wcs != L'\0'); - - *cp = '\0'; - -# ifdef _LIBC - return __wctype (s); -# else - return wctype (s); -# endif -} -# define IS_CHAR_CLASS(string) is_char_class (string) - -# include "fnmatch_loop.c" -# endif - - -int -fnmatch (const char *pattern, const char *string, int flags) -{ -# if HANDLE_MULTIBYTE -# define ALLOCA_LIMIT 2000 - if (__builtin_expect (MB_CUR_MAX, 1) != 1) - { - mbstate_t ps; - size_t patsize; - size_t strsize; - size_t totsize; - wchar_t *wpattern; - wchar_t *wstring; - int res; - - /* Calculate the size needed to convert the strings to - wide characters. */ - memset (&ps, '\0', sizeof (ps)); - patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1; - if (__builtin_expect (patsize != 0, 1)) - { - assert (mbsinit (&ps)); - strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; - if (__builtin_expect (strsize != 0, 1)) - { - assert (mbsinit (&ps)); - totsize = patsize + strsize; - if (__builtin_expect (! (patsize <= totsize - && totsize <= SIZE_MAX / sizeof (wchar_t)), - 0)) - { - errno = ENOMEM; - return -1; - } - - /* Allocate room for the wide characters. */ - if (__builtin_expect (totsize < ALLOCA_LIMIT, 1)) - wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t)); - else - { - wpattern = malloc (totsize * sizeof (wchar_t)); - if (__builtin_expect (! wpattern, 0)) - { - errno = ENOMEM; - return -1; - } - } - wstring = wpattern + patsize; - - /* Convert the strings into wide characters. */ - mbsrtowcs (wpattern, &pattern, patsize, &ps); - assert (mbsinit (&ps)); - mbsrtowcs (wstring, &string, strsize, &ps); - - res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, - flags & FNM_PERIOD, flags); - - if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0)) - free (wpattern); - return res; - } - } - } - -# endif /* HANDLE_MULTIBYTE */ - - return internal_fnmatch (pattern, string, string + strlen (string), - flags & FNM_PERIOD, flags); -} - -# ifdef _LIBC -# undef fnmatch -versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3); -# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3) -strong_alias (__fnmatch, __fnmatch_old) -compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0); -# endif -libc_hidden_ver (__fnmatch, fnmatch) -# endif - -#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/src/bin/tar/lib/fnmatch.h b/src/bin/tar/lib/fnmatch.h deleted file mode 100644 index b086b45aac..0000000000 --- a/src/bin/tar/lib/fnmatch.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003, - 2005, 2007 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _FNMATCH_H -#define _FNMATCH_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* We #undef these before defining them because some losing systems - (HP-UX A.08.07 for example) define these in . */ -#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. */ -# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ -#endif - -/* Value returned by `fnmatch' if STRING does not match PATTERN. */ -#define FNM_NOMATCH 1 - -/* This value is returned if the implementation does not support - `fnmatch'. Since this is not the case here it will never be - returned but the conformance test suites still require the symbol - to be defined. */ -#ifdef _XOPEN_SOURCE -# define FNM_NOSYS (-1) -#endif - -/* Match NAME against the file name pattern PATTERN, - returning zero if it matches, FNM_NOMATCH if not. */ -extern int fnmatch (const char *__pattern, const char *__name, - int __flags); - -#ifdef __cplusplus -} -#endif - -#endif /* fnmatch.h */ diff --git a/src/bin/tar/lib/fnmatch.in.h b/src/bin/tar/lib/fnmatch.in.h deleted file mode 100644 index b086b45aac..0000000000 --- a/src/bin/tar/lib/fnmatch.in.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003, - 2005, 2007 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _FNMATCH_H -#define _FNMATCH_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* We #undef these before defining them because some losing systems - (HP-UX A.08.07 for example) define these in . */ -#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. */ -# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ -#endif - -/* Value returned by `fnmatch' if STRING does not match PATTERN. */ -#define FNM_NOMATCH 1 - -/* This value is returned if the implementation does not support - `fnmatch'. Since this is not the case here it will never be - returned but the conformance test suites still require the symbol - to be defined. */ -#ifdef _XOPEN_SOURCE -# define FNM_NOSYS (-1) -#endif - -/* Match NAME against the file name pattern PATTERN, - returning zero if it matches, FNM_NOMATCH if not. */ -extern int fnmatch (const char *__pattern, const char *__name, - int __flags); - -#ifdef __cplusplus -} -#endif - -#endif /* fnmatch.h */ diff --git a/src/bin/tar/lib/fnmatch_loop.c b/src/bin/tar/lib/fnmatch_loop.c deleted file mode 100644 index d1008c247d..0000000000 --- a/src/bin/tar/lib/fnmatch_loop.c +++ /dev/null @@ -1,1210 +0,0 @@ -/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Match STRING against the file name pattern PATTERN, returning zero if - it matches, nonzero if not. */ -static int EXT (INT opt, const CHAR *pattern, const CHAR *string, - const CHAR *string_end, bool no_leading_period, int flags) - internal_function; -static const CHAR *END (const CHAR *patternp) internal_function; - -static int -internal_function -FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, - bool no_leading_period, int flags) -{ - register const CHAR *p = pattern, *n = string; - register UCHAR c; -#ifdef _LIBC -# if WIDE_CHAR_VERSION - const char *collseq = (const char *) - _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC); -# else - const UCHAR *collseq = (const UCHAR *) - _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB); -# endif -#endif - - while ((c = *p++) != L_('\0')) - { - bool new_no_leading_period = false; - c = FOLD (c); - - switch (c) - { - case L_('?'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; - - res = EXT (c, p, n, string_end, no_leading_period, - flags); - if (res != -1) - return res; - } - - if (n == string_end) - return FNM_NOMATCH; - else if (*n == L_('/') && (flags & FNM_FILE_NAME)) - return FNM_NOMATCH; - else if (*n == L_('.') && no_leading_period) - return FNM_NOMATCH; - break; - - case L_('\\'): - if (!(flags & FNM_NOESCAPE)) - { - c = *p++; - if (c == L_('\0')) - /* Trailing \ loses. */ - return FNM_NOMATCH; - c = FOLD (c); - } - if (n == string_end || FOLD ((UCHAR) *n) != c) - return FNM_NOMATCH; - break; - - case L_('*'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; - - res = EXT (c, p, n, string_end, no_leading_period, - flags); - if (res != -1) - return res; - } - - if (n != string_end && *n == L_('.') && no_leading_period) - return FNM_NOMATCH; - - for (c = *p++; c == L_('?') || c == L_('*'); c = *p++) - { - if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0) - { - const CHAR *endp = END (p); - if (endp != p) - { - /* This is a pattern. Skip over it. */ - p = endp; - continue; - } - } - - if (c == L_('?')) - { - /* A ? needs to match one character. */ - if (n == string_end) - /* There isn't another character; no match. */ - return FNM_NOMATCH; - else if (*n == L_('/') - && __builtin_expect (flags & FNM_FILE_NAME, 0)) - /* A slash does not match a wildcard under - FNM_FILE_NAME. */ - return FNM_NOMATCH; - else - /* One character of the string is consumed in matching - this ? wildcard, so *??? won't match if there are - less than three characters. */ - ++n; - } - } - - if (c == L_('\0')) - /* The wildcard(s) is/are the last element of the pattern. - If the name is a file name and contains another slash - this means it cannot match, unless the FNM_LEADING_DIR - flag is set. */ - { - int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH; - - if (flags & FNM_FILE_NAME) - { - if (flags & FNM_LEADING_DIR) - result = 0; - else - { - if (MEMCHR (n, L_('/'), string_end - n) == NULL) - result = 0; - } - } - - return result; - } - else - { - const CHAR *endp; - - endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'), - string_end - n); - if (endp == NULL) - endp = string_end; - - if (c == L_('[') - || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0 - && (c == L_('@') || c == L_('+') || c == L_('!')) - && *p == L_('('))) - { - int flags2 = ((flags & FNM_FILE_NAME) - ? flags : (flags & ~FNM_PERIOD)); - bool no_leading_period2 = no_leading_period; - - for (--p; n < endp; ++n, no_leading_period2 = false) - if (FCT (p, n, string_end, no_leading_period2, flags2) - == 0) - return 0; - } - else if (c == L_('/') && (flags & FNM_FILE_NAME)) - { - while (n < string_end && *n != L_('/')) - ++n; - if (n < string_end && *n == L_('/') - && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags) - == 0)) - return 0; - } - else - { - int flags2 = ((flags & FNM_FILE_NAME) - ? flags : (flags & ~FNM_PERIOD)); - int no_leading_period2 = no_leading_period; - - if (c == L_('\\') && !(flags & FNM_NOESCAPE)) - c = *p; - c = FOLD (c); - for (--p; n < endp; ++n, no_leading_period2 = false) - if (FOLD ((UCHAR) *n) == c - && (FCT (p, n, string_end, no_leading_period2, flags2) - == 0)) - return 0; - } - } - - /* If we come here no match is possible with the wildcard. */ - return FNM_NOMATCH; - - case L_('['): - { - /* Nonzero if the sense of the character class is inverted. */ - register bool not; - CHAR cold; - UCHAR fn; - - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - - if (n == string_end) - return FNM_NOMATCH; - - if (*n == L_('.') && no_leading_period) - return FNM_NOMATCH; - - if (*n == L_('/') && (flags & FNM_FILE_NAME)) - /* `/' cannot be matched. */ - return FNM_NOMATCH; - - not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^'))); - if (not) - ++p; - - fn = FOLD ((UCHAR) *n); - - c = *p++; - for (;;) - { - if (!(flags & FNM_NOESCAPE) && c == L_('\\')) - { - if (*p == L_('\0')) - return FNM_NOMATCH; - c = FOLD ((UCHAR) *p); - ++p; - - goto normal_bracket; - } - else if (c == L_('[') && *p == L_(':')) - { - /* Leave room for the null. */ - CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; - size_t c1 = 0; -#if defined _LIBC || WIDE_CHAR_SUPPORT - wctype_t wt; -#endif - const CHAR *startp = p; - - for (;;) - { - if (c1 == CHAR_CLASS_MAX_LENGTH) - /* The name is too long and therefore the pattern - is ill-formed. */ - return FNM_NOMATCH; - - c = *++p; - if (c == L_(':') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c < L_('a') || c >= L_('z')) - { - /* This cannot possibly be a character class name. - Match it as a normal range. */ - p = startp; - c = L_('['); - goto normal_bracket; - } - str[c1++] = c; - } - str[c1] = L_('\0'); - -#if defined _LIBC || WIDE_CHAR_SUPPORT - wt = IS_CHAR_CLASS (str); - if (wt == 0) - /* Invalid character class name. */ - return FNM_NOMATCH; - -# if defined _LIBC && ! WIDE_CHAR_VERSION - /* The following code is glibc specific but does - there a good job in speeding up the code since - we can avoid the btowc() call. */ - if (_ISCTYPE ((UCHAR) *n, wt)) - goto matched; -# else - if (ISWCTYPE (BTOWC ((UCHAR) *n), wt)) - goto matched; -# endif -#else - if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n)) - || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n)) - || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n)) - || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n)) - || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n)) - || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n)) - || (STREQ (str, L_("lower")) && islower ((UCHAR) *n)) - || (STREQ (str, L_("print")) && isprint ((UCHAR) *n)) - || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n)) - || (STREQ (str, L_("space")) && isspace ((UCHAR) *n)) - || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n)) - || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n))) - goto matched; -#endif - c = *p++; - } -#ifdef _LIBC - else if (c == L_('[') && *p == L_('=')) - { - UCHAR str[1]; - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - const CHAR *startp = p; - - c = *++p; - if (c == L_('\0')) - { - p = startp; - c = L_('['); - goto normal_bracket; - } - str[0] = c; - - c = *++p; - if (c != L_('=') || p[1] != L_(']')) - { - p = startp; - c = L_('['); - goto normal_bracket; - } - p += 2; - - if (nrules == 0) - { - if ((UCHAR) *n == str[0]) - goto matched; - } - else - { - const int32_t *table; -# if WIDE_CHAR_VERSION - const int32_t *weights; - const int32_t *extra; -# else - const unsigned char *weights; - const unsigned char *extra; -# endif - const int32_t *indirect; - int32_t idx; - const UCHAR *cp = (const UCHAR *) str; - - /* This #include defines a local function! */ -# if WIDE_CHAR_VERSION -# include -# else -# include -# endif - -# if WIDE_CHAR_VERSION - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); - weights = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); - extra = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); -# else - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); -# endif - - idx = findidx (&cp); - if (idx != 0) - { - /* We found a table entry. Now see whether the - character we are currently at has the same - equivalance class value. */ - int len = weights[idx]; - int32_t idx2; - const UCHAR *np = (const UCHAR *) n; - - idx2 = findidx (&np); - if (idx2 != 0 && len == weights[idx2]) - { - int cnt = 0; - - while (cnt < len - && (weights[idx + 1 + cnt] - == weights[idx2 + 1 + cnt])) - ++cnt; - - if (cnt == len) - goto matched; - } - } - } - - c = *p++; - } -#endif - else if (c == L_('\0')) - /* [ (unterminated) loses. */ - return FNM_NOMATCH; - else - { - bool is_range = false; - -#ifdef _LIBC - bool is_seqval = false; - - if (c == L_('[') && *p == L_('.')) - { - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - const CHAR *startp = p; - size_t c1 = 0; - - while (1) - { - c = *++p; - if (c == L_('.') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c == '\0') - return FNM_NOMATCH; - ++c1; - } - - /* We have to handling the symbols differently in - ranges since then the collation sequence is - important. */ - is_range = *p == L_('-') && p[1] != L_('\0'); - - if (nrules == 0) - { - /* There are no names defined in the collation - data. Therefore we only accept the trivial - names consisting of the character itself. */ - if (c1 != 1) - return FNM_NOMATCH; - - if (!is_range && *n == startp[1]) - goto matched; - - cold = startp[1]; - c = *p++; - } - else - { - int32_t table_size; - const int32_t *symb_table; -# ifdef WIDE_CHAR_VERSION - char str[c1]; - size_t strcnt; -# else -# define str (startp + 1) -# endif - const unsigned char *extra; - int32_t idx; - int32_t elem; - int32_t second; - int32_t hash; - -# ifdef WIDE_CHAR_VERSION - /* We have to convert the name to a single-byte - string. This is possible since the names - consist of ASCII characters and the internal - representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; -# endif - - table_size = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); - - /* Locate the character in the hashing table. */ - hash = elem_hash (str, c1); - - idx = 0; - elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - second = hash % (table_size - 2) + 1; - - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && (c1 - == extra[symb_table[2 * elem + 1]]) - && memcmp (str, - &extra[symb_table[2 * elem - + 1] - + 1], c1) == 0) - { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; - } - - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } - - if (symb_table[2 * elem] != 0) - { - /* Compare the byte sequence but only if - this is not part of a range. */ -# ifdef WIDE_CHAR_VERSION - int32_t *wextra; - - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - - wextra = (int32_t *) &extra[idx + 4]; -# endif - - if (! is_range) - { -# ifdef WIDE_CHAR_VERSION - for (c1 = 0; - (int32_t) c1 < wextra[idx]; - ++c1) - if (n[c1] != wextra[1 + c1]) - break; - - if ((int32_t) c1 == wextra[idx]) - goto matched; -# else - for (c1 = 0; c1 < extra[idx]; ++c1) - if (n[c1] != extra[1 + c1]) - break; - - if (c1 == extra[idx]) - goto matched; -# endif - } - - /* Get the collation sequence value. */ - is_seqval = true; -# ifdef WIDE_CHAR_VERSION - cold = wextra[1 + wextra[idx]]; -# else - /* Adjust for the alignment. */ - idx += 1 + extra[idx]; - idx = (idx + 3) & ~4; - cold = *((int32_t *) &extra[idx]); -# endif - - c = *p++; - } - else if (c1 == 1) - { - /* No valid character. Match it as a - single byte. */ - if (!is_range && *n == str[0]) - goto matched; - - cold = str[0]; - c = *p++; - } - else - return FNM_NOMATCH; - } - } - else -# undef str -#endif - { - c = FOLD (c); - normal_bracket: - - /* We have to handling the symbols differently in - ranges since then the collation sequence is - important. */ - is_range = (*p == L_('-') && p[1] != L_('\0') - && p[1] != L_(']')); - - if (!is_range && c == fn) - goto matched; - -#if _LIBC - /* This is needed if we goto normal_bracket; from - outside of is_seqval's scope. */ - is_seqval = false; -#endif - - cold = c; - c = *p++; - } - - if (c == L_('-') && *p != L_(']')) - { -#if _LIBC - /* We have to find the collation sequence - value for C. Collation sequence is nothing - we can regularly access. The sequence - value is defined by the order in which the - definitions of the collation values for the - various characters appear in the source - file. A strange concept, nowhere - documented. */ - uint32_t fcollseq; - uint32_t lcollseq; - UCHAR cend = *p++; - -# ifdef WIDE_CHAR_VERSION - /* Search in the `names' array for the characters. */ - fcollseq = __collseq_table_lookup (collseq, fn); - if (fcollseq == ~((uint32_t) 0)) - /* XXX We don't know anything about the character - we are supposed to match. This means we are - failing. */ - goto range_not_matched; - - if (is_seqval) - lcollseq = cold; - else - lcollseq = __collseq_table_lookup (collseq, cold); -# else - fcollseq = collseq[fn]; - lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; -# endif - - is_seqval = false; - if (cend == L_('[') && *p == L_('.')) - { - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_NRULES); - const CHAR *startp = p; - size_t c1 = 0; - - while (1) - { - c = *++p; - if (c == L_('.') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c == '\0') - return FNM_NOMATCH; - ++c1; - } - - if (nrules == 0) - { - /* There are no names defined in the - collation data. Therefore we only - accept the trivial names consisting - of the character itself. */ - if (c1 != 1) - return FNM_NOMATCH; - - cend = startp[1]; - } - else - { - int32_t table_size; - const int32_t *symb_table; -# ifdef WIDE_CHAR_VERSION - char str[c1]; - size_t strcnt; -# else -# define str (startp + 1) -# endif - const unsigned char *extra; - int32_t idx; - int32_t elem; - int32_t second; - int32_t hash; - -# ifdef WIDE_CHAR_VERSION - /* We have to convert the name to a single-byte - string. This is possible since the names - consist of ASCII characters and the internal - representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; -# endif - - table_size = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); - - /* Locate the character in the hashing - table. */ - hash = elem_hash (str, c1); - - idx = 0; - elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - second = hash % (table_size - 2) + 1; - - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && (c1 - == extra[symb_table[2 * elem + 1]]) - && memcmp (str, - &extra[symb_table[2 * elem + 1] - + 1], c1) == 0) - { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; - } - - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } - - if (symb_table[2 * elem] != 0) - { - /* Compare the byte sequence but only if - this is not part of a range. */ -# ifdef WIDE_CHAR_VERSION - int32_t *wextra; - - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~4; - - wextra = (int32_t *) &extra[idx + 4]; -# endif - /* Get the collation sequence value. */ - is_seqval = true; -# ifdef WIDE_CHAR_VERSION - cend = wextra[1 + wextra[idx]]; -# else - /* Adjust for the alignment. */ - idx += 1 + extra[idx]; - idx = (idx + 3) & ~4; - cend = *((int32_t *) &extra[idx]); -# endif - } - else if (symb_table[2 * elem] != 0 && c1 == 1) - { - cend = str[0]; - c = *p++; - } - else - return FNM_NOMATCH; - } -# undef str - } - else - { - if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) - cend = *p++; - if (cend == L_('\0')) - return FNM_NOMATCH; - cend = FOLD (cend); - } - - /* XXX It is not entirely clear to me how to handle - characters which are not mentioned in the - collation specification. */ - if ( -# ifdef WIDE_CHAR_VERSION - lcollseq == 0xffffffff || -# endif - lcollseq <= fcollseq) - { - /* We have to look at the upper bound. */ - uint32_t hcollseq; - - if (is_seqval) - hcollseq = cend; - else - { -# ifdef WIDE_CHAR_VERSION - hcollseq = - __collseq_table_lookup (collseq, cend); - if (hcollseq == ~((uint32_t) 0)) - { - /* Hum, no information about the upper - bound. The matching succeeds if the - lower bound is matched exactly. */ - if (lcollseq != fcollseq) - goto range_not_matched; - - goto matched; - } -# else - hcollseq = collseq[cend]; -# endif - } - - if (lcollseq <= hcollseq && fcollseq <= hcollseq) - goto matched; - } -# ifdef WIDE_CHAR_VERSION - range_not_matched: -# endif -#else - /* We use a boring value comparison of the character - values. This is better than comparing using - `strcoll' since the latter would have surprising - and sometimes fatal consequences. */ - UCHAR cend = *p++; - - if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) - cend = *p++; - if (cend == L_('\0')) - return FNM_NOMATCH; - - /* It is a range. */ - if (cold <= fn && fn <= cend) - goto matched; -#endif - - c = *p++; - } - } - - if (c == L_(']')) - break; - } - - if (!not) - return FNM_NOMATCH; - break; - - matched: - /* Skip the rest of the [...] that already matched. */ - do - { - ignore_next: - c = *p++; - - if (c == L_('\0')) - /* [... (unterminated) loses. */ - return FNM_NOMATCH; - - if (!(flags & FNM_NOESCAPE) && c == L_('\\')) - { - if (*p == L_('\0')) - return FNM_NOMATCH; - /* XXX 1003.2d11 is unclear if this is right. */ - ++p; - } - else if (c == L_('[') && *p == L_(':')) - { - int c1 = 0; - const CHAR *startp = p; - - while (1) - { - c = *++p; - if (++c1 == CHAR_CLASS_MAX_LENGTH) - return FNM_NOMATCH; - - if (*p == L_(':') && p[1] == L_(']')) - break; - - if (c < L_('a') || c >= L_('z')) - { - p = startp; - goto ignore_next; - } - } - p += 2; - c = *p++; - } - else if (c == L_('[') && *p == L_('=')) - { - c = *++p; - if (c == L_('\0')) - return FNM_NOMATCH; - c = *++p; - if (c != L_('=') || p[1] != L_(']')) - return FNM_NOMATCH; - p += 2; - c = *p++; - } - else if (c == L_('[') && *p == L_('.')) - { - ++p; - while (1) - { - c = *++p; - if (c == '\0') - return FNM_NOMATCH; - - if (*p == L_('.') && p[1] == L_(']')) - break; - } - p += 2; - c = *p++; - } - } - while (c != L_(']')); - if (not) - return FNM_NOMATCH; - } - break; - - case L_('+'): - case L_('@'): - case L_('!'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; - - res = EXT (c, p, n, string_end, no_leading_period, flags); - if (res != -1) - return res; - } - goto normal_match; - - case L_('/'): - if (NO_LEADING_PERIOD (flags)) - { - if (n == string_end || c != (UCHAR) *n) - return FNM_NOMATCH; - - new_no_leading_period = true; - break; - } - /* FALLTHROUGH */ - default: - normal_match: - if (n == string_end || c != FOLD ((UCHAR) *n)) - return FNM_NOMATCH; - } - - no_leading_period = new_no_leading_period; - ++n; - } - - if (n == string_end) - return 0; - - if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/')) - /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ - return 0; - - return FNM_NOMATCH; -} - - -static const CHAR * -internal_function -END (const CHAR *pattern) -{ - const CHAR *p = pattern; - - while (1) - if (*++p == L_('\0')) - /* This is an invalid pattern. */ - return pattern; - else if (*p == L_('[')) - { - /* Handle brackets special. */ - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - - /* Skip the not sign. We have to recognize it because of a possibly - following ']'. */ - if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) - ++p; - /* A leading ']' is recognized as such. */ - if (*p == L_(']')) - ++p; - /* Skip over all characters of the list. */ - while (*p != L_(']')) - if (*p++ == L_('\0')) - /* This is no valid pattern. */ - return pattern; - } - else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') - || *p == L_('!')) && p[1] == L_('(')) - p = END (p + 1); - else if (*p == L_(')')) - break; - - return p + 1; -} - - -static int -internal_function -EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, - bool no_leading_period, int flags) -{ - const CHAR *startp; - size_t level; - struct patternlist - { - struct patternlist *next; - CHAR str[1]; - } *list = NULL; - struct patternlist **lastp = &list; - size_t pattern_len = STRLEN (pattern); - const CHAR *p; - const CHAR *rs; - enum { ALLOCA_LIMIT = 8000 }; - - /* Parse the pattern. Store the individual parts in the list. */ - level = 0; - for (startp = p = pattern + 1; ; ++p) - if (*p == L_('\0')) - /* This is an invalid pattern. */ - return -1; - else if (*p == L_('[')) - { - /* Handle brackets special. */ - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - - /* Skip the not sign. We have to recognize it because of a possibly - following ']'. */ - if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) - ++p; - /* A leading ']' is recognized as such. */ - if (*p == L_(']')) - ++p; - /* Skip over all characters of the list. */ - while (*p != L_(']')) - if (*p++ == L_('\0')) - /* This is no valid pattern. */ - return -1; - } - else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') - || *p == L_('!')) && p[1] == L_('(')) - /* Remember the nesting level. */ - ++level; - else if (*p == L_(')')) - { - if (level-- == 0) - { - /* This means we found the end of the pattern. */ -#define NEW_PATTERN \ - struct patternlist *newp; \ - size_t plen; \ - size_t plensize; \ - size_t newpsize; \ - \ - plen = (opt == L_('?') || opt == L_('@') \ - ? pattern_len \ - : p - startp + 1); \ - plensize = plen * sizeof (CHAR); \ - newpsize = offsetof (struct patternlist, str) + plensize; \ - if ((size_t) -1 / sizeof (CHAR) < plen \ - || newpsize < offsetof (struct patternlist, str) \ - || ALLOCA_LIMIT <= newpsize) \ - return -1; \ - newp = (struct patternlist *) alloca (newpsize); \ - *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ - newp->next = NULL; \ - *lastp = newp; \ - lastp = &newp->next - NEW_PATTERN; - break; - } - } - else if (*p == L_('|')) - { - if (level == 0) - { - NEW_PATTERN; - startp = p + 1; - } - } - assert (list != NULL); - assert (p[-1] == L_(')')); -#undef NEW_PATTERN - - switch (opt) - { - case L_('*'): - if (FCT (p, string, string_end, no_leading_period, flags) == 0) - return 0; - /* FALLTHROUGH */ - - case L_('+'): - do - { - for (rs = string; rs <= string_end; ++rs) - /* First match the prefix with the current pattern with the - current pattern. */ - if (FCT (list->str, string, rs, no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0 - /* This was successful. Now match the rest with the rest - of the pattern. */ - && (FCT (p, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD) == 0 - /* This didn't work. Try the whole pattern. */ - || (rs != string - && FCT (pattern - 1, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD) == 0))) - /* It worked. Signal success. */ - return 0; - } - while ((list = list->next) != NULL); - - /* None of the patterns lead to a match. */ - return FNM_NOMATCH; - - case L_('?'): - if (FCT (p, string, string_end, no_leading_period, flags) == 0) - return 0; - /* FALLTHROUGH */ - - case L_('@'): - do - /* I cannot believe it but `strcat' is actually acceptable - here. Match the entire string with the prefix from the - pattern list and the rest of the pattern following the - pattern list. */ - if (FCT (STRCAT (list->str, p), string, string_end, - no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) - /* It worked. Signal success. */ - return 0; - while ((list = list->next) != NULL); - - /* None of the patterns lead to a match. */ - return FNM_NOMATCH; - - case L_('!'): - for (rs = string; rs <= string_end; ++rs) - { - struct patternlist *runp; - - for (runp = list; runp != NULL; runp = runp->next) - if (FCT (runp->str, string, rs, no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) - break; - - /* If none of the patterns matched see whether the rest does. */ - if (runp == NULL - && (FCT (p, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) - == 0)) - /* This is successful. */ - return 0; - } - - /* None of the patterns together with the rest of the pattern - lead to a match. */ - return FNM_NOMATCH; - - default: - assert (! "Invalid extended matching operator"); - break; - } - - return -1; -} - - -#undef FOLD -#undef CHAR -#undef UCHAR -#undef INT -#undef FCT -#undef EXT -#undef END -#undef MEMPCPY -#undef MEMCHR -#undef STRCOLL -#undef STRLEN -#undef STRCAT -#undef L_ -#undef BTOWC diff --git a/src/bin/tar/lib/fpending.c b/src/bin/tar/lib/fpending.c deleted file mode 100644 index 4b982ba4f4..0000000000 --- a/src/bin/tar/lib/fpending.c +++ /dev/null @@ -1,30 +0,0 @@ -/* fpending.c -- return the number of pending output bytes on a stream - Copyright (C) 2000, 2004, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -#include "fpending.h" - -/* Return the number of pending (aka buffered, unflushed) - bytes on the stream, FP, that is open for writing. */ -size_t -__fpending (FILE *fp) -{ - return PENDING_OUTPUT_N_BYTES; -} diff --git a/src/bin/tar/lib/fpending.h b/src/bin/tar/lib/fpending.h deleted file mode 100644 index 8a8aabcc22..0000000000 --- a/src/bin/tar/lib/fpending.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Declare __fpending. - - Copyright (C) 2000, 2003, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - Written by Jim Meyering. */ - -#include -#include - -#ifndef HAVE_DECL___FPENDING -"this configure-time declaration test was not run" -#endif - -#if HAVE_DECL___FPENDING -# if HAVE_STDIO_EXT_H -# include -# endif -#else -size_t __fpending (FILE *); -#endif diff --git a/src/bin/tar/lib/fstatat.c b/src/bin/tar/lib/fstatat.c deleted file mode 100644 index 92a516457f..0000000000 --- a/src/bin/tar/lib/fstatat.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Work around an fstatat bug on Solaris 9. - - Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert and Jim Meyering. */ - -#include - -#define COMPILING_FSTATAT 1 -#include "openat.h" - -#include -#include - -/* fstatat should always follow symbolic links that end in /, but on - Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified. This is - the same problem that lstat.c addresses, so solve it in a similar - way. */ - -int -rpl_fstatat (int fd, char const *file, struct stat *st, int flag) -{ - int result = fstatat (fd, file, st, flag); - - if (result == 0 && (flag & AT_SYMLINK_NOFOLLOW) && S_ISLNK (st->st_mode) - && file[strlen (file) - 1] == '/') - { - /* FILE refers to a symbolic link and the name ends with a slash. - Get info about the link's referent. */ - result = fstatat (fd, file, st, flag & ~AT_SYMLINK_NOFOLLOW); - if (result == 0 && ! S_ISDIR (st->st_mode)) - { - /* fstatat succeeded and FILE references a non-directory. - But it was specified via a name including a trailing - slash. Fail with errno set to ENOTDIR to indicate the - contradiction. */ - errno = ENOTDIR; - return -1; - } - } - - return result; -} diff --git a/src/bin/tar/lib/ftruncate.c b/src/bin/tar/lib/ftruncate.c deleted file mode 100644 index ff7d11b090..0000000000 --- a/src/bin/tar/lib/ftruncate.c +++ /dev/null @@ -1,90 +0,0 @@ -/* ftruncate emulations that work on some System V's. - This file is in the public domain. */ - -#include - -/* Specification. */ -#include - -#include -#include - -#ifdef F_CHSIZE - -int -ftruncate (int fd, off_t length) -{ - return fcntl (fd, F_CHSIZE, length); -} - -#else /* not F_CHSIZE */ -# ifdef F_FREESP - -/* By William Kucharski . */ - -# include -# include - -int -ftruncate (int fd, off_t length) -{ - struct flock fl; - struct stat filebuf; - - if (fstat (fd, &filebuf) < 0) - return -1; - - if (filebuf.st_size < length) - { - /* Extend file length. */ - if (lseek (fd, (length - 1), SEEK_SET) < 0) - return -1; - - /* Write a "0" byte. */ - if (write (fd, "", 1) != 1) - return -1; - } - else - { - - /* Truncate length. */ - - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = length; - fl.l_type = F_WRLCK; /* write lock on file space */ - - /* This relies on the *undocumented* F_FREESP argument to fcntl, - which truncates the file so that it ends at the position - indicated by fl.l_start. Will minor miracles never cease? */ - - if (fcntl (fd, F_FREESP, &fl) < 0) - return -1; - } - - return 0; -} - -# else /* not F_CHSIZE nor F_FREESP */ -# if HAVE_CHSIZE /* native Windows, e.g. mingw */ - -int -ftruncate (int fd, off_t length) -{ - return chsize (fd, length); -} - -# else /* not F_CHSIZE nor F_FREESP nor HAVE_CHSIZE */ - -# include - -int -ftruncate (int fd, off_t length) -{ - errno = EIO; - return -1; -} - -# endif /* not HAVE_CHSIZE */ -# endif /* not F_FREESP */ -#endif /* not F_CHSIZE */ diff --git a/src/bin/tar/lib/full-write.c b/src/bin/tar/lib/full-write.c deleted file mode 100644 index cc168720ea..0000000000 --- a/src/bin/tar/lib/full-write.c +++ /dev/null @@ -1,81 +0,0 @@ -/* An interface to read and write that retries (if necessary) until complete. - - Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#ifdef FULL_READ -# include "full-read.h" -#else -# include "full-write.h" -#endif - -#include - -#ifdef FULL_READ -# include "safe-read.h" -# define safe_rw safe_read -# define full_rw full_read -# undef const -# define const /* empty */ -#else -# include "safe-write.h" -# define safe_rw safe_write -# define full_rw full_write -#endif - -#ifdef FULL_READ -/* Set errno to zero upon EOF. */ -# define ZERO_BYTE_TRANSFER_ERRNO 0 -#else -/* Some buggy drivers return 0 when one tries to write beyond - a device's end. (Example: Linux 1.2.13 on /dev/fd0.) - Set errno to ENOSPC so they get a sensible diagnostic. */ -# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC -#endif - -/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if - interrupted or if a partial write(read) occurs. Return the number - of bytes transferred. - When writing, set errno if fewer than COUNT bytes are written. - When reading, if fewer than COUNT bytes are read, you must examine - errno to distinguish failure from EOF (errno == 0). */ -size_t -full_rw (int fd, const void *buf, size_t count) -{ - size_t total = 0; - const char *ptr = (const char *) buf; - - while (count > 0) - { - size_t n_rw = safe_rw (fd, ptr, count); - if (n_rw == (size_t) -1) - break; - if (n_rw == 0) - { - errno = ZERO_BYTE_TRANSFER_ERRNO; - break; - } - total += n_rw; - ptr += n_rw; - count -= n_rw; - } - - return total; -} diff --git a/src/bin/tar/lib/full-write.h b/src/bin/tar/lib/full-write.h deleted file mode 100644 index d20d2fe4ab..0000000000 --- a/src/bin/tar/lib/full-write.h +++ /dev/null @@ -1,35 +0,0 @@ -/* An interface to write() that writes all it is asked to write. - - Copyright (C) 2002-2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted - or if partial writes occur. Return the number of bytes successfully - written, setting errno if that is less than COUNT. */ -extern size_t full_write (int fd, const void *buf, size_t count); - - -#ifdef __cplusplus -} -#endif diff --git a/src/bin/tar/lib/getcwd.c b/src/bin/tar/lib/getcwd.c deleted file mode 100644 index 23b35de679..0000000000 --- a/src/bin/tar/lib/getcwd.c +++ /dev/null @@ -1,428 +0,0 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2004,2005,2006,2007 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if !_LIBC -# include -# include -# include "dirfd.h" -#endif - -#include -#include -#include -#include -#include - -#include /* For AT_FDCWD on Solaris 9. */ - -#ifndef __set_errno -# define __set_errno(val) (errno = (val)) -#endif - -#include -#ifndef _D_EXACT_NAMLEN -# define _D_EXACT_NAMLEN(d) strlen ((d)->d_name) -#endif -#ifndef _D_ALLOC_NAMLEN -# define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1) -#endif - -#include -#include -#include - -#if _LIBC -# ifndef mempcpy -# define mempcpy __mempcpy -# endif -#endif - -#include - -/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its - value exceeds INT_MAX, so its use as an int doesn't conform to the - C standard, and GCC and Sun C complain in some cases. */ -#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553 -# undef AT_FDCWD -# define AT_FDCWD (-3041965) -#endif - -#ifdef ENAMETOOLONG -# define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG) -#else -# define is_ENAMETOOLONG(x) 0 -#endif - -#ifndef MAX -# define MAX(a, b) ((a) < (b) ? (b) : (a)) -#endif -#ifndef MIN -# define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - -#ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# else -# define PATH_MAX 1024 -# endif -#endif - -#if D_INO_IN_DIRENT -# define MATCHING_INO(dp, ino) ((dp)->d_ino == (ino)) -#else -# define MATCHING_INO(dp, ino) true -#endif - -#if !_LIBC -# define __getcwd getcwd -# define __lstat lstat -# define __closedir closedir -# define __opendir opendir -# define __readdir readdir -#endif - -/* The results of opendir() in this file are not used with dirfd and fchdir, - therefore save some unnecessary recursion in fchdir.c. */ -#undef opendir -#undef closedir - -/* Get the name of the current working directory, and put it in SIZE - bytes of BUF. Returns NULL if the directory couldn't be determined or - SIZE was too small. If successful, returns BUF. In GNU, if BUF is - NULL, an array is allocated with `malloc'; the array is SIZE bytes long, - unless SIZE == 0, in which case it is as big as necessary. */ - -char * -__getcwd (char *buf, size_t size) -{ - /* Lengths of big file name components and entire file names, and a - deep level of file name nesting. These numbers are not upper - bounds; they are merely large values suitable for initial - allocations, designed to be large enough for most real-world - uses. */ - enum - { - BIG_FILE_NAME_COMPONENT_LENGTH = 255, - BIG_FILE_NAME_LENGTH = MIN (4095, PATH_MAX - 1), - DEEP_NESTING = 100 - }; - -#ifdef AT_FDCWD - int fd = AT_FDCWD; - bool fd_needs_closing = false; -#else - char dots[DEEP_NESTING * sizeof ".." + BIG_FILE_NAME_COMPONENT_LENGTH + 1]; - char *dotlist = dots; - size_t dotsize = sizeof dots; - size_t dotlen = 0; -#endif - DIR *dirstream = NULL; - dev_t rootdev, thisdev; - ino_t rootino, thisino; - char *dir; - register char *dirp; - struct stat st; - size_t allocated = size; - size_t used; - -#if HAVE_PARTLY_WORKING_GETCWD - /* The system getcwd works, except it sometimes fails when it - shouldn't, setting errno to ERANGE, ENAMETOOLONG, or ENOENT. If - AT_FDCWD is not defined, the algorithm below is O(N**2) and this - is much slower than the system getcwd (at least on GNU/Linux). - So trust the system getcwd's results unless they look - suspicious. - - Use the system getcwd even if we have openat support, since the - system getcwd works even when a parent is unreadable, while the - openat-based approach does not. */ - -# undef getcwd - dir = getcwd (buf, size); - if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT)) - return dir; -#endif - - if (size == 0) - { - if (buf != NULL) - { - __set_errno (EINVAL); - return NULL; - } - - allocated = BIG_FILE_NAME_LENGTH + 1; - } - - if (buf == NULL) - { - dir = malloc (allocated); - if (dir == NULL) - return NULL; - } - else - dir = buf; - - dirp = dir + allocated; - *--dirp = '\0'; - - if (__lstat (".", &st) < 0) - goto lose; - thisdev = st.st_dev; - thisino = st.st_ino; - - if (__lstat ("/", &st) < 0) - goto lose; - rootdev = st.st_dev; - rootino = st.st_ino; - - while (!(thisdev == rootdev && thisino == rootino)) - { - struct dirent *d; - dev_t dotdev; - ino_t dotino; - bool mount_point; - int parent_status; - size_t dirroom; - size_t namlen; - bool use_d_ino = true; - - /* Look at the parent directory. */ -#ifdef AT_FDCWD - fd = openat (fd, "..", O_RDONLY); - if (fd < 0) - goto lose; - fd_needs_closing = true; - parent_status = fstat (fd, &st); -#else - dotlist[dotlen++] = '.'; - dotlist[dotlen++] = '.'; - dotlist[dotlen] = '\0'; - parent_status = __lstat (dotlist, &st); -#endif - if (parent_status != 0) - goto lose; - - if (dirstream && __closedir (dirstream) != 0) - { - dirstream = NULL; - goto lose; - } - - /* Figure out if this directory is a mount point. */ - dotdev = st.st_dev; - dotino = st.st_ino; - mount_point = dotdev != thisdev; - - /* Search for the last directory. */ -#ifdef AT_FDCWD - dirstream = fdopendir (fd); - if (dirstream == NULL) - goto lose; - /* Reset fd. It may have been closed by fdopendir. */ - fd = dirfd (dirstream); - fd_needs_closing = false; -#else - dirstream = __opendir (dotlist); - if (dirstream == NULL) - goto lose; - dotlist[dotlen++] = '/'; -#endif - for (;;) - { - /* Clear errno to distinguish EOF from error if readdir returns - NULL. */ - __set_errno (0); - d = __readdir (dirstream); - - /* When we've iterated through all directory entries without finding - one with a matching d_ino, rewind the stream and consider each - name again, but this time, using lstat. This is necessary in a - chroot on at least one system (glibc-2.3.6 + linux 2.6.12), where - .., ../.., ../../.., etc. all had the same device number, yet the - d_ino values for entries in / did not match those obtained - via lstat. */ - if (d == NULL && errno == 0 && use_d_ino) - { - use_d_ino = false; - rewinddir (dirstream); - d = __readdir (dirstream); - } - - if (d == NULL) - { - if (errno == 0) - /* EOF on dirstream, which can mean e.g., that the current - directory has been removed. */ - __set_errno (ENOENT); - goto lose; - } - if (d->d_name[0] == '.' && - (d->d_name[1] == '\0' || - (d->d_name[1] == '.' && d->d_name[2] == '\0'))) - continue; - - if (use_d_ino) - { - bool match = (MATCHING_INO (d, thisino) || mount_point); - if (! match) - continue; - } - - { - int entry_status; -#ifdef AT_FDCWD - entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); -#else - /* Compute size needed for this file name, or for the file - name ".." in the same directory, whichever is larger. - Room for ".." might be needed the next time through - the outer loop. */ - size_t name_alloc = _D_ALLOC_NAMLEN (d); - size_t filesize = dotlen + MAX (sizeof "..", name_alloc); - - if (filesize < dotlen) - goto memory_exhausted; - - if (dotsize < filesize) - { - /* My, what a deep directory tree you have, Grandma. */ - size_t newsize = MAX (filesize, dotsize * 2); - size_t i; - if (newsize < dotsize) - goto memory_exhausted; - if (dotlist != dots) - free (dotlist); - dotlist = malloc (newsize); - if (dotlist == NULL) - goto lose; - dotsize = newsize; - - i = 0; - do - { - dotlist[i++] = '.'; - dotlist[i++] = '.'; - dotlist[i++] = '/'; - } - while (i < dotlen); - } - - memcpy (dotlist + dotlen, d->d_name, _D_ALLOC_NAMLEN (d)); - entry_status = __lstat (dotlist, &st); -#endif - /* We don't fail here if we cannot stat() a directory entry. - This can happen when (network) file systems fail. If this - entry is in fact the one we are looking for we will find - out soon as we reach the end of the directory without - having found anything. */ - if (entry_status == 0 && S_ISDIR (st.st_mode) - && st.st_dev == thisdev && st.st_ino == thisino) - break; - } - } - - dirroom = dirp - dir; - namlen = _D_EXACT_NAMLEN (d); - - if (dirroom <= namlen) - { - if (size != 0) - { - __set_errno (ERANGE); - goto lose; - } - else - { - char *tmp; - size_t oldsize = allocated; - - allocated += MAX (allocated, namlen); - if (allocated < oldsize - || ! (tmp = realloc (dir, allocated))) - goto memory_exhausted; - - /* Move current contents up to the end of the buffer. - This is guaranteed to be non-overlapping. */ - dirp = memcpy (tmp + allocated - (oldsize - dirroom), - tmp + dirroom, - oldsize - dirroom); - dir = tmp; - } - } - dirp -= namlen; - memcpy (dirp, d->d_name, namlen); - *--dirp = '/'; - - thisdev = dotdev; - thisino = dotino; - } - - if (dirstream && __closedir (dirstream) != 0) - { - dirstream = NULL; - goto lose; - } - - if (dirp == &dir[allocated - 1]) - *--dirp = '/'; - -#ifndef AT_FDCWD - if (dotlist != dots) - free (dotlist); -#endif - - used = dir + allocated - dirp; - memmove (dir, dirp, used); - - if (size == 0) - /* Ensure that the buffer is only as large as necessary. */ - buf = realloc (dir, used); - - if (buf == NULL) - /* Either buf was NULL all along, or `realloc' failed but - we still have the original string. */ - buf = dir; - - return buf; - - memory_exhausted: - __set_errno (ENOMEM); - lose: - { - int save = errno; - if (dirstream) - __closedir (dirstream); -#ifdef AT_FDCWD - if (fd_needs_closing) - close (fd); -#else - if (dotlist != dots) - free (dotlist); -#endif - if (buf == NULL) - free (dir); - __set_errno (save); - } - return NULL; -} - -#ifdef weak_alias -weak_alias (__getcwd, getcwd) -#endif diff --git a/src/bin/tar/lib/getdate.c b/src/bin/tar/lib/getdate.c deleted file mode 100644 index 6d433a1eb3..0000000000 --- a/src/bin/tar/lib/getdate.c +++ /dev/null @@ -1,3299 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - tAGO = 258, - tDST = 259, - tYEAR_UNIT = 260, - tMONTH_UNIT = 261, - tHOUR_UNIT = 262, - tMINUTE_UNIT = 263, - tSEC_UNIT = 264, - tDAY_UNIT = 265, - tDAY = 266, - tDAYZONE = 267, - tLOCAL_ZONE = 268, - tMERIDIAN = 269, - tMONTH = 270, - tORDINAL = 271, - tZONE = 272, - tSNUMBER = 273, - tUNUMBER = 274, - tSDECIMAL_NUMBER = 275, - tUDECIMAL_NUMBER = 276 - }; -#endif -/* Tokens. */ -#define tAGO 258 -#define tDST 259 -#define tYEAR_UNIT 260 -#define tMONTH_UNIT 261 -#define tHOUR_UNIT 262 -#define tMINUTE_UNIT 263 -#define tSEC_UNIT 264 -#define tDAY_UNIT 265 -#define tDAY 266 -#define tDAYZONE 267 -#define tLOCAL_ZONE 268 -#define tMERIDIAN 269 -#define tMONTH 270 -#define tORDINAL 271 -#define tZONE 272 -#define tSNUMBER 273 -#define tUNUMBER 274 -#define tSDECIMAL_NUMBER 275 -#define tUDECIMAL_NUMBER 276 - - - - -/* Copy the first part of user declarations. */ -#line 1 "getdate.y" - -/* Parse a string into an internal time stamp. - - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Originally written by Steven M. Bellovin while - at the University of North Carolina at Chapel Hill. Later tweaked by - a couple of people on Usenet. Completely overhauled by Rich $alz - and Jim Berets in August, 1990. - - Modified by Paul Eggert in August 1999 to do - the right thing about local DST. Also modified by Paul Eggert - in February 2004 to support - nanosecond-resolution time stamps, and in October 2004 to support - TZ strings in dates. */ - -/* FIXME: Check for arithmetic overflow in all cases, not just - some of them. */ - -#include - -#include "getdate.h" - -#include "intprops.h" -#include "timespec.h" -#include "verify.h" - -/* There's no need to extend the stack, so there's no need to involve - alloca. */ -#define YYSTACK_USE_ALLOCA 0 - -/* Tell Bison how much stack space is needed. 20 should be plenty for - this grammar, which is not right recursive. Beware setting it too - high, since that might cause problems on machines whose - implementations have lame stack-overflow checking. */ -#define YYMAXDEPTH 20 -#define YYINITDEPTH YYMAXDEPTH - -/* Since the code of getdate.y is not included in the Emacs executable - itself, there is no need to #define static in this file. Even if - the code were included in the Emacs executable, it probably - wouldn't do any harm to #undef it here; this will only cause - problems if we try to write to a static variable, which I don't - think this code needs to do. */ -#ifdef emacs -# undef static -#endif - -#include -#include -#include -#include -#include - -#include "setenv.h" -#include "xalloc.h" - - -/* ISDIGIT differs from isdigit, as follows: - - Its arg may be any int or unsigned int; it need not be an unsigned char - or EOF. - - It's typically faster. - POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to - isdigit unless it's important to use the locale's definition - of `digit' even when the host does not conform to POSIX. */ -#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) - -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -#endif - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - -/* Shift A right by B bits portably, by dividing A by 2**B and - truncating towards minus infinity. A and B should be free of side - effects, and B should be in the range 0 <= B <= INT_BITS - 2, where - INT_BITS is the number of useful bits in an int. GNU code can - assume that INT_BITS is at least 32. - - ISO C99 says that A >> B is implementation-defined if A < 0. Some - implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift - right in the usual way when A < 0, so SHR falls back on division if - ordinary A >> B doesn't seem to be the usual signed shift. */ -#define SHR(a, b) \ - (-1 >> 1 == -1 \ - ? (a) >> (b) \ - : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) - -#define EPOCH_YEAR 1970 -#define TM_YEAR_BASE 1900 - -#define HOUR(x) ((x) * 60) - -/* Lots of this code assumes time_t and time_t-like values fit into - long int. It also assumes that signed integer overflow silently - wraps around, but there's no portable way to check for that at - compile-time. */ -verify (TYPE_IS_INTEGER (time_t)); -verify (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= LONG_MAX); - -/* An integer value, and the number of digits in its textual - representation. */ -typedef struct -{ - bool negative; - long int value; - size_t digits; -} textint; - -/* An entry in the lexical lookup table. */ -typedef struct -{ - char const *name; - int type; - int value; -} table; - -/* Meridian: am, pm, or 24-hour style. */ -enum { MERam, MERpm, MER24 }; - -enum { BILLION = 1000000000, LOG10_BILLION = 9 }; - -/* Relative times. */ -typedef struct -{ - /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */ - long int year; - long int month; - long int day; - long int hour; - long int minutes; - long int seconds; - long int ns; -} relative_time; - -#if HAVE_COMPOUND_LITERALS -# define RELATIVE_TIME_0 ((relative_time) { 0, 0, 0, 0, 0, 0, 0 }) -#else -static relative_time const RELATIVE_TIME_0; -#endif - -/* Information passed to and from the parser. */ -typedef struct -{ - /* The input string remaining to be parsed. */ - const char *input; - - /* N, if this is the Nth Tuesday. */ - long int day_ordinal; - - /* Day of week; Sunday is 0. */ - int day_number; - - /* tm_isdst flag for the local zone. */ - int local_isdst; - - /* Time zone, in minutes east of UTC. */ - long int time_zone; - - /* Style used for time. */ - int meridian; - - /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds. */ - textint year; - long int month; - long int day; - long int hour; - long int minutes; - struct timespec seconds; /* includes nanoseconds */ - - /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */ - relative_time rel; - - /* Presence or counts of nonterminals of various flavors parsed so far. */ - bool timespec_seen; - bool rels_seen; - size_t dates_seen; - size_t days_seen; - size_t local_zones_seen; - size_t dsts_seen; - size_t times_seen; - size_t zones_seen; - - /* Table of local time zone abbrevations, terminated by a null entry. */ - table local_time_zone_table[3]; -} parser_control; - -union YYSTYPE; -static int yylex (union YYSTYPE *, parser_control *); -static int yyerror (parser_control const *, char const *); -static long int time_zone_hhmm (textint, long int); - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 224 "getdate.y" -{ - long int intval; - textint textintval; - struct timespec timespec; - relative_time rel; -} -/* Line 187 of yacc.c. */ -#line 358 "getdate.c" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 216 of yacc.c. */ -#line 371 "getdate.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) -#else -static int -YYID (i) - int i; -#endif -{ - return i; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 12 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 91 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 26 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 19 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 78 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 96 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 276 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 24, 2, 2, 25, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 23, 2, - 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 7, 10, 11, 14, 16, 18, - 20, 22, 24, 26, 28, 31, 36, 42, 49, 57, - 59, 62, 64, 67, 71, 73, 76, 78, 81, 84, - 87, 91, 97, 101, 105, 109, 112, 117, 120, 124, - 127, 129, 132, 135, 137, 140, 143, 145, 148, 151, - 153, 156, 159, 161, 164, 167, 169, 172, 175, 178, - 181, 183, 185, 188, 191, 194, 197, 200, 203, 205, - 207, 209, 211, 213, 215, 217, 218, 221, 222 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 27, 0, -1, 28, -1, 29, -1, 22, 39, -1, - -1, 29, 30, -1, 31, -1, 32, -1, 33, -1, - 35, -1, 34, -1, 36, -1, 42, -1, 19, 14, - -1, 19, 23, 19, 44, -1, 19, 23, 19, 18, - 43, -1, 19, 23, 19, 23, 41, 44, -1, 19, - 23, 19, 23, 41, 18, 43, -1, 13, -1, 13, - 4, -1, 17, -1, 17, 38, -1, 17, 18, 43, - -1, 12, -1, 17, 4, -1, 11, -1, 11, 24, - -1, 16, 11, -1, 19, 11, -1, 19, 25, 19, - -1, 19, 25, 19, 25, 19, -1, 19, 18, 18, - -1, 19, 15, 18, -1, 15, 18, 18, -1, 15, - 19, -1, 15, 19, 24, 19, -1, 19, 15, -1, - 19, 15, 19, -1, 37, 3, -1, 37, -1, 16, - 5, -1, 19, 5, -1, 5, -1, 16, 6, -1, - 19, 6, -1, 6, -1, 16, 10, -1, 19, 10, - -1, 10, -1, 16, 7, -1, 19, 7, -1, 7, - -1, 16, 8, -1, 19, 8, -1, 8, -1, 16, - 9, -1, 19, 9, -1, 20, 9, -1, 21, 9, - -1, 9, -1, 38, -1, 18, 5, -1, 18, 6, - -1, 18, 10, -1, 18, 7, -1, 18, 8, -1, - 18, 9, -1, 40, -1, 41, -1, 20, -1, 18, - -1, 21, -1, 19, -1, 19, -1, -1, 23, 19, - -1, -1, 14, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 250, 250, 251, 255, 262, 264, 268, 270, 272, - 274, 276, 278, 280, 284, 292, 300, 310, 317, 329, - 334, 342, 344, 354, 356, 358, 363, 368, 373, 378, - 386, 391, 411, 418, 426, 434, 439, 445, 450, 459, - 469, 482, 484, 486, 488, 490, 492, 494, 496, 498, - 500, 502, 504, 506, 508, 510, 512, 514, 516, 518, - 520, 522, 526, 528, 530, 532, 534, 536, 540, 540, - 543, 544, 549, 550, 555, 593, 594, 600, 601 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "tAGO", "tDST", "tYEAR_UNIT", - "tMONTH_UNIT", "tHOUR_UNIT", "tMINUTE_UNIT", "tSEC_UNIT", "tDAY_UNIT", - "tDAY", "tDAYZONE", "tLOCAL_ZONE", "tMERIDIAN", "tMONTH", "tORDINAL", - "tZONE", "tSNUMBER", "tUNUMBER", "tSDECIMAL_NUMBER", "tUDECIMAL_NUMBER", - "'@'", "':'", "','", "'/'", "$accept", "spec", "timespec", "items", - "item", "time", "local_zone", "zone", "day", "date", "rel", "relunit", - "relunit_snumber", "seconds", "signed_seconds", "unsigned_seconds", - "number", "o_colon_minutes", "o_merid", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 64, 58, 44, 47 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 26, 27, 27, 28, 29, 29, 30, 30, 30, - 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, - 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, - 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, - 40, 40, 41, 41, 42, 43, 43, 44, 44 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 2, 0, 2, 1, 1, 1, - 1, 1, 1, 1, 2, 4, 5, 6, 7, 1, - 2, 1, 2, 3, 1, 2, 1, 2, 2, 2, - 3, 5, 3, 3, 3, 2, 4, 2, 3, 2, - 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, - 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, - 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 0, 2, 0, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 5, 0, 0, 2, 3, 71, 73, 70, 72, 4, - 68, 69, 1, 43, 46, 52, 55, 60, 49, 26, - 24, 19, 0, 0, 21, 0, 74, 0, 0, 6, - 7, 8, 9, 11, 10, 12, 40, 61, 13, 27, - 20, 0, 35, 41, 44, 50, 53, 56, 47, 28, - 25, 75, 22, 62, 63, 65, 66, 67, 64, 42, - 45, 51, 54, 57, 48, 29, 14, 37, 0, 0, - 0, 58, 59, 39, 34, 0, 0, 23, 33, 38, - 32, 77, 30, 36, 76, 78, 75, 0, 15, 0, - 16, 77, 31, 75, 17, 18 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 2, 3, 4, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 9, 10, 11, 38, 77, 88 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -79 -static const yytype_int8 yypact[] = -{ - -10, 47, 27, -79, 25, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, 5, - -79, 59, 43, 42, 10, 49, -5, 62, 63, -79, - -79, -79, -79, -79, -79, -79, 70, -79, -79, -79, - -79, 56, 52, -79, -79, -79, -79, -79, -79, -79, - -79, 16, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, 51, 57, 58, - 60, -79, -79, -79, -79, 61, 64, -79, -79, -79, - -79, -7, 53, -79, -79, -79, 65, -2, -79, 66, - -79, 46, -79, 65, -79, -79 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, 67, -79, -79, -6, -79, -78, -9 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 59, 60, 61, 62, 63, 64, 65, 85, 90, 66, - 67, 86, 1, 68, 50, 95, 87, 6, 69, 8, - 70, 53, 54, 55, 56, 57, 58, 12, 51, 39, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 76, - 22, 23, 24, 25, 26, 27, 28, 43, 44, 45, - 46, 47, 48, 49, 53, 54, 55, 56, 57, 58, - 85, 41, 42, 40, 93, 5, 6, 7, 8, 78, - 79, 71, 72, 73, 74, 80, 75, 81, 89, 82, - 83, 91, 94, 84, 0, 92, 0, 0, 76, 0, - 0, 52 -}; - -static const yytype_int8 yycheck[] = -{ - 5, 6, 7, 8, 9, 10, 11, 14, 86, 14, - 15, 18, 22, 18, 4, 93, 23, 19, 23, 21, - 25, 5, 6, 7, 8, 9, 10, 0, 18, 24, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 23, - 15, 16, 17, 18, 19, 20, 21, 5, 6, 7, - 8, 9, 10, 11, 5, 6, 7, 8, 9, 10, - 14, 18, 19, 4, 18, 18, 19, 20, 21, 18, - 19, 9, 9, 3, 18, 18, 24, 19, 25, 19, - 19, 87, 91, 19, -1, 19, -1, -1, 23, -1, - -1, 24 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 22, 27, 28, 29, 18, 19, 20, 21, 39, - 40, 41, 0, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 15, 16, 17, 18, 19, 20, 21, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 42, 24, - 4, 18, 19, 5, 6, 7, 8, 9, 10, 11, - 4, 18, 38, 5, 6, 7, 8, 9, 10, 5, - 6, 7, 8, 9, 10, 11, 14, 15, 18, 23, - 25, 9, 9, 3, 18, 24, 23, 43, 18, 19, - 18, 19, 19, 19, 19, 14, 18, 23, 44, 25, - 43, 41, 19, 18, 44, 43 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (pc, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, pc) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, pc); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - parser_control *pc; -#endif -{ - if (!yyvaluep) - return; - YYUSE (pc); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, pc) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - parser_control *pc; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else -static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule, parser_control *pc) -#else -static void -yy_reduce_print (yyvsp, yyrule, pc) - YYSTYPE *yyvsp; - int yyrule; - parser_control *pc; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , pc); - fprintf (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule, pc); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_control *pc) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, pc) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - parser_control *pc; -#endif -{ - YYUSE (yyvaluep); - YYUSE (pc); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (parser_control *pc); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (parser_control *pc) -#else -int -yyparse (pc) - parser_control *pc; -#endif -#endif -{ - /* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: -#line 256 "getdate.y" - { - pc->seconds = (yyvsp[(2) - (2)].timespec); - pc->timespec_seen = true; - } - break; - - case 7: -#line 269 "getdate.y" - { pc->times_seen++; } - break; - - case 8: -#line 271 "getdate.y" - { pc->local_zones_seen++; } - break; - - case 9: -#line 273 "getdate.y" - { pc->zones_seen++; } - break; - - case 10: -#line 275 "getdate.y" - { pc->dates_seen++; } - break; - - case 11: -#line 277 "getdate.y" - { pc->days_seen++; } - break; - - case 12: -#line 279 "getdate.y" - { pc->rels_seen = true; } - break; - - case 14: -#line 285 "getdate.y" - { - pc->hour = (yyvsp[(1) - (2)].textintval).value; - pc->minutes = 0; - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = (yyvsp[(2) - (2)].intval); - } - break; - - case 15: -#line 293 "getdate.y" - { - pc->hour = (yyvsp[(1) - (4)].textintval).value; - pc->minutes = (yyvsp[(3) - (4)].textintval).value; - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = (yyvsp[(4) - (4)].intval); - } - break; - - case 16: -#line 301 "getdate.y" - { - pc->hour = (yyvsp[(1) - (5)].textintval).value; - pc->minutes = (yyvsp[(3) - (5)].textintval).value; - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = MER24; - pc->zones_seen++; - pc->time_zone = time_zone_hhmm ((yyvsp[(4) - (5)].textintval), (yyvsp[(5) - (5)].intval)); - } - break; - - case 17: -#line 311 "getdate.y" - { - pc->hour = (yyvsp[(1) - (6)].textintval).value; - pc->minutes = (yyvsp[(3) - (6)].textintval).value; - pc->seconds = (yyvsp[(5) - (6)].timespec); - pc->meridian = (yyvsp[(6) - (6)].intval); - } - break; - - case 18: -#line 318 "getdate.y" - { - pc->hour = (yyvsp[(1) - (7)].textintval).value; - pc->minutes = (yyvsp[(3) - (7)].textintval).value; - pc->seconds = (yyvsp[(5) - (7)].timespec); - pc->meridian = MER24; - pc->zones_seen++; - pc->time_zone = time_zone_hhmm ((yyvsp[(6) - (7)].textintval), (yyvsp[(7) - (7)].intval)); - } - break; - - case 19: -#line 330 "getdate.y" - { - pc->local_isdst = (yyvsp[(1) - (1)].intval); - pc->dsts_seen += (0 < (yyvsp[(1) - (1)].intval)); - } - break; - - case 20: -#line 335 "getdate.y" - { - pc->local_isdst = 1; - pc->dsts_seen += (0 < (yyvsp[(1) - (2)].intval)) + 1; - } - break; - - case 21: -#line 343 "getdate.y" - { pc->time_zone = (yyvsp[(1) - (1)].intval); } - break; - - case 22: -#line 345 "getdate.y" - { pc->time_zone = (yyvsp[(1) - (2)].intval); - pc->rel.ns += (yyvsp[(2) - (2)].rel).ns; - pc->rel.seconds += (yyvsp[(2) - (2)].rel).seconds; - pc->rel.minutes += (yyvsp[(2) - (2)].rel).minutes; - pc->rel.hour += (yyvsp[(2) - (2)].rel).hour; - pc->rel.day += (yyvsp[(2) - (2)].rel).day; - pc->rel.month += (yyvsp[(2) - (2)].rel).month; - pc->rel.year += (yyvsp[(2) - (2)].rel).year; - pc->rels_seen = true; } - break; - - case 23: -#line 355 "getdate.y" - { pc->time_zone = (yyvsp[(1) - (3)].intval) + time_zone_hhmm ((yyvsp[(2) - (3)].textintval), (yyvsp[(3) - (3)].intval)); } - break; - - case 24: -#line 357 "getdate.y" - { pc->time_zone = (yyvsp[(1) - (1)].intval) + 60; } - break; - - case 25: -#line 359 "getdate.y" - { pc->time_zone = (yyvsp[(1) - (2)].intval) + 60; } - break; - - case 26: -#line 364 "getdate.y" - { - pc->day_ordinal = 1; - pc->day_number = (yyvsp[(1) - (1)].intval); - } - break; - - case 27: -#line 369 "getdate.y" - { - pc->day_ordinal = 1; - pc->day_number = (yyvsp[(1) - (2)].intval); - } - break; - - case 28: -#line 374 "getdate.y" - { - pc->day_ordinal = (yyvsp[(1) - (2)].intval); - pc->day_number = (yyvsp[(2) - (2)].intval); - } - break; - - case 29: -#line 379 "getdate.y" - { - pc->day_ordinal = (yyvsp[(1) - (2)].textintval).value; - pc->day_number = (yyvsp[(2) - (2)].intval); - } - break; - - case 30: -#line 387 "getdate.y" - { - pc->month = (yyvsp[(1) - (3)].textintval).value; - pc->day = (yyvsp[(3) - (3)].textintval).value; - } - break; - - case 31: -#line 392 "getdate.y" - { - /* Interpret as YYYY/MM/DD if the first value has 4 or more digits, - otherwise as MM/DD/YY. - The goal in recognizing YYYY/MM/DD is solely to support legacy - machine-generated dates like those in an RCS log listing. If - you want portability, use the ISO 8601 format. */ - if (4 <= (yyvsp[(1) - (5)].textintval).digits) - { - pc->year = (yyvsp[(1) - (5)].textintval); - pc->month = (yyvsp[(3) - (5)].textintval).value; - pc->day = (yyvsp[(5) - (5)].textintval).value; - } - else - { - pc->month = (yyvsp[(1) - (5)].textintval).value; - pc->day = (yyvsp[(3) - (5)].textintval).value; - pc->year = (yyvsp[(5) - (5)].textintval); - } - } - break; - - case 32: -#line 412 "getdate.y" - { - /* ISO 8601 format. YYYY-MM-DD. */ - pc->year = (yyvsp[(1) - (3)].textintval); - pc->month = -(yyvsp[(2) - (3)].textintval).value; - pc->day = -(yyvsp[(3) - (3)].textintval).value; - } - break; - - case 33: -#line 419 "getdate.y" - { - /* e.g. 17-JUN-1992. */ - pc->day = (yyvsp[(1) - (3)].textintval).value; - pc->month = (yyvsp[(2) - (3)].intval); - pc->year.value = -(yyvsp[(3) - (3)].textintval).value; - pc->year.digits = (yyvsp[(3) - (3)].textintval).digits; - } - break; - - case 34: -#line 427 "getdate.y" - { - /* e.g. JUN-17-1992. */ - pc->month = (yyvsp[(1) - (3)].intval); - pc->day = -(yyvsp[(2) - (3)].textintval).value; - pc->year.value = -(yyvsp[(3) - (3)].textintval).value; - pc->year.digits = (yyvsp[(3) - (3)].textintval).digits; - } - break; - - case 35: -#line 435 "getdate.y" - { - pc->month = (yyvsp[(1) - (2)].intval); - pc->day = (yyvsp[(2) - (2)].textintval).value; - } - break; - - case 36: -#line 440 "getdate.y" - { - pc->month = (yyvsp[(1) - (4)].intval); - pc->day = (yyvsp[(2) - (4)].textintval).value; - pc->year = (yyvsp[(4) - (4)].textintval); - } - break; - - case 37: -#line 446 "getdate.y" - { - pc->day = (yyvsp[(1) - (2)].textintval).value; - pc->month = (yyvsp[(2) - (2)].intval); - } - break; - - case 38: -#line 451 "getdate.y" - { - pc->day = (yyvsp[(1) - (3)].textintval).value; - pc->month = (yyvsp[(2) - (3)].intval); - pc->year = (yyvsp[(3) - (3)].textintval); - } - break; - - case 39: -#line 460 "getdate.y" - { - pc->rel.ns -= (yyvsp[(1) - (2)].rel).ns; - pc->rel.seconds -= (yyvsp[(1) - (2)].rel).seconds; - pc->rel.minutes -= (yyvsp[(1) - (2)].rel).minutes; - pc->rel.hour -= (yyvsp[(1) - (2)].rel).hour; - pc->rel.day -= (yyvsp[(1) - (2)].rel).day; - pc->rel.month -= (yyvsp[(1) - (2)].rel).month; - pc->rel.year -= (yyvsp[(1) - (2)].rel).year; - } - break; - - case 40: -#line 470 "getdate.y" - { - pc->rel.ns += (yyvsp[(1) - (1)].rel).ns; - pc->rel.seconds += (yyvsp[(1) - (1)].rel).seconds; - pc->rel.minutes += (yyvsp[(1) - (1)].rel).minutes; - pc->rel.hour += (yyvsp[(1) - (1)].rel).hour; - pc->rel.day += (yyvsp[(1) - (1)].rel).day; - pc->rel.month += (yyvsp[(1) - (1)].rel).month; - pc->rel.year += (yyvsp[(1) - (1)].rel).year; - } - break; - - case 41: -#line 483 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].intval); } - break; - - case 42: -#line 485 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 43: -#line 487 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = 1; } - break; - - case 44: -#line 489 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].intval); } - break; - - case 45: -#line 491 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 46: -#line 493 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = 1; } - break; - - case 47: -#line 495 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); } - break; - - case 48: -#line 497 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); } - break; - - case 49: -#line 499 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (1)].intval); } - break; - - case 50: -#line 501 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].intval); } - break; - - case 51: -#line 503 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 52: -#line 505 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = 1; } - break; - - case 53: -#line 507 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].intval); } - break; - - case 54: -#line 509 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 55: -#line 511 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = 1; } - break; - - case 56: -#line 513 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].intval); } - break; - - case 57: -#line 515 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 58: -#line 517 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; } - break; - - case 59: -#line 519 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; } - break; - - case 60: -#line 521 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = 1; } - break; - - case 62: -#line 527 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 63: -#line 529 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 64: -#line 531 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); } - break; - - case 65: -#line 533 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 66: -#line 535 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 67: -#line 537 "getdate.y" - { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].textintval).value; } - break; - - case 71: -#line 545 "getdate.y" - { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; } - break; - - case 73: -#line 551 "getdate.y" - { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; } - break; - - case 74: -#line 556 "getdate.y" - { - if (pc->dates_seen && ! pc->year.digits - && ! pc->rels_seen && (pc->times_seen || 2 < (yyvsp[(1) - (1)].textintval).digits)) - pc->year = (yyvsp[(1) - (1)].textintval); - else - { - if (4 < (yyvsp[(1) - (1)].textintval).digits) - { - pc->dates_seen++; - pc->day = (yyvsp[(1) - (1)].textintval).value % 100; - pc->month = ((yyvsp[(1) - (1)].textintval).value / 100) % 100; - pc->year.value = (yyvsp[(1) - (1)].textintval).value / 10000; - pc->year.digits = (yyvsp[(1) - (1)].textintval).digits - 4; - } - else - { - pc->times_seen++; - if ((yyvsp[(1) - (1)].textintval).digits <= 2) - { - pc->hour = (yyvsp[(1) - (1)].textintval).value; - pc->minutes = 0; - } - else - { - pc->hour = (yyvsp[(1) - (1)].textintval).value / 100; - pc->minutes = (yyvsp[(1) - (1)].textintval).value % 100; - } - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = MER24; - } - } - } - break; - - case 75: -#line 593 "getdate.y" - { (yyval.intval) = -1; } - break; - - case 76: -#line 595 "getdate.y" - { (yyval.intval) = (yyvsp[(2) - (2)].textintval).value; } - break; - - case 77: -#line 600 "getdate.y" - { (yyval.intval) = MER24; } - break; - - case 78: -#line 602 "getdate.y" - { (yyval.intval) = (yyvsp[(1) - (1)].intval); } - break; - - -/* Line 1267 of yacc.c. */ -#line 2159 "getdate.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (pc, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (pc, yymsg); - } - else - { - yyerror (pc, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, pc); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp, pc); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (pc, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, pc); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, pc); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -#line 605 "getdate.y" - - -static table const meridian_table[] = -{ - { "AM", tMERIDIAN, MERam }, - { "A.M.", tMERIDIAN, MERam }, - { "PM", tMERIDIAN, MERpm }, - { "P.M.", tMERIDIAN, MERpm }, - { NULL, 0, 0 } -}; - -static table const dst_table[] = -{ - { "DST", tDST, 0 } -}; - -static table const month_and_day_table[] = -{ - { "JANUARY", tMONTH, 1 }, - { "FEBRUARY", tMONTH, 2 }, - { "MARCH", tMONTH, 3 }, - { "APRIL", tMONTH, 4 }, - { "MAY", tMONTH, 5 }, - { "JUNE", tMONTH, 6 }, - { "JULY", tMONTH, 7 }, - { "AUGUST", tMONTH, 8 }, - { "SEPTEMBER",tMONTH, 9 }, - { "SEPT", tMONTH, 9 }, - { "OCTOBER", tMONTH, 10 }, - { "NOVEMBER", tMONTH, 11 }, - { "DECEMBER", tMONTH, 12 }, - { "SUNDAY", tDAY, 0 }, - { "MONDAY", tDAY, 1 }, - { "TUESDAY", tDAY, 2 }, - { "TUES", tDAY, 2 }, - { "WEDNESDAY",tDAY, 3 }, - { "WEDNES", tDAY, 3 }, - { "THURSDAY", tDAY, 4 }, - { "THUR", tDAY, 4 }, - { "THURS", tDAY, 4 }, - { "FRIDAY", tDAY, 5 }, - { "SATURDAY", tDAY, 6 }, - { NULL, 0, 0 } -}; - -static table const time_units_table[] = -{ - { "YEAR", tYEAR_UNIT, 1 }, - { "MONTH", tMONTH_UNIT, 1 }, - { "FORTNIGHT",tDAY_UNIT, 14 }, - { "WEEK", tDAY_UNIT, 7 }, - { "DAY", tDAY_UNIT, 1 }, - { "HOUR", tHOUR_UNIT, 1 }, - { "MINUTE", tMINUTE_UNIT, 1 }, - { "MIN", tMINUTE_UNIT, 1 }, - { "SECOND", tSEC_UNIT, 1 }, - { "SEC", tSEC_UNIT, 1 }, - { NULL, 0, 0 } -}; - -/* Assorted relative-time words. */ -static table const relative_time_table[] = -{ - { "TOMORROW", tDAY_UNIT, 1 }, - { "YESTERDAY",tDAY_UNIT, -1 }, - { "TODAY", tDAY_UNIT, 0 }, - { "NOW", tDAY_UNIT, 0 }, - { "LAST", tORDINAL, -1 }, - { "THIS", tORDINAL, 0 }, - { "NEXT", tORDINAL, 1 }, - { "FIRST", tORDINAL, 1 }, -/*{ "SECOND", tORDINAL, 2 }, */ - { "THIRD", tORDINAL, 3 }, - { "FOURTH", tORDINAL, 4 }, - { "FIFTH", tORDINAL, 5 }, - { "SIXTH", tORDINAL, 6 }, - { "SEVENTH", tORDINAL, 7 }, - { "EIGHTH", tORDINAL, 8 }, - { "NINTH", tORDINAL, 9 }, - { "TENTH", tORDINAL, 10 }, - { "ELEVENTH", tORDINAL, 11 }, - { "TWELFTH", tORDINAL, 12 }, - { "AGO", tAGO, 1 }, - { NULL, 0, 0 } -}; - -/* The universal time zone table. These labels can be used even for - time stamps that would not otherwise be valid, e.g., GMT time - stamps in London during summer. */ -static table const universal_time_zone_table[] = -{ - { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */ - { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ - { "UTC", tZONE, HOUR ( 0) }, - { NULL, 0, 0 } -}; - -/* The time zone table. This table is necessarily incomplete, as time - zone abbreviations are ambiguous; e.g. Australians interpret "EST" - as Eastern time in Australia, not as US Eastern Standard Time. - You cannot rely on getdate to handle arbitrary time zone - abbreviations; use numeric abbreviations like `-0500' instead. */ -static table const time_zone_table[] = -{ - { "WET", tZONE, HOUR ( 0) }, /* Western European */ - { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */ - { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */ - { "ART", tZONE, -HOUR ( 3) }, /* Argentina */ - { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */ - { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */ - { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */ - { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */ - { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */ - { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */ - { "CLT", tZONE, -HOUR ( 4) }, /* Chile */ - { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */ - { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */ - { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */ - { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */ - { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */ - { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */ - { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */ - { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */ - { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */ - { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */ - { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */ - { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */ - { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */ - { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */ - { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */ - { "WAT", tZONE, HOUR ( 1) }, /* West Africa */ - { "CET", tZONE, HOUR ( 1) }, /* Central European */ - { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */ - { "MET", tZONE, HOUR ( 1) }, /* Middle European */ - { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */ - { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ - { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ - { "EET", tZONE, HOUR ( 2) }, /* Eastern European */ - { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */ - { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */ - { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */ - { "EAT", tZONE, HOUR ( 3) }, /* East Africa */ - { "MSK", tZONE, HOUR ( 3) }, /* Moscow */ - { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */ - { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */ - { "SGT", tZONE, HOUR ( 8) }, /* Singapore */ - { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */ - { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */ - { "GST", tZONE, HOUR (10) }, /* Guam Standard */ - { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */ - { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */ - { NULL, 0, 0 } -}; - -/* Military time zone table. */ -static table const military_table[] = -{ - { "A", tZONE, -HOUR ( 1) }, - { "B", tZONE, -HOUR ( 2) }, - { "C", tZONE, -HOUR ( 3) }, - { "D", tZONE, -HOUR ( 4) }, - { "E", tZONE, -HOUR ( 5) }, - { "F", tZONE, -HOUR ( 6) }, - { "G", tZONE, -HOUR ( 7) }, - { "H", tZONE, -HOUR ( 8) }, - { "I", tZONE, -HOUR ( 9) }, - { "K", tZONE, -HOUR (10) }, - { "L", tZONE, -HOUR (11) }, - { "M", tZONE, -HOUR (12) }, - { "N", tZONE, HOUR ( 1) }, - { "O", tZONE, HOUR ( 2) }, - { "P", tZONE, HOUR ( 3) }, - { "Q", tZONE, HOUR ( 4) }, - { "R", tZONE, HOUR ( 5) }, - { "S", tZONE, HOUR ( 6) }, - { "T", tZONE, HOUR ( 7) }, - { "U", tZONE, HOUR ( 8) }, - { "V", tZONE, HOUR ( 9) }, - { "W", tZONE, HOUR (10) }, - { "X", tZONE, HOUR (11) }, - { "Y", tZONE, HOUR (12) }, - { "Z", tZONE, HOUR ( 0) }, - { NULL, 0, 0 } -}; - - - -/* Convert a time zone expressed as HH:MM into an integer count of - minutes. If MM is negative, then S is of the form HHMM and needs - to be picked apart; otherwise, S is of the form HH. */ - -static long int -time_zone_hhmm (textint s, long int mm) -{ - if (mm < 0) - return (s.value / 100) * 60 + s.value % 100; - else - return s.value * 60 + (s.negative ? -mm : mm); -} - -static int -to_hour (long int hours, int meridian) -{ - switch (meridian) - { - default: /* Pacify GCC. */ - case MER24: - return 0 <= hours && hours < 24 ? hours : -1; - case MERam: - return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1; - case MERpm: - return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1; - } -} - -static long int -to_year (textint textyear) -{ - long int year = textyear.value; - - if (year < 0) - year = -year; - - /* XPG4 suggests that years 00-68 map to 2000-2068, and - years 69-99 map to 1969-1999. */ - else if (textyear.digits == 2) - year += year < 69 ? 2000 : 1900; - - return year; -} - -static table const * -lookup_zone (parser_control const *pc, char const *name) -{ - table const *tp; - - for (tp = universal_time_zone_table; tp->name; tp++) - if (strcmp (name, tp->name) == 0) - return tp; - - /* Try local zone abbreviations before those in time_zone_table, as - the local ones are more likely to be right. */ - for (tp = pc->local_time_zone_table; tp->name; tp++) - if (strcmp (name, tp->name) == 0) - return tp; - - for (tp = time_zone_table; tp->name; tp++) - if (strcmp (name, tp->name) == 0) - return tp; - - return NULL; -} - -#if ! HAVE_TM_GMTOFF -/* Yield the difference between *A and *B, - measured in seconds, ignoring leap seconds. - The body of this function is taken directly from the GNU C Library; - see src/strftime.c. */ -static long int -tm_diff (struct tm const *a, struct tm const *b) -{ - /* Compute intervening leap days correctly even if year is negative. - Take care to avoid int overflow in leap day calculations. */ - int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3); - int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3); - int a100 = a4 / 25 - (a4 % 25 < 0); - int b100 = b4 / 25 - (b4 % 25 < 0); - int a400 = SHR (a100, 2); - int b400 = SHR (b100, 2); - int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); - long int ayear = a->tm_year; - long int years = ayear - b->tm_year; - long int days = (365 * years + intervening_leap_days - + (a->tm_yday - b->tm_yday)); - return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) - + (a->tm_min - b->tm_min)) - + (a->tm_sec - b->tm_sec)); -} -#endif /* ! HAVE_TM_GMTOFF */ - -static table const * -lookup_word (parser_control const *pc, char *word) -{ - char *p; - char *q; - size_t wordlen; - table const *tp; - bool period_found; - bool abbrev; - - /* Make it uppercase. */ - for (p = word; *p; p++) - { - unsigned char ch = *p; - *p = toupper (ch); - } - - for (tp = meridian_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - - /* See if we have an abbreviation for a month. */ - wordlen = strlen (word); - abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.'); - - for (tp = month_and_day_table; tp->name; tp++) - if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0) - return tp; - - if ((tp = lookup_zone (pc, word))) - return tp; - - if (strcmp (word, dst_table[0].name) == 0) - return dst_table; - - for (tp = time_units_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - - /* Strip off any plural and try the units table again. */ - if (word[wordlen - 1] == 'S') - { - word[wordlen - 1] = '\0'; - for (tp = time_units_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */ - } - - for (tp = relative_time_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - - /* Military time zones. */ - if (wordlen == 1) - for (tp = military_table; tp->name; tp++) - if (word[0] == tp->name[0]) - return tp; - - /* Drop out any periods and try the time zone table again. */ - for (period_found = false, p = q = word; (*p = *q); q++) - if (*q == '.') - period_found = true; - else - p++; - if (period_found && (tp = lookup_zone (pc, word))) - return tp; - - return NULL; -} - -static int -yylex (YYSTYPE *lvalp, parser_control *pc) -{ - unsigned char c; - size_t count; - - for (;;) - { - while (c = *pc->input, isspace (c)) - pc->input++; - - if (ISDIGIT (c) || c == '-' || c == '+') - { - char const *p; - int sign; - unsigned long int value; - if (c == '-' || c == '+') - { - sign = c == '-' ? -1 : 1; - while (c = *++pc->input, isspace (c)) - continue; - if (! ISDIGIT (c)) - /* skip the '-' sign */ - continue; - } - else - sign = 0; - p = pc->input; - for (value = 0; ; value *= 10) - { - unsigned long int value1 = value + (c - '0'); - if (value1 < value) - return '?'; - value = value1; - c = *++p; - if (! ISDIGIT (c)) - break; - if (ULONG_MAX / 10 < value) - return '?'; - } - if ((c == '.' || c == ',') && ISDIGIT (p[1])) - { - time_t s; - int ns; - int digits; - unsigned long int value1; - - /* Check for overflow when converting value to time_t. */ - if (sign < 0) - { - s = - value; - if (0 < s) - return '?'; - value1 = -s; - } - else - { - s = value; - if (s < 0) - return '?'; - value1 = s; - } - if (value != value1) - return '?'; - - /* Accumulate fraction, to ns precision. */ - p++; - ns = *p++ - '0'; - for (digits = 2; digits <= LOG10_BILLION; digits++) - { - ns *= 10; - if (ISDIGIT (*p)) - ns += *p++ - '0'; - } - - /* Skip excess digits, truncating toward -Infinity. */ - if (sign < 0) - for (; ISDIGIT (*p); p++) - if (*p != '0') - { - ns++; - break; - } - while (ISDIGIT (*p)) - p++; - - /* Adjust to the timespec convention, which is that - tv_nsec is always a positive offset even if tv_sec is - negative. */ - if (sign < 0 && ns) - { - s--; - if (! (s < 0)) - return '?'; - ns = BILLION - ns; - } - - lvalp->timespec.tv_sec = s; - lvalp->timespec.tv_nsec = ns; - pc->input = p; - return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER; - } - else - { - lvalp->textintval.negative = sign < 0; - if (sign < 0) - { - lvalp->textintval.value = - value; - if (0 < lvalp->textintval.value) - return '?'; - } - else - { - lvalp->textintval.value = value; - if (lvalp->textintval.value < 0) - return '?'; - } - lvalp->textintval.digits = p - pc->input; - pc->input = p; - return sign ? tSNUMBER : tUNUMBER; - } - } - - if (isalpha (c)) - { - char buff[20]; - char *p = buff; - table const *tp; - - do - { - if (p < buff + sizeof buff - 1) - *p++ = c; - c = *++pc->input; - } - while (isalpha (c) || c == '.'); - - *p = '\0'; - tp = lookup_word (pc, buff); - if (! tp) - return '?'; - lvalp->intval = tp->value; - return tp->type; - } - - if (c != '(') - return *pc->input++; - count = 0; - do - { - c = *pc->input++; - if (c == '\0') - return c; - if (c == '(') - count++; - else if (c == ')') - count--; - } - while (count != 0); - } -} - -/* Do nothing if the parser reports an error. */ -static int -yyerror (parser_control const *pc ATTRIBUTE_UNUSED, - char const *s ATTRIBUTE_UNUSED) -{ - return 0; -} - -/* If *TM0 is the old and *TM1 is the new value of a struct tm after - passing it to mktime, return true if it's OK that mktime returned T. - It's not OK if *TM0 has out-of-range members. */ - -static bool -mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t) -{ - if (t == (time_t) -1) - { - /* Guard against falsely reporting an error when parsing a time - stamp that happens to equal (time_t) -1, on a host that - supports such a time stamp. */ - tm1 = localtime (&t); - if (!tm1) - return false; - } - - return ! ((tm0->tm_sec ^ tm1->tm_sec) - | (tm0->tm_min ^ tm1->tm_min) - | (tm0->tm_hour ^ tm1->tm_hour) - | (tm0->tm_mday ^ tm1->tm_mday) - | (tm0->tm_mon ^ tm1->tm_mon) - | (tm0->tm_year ^ tm1->tm_year)); -} - -/* A reasonable upper bound for the size of ordinary TZ strings. - Use heap allocation if TZ's length exceeds this. */ -enum { TZBUFSIZE = 100 }; - -/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated - otherwise. */ -static char * -get_tz (char tzbuf[TZBUFSIZE]) -{ - char *tz = getenv ("TZ"); - if (tz) - { - size_t tzsize = strlen (tz) + 1; - tz = (tzsize <= TZBUFSIZE - ? memcpy (tzbuf, tz, tzsize) - : xmemdup (tz, tzsize)); - } - return tz; -} - -/* Parse a date/time string, storing the resulting time value into *RESULT. - The string itself is pointed to by P. Return true if successful. - P can be an incomplete or relative time specification; if so, use - *NOW as the basis for the returned time. */ -bool -get_date (struct timespec *result, char const *p, struct timespec const *now) -{ - time_t Start; - long int Start_ns; - struct tm const *tmp; - struct tm tm; - struct tm tm0; - parser_control pc; - struct timespec gettime_buffer; - unsigned char c; - bool tz_was_altered = false; - char *tz0 = NULL; - char tz0buf[TZBUFSIZE]; - bool ok = true; - - if (! now) - { - gettime (&gettime_buffer); - now = &gettime_buffer; - } - - Start = now->tv_sec; - Start_ns = now->tv_nsec; - - tmp = localtime (&now->tv_sec); - if (! tmp) - return false; - - while (c = *p, isspace (c)) - p++; - - if (strncmp (p, "TZ=\"", 4) == 0) - { - char const *tzbase = p + 4; - size_t tzsize = 1; - char const *s; - - for (s = tzbase; *s; s++, tzsize++) - if (*s == '\\') - { - s++; - if (! (*s == '\\' || *s == '"')) - break; - } - else if (*s == '"') - { - char *z; - char *tz1; - char tz1buf[TZBUFSIZE]; - bool large_tz = TZBUFSIZE < tzsize; - bool setenv_ok; - tz0 = get_tz (tz0buf); - z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf; - for (s = tzbase; *s != '"'; s++) - *z++ = *(s += *s == '\\'); - *z = '\0'; - setenv_ok = setenv ("TZ", tz1, 1) == 0; - if (large_tz) - free (tz1); - if (!setenv_ok) - goto fail; - tz_was_altered = true; - p = s + 1; - } - } - - pc.input = p; - pc.year.value = tmp->tm_year; - pc.year.value += TM_YEAR_BASE; - pc.year.digits = 0; - pc.month = tmp->tm_mon + 1; - pc.day = tmp->tm_mday; - pc.hour = tmp->tm_hour; - pc.minutes = tmp->tm_min; - pc.seconds.tv_sec = tmp->tm_sec; - pc.seconds.tv_nsec = Start_ns; - tm.tm_isdst = tmp->tm_isdst; - - pc.meridian = MER24; - pc.rel = RELATIVE_TIME_0; - pc.timespec_seen = false; - pc.rels_seen = false; - pc.dates_seen = 0; - pc.days_seen = 0; - pc.times_seen = 0; - pc.local_zones_seen = 0; - pc.dsts_seen = 0; - pc.zones_seen = 0; - -#if HAVE_STRUCT_TM_TM_ZONE - pc.local_time_zone_table[0].name = tmp->tm_zone; - pc.local_time_zone_table[0].type = tLOCAL_ZONE; - pc.local_time_zone_table[0].value = tmp->tm_isdst; - pc.local_time_zone_table[1].name = NULL; - - /* Probe the names used in the next three calendar quarters, looking - for a tm_isdst different from the one we already have. */ - { - int quarter; - for (quarter = 1; quarter <= 3; quarter++) - { - time_t probe = Start + quarter * (90 * 24 * 60 * 60); - struct tm const *probe_tm = localtime (&probe); - if (probe_tm && probe_tm->tm_zone - && probe_tm->tm_isdst != pc.local_time_zone_table[0].value) - { - { - pc.local_time_zone_table[1].name = probe_tm->tm_zone; - pc.local_time_zone_table[1].type = tLOCAL_ZONE; - pc.local_time_zone_table[1].value = probe_tm->tm_isdst; - pc.local_time_zone_table[2].name = NULL; - } - break; - } - } - } -#else -#if HAVE_TZNAME - { -# ifndef tzname - extern char *tzname[]; -# endif - int i; - for (i = 0; i < 2; i++) - { - pc.local_time_zone_table[i].name = tzname[i]; - pc.local_time_zone_table[i].type = tLOCAL_ZONE; - pc.local_time_zone_table[i].value = i; - } - pc.local_time_zone_table[i].name = NULL; - } -#else - pc.local_time_zone_table[0].name = NULL; -#endif -#endif - - if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name - && ! strcmp (pc.local_time_zone_table[0].name, - pc.local_time_zone_table[1].name)) - { - /* This locale uses the same abbrevation for standard and - daylight times. So if we see that abbreviation, we don't - know whether it's daylight time. */ - pc.local_time_zone_table[0].value = -1; - pc.local_time_zone_table[1].name = NULL; - } - - if (yyparse (&pc) != 0) - goto fail; - - if (pc.timespec_seen) - *result = pc.seconds; - else - { - if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen - | (pc.local_zones_seen + pc.zones_seen))) - goto fail; - - tm.tm_year = to_year (pc.year) - TM_YEAR_BASE; - tm.tm_mon = pc.month - 1; - tm.tm_mday = pc.day; - if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen)) - { - tm.tm_hour = to_hour (pc.hour, pc.meridian); - if (tm.tm_hour < 0) - goto fail; - tm.tm_min = pc.minutes; - tm.tm_sec = pc.seconds.tv_sec; - } - else - { - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - pc.seconds.tv_nsec = 0; - } - - /* Let mktime deduce tm_isdst if we have an absolute time stamp. */ - if (pc.dates_seen | pc.days_seen | pc.times_seen) - tm.tm_isdst = -1; - - /* But if the input explicitly specifies local time with or without - DST, give mktime that information. */ - if (pc.local_zones_seen) - tm.tm_isdst = pc.local_isdst; - - tm0 = tm; - - Start = mktime (&tm); - - if (! mktime_ok (&tm0, &tm, Start)) - { - if (! pc.zones_seen) - goto fail; - else - { - /* Guard against falsely reporting errors near the time_t - boundaries when parsing times in other time zones. For - example, suppose the input string "1969-12-31 23:00:00 -0100", - the current time zone is 8 hours ahead of UTC, and the min - time_t value is 1970-01-01 00:00:00 UTC. Then the min - localtime value is 1970-01-01 08:00:00, and mktime will - therefore fail on 1969-12-31 23:00:00. To work around the - problem, set the time zone to 1 hour behind UTC temporarily - by setting TZ="XXX1:00" and try mktime again. */ - - long int time_zone = pc.time_zone; - long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone; - long int abs_time_zone_hour = abs_time_zone / 60; - int abs_time_zone_min = abs_time_zone % 60; - char tz1buf[sizeof "XXX+0:00" - + sizeof pc.time_zone * CHAR_BIT / 3]; - if (!tz_was_altered) - tz0 = get_tz (tz0buf); - sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0), - abs_time_zone_hour, abs_time_zone_min); - if (setenv ("TZ", tz1buf, 1) != 0) - goto fail; - tz_was_altered = true; - tm = tm0; - Start = mktime (&tm); - if (! mktime_ok (&tm0, &tm, Start)) - goto fail; - } - } - - if (pc.days_seen && ! pc.dates_seen) - { - tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7 - + 7 * (pc.day_ordinal - (0 < pc.day_ordinal))); - tm.tm_isdst = -1; - Start = mktime (&tm); - if (Start == (time_t) -1) - goto fail; - } - - if (pc.zones_seen) - { - long int delta = pc.time_zone * 60; - time_t t1; -#ifdef HAVE_TM_GMTOFF - delta -= tm.tm_gmtoff; -#else - time_t t = Start; - struct tm const *gmt = gmtime (&t); - if (! gmt) - goto fail; - delta -= tm_diff (&tm, gmt); -#endif - t1 = Start - delta; - if ((Start < t1) != (delta < 0)) - goto fail; /* time_t overflow */ - Start = t1; - } - - /* Add relative date. */ - if (pc.rel.year | pc.rel.month | pc.rel.day) - { - int year = tm.tm_year + pc.rel.year; - int month = tm.tm_mon + pc.rel.month; - int day = tm.tm_mday + pc.rel.day; - if (((year < tm.tm_year) ^ (pc.rel.year < 0)) - | ((month < tm.tm_mon) ^ (pc.rel.month < 0)) - | ((day < tm.tm_mday) ^ (pc.rel.day < 0))) - goto fail; - tm.tm_year = year; - tm.tm_mon = month; - tm.tm_mday = day; - tm.tm_hour = tm0.tm_hour; - tm.tm_min = tm0.tm_min; - tm.tm_sec = tm0.tm_sec; - tm.tm_isdst = tm0.tm_isdst; - Start = mktime (&tm); - if (Start == (time_t) -1) - goto fail; - } - - /* Add relative hours, minutes, and seconds. On hosts that support - leap seconds, ignore the possibility of leap seconds; e.g., - "+ 10 minutes" adds 600 seconds, even if one of them is a - leap second. Typically this is not what the user wants, but it's - too hard to do it the other way, because the time zone indicator - must be applied before relative times, and if mktime is applied - again the time zone will be lost. */ - { - long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns; - long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION; - time_t t0 = Start; - long int d1 = 60 * 60 * pc.rel.hour; - time_t t1 = t0 + d1; - long int d2 = 60 * pc.rel.minutes; - time_t t2 = t1 + d2; - long int d3 = pc.rel.seconds; - time_t t3 = t2 + d3; - long int d4 = (sum_ns - normalized_ns) / BILLION; - time_t t4 = t3 + d4; - - if ((d1 / (60 * 60) ^ pc.rel.hour) - | (d2 / 60 ^ pc.rel.minutes) - | ((t1 < t0) ^ (d1 < 0)) - | ((t2 < t1) ^ (d2 < 0)) - | ((t3 < t2) ^ (d3 < 0)) - | ((t4 < t3) ^ (d4 < 0))) - goto fail; - - result->tv_sec = t4; - result->tv_nsec = normalized_ns; - } - } - - goto done; - - fail: - ok = false; - done: - if (tz_was_altered) - ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0; - if (tz0 != tz0buf) - free (tz0); - return ok; -} - -#if TEST - -int -main (int ac, char **av) -{ - char buff[BUFSIZ]; - - printf ("Enter date, or blank line to exit.\n\t> "); - fflush (stdout); - - buff[BUFSIZ - 1] = '\0'; - while (fgets (buff, BUFSIZ - 1, stdin) && buff[0]) - { - struct timespec d; - struct tm const *tm; - if (! get_date (&d, buff, NULL)) - printf ("Bad format - couldn't convert.\n"); - else if (! (tm = localtime (&d.tv_sec))) - { - long int sec = d.tv_sec; - printf ("localtime (%ld) failed\n", sec); - } - else - { - int ns = d.tv_nsec; - printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n", - tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, ns); - } - printf ("\t> "); - fflush (stdout); - } - return 0; -} -#endif /* TEST */ - diff --git a/src/bin/tar/lib/getdate.h b/src/bin/tar/lib/getdate.h deleted file mode 100644 index 142231e286..0000000000 --- a/src/bin/tar/lib/getdate.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Parse a string into an internal time stamp. - - Copyright (C) 1995, 1997, 1998, 2003, 2004, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include - -bool get_date (struct timespec *, char const *, struct timespec const *); diff --git a/src/bin/tar/lib/getdate.y b/src/bin/tar/lib/getdate.y deleted file mode 100644 index e34f4a942e..0000000000 --- a/src/bin/tar/lib/getdate.y +++ /dev/null @@ -1,1530 +0,0 @@ -%{ -/* Parse a string into an internal time stamp. - - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Originally written by Steven M. Bellovin while - at the University of North Carolina at Chapel Hill. Later tweaked by - a couple of people on Usenet. Completely overhauled by Rich $alz - and Jim Berets in August, 1990. - - Modified by Paul Eggert in August 1999 to do - the right thing about local DST. Also modified by Paul Eggert - in February 2004 to support - nanosecond-resolution time stamps, and in October 2004 to support - TZ strings in dates. */ - -/* FIXME: Check for arithmetic overflow in all cases, not just - some of them. */ - -#include - -#include "getdate.h" - -#include "intprops.h" -#include "timespec.h" -#include "verify.h" - -/* There's no need to extend the stack, so there's no need to involve - alloca. */ -#define YYSTACK_USE_ALLOCA 0 - -/* Tell Bison how much stack space is needed. 20 should be plenty for - this grammar, which is not right recursive. Beware setting it too - high, since that might cause problems on machines whose - implementations have lame stack-overflow checking. */ -#define YYMAXDEPTH 20 -#define YYINITDEPTH YYMAXDEPTH - -/* Since the code of getdate.y is not included in the Emacs executable - itself, there is no need to #define static in this file. Even if - the code were included in the Emacs executable, it probably - wouldn't do any harm to #undef it here; this will only cause - problems if we try to write to a static variable, which I don't - think this code needs to do. */ -#ifdef emacs -# undef static -#endif - -#include -#include -#include -#include -#include - -#include "setenv.h" -#include "xalloc.h" - - -/* ISDIGIT differs from isdigit, as follows: - - Its arg may be any int or unsigned int; it need not be an unsigned char - or EOF. - - It's typically faster. - POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to - isdigit unless it's important to use the locale's definition - of `digit' even when the host does not conform to POSIX. */ -#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9) - -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -#endif - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - -/* Shift A right by B bits portably, by dividing A by 2**B and - truncating towards minus infinity. A and B should be free of side - effects, and B should be in the range 0 <= B <= INT_BITS - 2, where - INT_BITS is the number of useful bits in an int. GNU code can - assume that INT_BITS is at least 32. - - ISO C99 says that A >> B is implementation-defined if A < 0. Some - implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift - right in the usual way when A < 0, so SHR falls back on division if - ordinary A >> B doesn't seem to be the usual signed shift. */ -#define SHR(a, b) \ - (-1 >> 1 == -1 \ - ? (a) >> (b) \ - : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) - -#define EPOCH_YEAR 1970 -#define TM_YEAR_BASE 1900 - -#define HOUR(x) ((x) * 60) - -/* Lots of this code assumes time_t and time_t-like values fit into - long int. It also assumes that signed integer overflow silently - wraps around, but there's no portable way to check for that at - compile-time. */ -verify (TYPE_IS_INTEGER (time_t)); -verify (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= LONG_MAX); - -/* An integer value, and the number of digits in its textual - representation. */ -typedef struct -{ - bool negative; - long int value; - size_t digits; -} textint; - -/* An entry in the lexical lookup table. */ -typedef struct -{ - char const *name; - int type; - int value; -} table; - -/* Meridian: am, pm, or 24-hour style. */ -enum { MERam, MERpm, MER24 }; - -enum { BILLION = 1000000000, LOG10_BILLION = 9 }; - -/* Relative times. */ -typedef struct -{ - /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */ - long int year; - long int month; - long int day; - long int hour; - long int minutes; - long int seconds; - long int ns; -} relative_time; - -#if HAVE_COMPOUND_LITERALS -# define RELATIVE_TIME_0 ((relative_time) { 0, 0, 0, 0, 0, 0, 0 }) -#else -static relative_time const RELATIVE_TIME_0; -#endif - -/* Information passed to and from the parser. */ -typedef struct -{ - /* The input string remaining to be parsed. */ - const char *input; - - /* N, if this is the Nth Tuesday. */ - long int day_ordinal; - - /* Day of week; Sunday is 0. */ - int day_number; - - /* tm_isdst flag for the local zone. */ - int local_isdst; - - /* Time zone, in minutes east of UTC. */ - long int time_zone; - - /* Style used for time. */ - int meridian; - - /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds. */ - textint year; - long int month; - long int day; - long int hour; - long int minutes; - struct timespec seconds; /* includes nanoseconds */ - - /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */ - relative_time rel; - - /* Presence or counts of nonterminals of various flavors parsed so far. */ - bool timespec_seen; - bool rels_seen; - size_t dates_seen; - size_t days_seen; - size_t local_zones_seen; - size_t dsts_seen; - size_t times_seen; - size_t zones_seen; - - /* Table of local time zone abbrevations, terminated by a null entry. */ - table local_time_zone_table[3]; -} parser_control; - -union YYSTYPE; -static int yylex (union YYSTYPE *, parser_control *); -static int yyerror (parser_control const *, char const *); -static long int time_zone_hhmm (textint, long int); - -%} - -/* We want a reentrant parser, even if the TZ manipulation and the calls to - localtime and gmtime are not reentrant. */ -%pure-parser -%parse-param { parser_control *pc } -%lex-param { parser_control *pc } - -/* This grammar has 20 shift/reduce conflicts. */ -%expect 20 - -%union -{ - long int intval; - textint textintval; - struct timespec timespec; - relative_time rel; -} - -%token tAGO tDST - -%token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT -%token tDAY_UNIT - -%token tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN -%token tMONTH tORDINAL tZONE - -%token tSNUMBER tUNUMBER -%token tSDECIMAL_NUMBER tUDECIMAL_NUMBER - -%type o_colon_minutes o_merid -%type seconds signed_seconds unsigned_seconds - -%type relunit relunit_snumber - -%% - -spec: - timespec - | items - ; - -timespec: - '@' seconds - { - pc->seconds = $2; - pc->timespec_seen = true; - } - ; - -items: - /* empty */ - | items item - ; - -item: - time - { pc->times_seen++; } - | local_zone - { pc->local_zones_seen++; } - | zone - { pc->zones_seen++; } - | date - { pc->dates_seen++; } - | day - { pc->days_seen++; } - | rel - { pc->rels_seen = true; } - | number - ; - -time: - tUNUMBER tMERIDIAN - { - pc->hour = $1.value; - pc->minutes = 0; - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = $2; - } - | tUNUMBER ':' tUNUMBER o_merid - { - pc->hour = $1.value; - pc->minutes = $3.value; - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = $4; - } - | tUNUMBER ':' tUNUMBER tSNUMBER o_colon_minutes - { - pc->hour = $1.value; - pc->minutes = $3.value; - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = MER24; - pc->zones_seen++; - pc->time_zone = time_zone_hhmm ($4, $5); - } - | tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_merid - { - pc->hour = $1.value; - pc->minutes = $3.value; - pc->seconds = $5; - pc->meridian = $6; - } - | tUNUMBER ':' tUNUMBER ':' unsigned_seconds tSNUMBER o_colon_minutes - { - pc->hour = $1.value; - pc->minutes = $3.value; - pc->seconds = $5; - pc->meridian = MER24; - pc->zones_seen++; - pc->time_zone = time_zone_hhmm ($6, $7); - } - ; - -local_zone: - tLOCAL_ZONE - { - pc->local_isdst = $1; - pc->dsts_seen += (0 < $1); - } - | tLOCAL_ZONE tDST - { - pc->local_isdst = 1; - pc->dsts_seen += (0 < $1) + 1; - } - ; - -zone: - tZONE - { pc->time_zone = $1; } - | tZONE relunit_snumber - { pc->time_zone = $1; - pc->rel.ns += $2.ns; - pc->rel.seconds += $2.seconds; - pc->rel.minutes += $2.minutes; - pc->rel.hour += $2.hour; - pc->rel.day += $2.day; - pc->rel.month += $2.month; - pc->rel.year += $2.year; - pc->rels_seen = true; } - | tZONE tSNUMBER o_colon_minutes - { pc->time_zone = $1 + time_zone_hhmm ($2, $3); } - | tDAYZONE - { pc->time_zone = $1 + 60; } - | tZONE tDST - { pc->time_zone = $1 + 60; } - ; - -day: - tDAY - { - pc->day_ordinal = 1; - pc->day_number = $1; - } - | tDAY ',' - { - pc->day_ordinal = 1; - pc->day_number = $1; - } - | tORDINAL tDAY - { - pc->day_ordinal = $1; - pc->day_number = $2; - } - | tUNUMBER tDAY - { - pc->day_ordinal = $1.value; - pc->day_number = $2; - } - ; - -date: - tUNUMBER '/' tUNUMBER - { - pc->month = $1.value; - pc->day = $3.value; - } - | tUNUMBER '/' tUNUMBER '/' tUNUMBER - { - /* Interpret as YYYY/MM/DD if the first value has 4 or more digits, - otherwise as MM/DD/YY. - The goal in recognizing YYYY/MM/DD is solely to support legacy - machine-generated dates like those in an RCS log listing. If - you want portability, use the ISO 8601 format. */ - if (4 <= $1.digits) - { - pc->year = $1; - pc->month = $3.value; - pc->day = $5.value; - } - else - { - pc->month = $1.value; - pc->day = $3.value; - pc->year = $5; - } - } - | tUNUMBER tSNUMBER tSNUMBER - { - /* ISO 8601 format. YYYY-MM-DD. */ - pc->year = $1; - pc->month = -$2.value; - pc->day = -$3.value; - } - | tUNUMBER tMONTH tSNUMBER - { - /* e.g. 17-JUN-1992. */ - pc->day = $1.value; - pc->month = $2; - pc->year.value = -$3.value; - pc->year.digits = $3.digits; - } - | tMONTH tSNUMBER tSNUMBER - { - /* e.g. JUN-17-1992. */ - pc->month = $1; - pc->day = -$2.value; - pc->year.value = -$3.value; - pc->year.digits = $3.digits; - } - | tMONTH tUNUMBER - { - pc->month = $1; - pc->day = $2.value; - } - | tMONTH tUNUMBER ',' tUNUMBER - { - pc->month = $1; - pc->day = $2.value; - pc->year = $4; - } - | tUNUMBER tMONTH - { - pc->day = $1.value; - pc->month = $2; - } - | tUNUMBER tMONTH tUNUMBER - { - pc->day = $1.value; - pc->month = $2; - pc->year = $3; - } - ; - -rel: - relunit tAGO - { - pc->rel.ns -= $1.ns; - pc->rel.seconds -= $1.seconds; - pc->rel.minutes -= $1.minutes; - pc->rel.hour -= $1.hour; - pc->rel.day -= $1.day; - pc->rel.month -= $1.month; - pc->rel.year -= $1.year; - } - | relunit - { - pc->rel.ns += $1.ns; - pc->rel.seconds += $1.seconds; - pc->rel.minutes += $1.minutes; - pc->rel.hour += $1.hour; - pc->rel.day += $1.day; - pc->rel.month += $1.month; - pc->rel.year += $1.year; - } - ; - -relunit: - tORDINAL tYEAR_UNIT - { $$ = RELATIVE_TIME_0; $$.year = $1; } - | tUNUMBER tYEAR_UNIT - { $$ = RELATIVE_TIME_0; $$.year = $1.value; } - | tYEAR_UNIT - { $$ = RELATIVE_TIME_0; $$.year = 1; } - | tORDINAL tMONTH_UNIT - { $$ = RELATIVE_TIME_0; $$.month = $1; } - | tUNUMBER tMONTH_UNIT - { $$ = RELATIVE_TIME_0; $$.month = $1.value; } - | tMONTH_UNIT - { $$ = RELATIVE_TIME_0; $$.month = 1; } - | tORDINAL tDAY_UNIT - { $$ = RELATIVE_TIME_0; $$.day = $1 * $2; } - | tUNUMBER tDAY_UNIT - { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; } - | tDAY_UNIT - { $$ = RELATIVE_TIME_0; $$.day = $1; } - | tORDINAL tHOUR_UNIT - { $$ = RELATIVE_TIME_0; $$.hour = $1; } - | tUNUMBER tHOUR_UNIT - { $$ = RELATIVE_TIME_0; $$.hour = $1.value; } - | tHOUR_UNIT - { $$ = RELATIVE_TIME_0; $$.hour = 1; } - | tORDINAL tMINUTE_UNIT - { $$ = RELATIVE_TIME_0; $$.minutes = $1; } - | tUNUMBER tMINUTE_UNIT - { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; } - | tMINUTE_UNIT - { $$ = RELATIVE_TIME_0; $$.minutes = 1; } - | tORDINAL tSEC_UNIT - { $$ = RELATIVE_TIME_0; $$.seconds = $1; } - | tUNUMBER tSEC_UNIT - { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; } - | tSDECIMAL_NUMBER tSEC_UNIT - { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; } - | tUDECIMAL_NUMBER tSEC_UNIT - { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; } - | tSEC_UNIT - { $$ = RELATIVE_TIME_0; $$.seconds = 1; } - | relunit_snumber - ; - -relunit_snumber: - tSNUMBER tYEAR_UNIT - { $$ = RELATIVE_TIME_0; $$.year = $1.value; } - | tSNUMBER tMONTH_UNIT - { $$ = RELATIVE_TIME_0; $$.month = $1.value; } - | tSNUMBER tDAY_UNIT - { $$ = RELATIVE_TIME_0; $$.day = $1.value * $2; } - | tSNUMBER tHOUR_UNIT - { $$ = RELATIVE_TIME_0; $$.hour = $1.value; } - | tSNUMBER tMINUTE_UNIT - { $$ = RELATIVE_TIME_0; $$.minutes = $1.value; } - | tSNUMBER tSEC_UNIT - { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; } - ; - -seconds: signed_seconds | unsigned_seconds; - -signed_seconds: - tSDECIMAL_NUMBER - | tSNUMBER - { $$.tv_sec = $1.value; $$.tv_nsec = 0; } - ; - -unsigned_seconds: - tUDECIMAL_NUMBER - | tUNUMBER - { $$.tv_sec = $1.value; $$.tv_nsec = 0; } - ; - -number: - tUNUMBER - { - if (pc->dates_seen && ! pc->year.digits - && ! pc->rels_seen && (pc->times_seen || 2 < $1.digits)) - pc->year = $1; - else - { - if (4 < $1.digits) - { - pc->dates_seen++; - pc->day = $1.value % 100; - pc->month = ($1.value / 100) % 100; - pc->year.value = $1.value / 10000; - pc->year.digits = $1.digits - 4; - } - else - { - pc->times_seen++; - if ($1.digits <= 2) - { - pc->hour = $1.value; - pc->minutes = 0; - } - else - { - pc->hour = $1.value / 100; - pc->minutes = $1.value % 100; - } - pc->seconds.tv_sec = 0; - pc->seconds.tv_nsec = 0; - pc->meridian = MER24; - } - } - } - ; - -o_colon_minutes: - /* empty */ - { $$ = -1; } - | ':' tUNUMBER - { $$ = $2.value; } - ; - -o_merid: - /* empty */ - { $$ = MER24; } - | tMERIDIAN - { $$ = $1; } - ; - -%% - -static table const meridian_table[] = -{ - { "AM", tMERIDIAN, MERam }, - { "A.M.", tMERIDIAN, MERam }, - { "PM", tMERIDIAN, MERpm }, - { "P.M.", tMERIDIAN, MERpm }, - { NULL, 0, 0 } -}; - -static table const dst_table[] = -{ - { "DST", tDST, 0 } -}; - -static table const month_and_day_table[] = -{ - { "JANUARY", tMONTH, 1 }, - { "FEBRUARY", tMONTH, 2 }, - { "MARCH", tMONTH, 3 }, - { "APRIL", tMONTH, 4 }, - { "MAY", tMONTH, 5 }, - { "JUNE", tMONTH, 6 }, - { "JULY", tMONTH, 7 }, - { "AUGUST", tMONTH, 8 }, - { "SEPTEMBER",tMONTH, 9 }, - { "SEPT", tMONTH, 9 }, - { "OCTOBER", tMONTH, 10 }, - { "NOVEMBER", tMONTH, 11 }, - { "DECEMBER", tMONTH, 12 }, - { "SUNDAY", tDAY, 0 }, - { "MONDAY", tDAY, 1 }, - { "TUESDAY", tDAY, 2 }, - { "TUES", tDAY, 2 }, - { "WEDNESDAY",tDAY, 3 }, - { "WEDNES", tDAY, 3 }, - { "THURSDAY", tDAY, 4 }, - { "THUR", tDAY, 4 }, - { "THURS", tDAY, 4 }, - { "FRIDAY", tDAY, 5 }, - { "SATURDAY", tDAY, 6 }, - { NULL, 0, 0 } -}; - -static table const time_units_table[] = -{ - { "YEAR", tYEAR_UNIT, 1 }, - { "MONTH", tMONTH_UNIT, 1 }, - { "FORTNIGHT",tDAY_UNIT, 14 }, - { "WEEK", tDAY_UNIT, 7 }, - { "DAY", tDAY_UNIT, 1 }, - { "HOUR", tHOUR_UNIT, 1 }, - { "MINUTE", tMINUTE_UNIT, 1 }, - { "MIN", tMINUTE_UNIT, 1 }, - { "SECOND", tSEC_UNIT, 1 }, - { "SEC", tSEC_UNIT, 1 }, - { NULL, 0, 0 } -}; - -/* Assorted relative-time words. */ -static table const relative_time_table[] = -{ - { "TOMORROW", tDAY_UNIT, 1 }, - { "YESTERDAY",tDAY_UNIT, -1 }, - { "TODAY", tDAY_UNIT, 0 }, - { "NOW", tDAY_UNIT, 0 }, - { "LAST", tORDINAL, -1 }, - { "THIS", tORDINAL, 0 }, - { "NEXT", tORDINAL, 1 }, - { "FIRST", tORDINAL, 1 }, -/*{ "SECOND", tORDINAL, 2 }, */ - { "THIRD", tORDINAL, 3 }, - { "FOURTH", tORDINAL, 4 }, - { "FIFTH", tORDINAL, 5 }, - { "SIXTH", tORDINAL, 6 }, - { "SEVENTH", tORDINAL, 7 }, - { "EIGHTH", tORDINAL, 8 }, - { "NINTH", tORDINAL, 9 }, - { "TENTH", tORDINAL, 10 }, - { "ELEVENTH", tORDINAL, 11 }, - { "TWELFTH", tORDINAL, 12 }, - { "AGO", tAGO, 1 }, - { NULL, 0, 0 } -}; - -/* The universal time zone table. These labels can be used even for - time stamps that would not otherwise be valid, e.g., GMT time - stamps in London during summer. */ -static table const universal_time_zone_table[] = -{ - { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */ - { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ - { "UTC", tZONE, HOUR ( 0) }, - { NULL, 0, 0 } -}; - -/* The time zone table. This table is necessarily incomplete, as time - zone abbreviations are ambiguous; e.g. Australians interpret "EST" - as Eastern time in Australia, not as US Eastern Standard Time. - You cannot rely on getdate to handle arbitrary time zone - abbreviations; use numeric abbreviations like `-0500' instead. */ -static table const time_zone_table[] = -{ - { "WET", tZONE, HOUR ( 0) }, /* Western European */ - { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */ - { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */ - { "ART", tZONE, -HOUR ( 3) }, /* Argentina */ - { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */ - { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */ - { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */ - { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */ - { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */ - { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */ - { "CLT", tZONE, -HOUR ( 4) }, /* Chile */ - { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */ - { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */ - { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */ - { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */ - { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */ - { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */ - { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */ - { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */ - { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */ - { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */ - { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */ - { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */ - { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */ - { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */ - { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */ - { "WAT", tZONE, HOUR ( 1) }, /* West Africa */ - { "CET", tZONE, HOUR ( 1) }, /* Central European */ - { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */ - { "MET", tZONE, HOUR ( 1) }, /* Middle European */ - { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */ - { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ - { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ - { "EET", tZONE, HOUR ( 2) }, /* Eastern European */ - { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */ - { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */ - { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */ - { "EAT", tZONE, HOUR ( 3) }, /* East Africa */ - { "MSK", tZONE, HOUR ( 3) }, /* Moscow */ - { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */ - { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */ - { "SGT", tZONE, HOUR ( 8) }, /* Singapore */ - { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */ - { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */ - { "GST", tZONE, HOUR (10) }, /* Guam Standard */ - { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */ - { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */ - { NULL, 0, 0 } -}; - -/* Military time zone table. */ -static table const military_table[] = -{ - { "A", tZONE, -HOUR ( 1) }, - { "B", tZONE, -HOUR ( 2) }, - { "C", tZONE, -HOUR ( 3) }, - { "D", tZONE, -HOUR ( 4) }, - { "E", tZONE, -HOUR ( 5) }, - { "F", tZONE, -HOUR ( 6) }, - { "G", tZONE, -HOUR ( 7) }, - { "H", tZONE, -HOUR ( 8) }, - { "I", tZONE, -HOUR ( 9) }, - { "K", tZONE, -HOUR (10) }, - { "L", tZONE, -HOUR (11) }, - { "M", tZONE, -HOUR (12) }, - { "N", tZONE, HOUR ( 1) }, - { "O", tZONE, HOUR ( 2) }, - { "P", tZONE, HOUR ( 3) }, - { "Q", tZONE, HOUR ( 4) }, - { "R", tZONE, HOUR ( 5) }, - { "S", tZONE, HOUR ( 6) }, - { "T", tZONE, HOUR ( 7) }, - { "U", tZONE, HOUR ( 8) }, - { "V", tZONE, HOUR ( 9) }, - { "W", tZONE, HOUR (10) }, - { "X", tZONE, HOUR (11) }, - { "Y", tZONE, HOUR (12) }, - { "Z", tZONE, HOUR ( 0) }, - { NULL, 0, 0 } -}; - - - -/* Convert a time zone expressed as HH:MM into an integer count of - minutes. If MM is negative, then S is of the form HHMM and needs - to be picked apart; otherwise, S is of the form HH. */ - -static long int -time_zone_hhmm (textint s, long int mm) -{ - if (mm < 0) - return (s.value / 100) * 60 + s.value % 100; - else - return s.value * 60 + (s.negative ? -mm : mm); -} - -static int -to_hour (long int hours, int meridian) -{ - switch (meridian) - { - default: /* Pacify GCC. */ - case MER24: - return 0 <= hours && hours < 24 ? hours : -1; - case MERam: - return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1; - case MERpm: - return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1; - } -} - -static long int -to_year (textint textyear) -{ - long int year = textyear.value; - - if (year < 0) - year = -year; - - /* XPG4 suggests that years 00-68 map to 2000-2068, and - years 69-99 map to 1969-1999. */ - else if (textyear.digits == 2) - year += year < 69 ? 2000 : 1900; - - return year; -} - -static table const * -lookup_zone (parser_control const *pc, char const *name) -{ - table const *tp; - - for (tp = universal_time_zone_table; tp->name; tp++) - if (strcmp (name, tp->name) == 0) - return tp; - - /* Try local zone abbreviations before those in time_zone_table, as - the local ones are more likely to be right. */ - for (tp = pc->local_time_zone_table; tp->name; tp++) - if (strcmp (name, tp->name) == 0) - return tp; - - for (tp = time_zone_table; tp->name; tp++) - if (strcmp (name, tp->name) == 0) - return tp; - - return NULL; -} - -#if ! HAVE_TM_GMTOFF -/* Yield the difference between *A and *B, - measured in seconds, ignoring leap seconds. - The body of this function is taken directly from the GNU C Library; - see src/strftime.c. */ -static long int -tm_diff (struct tm const *a, struct tm const *b) -{ - /* Compute intervening leap days correctly even if year is negative. - Take care to avoid int overflow in leap day calculations. */ - int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3); - int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3); - int a100 = a4 / 25 - (a4 % 25 < 0); - int b100 = b4 / 25 - (b4 % 25 < 0); - int a400 = SHR (a100, 2); - int b400 = SHR (b100, 2); - int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); - long int ayear = a->tm_year; - long int years = ayear - b->tm_year; - long int days = (365 * years + intervening_leap_days - + (a->tm_yday - b->tm_yday)); - return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) - + (a->tm_min - b->tm_min)) - + (a->tm_sec - b->tm_sec)); -} -#endif /* ! HAVE_TM_GMTOFF */ - -static table const * -lookup_word (parser_control const *pc, char *word) -{ - char *p; - char *q; - size_t wordlen; - table const *tp; - bool period_found; - bool abbrev; - - /* Make it uppercase. */ - for (p = word; *p; p++) - { - unsigned char ch = *p; - *p = toupper (ch); - } - - for (tp = meridian_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - - /* See if we have an abbreviation for a month. */ - wordlen = strlen (word); - abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.'); - - for (tp = month_and_day_table; tp->name; tp++) - if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0) - return tp; - - if ((tp = lookup_zone (pc, word))) - return tp; - - if (strcmp (word, dst_table[0].name) == 0) - return dst_table; - - for (tp = time_units_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - - /* Strip off any plural and try the units table again. */ - if (word[wordlen - 1] == 'S') - { - word[wordlen - 1] = '\0'; - for (tp = time_units_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */ - } - - for (tp = relative_time_table; tp->name; tp++) - if (strcmp (word, tp->name) == 0) - return tp; - - /* Military time zones. */ - if (wordlen == 1) - for (tp = military_table; tp->name; tp++) - if (word[0] == tp->name[0]) - return tp; - - /* Drop out any periods and try the time zone table again. */ - for (period_found = false, p = q = word; (*p = *q); q++) - if (*q == '.') - period_found = true; - else - p++; - if (period_found && (tp = lookup_zone (pc, word))) - return tp; - - return NULL; -} - -static int -yylex (YYSTYPE *lvalp, parser_control *pc) -{ - unsigned char c; - size_t count; - - for (;;) - { - while (c = *pc->input, isspace (c)) - pc->input++; - - if (ISDIGIT (c) || c == '-' || c == '+') - { - char const *p; - int sign; - unsigned long int value; - if (c == '-' || c == '+') - { - sign = c == '-' ? -1 : 1; - while (c = *++pc->input, isspace (c)) - continue; - if (! ISDIGIT (c)) - /* skip the '-' sign */ - continue; - } - else - sign = 0; - p = pc->input; - for (value = 0; ; value *= 10) - { - unsigned long int value1 = value + (c - '0'); - if (value1 < value) - return '?'; - value = value1; - c = *++p; - if (! ISDIGIT (c)) - break; - if (ULONG_MAX / 10 < value) - return '?'; - } - if ((c == '.' || c == ',') && ISDIGIT (p[1])) - { - time_t s; - int ns; - int digits; - unsigned long int value1; - - /* Check for overflow when converting value to time_t. */ - if (sign < 0) - { - s = - value; - if (0 < s) - return '?'; - value1 = -s; - } - else - { - s = value; - if (s < 0) - return '?'; - value1 = s; - } - if (value != value1) - return '?'; - - /* Accumulate fraction, to ns precision. */ - p++; - ns = *p++ - '0'; - for (digits = 2; digits <= LOG10_BILLION; digits++) - { - ns *= 10; - if (ISDIGIT (*p)) - ns += *p++ - '0'; - } - - /* Skip excess digits, truncating toward -Infinity. */ - if (sign < 0) - for (; ISDIGIT (*p); p++) - if (*p != '0') - { - ns++; - break; - } - while (ISDIGIT (*p)) - p++; - - /* Adjust to the timespec convention, which is that - tv_nsec is always a positive offset even if tv_sec is - negative. */ - if (sign < 0 && ns) - { - s--; - if (! (s < 0)) - return '?'; - ns = BILLION - ns; - } - - lvalp->timespec.tv_sec = s; - lvalp->timespec.tv_nsec = ns; - pc->input = p; - return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER; - } - else - { - lvalp->textintval.negative = sign < 0; - if (sign < 0) - { - lvalp->textintval.value = - value; - if (0 < lvalp->textintval.value) - return '?'; - } - else - { - lvalp->textintval.value = value; - if (lvalp->textintval.value < 0) - return '?'; - } - lvalp->textintval.digits = p - pc->input; - pc->input = p; - return sign ? tSNUMBER : tUNUMBER; - } - } - - if (isalpha (c)) - { - char buff[20]; - char *p = buff; - table const *tp; - - do - { - if (p < buff + sizeof buff - 1) - *p++ = c; - c = *++pc->input; - } - while (isalpha (c) || c == '.'); - - *p = '\0'; - tp = lookup_word (pc, buff); - if (! tp) - return '?'; - lvalp->intval = tp->value; - return tp->type; - } - - if (c != '(') - return *pc->input++; - count = 0; - do - { - c = *pc->input++; - if (c == '\0') - return c; - if (c == '(') - count++; - else if (c == ')') - count--; - } - while (count != 0); - } -} - -/* Do nothing if the parser reports an error. */ -static int -yyerror (parser_control const *pc ATTRIBUTE_UNUSED, - char const *s ATTRIBUTE_UNUSED) -{ - return 0; -} - -/* If *TM0 is the old and *TM1 is the new value of a struct tm after - passing it to mktime, return true if it's OK that mktime returned T. - It's not OK if *TM0 has out-of-range members. */ - -static bool -mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t) -{ - if (t == (time_t) -1) - { - /* Guard against falsely reporting an error when parsing a time - stamp that happens to equal (time_t) -1, on a host that - supports such a time stamp. */ - tm1 = localtime (&t); - if (!tm1) - return false; - } - - return ! ((tm0->tm_sec ^ tm1->tm_sec) - | (tm0->tm_min ^ tm1->tm_min) - | (tm0->tm_hour ^ tm1->tm_hour) - | (tm0->tm_mday ^ tm1->tm_mday) - | (tm0->tm_mon ^ tm1->tm_mon) - | (tm0->tm_year ^ tm1->tm_year)); -} - -/* A reasonable upper bound for the size of ordinary TZ strings. - Use heap allocation if TZ's length exceeds this. */ -enum { TZBUFSIZE = 100 }; - -/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated - otherwise. */ -static char * -get_tz (char tzbuf[TZBUFSIZE]) -{ - char *tz = getenv ("TZ"); - if (tz) - { - size_t tzsize = strlen (tz) + 1; - tz = (tzsize <= TZBUFSIZE - ? memcpy (tzbuf, tz, tzsize) - : xmemdup (tz, tzsize)); - } - return tz; -} - -/* Parse a date/time string, storing the resulting time value into *RESULT. - The string itself is pointed to by P. Return true if successful. - P can be an incomplete or relative time specification; if so, use - *NOW as the basis for the returned time. */ -bool -get_date (struct timespec *result, char const *p, struct timespec const *now) -{ - time_t Start; - long int Start_ns; - struct tm const *tmp; - struct tm tm; - struct tm tm0; - parser_control pc; - struct timespec gettime_buffer; - unsigned char c; - bool tz_was_altered = false; - char *tz0 = NULL; - char tz0buf[TZBUFSIZE]; - bool ok = true; - - if (! now) - { - gettime (&gettime_buffer); - now = &gettime_buffer; - } - - Start = now->tv_sec; - Start_ns = now->tv_nsec; - - tmp = localtime (&now->tv_sec); - if (! tmp) - return false; - - while (c = *p, isspace (c)) - p++; - - if (strncmp (p, "TZ=\"", 4) == 0) - { - char const *tzbase = p + 4; - size_t tzsize = 1; - char const *s; - - for (s = tzbase; *s; s++, tzsize++) - if (*s == '\\') - { - s++; - if (! (*s == '\\' || *s == '"')) - break; - } - else if (*s == '"') - { - char *z; - char *tz1; - char tz1buf[TZBUFSIZE]; - bool large_tz = TZBUFSIZE < tzsize; - bool setenv_ok; - tz0 = get_tz (tz0buf); - z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf; - for (s = tzbase; *s != '"'; s++) - *z++ = *(s += *s == '\\'); - *z = '\0'; - setenv_ok = setenv ("TZ", tz1, 1) == 0; - if (large_tz) - free (tz1); - if (!setenv_ok) - goto fail; - tz_was_altered = true; - p = s + 1; - } - } - - pc.input = p; - pc.year.value = tmp->tm_year; - pc.year.value += TM_YEAR_BASE; - pc.year.digits = 0; - pc.month = tmp->tm_mon + 1; - pc.day = tmp->tm_mday; - pc.hour = tmp->tm_hour; - pc.minutes = tmp->tm_min; - pc.seconds.tv_sec = tmp->tm_sec; - pc.seconds.tv_nsec = Start_ns; - tm.tm_isdst = tmp->tm_isdst; - - pc.meridian = MER24; - pc.rel = RELATIVE_TIME_0; - pc.timespec_seen = false; - pc.rels_seen = false; - pc.dates_seen = 0; - pc.days_seen = 0; - pc.times_seen = 0; - pc.local_zones_seen = 0; - pc.dsts_seen = 0; - pc.zones_seen = 0; - -#if HAVE_STRUCT_TM_TM_ZONE - pc.local_time_zone_table[0].name = tmp->tm_zone; - pc.local_time_zone_table[0].type = tLOCAL_ZONE; - pc.local_time_zone_table[0].value = tmp->tm_isdst; - pc.local_time_zone_table[1].name = NULL; - - /* Probe the names used in the next three calendar quarters, looking - for a tm_isdst different from the one we already have. */ - { - int quarter; - for (quarter = 1; quarter <= 3; quarter++) - { - time_t probe = Start + quarter * (90 * 24 * 60 * 60); - struct tm const *probe_tm = localtime (&probe); - if (probe_tm && probe_tm->tm_zone - && probe_tm->tm_isdst != pc.local_time_zone_table[0].value) - { - { - pc.local_time_zone_table[1].name = probe_tm->tm_zone; - pc.local_time_zone_table[1].type = tLOCAL_ZONE; - pc.local_time_zone_table[1].value = probe_tm->tm_isdst; - pc.local_time_zone_table[2].name = NULL; - } - break; - } - } - } -#else -#if HAVE_TZNAME - { -# ifndef tzname - extern char *tzname[]; -# endif - int i; - for (i = 0; i < 2; i++) - { - pc.local_time_zone_table[i].name = tzname[i]; - pc.local_time_zone_table[i].type = tLOCAL_ZONE; - pc.local_time_zone_table[i].value = i; - } - pc.local_time_zone_table[i].name = NULL; - } -#else - pc.local_time_zone_table[0].name = NULL; -#endif -#endif - - if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name - && ! strcmp (pc.local_time_zone_table[0].name, - pc.local_time_zone_table[1].name)) - { - /* This locale uses the same abbrevation for standard and - daylight times. So if we see that abbreviation, we don't - know whether it's daylight time. */ - pc.local_time_zone_table[0].value = -1; - pc.local_time_zone_table[1].name = NULL; - } - - if (yyparse (&pc) != 0) - goto fail; - - if (pc.timespec_seen) - *result = pc.seconds; - else - { - if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen - | (pc.local_zones_seen + pc.zones_seen))) - goto fail; - - tm.tm_year = to_year (pc.year) - TM_YEAR_BASE; - tm.tm_mon = pc.month - 1; - tm.tm_mday = pc.day; - if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen)) - { - tm.tm_hour = to_hour (pc.hour, pc.meridian); - if (tm.tm_hour < 0) - goto fail; - tm.tm_min = pc.minutes; - tm.tm_sec = pc.seconds.tv_sec; - } - else - { - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - pc.seconds.tv_nsec = 0; - } - - /* Let mktime deduce tm_isdst if we have an absolute time stamp. */ - if (pc.dates_seen | pc.days_seen | pc.times_seen) - tm.tm_isdst = -1; - - /* But if the input explicitly specifies local time with or without - DST, give mktime that information. */ - if (pc.local_zones_seen) - tm.tm_isdst = pc.local_isdst; - - tm0 = tm; - - Start = mktime (&tm); - - if (! mktime_ok (&tm0, &tm, Start)) - { - if (! pc.zones_seen) - goto fail; - else - { - /* Guard against falsely reporting errors near the time_t - boundaries when parsing times in other time zones. For - example, suppose the input string "1969-12-31 23:00:00 -0100", - the current time zone is 8 hours ahead of UTC, and the min - time_t value is 1970-01-01 00:00:00 UTC. Then the min - localtime value is 1970-01-01 08:00:00, and mktime will - therefore fail on 1969-12-31 23:00:00. To work around the - problem, set the time zone to 1 hour behind UTC temporarily - by setting TZ="XXX1:00" and try mktime again. */ - - long int time_zone = pc.time_zone; - long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone; - long int abs_time_zone_hour = abs_time_zone / 60; - int abs_time_zone_min = abs_time_zone % 60; - char tz1buf[sizeof "XXX+0:00" - + sizeof pc.time_zone * CHAR_BIT / 3]; - if (!tz_was_altered) - tz0 = get_tz (tz0buf); - sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0), - abs_time_zone_hour, abs_time_zone_min); - if (setenv ("TZ", tz1buf, 1) != 0) - goto fail; - tz_was_altered = true; - tm = tm0; - Start = mktime (&tm); - if (! mktime_ok (&tm0, &tm, Start)) - goto fail; - } - } - - if (pc.days_seen && ! pc.dates_seen) - { - tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7 - + 7 * (pc.day_ordinal - (0 < pc.day_ordinal))); - tm.tm_isdst = -1; - Start = mktime (&tm); - if (Start == (time_t) -1) - goto fail; - } - - if (pc.zones_seen) - { - long int delta = pc.time_zone * 60; - time_t t1; -#ifdef HAVE_TM_GMTOFF - delta -= tm.tm_gmtoff; -#else - time_t t = Start; - struct tm const *gmt = gmtime (&t); - if (! gmt) - goto fail; - delta -= tm_diff (&tm, gmt); -#endif - t1 = Start - delta; - if ((Start < t1) != (delta < 0)) - goto fail; /* time_t overflow */ - Start = t1; - } - - /* Add relative date. */ - if (pc.rel.year | pc.rel.month | pc.rel.day) - { - int year = tm.tm_year + pc.rel.year; - int month = tm.tm_mon + pc.rel.month; - int day = tm.tm_mday + pc.rel.day; - if (((year < tm.tm_year) ^ (pc.rel.year < 0)) - | ((month < tm.tm_mon) ^ (pc.rel.month < 0)) - | ((day < tm.tm_mday) ^ (pc.rel.day < 0))) - goto fail; - tm.tm_year = year; - tm.tm_mon = month; - tm.tm_mday = day; - tm.tm_hour = tm0.tm_hour; - tm.tm_min = tm0.tm_min; - tm.tm_sec = tm0.tm_sec; - tm.tm_isdst = tm0.tm_isdst; - Start = mktime (&tm); - if (Start == (time_t) -1) - goto fail; - } - - /* Add relative hours, minutes, and seconds. On hosts that support - leap seconds, ignore the possibility of leap seconds; e.g., - "+ 10 minutes" adds 600 seconds, even if one of them is a - leap second. Typically this is not what the user wants, but it's - too hard to do it the other way, because the time zone indicator - must be applied before relative times, and if mktime is applied - again the time zone will be lost. */ - { - long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns; - long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION; - time_t t0 = Start; - long int d1 = 60 * 60 * pc.rel.hour; - time_t t1 = t0 + d1; - long int d2 = 60 * pc.rel.minutes; - time_t t2 = t1 + d2; - long int d3 = pc.rel.seconds; - time_t t3 = t2 + d3; - long int d4 = (sum_ns - normalized_ns) / BILLION; - time_t t4 = t3 + d4; - - if ((d1 / (60 * 60) ^ pc.rel.hour) - | (d2 / 60 ^ pc.rel.minutes) - | ((t1 < t0) ^ (d1 < 0)) - | ((t2 < t1) ^ (d2 < 0)) - | ((t3 < t2) ^ (d3 < 0)) - | ((t4 < t3) ^ (d4 < 0))) - goto fail; - - result->tv_sec = t4; - result->tv_nsec = normalized_ns; - } - } - - goto done; - - fail: - ok = false; - done: - if (tz_was_altered) - ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0; - if (tz0 != tz0buf) - free (tz0); - return ok; -} - -#if TEST - -int -main (int ac, char **av) -{ - char buff[BUFSIZ]; - - printf ("Enter date, or blank line to exit.\n\t> "); - fflush (stdout); - - buff[BUFSIZ - 1] = '\0'; - while (fgets (buff, BUFSIZ - 1, stdin) && buff[0]) - { - struct timespec d; - struct tm const *tm; - if (! get_date (&d, buff, NULL)) - printf ("Bad format - couldn't convert.\n"); - else if (! (tm = localtime (&d.tv_sec))) - { - long int sec = d.tv_sec; - printf ("localtime (%ld) failed\n", sec); - } - else - { - int ns = d.tv_nsec; - printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n", - tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, ns); - } - printf ("\t> "); - fflush (stdout); - } - return 0; -} -#endif /* TEST */ diff --git a/src/bin/tar/lib/getdelim.c b/src/bin/tar/lib/getdelim.c deleted file mode 100644 index 0547c7fae2..0000000000 --- a/src/bin/tar/lib/getdelim.c +++ /dev/null @@ -1,133 +0,0 @@ -/* getdelim.c --- Implementation of replacement getdelim function. - Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Ported from glibc by Simon Josefsson. */ - -#include - -#include - -#include -#include -#include - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif -#ifndef SSIZE_MAX -# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) -#endif -#if !HAVE_FLOCKFILE -# undef flockfile -# define flockfile(x) ((void) 0) -#endif -#if !HAVE_FUNLOCKFILE -# undef funlockfile -# define funlockfile(x) ((void) 0) -#endif - -/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ -#ifndef EOVERFLOW -# define EOVERFLOW E2BIG -#endif - -/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and - NUL-terminate it). *LINEPTR is a pointer returned from malloc (or - NULL), pointing to *N characters of space. It is realloc'ed as - necessary. Returns the number of characters read (not including - the null terminator), or -1 on error or EOF. */ - -ssize_t -getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) -{ - ssize_t result; - size_t cur_len = 0; - - if (lineptr == NULL || n == NULL || fp == NULL) - { - errno = EINVAL; - return -1; - } - - flockfile (fp); - - if (*lineptr == NULL || *n == 0) - { - *n = 120; - *lineptr = (char *) realloc (*lineptr, *n); - if (*lineptr == NULL) - { - result = -1; - goto unlock_return; - } - } - - for (;;) - { - int i; - - i = getc (fp); - if (i == EOF) - { - result = -1; - break; - } - - /* Make enough space for len+1 (for final NUL) bytes. */ - if (cur_len + 1 >= *n) - { - size_t needed_max = - SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; - size_t needed = 2 * *n + 1; /* Be generous. */ - char *new_lineptr; - - if (needed_max < needed) - needed = needed_max; - if (cur_len + 1 >= needed) - { - result = -1; - errno = EOVERFLOW; - goto unlock_return; - } - - new_lineptr = (char *) realloc (*lineptr, needed); - if (new_lineptr == NULL) - { - result = -1; - goto unlock_return; - } - - *lineptr = new_lineptr; - *n = needed; - } - - (*lineptr)[cur_len] = i; - cur_len++; - - if (i == delimiter) - break; - } - (*lineptr)[cur_len] = '\0'; - result = cur_len ? cur_len : result; - - unlock_return: - funlockfile (fp); /* doesn't set errno */ - - return result; -} diff --git a/src/bin/tar/lib/getline.c b/src/bin/tar/lib/getline.c deleted file mode 100644 index 817c2813b3..0000000000 --- a/src/bin/tar/lib/getline.c +++ /dev/null @@ -1,29 +0,0 @@ -/* getline.c --- Implementation of replacement getline function. - Copyright (C) 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Written by Simon Josefsson. */ - -#include - -#include - -ssize_t -getline (char **lineptr, size_t *n, FILE *stream) -{ - return getdelim (lineptr, n, '\n', stream); -} diff --git a/src/bin/tar/lib/getopt.c b/src/bin/tar/lib/getopt.c deleted file mode 100644 index 3580ad825c..0000000000 --- a/src/bin/tar/lib/getopt.c +++ /dev/null @@ -1,1191 +0,0 @@ -/* 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 drepper@gnu.org - before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LIBC -# include -#endif - -#include "getopt.h" - -#include -#include -#include -#include - -#ifdef __VMS -# include -#endif - -#ifdef _LIBC -# include -#else -# include "gettext.h" -# define _(msgid) gettext (msgid) -#endif - -#if defined _LIBC && defined USE_IN_LIBIO -# include -#endif - -#ifndef attribute_hidden -# define attribute_hidden -#endif - -/* Unlike standard Unix `getopt', functions like `getopt_long' - let the user intersperse the options with the other arguments. - - As `getopt_long' 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. - - Using `getopt' or setting the environment variable POSIXLY_CORRECT - disables permutation. - Then the application's 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_int.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; - -/* 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 -1, 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. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* 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 = '?'; - -/* Keep a global copy of all internal members of getopt_data. */ - -static struct _getopt_data getopt_data; - - -#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV -extern char *getenv (); -#endif - -#ifdef _LIBC -/* Stored original parameters. - XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ -extern int __libc_argc; -extern char **__libc_argv; - -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -# ifdef USE_NONOPTION_FLAGS -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; -# endif - -# ifdef USE_NONOPTION_FLAGS -# define SWAP_FLAGS(ch1, ch2) \ - if (d->__nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -# else -# define SWAP_FLAGS(ch1, ch2) -# endif -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* 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 (char **argv, struct _getopt_data *d) -{ - int bottom = d->__first_nonopt; - int middle = d->__last_nonopt; - int top = d->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. */ - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - d->__nonoption_flags_max_len), - '\0', top + 1 - d->__nonoption_flags_max_len); - d->__nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - 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; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* 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; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - d->__first_nonopt += (d->optind - d->__last_nonopt); - d->__last_nonopt = d->optind; -} - -/* Initialize the internal data when the first call is made. */ - -static const char * -_getopt_initialize (int argc, char **argv, const char *optstring, - int posixly_correct, struct _getopt_data *d) -{ - /* 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. */ - - d->__first_nonopt = d->__last_nonopt = d->optind; - - d->__nextchar = NULL; - - d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - d->__ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - d->__ordering = REQUIRE_ORDER; - ++optstring; - } - else if (d->__posixly_correct) - d->__ordering = REQUIRE_ORDER; - else - d->__ordering = PERMUTE; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - if (!d->__posixly_correct - && argc == __libc_argc && argv == __libc_argv) - { - if (d->__nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - d->__nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = d->__nonoption_flags_max_len = strlen (orig_str); - if (d->__nonoption_flags_max_len < argc) - d->__nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (d->__nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - d->__nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', d->__nonoption_flags_max_len - len); - } - } - d->__nonoption_flags_len = d->__nonoption_flags_max_len; - } - else - d->__nonoption_flags_len = 0; -#endif - - 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 -1. - 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. - - 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. - - If POSIXLY_CORRECT is nonzero, behave as if the POSIXLY_CORRECT - environment variable were set. */ - -int -_getopt_internal_r (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, int posixly_correct, struct _getopt_data *d) -{ - int print_errors = d->opterr; - if (optstring[0] == ':') - print_errors = 0; - - if (argc < 1) - return -1; - - d->optarg = NULL; - - if (d->optind == 0 || !d->__initialized) - { - if (d->optind == 0) - d->optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring, - posixly_correct, d); - d->__initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ - || (d->optind < d->__nonoption_flags_len \ - && __getopt_nonoption_flags[d->optind] == '1')) -#else -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') -#endif - - if (d->__nextchar == NULL || *d->__nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (d->__last_nonopt > d->optind) - d->__last_nonopt = d->optind; - if (d->__first_nonopt > d->optind) - d->__first_nonopt = d->optind; - - if (d->__ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__last_nonopt != d->optind) - d->__first_nonopt = d->optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (d->optind < argc && NONOPTION_P) - d->optind++; - d->__last_nonopt = d->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 (d->optind != argc && !strcmp (argv[d->optind], "--")) - { - d->optind++; - - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__first_nonopt == d->__last_nonopt) - d->__first_nonopt = d->optind; - d->__last_nonopt = argc; - - d->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 (d->optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (d->__first_nonopt != d->__last_nonopt) - d->optind = d->__first_nonopt; - return -1; - } - - /* 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 (NONOPTION_P) - { - if (d->__ordering == REQUIRE_ORDER) - return -1; - d->optarg = argv[d->optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - d->__nextchar = (argv[d->optind] + 1 - + (longopts != NULL && argv[d->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[d->optind][1] == '-' - || (long_only && (argv[d->optind][2] - || !strchr (optstring, argv[d->optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = d->__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, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__nextchar) - == (unsigned int) 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 if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[d->optind]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - d->optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - d->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) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind - 1][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#else - fprintf (stderr, _("\ -%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#else - fprintf (stderr, _("\ -%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - - d->__nextchar += strlen (d->__nextchar); - - d->optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__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[d->optind][1] == '-' - || strchr (optstring, *d->__nextchar) == NULL) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), - argv[0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], d->__nextchar); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->__nextchar = (char *) ""; - d->optind++; - d->optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *d->__nextchar++; - char *temp = strchr (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*d->__nextchar == '\0') - ++d->optind; - - if (temp == NULL || c == ':') - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (d->__posixly_correct) - { - /* 1003.2 specifies the format of this message. */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: illegal option -- %c\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); -#endif - } - else - { -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: invalid option -- %c\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, - _("%s: option requires an argument -- %c\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `d->optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (d->__nextchar = nameend = d->optarg; *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, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__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 (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[d->optind]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - 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) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - - d->__nextchar += strlen (d->__nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]); -#endif - } - d->__nextchar += strlen (d->__nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - d->__nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - d->optind++; - } - else - d->optarg = NULL; - d->__nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option requires an argument -- %c\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - d->__nextchar = NULL; - } - } - return c; - } -} - -int -_getopt_internal (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, int posixly_correct) -{ - int result; - - getopt_data.optind = optind; - getopt_data.opterr = opterr; - - result = _getopt_internal_r (argc, argv, optstring, longopts, longind, - long_only, posixly_correct, &getopt_data); - - optind = getopt_data.optind; - optarg = getopt_data.optarg; - optopt = getopt_data.optopt; - - return result; -} - -/* glibc gets a LSB-compliant getopt. - Standalone applications get a POSIX-compliant getopt. */ -#if _LIBC -enum { POSIXLY_CORRECT = 0 }; -#else -enum { POSIXLY_CORRECT = 1 }; -#endif - -int -getopt (int argc, char *const *argv, const char *optstring) -{ - return _getopt_internal (argc, (char **) argv, optstring, NULL, NULL, 0, - POSIXLY_CORRECT); -} - - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (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 == -1) - 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 */ diff --git a/src/bin/tar/lib/getopt.h b/src/bin/tar/lib/getopt.h deleted file mode 100644 index 615ef9a3b6..0000000000 --- a/src/bin/tar/lib/getopt.h +++ /dev/null @@ -1,226 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006,2007 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -/* Standalone applications should #define __GETOPT_PREFIX to an - identifier that prefixes the external functions and variables - defined in this header. When this happens, include the - headers that might declare getopt so that they will not cause - confusion if included after this file. Then systematically rename - identifiers so that they do not collide with the system functions - and variables. Renaming avoids problems with some compilers and - linkers. */ -#if defined __GETOPT_PREFIX && !defined __need_getopt -# include -# include -# include -# undef __need_getopt -# undef getopt -# undef getopt_long -# undef getopt_long_only -# undef optarg -# undef opterr -# undef optind -# undef optopt -# define __GETOPT_CONCAT(x, y) x ## y -# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) -# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) -# define getopt __GETOPT_ID (getopt) -# define getopt_long __GETOPT_ID (getopt_long) -# define getopt_long_only __GETOPT_ID (getopt_long_only) -# define optarg __GETOPT_ID (optarg) -# define opterr __GETOPT_ID (opterr) -# define optind __GETOPT_ID (optind) -# define optopt __GETOPT_ID (optopt) -#endif - -/* Standalone applications get correct prototypes for getopt_long and - getopt_long_only; they declare "char **argv". libc uses prototypes - with "char *const *argv" that are incorrect because getopt_long and - getopt_long_only can permute argv; this is required for backward - compatibility (e.g., for LSB 2.0.1). - - This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt', - but it caused redefinition warnings if both unistd.h and getopt.h were - included, since unistd.h includes getopt.h having previously defined - __need_getopt. - - The only place where __getopt_argv_const is used is in definitions - of getopt_long and getopt_long_only below, but these are visible - only if __need_getopt is not defined, so it is quite safe to rewrite - the conditional as follows: -*/ -#if !defined __need_getopt -# if defined __GETOPT_PREFIX -# define __getopt_argv_const /* empty */ -# else -# define __getopt_argv_const const -# endif -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifndef __THROW -# ifndef __GNUC_PREREQ -# define __GNUC_PREREQ(maj, min) (0) -# endif -# if defined __cplusplus && __GNUC_PREREQ (2,8) -# define __THROW throw () -# else -# define __THROW -# endif -#endif - -#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 -1, 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; - -#ifndef __need_getopt -/* 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 -{ - const char *name; - /* 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 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `-', then non-option arguments are treated as - arguments to the option '\1'. This behavior is specific to the GNU - `getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in - the environment, then do not permute arguments. */ - -extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __THROW; - -#ifndef __need_getopt -extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; -extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW; - -#endif - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ diff --git a/src/bin/tar/lib/getopt1.c b/src/bin/tar/lib/getopt1.c deleted file mode 100644 index cc0746ea43..0000000000 --- a/src/bin/tar/lib/getopt1.c +++ /dev/null @@ -1,171 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef _LIBC -# include -#else -# include -# include "getopt.h" -#endif -#include "getopt_int.h" - -#include - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (int argc, char *__getopt_argv_const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 0, 0); -} - -int -_getopt_long_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) -{ - return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 0, 0, d); -} - -/* 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 (int argc, char *__getopt_argv_const *argv, - const char *options, - const struct option *long_options, int *opt_index) -{ - return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 1, 0); -} - -int -_getopt_long_only_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) -{ - return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 1, 0, d); -} - - -#ifdef TEST - -#include - -int -main (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 == -1) - 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 */ diff --git a/src/bin/tar/lib/getopt_int.h b/src/bin/tar/lib/getopt_int.h deleted file mode 100644 index 401579fd28..0000000000 --- a/src/bin/tar/lib/getopt_int.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Internal declarations for getopt. - Copyright (C) 1989-1994,1996-1999,2001,2003,2004 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GETOPT_INT_H -#define _GETOPT_INT_H 1 - -extern int _getopt_internal (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct); - - -/* Reentrant versions which can handle parsing multiple argument - vectors at the same time. */ - -/* Data type for reentrant functions. */ -struct _getopt_data -{ - /* These have exactly the same meaning as the corresponding global - variables, except that they are used for the reentrant - versions of getopt. */ - int optind; - int opterr; - int optopt; - char *optarg; - - /* Internal members. */ - - /* True if the internal members have been initialized. */ - int __initialized; - - /* 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. */ - char *__nextchar; - - /* 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, or by calling getopt. - - 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 -1 with `optind' != ARGC. */ - - enum - { - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER - } __ordering; - - /* If the POSIXLY_CORRECT environment variable is set - or getopt was called. */ - int __posixly_correct; - - - /* 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. */ - - int __first_nonopt; - int __last_nonopt; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - int __nonoption_flags_max_len; - int __nonoption_flags_len; -# endif -}; - -/* The initializer is necessary to set OPTIND and OPTERR to their - default values and to clear the initialization flag. */ -#define _GETOPT_DATA_INITIALIZER { 1, 1 } - -extern int _getopt_internal_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct, - struct _getopt_data *__data); - -extern int _getopt_long_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - struct _getopt_data *__data); - -extern int _getopt_long_only_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, - int *__longind, - struct _getopt_data *__data); - -#endif /* getopt_int.h */ diff --git a/src/bin/tar/lib/getpagesize.h b/src/bin/tar/lib/getpagesize.h deleted file mode 100644 index 8863336666..0000000000 --- a/src/bin/tar/lib/getpagesize.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Emulate getpagesize on systems that lack it. - Copyright (C) 1999, 2000, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#ifndef HAVE_GETPAGESIZE - -#include - -#if !defined getpagesize && defined _SC_PAGESIZE -# if ! (defined __VMS && __VMS_VER < 70000000) -# define getpagesize() sysconf (_SC_PAGESIZE) -# endif -#endif - -#if !defined getpagesize && defined __VMS -# ifdef __ALPHA -# define getpagesize() 8192 -# else -# define getpagesize() 512 -# endif -#endif - -/* This is for BeOS. */ -#if !defined getpagesize && HAVE_OS_H -# include -# if defined B_PAGE_SIZE -# define getpagesize() B_PAGE_SIZE -# endif -#endif - -/* This is for AmigaOS4.0. */ -#if !defined getpagesize && defined __amigaos4__ -# define getpagesize() 2048 -#endif - -#if !defined getpagesize && HAVE_SYS_PARAM_H -# include -# ifdef EXEC_PAGESIZE -# define getpagesize() EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define CLSIZE 1 -# endif -# define getpagesize() (NBPG * CLSIZE) -# else -# ifdef NBPC -# define getpagesize() NBPC -# endif -# endif -# endif -#endif - -#endif /* not HAVE_GETPAGESIZE */ diff --git a/src/bin/tar/lib/gettext.h b/src/bin/tar/lib/gettext.h deleted file mode 100644 index 9d76ec9afc..0000000000 --- a/src/bin/tar/lib/gettext.h +++ /dev/null @@ -1,270 +0,0 @@ -/* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include - -/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by - the gettext() and ngettext() macros. This is an alternative to calling - textdomain(), and is useful for libraries. */ -# ifdef DEFAULT_TEXT_DOMAIN -# undef gettext -# define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) -# endif - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of a NOP. We don't include - as well because people using "gettext.h" will not include , - and also including would fail on SunOS 4, whereas - is OK. */ -#if defined(__sun) -# include -#endif - -/* Many header files from the libstdc++ coming with g++ 3.3 or newer include - , which chokes if dcgettext is defined as a macro. So include - it now, to make later inclusions of a NOP. */ -#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) -# include -# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H -# include -# endif -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) -# define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) -# define textdomain(Domainname) ((const char *) (Domainname)) -# define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) -# define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) - -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -/* The separator between msgctxt and msgid in a .mo file. */ -#define GETTEXT_CONTEXT_GLUE "\004" - -/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a - MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be - short and rarely need to change. - The letter 'p' stands for 'particular' or 'special'. */ -#ifdef DEFAULT_TEXT_DOMAIN -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#else -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#endif -#define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) -#ifdef DEFAULT_TEXT_DOMAIN -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#else -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#endif -#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) -{ - const char *translation = dcgettext (domain, msg_ctxt_id, category); - if (translation == msg_ctxt_id) - return msgid; - else - return translation; -} - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - const char *translation = - dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); - if (translation == msg_ctxt_id || translation == msgid_plural) - return (n == 1 ? msgid : msgid_plural); - else - return translation; -} - -/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID - can be arbitrary expressions. But for string literals these macros are - less efficient than those above. */ - -#include - -#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ - (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ - /* || __STDC_VERSION__ >= 199901L */ ) - -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS -#include -#endif - -#define pgettext_expr(Msgctxt, Msgid) \ - dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) -#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcgettext (domain, msg_ctxt_id, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (translation != msg_ctxt_id) - return translation; - } - return msgid; -} - -#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (!(translation == msg_ctxt_id || translation == msgid_plural)) - return translation; - } - return (n == 1 ? msgid : msgid_plural); -} - -#endif /* _LIBGETTEXT_H */ diff --git a/src/bin/tar/lib/gettime.c b/src/bin/tar/lib/gettime.c deleted file mode 100644 index 86bd325091..0000000000 --- a/src/bin/tar/lib/gettime.c +++ /dev/null @@ -1,49 +0,0 @@ -/* gettime -- get the system clock - - Copyright (C) 2002, 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -#include "timespec.h" - -#include - -/* Get the system time into *TS. */ - -void -gettime (struct timespec *ts) -{ -#if HAVE_NANOTIME - nanotime (ts); -#else - -# if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME - if (clock_gettime (CLOCK_REALTIME, ts) == 0) - return; -# endif - - { - struct timeval tv; - gettimeofday (&tv, NULL); - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; - } - -#endif -} diff --git a/src/bin/tar/lib/gettimeofday.c b/src/bin/tar/lib/gettimeofday.c deleted file mode 100644 index bd5576cb09..0000000000 --- a/src/bin/tar/lib/gettimeofday.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Provide gettimeofday for systems that don't have it or for which it's broken. - - Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -/* Specification. */ -#include - -#include - -#if HAVE_SYS_TIMEB_H -# include -#endif - -#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME - -/* Work around the bug in some systems whereby gettimeofday clobbers - the static buffer that localtime uses for its return value. The - gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has - this problem. The tzset replacement is necessary for at least - Solaris 2.5, 2.5.1, and 2.6. */ - -static struct tm tm_zero_buffer; -static struct tm *localtime_buffer_addr = &tm_zero_buffer; - -/* This is a wrapper for localtime. It is used only on systems for which - gettimeofday clobbers the static buffer used for localtime's result. - - On the first call, record the address of the static buffer that - localtime uses for its result. */ - -struct tm * -localtime (time_t const *timep) -{ -#undef localtime - extern struct tm *localtime (time_t const *); - struct tm *tm = localtime (timep); - - if (localtime_buffer_addr == &tm_zero_buffer) - localtime_buffer_addr = tm; - - return tm; -} - -/* Same as above, since gmtime and localtime use the same buffer. */ -struct tm * -gmtime (time_t const *timep) -{ -#undef gmtime - extern struct tm *gmtime (time_t const *); - struct tm *tm = gmtime (timep); - - if (localtime_buffer_addr == &tm_zero_buffer) - localtime_buffer_addr = tm; - - return tm; -} - -#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */ - -#if TZSET_CLOBBERS_LOCALTIME -/* This is a wrapper for tzset, for systems on which tzset may clobber - the static buffer used for localtime's result. */ -void -tzset (void) -{ -#undef tzset - extern void tzset (void); - - /* Save and restore the contents of the buffer used for localtime's - result around the call to tzset. */ - struct tm save = *localtime_buffer_addr; - tzset (); - *localtime_buffer_addr = save; -} -#endif - -/* This is a wrapper for gettimeofday. It is used only on systems - that lack this function, or whose implementation of this function - causes problems. */ - -int -rpl_gettimeofday (struct timeval *restrict tv, void *restrict tz) -{ -#undef gettimeofday -#if HAVE_GETTIMEOFDAY -# if GETTIMEOFDAY_CLOBBERS_LOCALTIME - /* Save and restore the contents of the buffer used for localtime's - result around the call to gettimeofday. */ - struct tm save = *localtime_buffer_addr; -# endif - - int result = gettimeofday (tv, tz); - -# if GETTIMEOFDAY_CLOBBERS_LOCALTIME - *localtime_buffer_addr = save; -# endif - - return result; - -#else - -# if HAVE__FTIME - - struct _timeb timebuf; - _ftime (&timebuf); - tv->tv_sec = timebuf.time; - tv->tv_usec = timebuf.millitm * 1000; - -# else - -# if !defined OK_TO_USE_1S_CLOCK -# error "Only 1-second nominal clock resolution found. Is that intended?" \ - "If so, compile with the -DOK_TO_USE_1S_CLOCK option." -# endif - tv->tv_sec = time (NULL); - tv->tv_usec = 0; - -# endif - - return 0; - -#endif -} diff --git a/src/bin/tar/lib/gnulib.mk b/src/bin/tar/lib/gnulib.mk deleted file mode 100644 index 56082d22be..0000000000 --- a/src/bin/tar/lib/gnulib.mk +++ /dev/null @@ -1,1643 +0,0 @@ -## DO NOT EDIT! GENERATED AUTOMATICALLY! -## Process this file with automake to produce Makefile.in. -# Copyright (C) 2004-2007 Free Software Foundation, Inc. -# -# This file is free software, distributed under the terms of the GNU -# General Public License. As a special exception to the GNU General -# Public License, this file may be distributed as part of a program -# that contains a configuration script generated by Autoconf, under -# the same distribution terms as the rest of that program. -# -# Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl --lib=libtar --source-base=.#bootmp/lib --m4-base=.#bootmp/m4 --doc-base=.#bootmp/doc --aux-dir=.#bootmp/build-aux --avoid=lock --avoid=size_max --no-libtool --macro-prefix=gl alloca argmatch argp backupfile closeout configmake dirname error exclude exitfail fileblocks fnmatch-gnu ftruncate full-write getdate getline getopt getpagesize gettext gettime hash human inttostr inttypes lchown localcharset memset mkdtemp modechange obstack quote quotearg rmdir rpmatch safe-read save-cwd savedir setenv stat-time stdbool stdint stpcpy strdup strerror strtol strtoul timespec unlinkdir unlocked-io utime utimens version-etc-fsf xalloc xalloc-die xgetcwd xstrtoumax - -AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects - -noinst_HEADERS = -noinst_LIBRARIES = -noinst_LTLIBRARIES = -EXTRA_DIST = -BUILT_SOURCES = -SUFFIXES = -MOSTLYCLEANFILES = core *.stackdump -MOSTLYCLEANDIRS = -CLEANFILES = -DISTCLEANFILES = -MAINTAINERCLEANFILES = - -AM_CPPFLAGS = - -noinst_LIBRARIES += libtar.a - -libtar_a_SOURCES = -libtar_a_LIBADD = $(gl_LIBOBJS) -libtar_a_DEPENDENCIES = $(gl_LIBOBJS) -EXTRA_libtar_a_SOURCES = - -## begin gnulib module absolute-header - -# Use this preprocessor expression to decide whether #include_next works. -# Do not rely on a 'configure'-time test for this, since the expression -# might appear in an installed header, which is used by some other compiler. -HAVE_INCLUDE_NEXT = (__GNUC__ || 60000000 <= __DECC_VER) - -## end gnulib module absolute-header - -## begin gnulib module alloca - - -EXTRA_DIST += alloca.c - -EXTRA_libtar_a_SOURCES += alloca.c - -libtar_a_LIBADD += @ALLOCA@ -libtar_a_DEPENDENCIES += @ALLOCA@ -## end gnulib module alloca - -## begin gnulib module alloca-opt - -BUILT_SOURCES += $(ALLOCA_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -alloca.h: alloca.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/alloca.in.h; \ - } > $@-t - mv -f $@-t $@ -MOSTLYCLEANFILES += alloca.h alloca.h-t - -EXTRA_DIST += alloca.in.h - -## end gnulib module alloca-opt - -## begin gnulib module argmatch - - -EXTRA_DIST += argmatch.c argmatch.h - -EXTRA_libtar_a_SOURCES += argmatch.c - -## end gnulib module argmatch - -## begin gnulib module argp - -libtar_a_SOURCES += argp.h argp-ba.c argp-eexst.c \ - argp-fmtstream.c argp-fmtstream.h argp-fs-xinl.c argp-help.c \ - argp-namefrob.h argp-parse.c argp-pin.c argp-pv.c argp-pvh.c \ - argp-xinl.c - -## end gnulib module argp - -## begin gnulib module backupfile - - -EXTRA_DIST += backupfile.c backupfile.h - -EXTRA_libtar_a_SOURCES += backupfile.c - -## end gnulib module backupfile - -## begin gnulib module canonicalize-lgpl - - -EXTRA_DIST += canonicalize-lgpl.c canonicalize.h - -EXTRA_libtar_a_SOURCES += canonicalize-lgpl.c - -## end gnulib module canonicalize-lgpl - -## begin gnulib module chdir-long - - -EXTRA_DIST += chdir-long.c chdir-long.h - -EXTRA_libtar_a_SOURCES += chdir-long.c - -## end gnulib module chdir-long - -## begin gnulib module chown - - -EXTRA_DIST += chown.c fchown-stub.c - -EXTRA_libtar_a_SOURCES += chown.c fchown-stub.c - -## end gnulib module chown - -## begin gnulib module close-stream - - -EXTRA_DIST += close-stream.c close-stream.h - -EXTRA_libtar_a_SOURCES += close-stream.c - -## end gnulib module close-stream - -## begin gnulib module closeout - - -EXTRA_DIST += closeout.c closeout.h - -EXTRA_libtar_a_SOURCES += closeout.c - -## end gnulib module closeout - -## begin gnulib module configmake - -# Retrieve values of the variables through 'configure' followed by -# 'make', not directly through 'configure', so that a user who -# sets some of these variables consistently on the 'make' command -# line gets correct results. -# -# One advantage of this approach, compared to the classical -# approach of adding -DLIBDIR=\"$(libdir)\" etc. to AM_CPPFLAGS, -# is that it protects against the use of undefined variables. -# If, say, $(libdir) is not set in the Makefile, LIBDIR is not -# defined by this module, and code using LIBDIR gives a -# compilation error. -# -# Another advantage is that 'make' output is shorter. -# -# Listed in the same order as the GNU makefile conventions. -# The Automake-defined pkg* macros are appended, in the order -# listed in the Automake 1.10a+ documentation. -configmake.h: Makefile - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - echo '#define PREFIX "$(prefix)"'; \ - echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ - echo '#define BINDIR "$(bindir)"'; \ - echo '#define SBINDIR "$(sbindir)"'; \ - echo '#define LIBEXECDIR "$(libexecdir)"'; \ - echo '#define DATAROOTDIR "$(datarootdir)"'; \ - echo '#define DATADIR "$(datadir)"'; \ - echo '#define SYSCONFDIR "$(sysconfdir)"'; \ - echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ - echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ - echo '#define INCLUDEDIR "$(includedir)"'; \ - echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ - echo '#define DOCDIR "$(docdir)"'; \ - echo '#define INFODIR "$(infodir)"'; \ - echo '#define HTMLDIR "$(htmldir)"'; \ - echo '#define DVIDIR "$(dvidir)"'; \ - echo '#define PDFDIR "$(pdfdir)"'; \ - echo '#define PSDIR "$(psdir)"'; \ - echo '#define LIBDIR "$(libdir)"'; \ - echo '#define LISPDIR "$(lispdir)"'; \ - echo '#define LOCALEDIR "$(localedir)"'; \ - echo '#define MANDIR "$(mandir)"'; \ - echo '#define MANEXT "$(manext)"'; \ - echo '#define PKGDATADIR "$(pkgdatadir)"'; \ - echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ - echo '#define PKGLIBDIR "$(pkglibdir)"'; \ - echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ - } | sed '/""/d' > $@-t - mv $@-t $@ -BUILT_SOURCES += configmake.h -CLEANFILES += configmake.h configmake.h-t - -## end gnulib module configmake - -## begin gnulib module dirfd - - -EXTRA_DIST += dirfd.c dirfd.h - -EXTRA_libtar_a_SOURCES += dirfd.c - -## end gnulib module dirfd - -## begin gnulib module dirname - - -EXTRA_DIST += basename.c dirname.c dirname.h stripslash.c - -EXTRA_libtar_a_SOURCES += basename.c dirname.c stripslash.c - -## end gnulib module dirname - -## begin gnulib module dup2 - - -EXTRA_DIST += dup2.c - -EXTRA_libtar_a_SOURCES += dup2.c - -## end gnulib module dup2 - -## begin gnulib module error - - -EXTRA_DIST += error.c error.h - -EXTRA_libtar_a_SOURCES += error.c - -## end gnulib module error - -## begin gnulib module exclude - - -EXTRA_DIST += exclude.c exclude.h - -EXTRA_libtar_a_SOURCES += exclude.c - -## end gnulib module exclude - -## begin gnulib module exitfail - - -EXTRA_DIST += exitfail.c exitfail.h - -EXTRA_libtar_a_SOURCES += exitfail.c - -## end gnulib module exitfail - -## begin gnulib module fchdir - -BUILT_SOURCES += $(DIRENT_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -dirent.h: dirent.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''NEXT_DIRENT_H''@|$(NEXT_DIRENT_H)|g' \ - -e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \ - < $(srcdir)/dirent.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += dirent.h dirent.h-t - -EXTRA_DIST += dirent.in.h fchdir.c - -EXTRA_libtar_a_SOURCES += fchdir.c - -## end gnulib module fchdir - -## begin gnulib module fcntl - -BUILT_SOURCES += $(FCNTL_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -fcntl.h: fcntl.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \ - < $(srcdir)/fcntl.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += fcntl.h fcntl.h-t - -EXTRA_DIST += fcntl.in.h - -## end gnulib module fcntl - -## begin gnulib module fcntl-safer - - -EXTRA_DIST += creat-safer.c fcntl--.h fcntl-safer.h open-safer.c - -EXTRA_libtar_a_SOURCES += creat-safer.c open-safer.c - -## end gnulib module fcntl-safer - -## begin gnulib module fileblocks - - -EXTRA_DIST += fileblocks.c - -EXTRA_libtar_a_SOURCES += fileblocks.c - -## end gnulib module fileblocks - -## begin gnulib module float - -BUILT_SOURCES += $(FLOAT_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -float.h: float.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ - < $(srcdir)/float.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += float.h float.h-t - -EXTRA_DIST += float.in.h - -## end gnulib module float - -## begin gnulib module fnmatch - -BUILT_SOURCES += $(FNMATCH_H) - -# We need the following in order to create when the system -# doesn't have one that supports the required API. -fnmatch.h: fnmatch.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/fnmatch.in.h; \ - } > $@-t - mv -f $@-t $@ -MOSTLYCLEANFILES += fnmatch.h fnmatch.h-t - -EXTRA_DIST += fnmatch.c fnmatch.in.h fnmatch_loop.c - -EXTRA_libtar_a_SOURCES += fnmatch.c fnmatch_loop.c - -## end gnulib module fnmatch - -## begin gnulib module fpending - - -EXTRA_DIST += fpending.c fpending.h - -EXTRA_libtar_a_SOURCES += fpending.c - -## end gnulib module fpending - -## begin gnulib module ftruncate - - -EXTRA_DIST += ftruncate.c - -EXTRA_libtar_a_SOURCES += ftruncate.c - -## end gnulib module ftruncate - -## begin gnulib module full-write - -libtar_a_SOURCES += full-write.h full-write.c - -## end gnulib module full-write - -## begin gnulib module getcwd - - -EXTRA_DIST += getcwd.c - -EXTRA_libtar_a_SOURCES += getcwd.c - -## end gnulib module getcwd - -## begin gnulib module getdate - -libtar_a_SOURCES += getdate.y -BUILT_SOURCES += getdate.c -MAINTAINERCLEANFILES += getdate.c -EXTRA_DIST += getdate.c - -EXTRA_DIST += getdate.h - -## end gnulib module getdate - -## begin gnulib module getdelim - - -EXTRA_DIST += getdelim.c - -EXTRA_libtar_a_SOURCES += getdelim.c - -## end gnulib module getdelim - -## begin gnulib module getline - - -EXTRA_DIST += getline.c - -EXTRA_libtar_a_SOURCES += getline.c - -## end gnulib module getline - -## begin gnulib module getopt - -BUILT_SOURCES += $(GETOPT_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -getopt.h: getopt.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/getopt.in.h; \ - } > $@-t - mv -f $@-t $@ -MOSTLYCLEANFILES += getopt.h getopt.h-t - -EXTRA_DIST += getopt.c getopt.in.h getopt1.c getopt_int.h - -EXTRA_libtar_a_SOURCES += getopt.c getopt1.c - -## end gnulib module getopt - -## begin gnulib module getpagesize - - -EXTRA_DIST += getpagesize.h - -## end gnulib module getpagesize - -## begin gnulib module gettext - -# This is for those projects which use "gettextize --intl" to put a source-code -# copy of libintl into their package. In such projects, every Makefile.am needs -# -I$(top_builddir)/intl, so that can be found in this directory. -# For the Makefile.ams in other directories it is the maintainer's -# responsibility; for the one from gnulib we do it here. -# This option has no effect when the user disables NLS (because then the intl -# directory contains no libintl.h file) or when the project does not use -# "gettextize --intl". -#AM_CPPFLAGS += -I$(top_builddir)/intl - -EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath - -## end gnulib module gettext - -## begin gnulib module gettext-h - -libtar_a_SOURCES += gettext.h - -## end gnulib module gettext-h - -## begin gnulib module gettime - - -EXTRA_DIST += gettime.c - -EXTRA_libtar_a_SOURCES += gettime.c - -## end gnulib module gettime - -## begin gnulib module gettimeofday - - -EXTRA_DIST += gettimeofday.c - -EXTRA_libtar_a_SOURCES += gettimeofday.c - -## end gnulib module gettimeofday - -## begin gnulib module hash - - -EXTRA_DIST += hash.c hash.h - -EXTRA_libtar_a_SOURCES += hash.c - -## end gnulib module hash - -## begin gnulib module havelib - - -EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath - -## end gnulib module havelib - -## begin gnulib module human - - -EXTRA_DIST += human.c human.h - -EXTRA_libtar_a_SOURCES += human.c - -## end gnulib module human - -## begin gnulib module intprops - - -EXTRA_DIST += intprops.h - -## end gnulib module intprops - -## begin gnulib module inttostr - - -EXTRA_DIST += imaxtostr.c inttostr.c inttostr.h offtostr.c uinttostr.c umaxtostr.c - -EXTRA_libtar_a_SOURCES += imaxtostr.c inttostr.c offtostr.c uinttostr.c umaxtostr.c - -## end gnulib module inttostr - -## begin gnulib module inttypes - -BUILT_SOURCES += $(INTTYPES_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -inttypes.h: inttypes.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_INTTYPES_H''@|$(NEXT_INTTYPES_H)|g' \ - -e 's/@''PRI_MACROS_BROKEN''@/$(PRI_MACROS_BROKEN)/g' \ - -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ - -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ - -e 's/@''PRIPTR_PREFIX''@/$(PRIPTR_PREFIX)/g' \ - -e 's/@''GNULIB_IMAXABS''@/$(GNULIB_IMAXABS)/g' \ - -e 's/@''GNULIB_IMAXDIV''@/$(GNULIB_IMAXDIV)/g' \ - -e 's/@''GNULIB_STRTOIMAX''@/$(GNULIB_STRTOIMAX)/g' \ - -e 's/@''GNULIB_STRTOUMAX''@/$(GNULIB_STRTOUMAX)/g' \ - -e 's/@''HAVE_DECL_IMAXABS''@/$(HAVE_DECL_IMAXABS)/g' \ - -e 's/@''HAVE_DECL_IMAXDIV''@/$(HAVE_DECL_IMAXDIV)/g' \ - -e 's/@''HAVE_DECL_STRTOIMAX''@/$(HAVE_DECL_STRTOIMAX)/g' \ - -e 's/@''HAVE_DECL_STRTOUMAX''@/$(HAVE_DECL_STRTOUMAX)/g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/inttypes.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += inttypes.h inttypes.h-t - -EXTRA_DIST += inttypes.in.h - -## end gnulib module inttypes - -## begin gnulib module lchown - - -EXTRA_DIST += lchown.c - -EXTRA_libtar_a_SOURCES += lchown.c - -## end gnulib module lchown - -## begin gnulib module link-warning - -LINK_WARNING_H=$(top_srcdir)/build-aux/link-warning.h - -EXTRA_DIST += $(top_srcdir)/build-aux/link-warning.h - -## end gnulib module link-warning - -## begin gnulib module localcharset - -libtar_a_SOURCES += localcharset.h localcharset.c - -# We need the following in order to install a simple file in $(libdir) -# which is shared with other installed packages. We use a list of referencing -# packages so that "make uninstall" will remove the file if and only if it -# is not used by another installed package. -# On systems with glibc-2.1 or newer, the file is redundant, therefore we -# avoid installing it. - -all-local: charset.alias ref-add.sed ref-del.sed - -charset_alias = $(DESTDIR)$(libdir)/charset.alias -charset_tmp = $(DESTDIR)$(libdir)/charset.tmp -install-exec-local: all-local - test $(GLIBC21) != no || $(mkinstalldirs) $(DESTDIR)$(libdir) - if test -f $(charset_alias); then \ - sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - else \ - if test $(GLIBC21) = no; then \ - sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - fi ; \ - fi - -uninstall-local: all-local - if test -f $(charset_alias); then \ - sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ - if grep '^# Packages using this file: $$' $(charset_tmp) \ - > /dev/null; then \ - rm -f $(charset_alias); \ - else \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ - fi; \ - rm -f $(charset_tmp); \ - fi - -charset.alias: config.charset - rm -f t-$@ $@ - $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ - mv t-$@ $@ - -SUFFIXES += .sed .sin -.sin.sed: - rm -f t-$@ $@ - sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ - mv t-$@ $@ - -CLEANFILES += charset.alias ref-add.sed ref-del.sed - -EXTRA_DIST += config.charset ref-add.sin ref-del.sin - -## end gnulib module localcharset - -## begin gnulib module lstat - - -EXTRA_DIST += lstat.c lstat.h - -EXTRA_libtar_a_SOURCES += lstat.c - -## end gnulib module lstat - -## begin gnulib module malloc - - -EXTRA_DIST += malloc.c - -EXTRA_libtar_a_SOURCES += malloc.c - -## end gnulib module malloc - -## begin gnulib module malloc-posix - - -EXTRA_DIST += malloc.c - -EXTRA_libtar_a_SOURCES += malloc.c - -## end gnulib module malloc-posix - -## begin gnulib module malloca - -libtar_a_SOURCES += malloca.c - -EXTRA_DIST += malloca.h malloca.valgrind - -## end gnulib module malloca - -## begin gnulib module mbchar - -libtar_a_SOURCES += mbchar.c - -EXTRA_DIST += mbchar.h - -## end gnulib module mbchar - -## begin gnulib module mbscasecmp - -libtar_a_SOURCES += mbscasecmp.c - -## end gnulib module mbscasecmp - -## begin gnulib module mbuiter - -libtar_a_SOURCES += mbuiter.h - -## end gnulib module mbuiter - -## begin gnulib module memchr - - -EXTRA_DIST += memchr.c - -EXTRA_libtar_a_SOURCES += memchr.c - -## end gnulib module memchr - -## begin gnulib module mempcpy - - -EXTRA_DIST += mempcpy.c - -EXTRA_libtar_a_SOURCES += mempcpy.c - -## end gnulib module mempcpy - -## begin gnulib module memrchr - - -EXTRA_DIST += memrchr.c - -EXTRA_libtar_a_SOURCES += memrchr.c - -## end gnulib module memrchr - -## begin gnulib module memset - - -EXTRA_DIST += memset.c - -EXTRA_libtar_a_SOURCES += memset.c - -## end gnulib module memset - -## begin gnulib module mkdtemp - - -EXTRA_DIST += mkdtemp.c - -EXTRA_libtar_a_SOURCES += mkdtemp.c - -## end gnulib module mkdtemp - -## begin gnulib module mktime - - -EXTRA_DIST += mktime.c - -EXTRA_libtar_a_SOURCES += mktime.c - -## end gnulib module mktime - -## begin gnulib module modechange - - -EXTRA_DIST += modechange.c modechange.h - -EXTRA_libtar_a_SOURCES += modechange.c - -## end gnulib module modechange - -## begin gnulib module obstack - - -EXTRA_DIST += obstack.c obstack.h - -EXTRA_libtar_a_SOURCES += obstack.c - -## end gnulib module obstack - -## begin gnulib module openat - - -EXTRA_DIST += at-func.c fchmodat.c fchownat.c fstatat.c mkdirat.c openat-priv.h openat-proc.c openat.c openat.h - -EXTRA_libtar_a_SOURCES += at-func.c fchmodat.c fchownat.c fstatat.c mkdirat.c openat-proc.c openat.c - -## end gnulib module openat - -## begin gnulib module openat-die - -libtar_a_SOURCES += openat-die.c - -## end gnulib module openat-die - -## begin gnulib module pathmax - - -EXTRA_DIST += pathmax.h - -## end gnulib module pathmax - -## begin gnulib module quote - - -EXTRA_DIST += quote.c quote.h - -EXTRA_libtar_a_SOURCES += quote.c - -## end gnulib module quote - -## begin gnulib module quotearg - - -EXTRA_DIST += quotearg.c quotearg.h - -EXTRA_libtar_a_SOURCES += quotearg.c - -## end gnulib module quotearg - -## begin gnulib module readlink - - -EXTRA_DIST += readlink.c - -EXTRA_libtar_a_SOURCES += readlink.c - -## end gnulib module readlink - -## begin gnulib module realloc-posix - - -EXTRA_DIST += realloc.c - -EXTRA_libtar_a_SOURCES += realloc.c - -## end gnulib module realloc-posix - -## begin gnulib module regex - - -EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c - -EXTRA_libtar_a_SOURCES += regcomp.c regex.c regex_internal.c regexec.c - -## end gnulib module regex - -## begin gnulib module rmdir - - -EXTRA_DIST += rmdir.c - -EXTRA_libtar_a_SOURCES += rmdir.c - -## end gnulib module rmdir - -## begin gnulib module rpmatch - - -EXTRA_DIST += rpmatch.c - -EXTRA_libtar_a_SOURCES += rpmatch.c - -## end gnulib module rpmatch - -## begin gnulib module safe-read - - -EXTRA_DIST += safe-read.c safe-read.h - -EXTRA_libtar_a_SOURCES += safe-read.c - -## end gnulib module safe-read - -## begin gnulib module safe-write - - -EXTRA_DIST += safe-write.c safe-write.h - -EXTRA_libtar_a_SOURCES += safe-write.c - -## end gnulib module safe-write - -## begin gnulib module same-inode - - -EXTRA_DIST += same-inode.h - -## end gnulib module same-inode - -## begin gnulib module save-cwd - - -EXTRA_DIST += save-cwd.c save-cwd.h - -EXTRA_libtar_a_SOURCES += save-cwd.c - -## end gnulib module save-cwd - -## begin gnulib module savedir - - -EXTRA_DIST += savedir.c savedir.h - -EXTRA_libtar_a_SOURCES += savedir.c - -## end gnulib module savedir - -## begin gnulib module setenv - - -EXTRA_DIST += setenv.c setenv.h unsetenv.c - -EXTRA_libtar_a_SOURCES += setenv.c unsetenv.c - -## end gnulib module setenv - -## begin gnulib module sleep - - -EXTRA_DIST += sleep.c - -EXTRA_libtar_a_SOURCES += sleep.c - -## end gnulib module sleep - -## begin gnulib module stat-macros - - -EXTRA_DIST += stat-macros.h - -## end gnulib module stat-macros - -## begin gnulib module stat-time - - -EXTRA_DIST += stat-time.h - -## end gnulib module stat-time - -## begin gnulib module stdbool - -BUILT_SOURCES += $(STDBOOL_H) - -# We need the following in order to create when the system -# doesn't have one that works. -stdbool.h: stdbool.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += stdbool.h stdbool.h-t - -EXTRA_DIST += stdbool.in.h - -## end gnulib module stdbool - -## begin gnulib module stdint - -BUILT_SOURCES += $(STDINT_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdint.h: stdint.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ - -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ - -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ - -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ - -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ - -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ - -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ - -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ - -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ - -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ - -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ - -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ - -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ - -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ - < $(srcdir)/stdint.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += stdint.h stdint.h-t - -EXTRA_DIST += stdint.in.h - -## end gnulib module stdint - -## begin gnulib module stdio - -BUILT_SOURCES += stdio.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdio.h: stdio.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ - -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ - -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ - -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ - -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ - -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ - -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ - -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ - -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ - -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ - -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ - -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \ - -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \ - -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ - -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ - -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ - -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ - -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ - -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ - -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ - -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ - -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ - -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ - -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ - -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ - -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ - -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ - -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ - -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ - -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ - -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \ - -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ - -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/stdio.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += stdio.h stdio.h-t - -EXTRA_DIST += stdio.in.h - -## end gnulib module stdio - -## begin gnulib module stdlib - -BUILT_SOURCES += stdlib.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdlib.h: stdlib.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ - -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ - -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \ - -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \ - -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ - -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ - -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ - -e 's|@''HAVE_CALLOC_POSIX''@|$(HAVE_CALLOC_POSIX)|g' \ - -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ - -e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \ - -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ - -e 's|@''HAVE_REALLOC_POSIX''@|$(HAVE_REALLOC_POSIX)|g' \ - -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/stdlib.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += stdlib.h stdlib.h-t - -EXTRA_DIST += stdlib.in.h - -## end gnulib module stdlib - -## begin gnulib module stpcpy - - -EXTRA_DIST += stpcpy.c - -EXTRA_libtar_a_SOURCES += stpcpy.c - -## end gnulib module stpcpy - -## begin gnulib module strcase - - -EXTRA_DIST += strcasecmp.c strncasecmp.c - -EXTRA_libtar_a_SOURCES += strcasecmp.c strncasecmp.c - -## end gnulib module strcase - -## begin gnulib module strchrnul - - -EXTRA_DIST += strchrnul.c - -EXTRA_libtar_a_SOURCES += strchrnul.c - -## end gnulib module strchrnul - -## begin gnulib module strdup - - -EXTRA_DIST += strdup.c - -EXTRA_libtar_a_SOURCES += strdup.c - -## end gnulib module strdup - -## begin gnulib module streq - - -EXTRA_DIST += streq.h - -## end gnulib module streq - -## begin gnulib module strerror - - -EXTRA_DIST += strerror.c - -EXTRA_libtar_a_SOURCES += strerror.c - -## end gnulib module strerror - -## begin gnulib module string - -BUILT_SOURCES += string.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -string.h: string.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ - -e 's|@''GNULIB_MBSLEN''@|$(GNULIB_MBSLEN)|g' \ - -e 's|@''GNULIB_MBSNLEN''@|$(GNULIB_MBSNLEN)|g' \ - -e 's|@''GNULIB_MBSCHR''@|$(GNULIB_MBSCHR)|g' \ - -e 's|@''GNULIB_MBSRCHR''@|$(GNULIB_MBSRCHR)|g' \ - -e 's|@''GNULIB_MBSSTR''@|$(GNULIB_MBSSTR)|g' \ - -e 's|@''GNULIB_MBSCASECMP''@|$(GNULIB_MBSCASECMP)|g' \ - -e 's|@''GNULIB_MBSNCASECMP''@|$(GNULIB_MBSNCASECMP)|g' \ - -e 's|@''GNULIB_MBSPCASECMP''@|$(GNULIB_MBSPCASECMP)|g' \ - -e 's|@''GNULIB_MBSCASESTR''@|$(GNULIB_MBSCASESTR)|g' \ - -e 's|@''GNULIB_MBSCSPN''@|$(GNULIB_MBSCSPN)|g' \ - -e 's|@''GNULIB_MBSPBRK''@|$(GNULIB_MBSPBRK)|g' \ - -e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \ - -e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \ - -e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \ - -e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \ - -e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \ - -e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \ - -e 's|@''GNULIB_STPCPY''@|$(GNULIB_STPCPY)|g' \ - -e 's|@''GNULIB_STPNCPY''@|$(GNULIB_STPNCPY)|g' \ - -e 's|@''GNULIB_STRCHRNUL''@|$(GNULIB_STRCHRNUL)|g' \ - -e 's|@''GNULIB_STRDUP''@|$(GNULIB_STRDUP)|g' \ - -e 's|@''GNULIB_STRNDUP''@|$(GNULIB_STRNDUP)|g' \ - -e 's|@''GNULIB_STRNLEN''@|$(GNULIB_STRNLEN)|g' \ - -e 's|@''GNULIB_STRPBRK''@|$(GNULIB_STRPBRK)|g' \ - -e 's|@''GNULIB_STRSEP''@|$(GNULIB_STRSEP)|g' \ - -e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \ - -e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \ - -e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \ - -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ - -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ - -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ - -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \ - -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ - -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ - -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ - -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ - -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ - -e 's|@''HAVE_STRNDUP''@|$(HAVE_STRNDUP)|g' \ - -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ - -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ - -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ - -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ - -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ - -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ - -e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \ - -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/string.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += string.h string.h-t - -EXTRA_DIST += string.in.h - -## end gnulib module string - -## begin gnulib module strndup - - -EXTRA_DIST += strndup.c - -EXTRA_libtar_a_SOURCES += strndup.c - -## end gnulib module strndup - -## begin gnulib module strnlen - - -EXTRA_DIST += strnlen.c - -EXTRA_libtar_a_SOURCES += strnlen.c - -## end gnulib module strnlen - -## begin gnulib module strnlen1 - -libtar_a_SOURCES += strnlen1.h strnlen1.c - -## end gnulib module strnlen1 - -## begin gnulib module strtoimax - - -EXTRA_DIST += strtoimax.c - -EXTRA_libtar_a_SOURCES += strtoimax.c - -## end gnulib module strtoimax - -## begin gnulib module strtol - - -EXTRA_DIST += strtol.c - -EXTRA_libtar_a_SOURCES += strtol.c - -## end gnulib module strtol - -## begin gnulib module strtoll - - -EXTRA_DIST += strtoll.c - -EXTRA_libtar_a_SOURCES += strtoll.c - -## end gnulib module strtoll - -## begin gnulib module strtoul - - -EXTRA_DIST += strtoul.c - -EXTRA_libtar_a_SOURCES += strtoul.c - -## end gnulib module strtoul - -## begin gnulib module strtoull - - -EXTRA_DIST += strtoull.c - -EXTRA_libtar_a_SOURCES += strtoull.c - -## end gnulib module strtoull - -## begin gnulib module strtoumax - - -EXTRA_DIST += strtoumax.c - -EXTRA_libtar_a_SOURCES += strtoumax.c - -## end gnulib module strtoumax - -## begin gnulib module sys_stat - -BUILT_SOURCES += $(SYS_STAT_H) - -# We need the following in order to create when the system -# has one that is incomplete. -sys/stat.h: sys_stat.in.h - @MKDIR_P@ sys - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \ - -e 's|@''HAVE_IO_H''@|$(HAVE_IO_H)|g' \ - -e 's|@''HAVE_LSTAT''@|$(HAVE_LSTAT)|g' \ - -e 's|@''HAVE_DECL_MKDIR''@|$(HAVE_DECL_MKDIR)|g' \ - < $(srcdir)/sys_stat.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += sys/stat.h sys/stat.h-t -MOSTLYCLEANDIRS += sys - -EXTRA_DIST += sys_stat.in.h - -## end gnulib module sys_stat - -## begin gnulib module sys_time - -BUILT_SOURCES += $(SYS_TIME_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -sys/time.h: sys_time.in.h - @MKDIR_P@ sys - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_SYS_TIME_H''@/$(HAVE_SYS_TIME_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_SYS_TIME_H''@|$(NEXT_SYS_TIME_H)|g' \ - -e 's/@''REPLACE_GETTIMEOFDAY''@/$(REPLACE_GETTIMEOFDAY)/g' \ - -e 's/@''HAVE_STRUCT_TIMEVAL''@/$(HAVE_STRUCT_TIMEVAL)/g' \ - < $(srcdir)/sys_time.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += sys/time.h sys/time.h-t - -EXTRA_DIST += sys_time.in.h - -## end gnulib module sys_time - -## begin gnulib module sysexits - -BUILT_SOURCES += $(SYSEXITS_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -sysexits.h: sysexits.in.h - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_H)|g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \ - < $(srcdir)/sysexits.in.h; \ - } > $@-t - mv -f $@-t $@ -MOSTLYCLEANFILES += sysexits.h sysexits.h-t - -EXTRA_DIST += sysexits.in.h - -## end gnulib module sysexits - -## begin gnulib module tempname - - -EXTRA_DIST += tempname.c tempname.h - -EXTRA_libtar_a_SOURCES += tempname.c - -## end gnulib module tempname - -## begin gnulib module time - -BUILT_SOURCES += time.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -time.h: time.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@NEXT_TIME_H''@|$(NEXT_TIME_H)|g' \ - -e 's|@REPLACE_LOCALTIME_R''@|$(REPLACE_LOCALTIME_R)|g' \ - -e 's|@REPLACE_NANOSLEEP''@|$(REPLACE_NANOSLEEP)|g' \ - -e 's|@REPLACE_STRPTIME''@|$(REPLACE_STRPTIME)|g' \ - -e 's|@REPLACE_TIMEGM''@|$(REPLACE_TIMEGM)|g' \ - -e 's|@SYS_TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(SYS_TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ - -e 's|@TIME_H_DEFINES_STRUCT_TIMESPEC''@|$(TIME_H_DEFINES_STRUCT_TIMESPEC)|g' \ - < $(srcdir)/time.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += time.h time.h-t - -EXTRA_DIST += time.in.h - -## end gnulib module time - -## begin gnulib module time_r - - -EXTRA_DIST += time_r.c - -EXTRA_libtar_a_SOURCES += time_r.c - -## end gnulib module time_r - -## begin gnulib module timespec - - -EXTRA_DIST += timespec.h - -## end gnulib module timespec - -## begin gnulib module unistd - -BUILT_SOURCES += unistd.h - -# We need the following in order to create an empty placeholder for -# when the system doesn't have one. -unistd.h: unistd.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ - -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \ - -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \ - -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \ - -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \ - -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \ - -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \ - -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ - -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ - -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ - -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ - -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ - -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ - -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ - -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ - -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \ - -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ - -e 's|@''REPLACE_FCHDIR''@|$(REPLACE_FCHDIR)|g' \ - -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ - -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ - -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ - < $(srcdir)/unistd.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += unistd.h unistd.h-t - -EXTRA_DIST += unistd.in.h - -## end gnulib module unistd - -## begin gnulib module unistd-safer - - -EXTRA_DIST += dup-safer.c fd-safer.c pipe-safer.c unistd--.h unistd-safer.h - -EXTRA_libtar_a_SOURCES += dup-safer.c fd-safer.c pipe-safer.c - -## end gnulib module unistd-safer - -## begin gnulib module unitypes - - -EXTRA_DIST += unitypes.h - -## end gnulib module unitypes - -## begin gnulib module uniwidth/base - - -EXTRA_DIST += localcharset.h uniwidth.h - -## end gnulib module uniwidth/base - -## begin gnulib module uniwidth/width - -libtar_a_SOURCES += uniwidth/width.c - -EXTRA_DIST += uniwidth/cjk.h - -## end gnulib module uniwidth/width - -## begin gnulib module unlinkdir - - -EXTRA_DIST += unlinkdir.c unlinkdir.h - -EXTRA_libtar_a_SOURCES += unlinkdir.c - -## end gnulib module unlinkdir - -## begin gnulib module unlocked-io - - -EXTRA_DIST += unlocked-io.h - -## end gnulib module unlocked-io - -## begin gnulib module utime - - -EXTRA_DIST += utime.c - -EXTRA_libtar_a_SOURCES += utime.c - -## end gnulib module utime - -## begin gnulib module utimens - - -EXTRA_DIST += utimens.c utimens.h - -EXTRA_libtar_a_SOURCES += utimens.c - -## end gnulib module utimens - -## begin gnulib module vasnprintf - - -EXTRA_DIST += asnprintf.c float+.h printf-args.c printf-args.h printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h - -EXTRA_libtar_a_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c - -## end gnulib module vasnprintf - -## begin gnulib module verify - -libtar_a_SOURCES += verify.h - -## end gnulib module verify - -## begin gnulib module version-etc - -libtar_a_SOURCES += version-etc.h version-etc.c - -## end gnulib module version-etc - -## begin gnulib module version-etc-fsf - -libtar_a_SOURCES += version-etc-fsf.c - -## end gnulib module version-etc-fsf - -## begin gnulib module vsnprintf - - -EXTRA_DIST += vsnprintf.c - -EXTRA_libtar_a_SOURCES += vsnprintf.c - -## end gnulib module vsnprintf - -## begin gnulib module wchar - -BUILT_SOURCES += $(WCHAR_H) - -# We need the following in order to create when the system -# version does not work standalone. -wchar.h: wchar.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ - -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ - -e 's|@''GNULIB_WCWIDTH''@|$(GNULIB_WCWIDTH)|g' \ - -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ - -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ - -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ - < $(srcdir)/wchar.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += wchar.h wchar.h-t - -EXTRA_DIST += wchar.in.h - -## end gnulib module wchar - -## begin gnulib module wctype - -BUILT_SOURCES += $(WCTYPE_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -wctype.h: wctype.in.h - rm -f $@-t $@ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ - -e 's/@''INCLUDE_NEXT''@/$(INCLUDE_NEXT)/g' \ - -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ - -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ - -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ - < $(srcdir)/wctype.in.h; \ - } > $@-t - mv $@-t $@ -MOSTLYCLEANFILES += wctype.h wctype.h-t - -EXTRA_DIST += wctype.in.h - -## end gnulib module wctype - -## begin gnulib module wcwidth - - -EXTRA_DIST += wcwidth.c - -EXTRA_libtar_a_SOURCES += wcwidth.c - -## end gnulib module wcwidth - -## begin gnulib module xalloc - - -EXTRA_DIST += xalloc.h xmalloc.c - -EXTRA_libtar_a_SOURCES += xmalloc.c - -## end gnulib module xalloc - -## begin gnulib module xalloc-die - -libtar_a_SOURCES += xalloc-die.c - -## end gnulib module xalloc-die - -## begin gnulib module xgetcwd - - -EXTRA_DIST += xgetcwd.c xgetcwd.h - -EXTRA_libtar_a_SOURCES += xgetcwd.c - -## end gnulib module xgetcwd - -## begin gnulib module xsize - -libtar_a_SOURCES += xsize.h - -## end gnulib module xsize - -## begin gnulib module xstrndup - -libtar_a_SOURCES += xstrndup.h xstrndup.c - -## end gnulib module xstrndup - -## begin gnulib module xstrtol - - -EXTRA_DIST += xstrtol-error.c xstrtol.c xstrtol.h xstrtoul.c - -EXTRA_libtar_a_SOURCES += xstrtol-error.c xstrtol.c xstrtoul.c - -## end gnulib module xstrtol - -## begin gnulib module xstrtoumax - -libtar_a_SOURCES += xstrtoumax.c - -## end gnulib module xstrtoumax - - -mostlyclean-local: mostlyclean-generic - @for dir in '' $(MOSTLYCLEANDIRS); do \ - if test -n "$$dir" && test -d $$dir; then \ - echo "rmdir $$dir"; rmdir $$dir; \ - fi; \ - done; \ - : diff --git a/src/bin/tar/lib/hash.c b/src/bin/tar/lib/hash.c deleted file mode 100644 index f0f481b328..0000000000 --- a/src/bin/tar/lib/hash.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* hash - hashing table processing. - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007 Free - Software Foundation, Inc. - - Written by Jim Meyering, 1992. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* A generic hash table package. */ - -/* Define USE_OBSTACK to 1 if you want the allocator to use obstacks instead - of malloc. If you change USE_OBSTACK, you have to recompile! */ - -#include - -#include "hash.h" -#include "xalloc.h" - -#include -#include -#include - -#if USE_OBSTACK -# include "obstack.h" -# ifndef obstack_chunk_alloc -# define obstack_chunk_alloc malloc -# endif -# ifndef obstack_chunk_free -# define obstack_chunk_free free -# endif -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -struct hash_table - { - /* The array of buckets starts at BUCKET and extends to BUCKET_LIMIT-1, - for a possibility of N_BUCKETS. Among those, N_BUCKETS_USED buckets - are not empty, there are N_ENTRIES active entries in the table. */ - struct hash_entry *bucket; - struct hash_entry const *bucket_limit; - size_t n_buckets; - size_t n_buckets_used; - size_t n_entries; - - /* Tuning arguments, kept in a physicaly separate structure. */ - const Hash_tuning *tuning; - - /* Three functions are given to `hash_initialize', see the documentation - block for this function. In a word, HASHER randomizes a user entry - into a number up from 0 up to some maximum minus 1; COMPARATOR returns - true if two user entries compare equally; and DATA_FREER is the cleanup - function for a user entry. */ - Hash_hasher hasher; - Hash_comparator comparator; - Hash_data_freer data_freer; - - /* A linked list of freed struct hash_entry structs. */ - struct hash_entry *free_entry_list; - -#if USE_OBSTACK - /* Whenever obstacks are used, it is possible to allocate all overflowed - entries into a single stack, so they all can be freed in a single - operation. It is not clear if the speedup is worth the trouble. */ - struct obstack entry_stack; -#endif - }; - -/* A hash table contains many internal entries, each holding a pointer to - some user provided data (also called a user entry). An entry indistinctly - refers to both the internal entry and its associated user entry. A user - entry contents may be hashed by a randomization function (the hashing - function, or just `hasher' for short) into a number (or `slot') between 0 - and the current table size. At each slot position in the hash table, - starts a linked chain of entries for which the user data all hash to this - slot. A bucket is the collection of all entries hashing to the same slot. - - A good `hasher' function will distribute entries rather evenly in buckets. - In the ideal case, the length of each bucket is roughly the number of - entries divided by the table size. Finding the slot for a data is usually - done in constant time by the `hasher', and the later finding of a precise - entry is linear in time with the size of the bucket. Consequently, a - larger hash table size (that is, a larger number of buckets) is prone to - yielding shorter chains, *given* the `hasher' function behaves properly. - - Long buckets slow down the lookup algorithm. One might use big hash table - sizes in hope to reduce the average length of buckets, but this might - become inordinate, as unused slots in the hash table take some space. The - best bet is to make sure you are using a good `hasher' function (beware - that those are not that easy to write! :-), and to use a table size - larger than the actual number of entries. */ - -/* If an insertion makes the ratio of nonempty buckets to table size larger - than the growth threshold (a number between 0.0 and 1.0), then increase - the table size by multiplying by the growth factor (a number greater than - 1.0). The growth threshold defaults to 0.8, and the growth factor - defaults to 1.414, meaning that the table will have doubled its size - every second time 80% of the buckets get used. */ -#define DEFAULT_GROWTH_THRESHOLD 0.8 -#define DEFAULT_GROWTH_FACTOR 1.414 - -/* If a deletion empties a bucket and causes the ratio of used buckets to - table size to become smaller than the shrink threshold (a number between - 0.0 and 1.0), then shrink the table by multiplying by the shrink factor (a - number greater than the shrink threshold but smaller than 1.0). The shrink - threshold and factor default to 0.0 and 1.0, meaning that the table never - shrinks. */ -#define DEFAULT_SHRINK_THRESHOLD 0.0 -#define DEFAULT_SHRINK_FACTOR 1.0 - -/* Use this to initialize or reset a TUNING structure to - some sensible values. */ -static const Hash_tuning default_tuning = - { - DEFAULT_SHRINK_THRESHOLD, - DEFAULT_SHRINK_FACTOR, - DEFAULT_GROWTH_THRESHOLD, - DEFAULT_GROWTH_FACTOR, - false - }; - -/* Information and lookup. */ - -/* The following few functions provide information about the overall hash - table organization: the number of entries, number of buckets and maximum - length of buckets. */ - -/* Return the number of buckets in the hash table. The table size, the total - number of buckets (used plus unused), or the maximum number of slots, are - the same quantity. */ - -size_t -hash_get_n_buckets (const Hash_table *table) -{ - return table->n_buckets; -} - -/* Return the number of slots in use (non-empty buckets). */ - -size_t -hash_get_n_buckets_used (const Hash_table *table) -{ - return table->n_buckets_used; -} - -/* Return the number of active entries. */ - -size_t -hash_get_n_entries (const Hash_table *table) -{ - return table->n_entries; -} - -/* Return the length of the longest chain (bucket). */ - -size_t -hash_get_max_bucket_length (const Hash_table *table) -{ - struct hash_entry const *bucket; - size_t max_bucket_length = 0; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - struct hash_entry const *cursor = bucket; - size_t bucket_length = 1; - - while (cursor = cursor->next, cursor) - bucket_length++; - - if (bucket_length > max_bucket_length) - max_bucket_length = bucket_length; - } - } - - return max_bucket_length; -} - -/* Do a mild validation of a hash table, by traversing it and checking two - statistics. */ - -bool -hash_table_ok (const Hash_table *table) -{ - struct hash_entry const *bucket; - size_t n_buckets_used = 0; - size_t n_entries = 0; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - struct hash_entry const *cursor = bucket; - - /* Count bucket head. */ - n_buckets_used++; - n_entries++; - - /* Count bucket overflow. */ - while (cursor = cursor->next, cursor) - n_entries++; - } - } - - if (n_buckets_used == table->n_buckets_used && n_entries == table->n_entries) - return true; - - return false; -} - -void -hash_print_statistics (const Hash_table *table, FILE *stream) -{ - size_t n_entries = hash_get_n_entries (table); - size_t n_buckets = hash_get_n_buckets (table); - size_t n_buckets_used = hash_get_n_buckets_used (table); - size_t max_bucket_length = hash_get_max_bucket_length (table); - - fprintf (stream, "# entries: %lu\n", (unsigned long int) n_entries); - fprintf (stream, "# buckets: %lu\n", (unsigned long int) n_buckets); - fprintf (stream, "# buckets used: %lu (%.2f%%)\n", - (unsigned long int) n_buckets_used, - (100.0 * n_buckets_used) / n_buckets); - fprintf (stream, "max bucket length: %lu\n", - (unsigned long int) max_bucket_length); -} - -/* If ENTRY matches an entry already in the hash table, return the - entry from the table. Otherwise, return NULL. */ - -void * -hash_lookup (const Hash_table *table, const void *entry) -{ - struct hash_entry const *bucket - = table->bucket + table->hasher (entry, table->n_buckets); - struct hash_entry const *cursor; - - if (! (bucket < table->bucket_limit)) - abort (); - - if (bucket->data == NULL) - return NULL; - - for (cursor = bucket; cursor; cursor = cursor->next) - if (table->comparator (entry, cursor->data)) - return cursor->data; - - return NULL; -} - -/* Walking. */ - -/* The functions in this page traverse the hash table and process the - contained entries. For the traversal to work properly, the hash table - should not be resized nor modified while any particular entry is being - processed. In particular, entries should not be added or removed. */ - -/* Return the first data in the table, or NULL if the table is empty. */ - -void * -hash_get_first (const Hash_table *table) -{ - struct hash_entry const *bucket; - - if (table->n_entries == 0) - return NULL; - - for (bucket = table->bucket; ; bucket++) - if (! (bucket < table->bucket_limit)) - abort (); - else if (bucket->data) - return bucket->data; -} - -/* Return the user data for the entry following ENTRY, where ENTRY has been - returned by a previous call to either `hash_get_first' or `hash_get_next'. - Return NULL if there are no more entries. */ - -void * -hash_get_next (const Hash_table *table, const void *entry) -{ - struct hash_entry const *bucket - = table->bucket + table->hasher (entry, table->n_buckets); - struct hash_entry const *cursor; - - if (! (bucket < table->bucket_limit)) - abort (); - - /* Find next entry in the same bucket. */ - for (cursor = bucket; cursor; cursor = cursor->next) - if (cursor->data == entry && cursor->next) - return cursor->next->data; - - /* Find first entry in any subsequent bucket. */ - while (++bucket < table->bucket_limit) - if (bucket->data) - return bucket->data; - - /* None found. */ - return NULL; -} - -/* Fill BUFFER with pointers to active user entries in the hash table, then - return the number of pointers copied. Do not copy more than BUFFER_SIZE - pointers. */ - -size_t -hash_get_entries (const Hash_table *table, void **buffer, - size_t buffer_size) -{ - size_t counter = 0; - struct hash_entry const *bucket; - struct hash_entry const *cursor; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - for (cursor = bucket; cursor; cursor = cursor->next) - { - if (counter >= buffer_size) - return counter; - buffer[counter++] = cursor->data; - } - } - } - - return counter; -} - -/* Call a PROCESSOR function for each entry of a hash table, and return the - number of entries for which the processor function returned success. A - pointer to some PROCESSOR_DATA which will be made available to each call to - the processor function. The PROCESSOR accepts two arguments: the first is - the user entry being walked into, the second is the value of PROCESSOR_DATA - as received. The walking continue for as long as the PROCESSOR function - returns nonzero. When it returns zero, the walking is interrupted. */ - -size_t -hash_do_for_each (const Hash_table *table, Hash_processor processor, - void *processor_data) -{ - size_t counter = 0; - struct hash_entry const *bucket; - struct hash_entry const *cursor; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - for (cursor = bucket; cursor; cursor = cursor->next) - { - if (!(*processor) (cursor->data, processor_data)) - return counter; - counter++; - } - } - } - - return counter; -} - -/* Allocation and clean-up. */ - -/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1. - This is a convenience routine for constructing other hashing functions. */ - -#if USE_DIFF_HASH - -/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see - B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm, - Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash - algorithms tend to be domain-specific, so what's good for [diffutils'] io.c - may not be good for your application." */ - -size_t -hash_string (const char *string, size_t n_buckets) -{ -# define ROTATE_LEFT(Value, Shift) \ - ((Value) << (Shift) | (Value) >> ((sizeof (size_t) * CHAR_BIT) - (Shift))) -# define HASH_ONE_CHAR(Value, Byte) \ - ((Byte) + ROTATE_LEFT (Value, 7)) - - size_t value = 0; - unsigned char ch; - - for (; (ch = *string); string++) - value = HASH_ONE_CHAR (value, ch); - return value % n_buckets; - -# undef ROTATE_LEFT -# undef HASH_ONE_CHAR -} - -#else /* not USE_DIFF_HASH */ - -/* This one comes from `recode', and performs a bit better than the above as - per a few experiments. It is inspired from a hashing routine found in the - very old Cyber `snoop', itself written in typical Greg Mansfield style. - (By the way, what happened to this excellent man? Is he still alive?) */ - -size_t -hash_string (const char *string, size_t n_buckets) -{ - size_t value = 0; - unsigned char ch; - - for (; (ch = *string); string++) - value = (value * 31 + ch) % n_buckets; - return value; -} - -#endif /* not USE_DIFF_HASH */ - -/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd - number at least equal to 11. */ - -static bool -is_prime (size_t candidate) -{ - size_t divisor = 3; - size_t square = divisor * divisor; - - while (square < candidate && (candidate % divisor)) - { - divisor++; - square += 4 * divisor; - divisor++; - } - - return (candidate % divisor ? true : false); -} - -/* Round a given CANDIDATE number up to the nearest prime, and return that - prime. Primes lower than 10 are merely skipped. */ - -static size_t -next_prime (size_t candidate) -{ - /* Skip small primes. */ - if (candidate < 10) - candidate = 10; - - /* Make it definitely odd. */ - candidate |= 1; - - while (!is_prime (candidate)) - candidate += 2; - - return candidate; -} - -void -hash_reset_tuning (Hash_tuning *tuning) -{ - *tuning = default_tuning; -} - -/* For the given hash TABLE, check the user supplied tuning structure for - reasonable values, and return true if there is no gross error with it. - Otherwise, definitively reset the TUNING field to some acceptable default - in the hash table (that is, the user loses the right of further modifying - tuning arguments), and return false. */ - -static bool -check_tuning (Hash_table *table) -{ - const Hash_tuning *tuning = table->tuning; - - /* Be a bit stricter than mathematics would require, so that - rounding errors in size calculations do not cause allocations to - fail to grow or shrink as they should. The smallest allocation - is 11 (due to next_prime's algorithm), so an epsilon of 0.1 - should be good enough. */ - float epsilon = 0.1f; - - if (epsilon < tuning->growth_threshold - && tuning->growth_threshold < 1 - epsilon - && 1 + epsilon < tuning->growth_factor - && 0 <= tuning->shrink_threshold - && tuning->shrink_threshold + epsilon < tuning->shrink_factor - && tuning->shrink_factor <= 1 - && tuning->shrink_threshold + epsilon < tuning->growth_threshold) - return true; - - table->tuning = &default_tuning; - return false; -} - -/* Allocate and return a new hash table, or NULL upon failure. The initial - number of buckets is automatically selected so as to _guarantee_ that you - may insert at least CANDIDATE different user entries before any growth of - the hash table size occurs. So, if have a reasonably tight a-priori upper - bound on the number of entries you intend to insert in the hash table, you - may save some table memory and insertion time, by specifying it here. If - the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE - argument has its meaning changed to the wanted number of buckets. - - TUNING points to a structure of user-supplied values, in case some fine - tuning is wanted over the default behavior of the hasher. If TUNING is - NULL, the default tuning parameters are used instead. - - The user-supplied HASHER function should be provided. It accepts two - arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a - slot number for that entry which should be in the range 0..TABLE_SIZE-1. - This slot number is then returned. - - The user-supplied COMPARATOR function should be provided. It accepts two - arguments pointing to user data, it then returns true for a pair of entries - that compare equal, or false otherwise. This function is internally called - on entries which are already known to hash to the same bucket index. - - The user-supplied DATA_FREER function, when not NULL, may be later called - with the user data as an argument, just before the entry containing the - data gets freed. This happens from within `hash_free' or `hash_clear'. - You should specify this function only if you want these functions to free - all of your `data' data. This is typically the case when your data is - simply an auxiliary struct that you have malloc'd to aggregate several - values. */ - -Hash_table * -hash_initialize (size_t candidate, const Hash_tuning *tuning, - Hash_hasher hasher, Hash_comparator comparator, - Hash_data_freer data_freer) -{ - Hash_table *table; - - if (hasher == NULL || comparator == NULL) - return NULL; - - table = malloc (sizeof *table); - if (table == NULL) - return NULL; - - if (!tuning) - tuning = &default_tuning; - table->tuning = tuning; - if (!check_tuning (table)) - { - /* Fail if the tuning options are invalid. This is the only occasion - when the user gets some feedback about it. Once the table is created, - if the user provides invalid tuning options, we silently revert to - using the defaults, and ignore further request to change the tuning - options. */ - goto fail; - } - - if (!tuning->is_n_buckets) - { - float new_candidate = candidate / tuning->growth_threshold; - if (SIZE_MAX <= new_candidate) - goto fail; - candidate = new_candidate; - } - - if (xalloc_oversized (candidate, sizeof *table->bucket)) - goto fail; - table->n_buckets = next_prime (candidate); - if (xalloc_oversized (table->n_buckets, sizeof *table->bucket)) - goto fail; - - table->bucket = calloc (table->n_buckets, sizeof *table->bucket); - if (table->bucket == NULL) - goto fail; - table->bucket_limit = table->bucket + table->n_buckets; - table->n_buckets_used = 0; - table->n_entries = 0; - - table->hasher = hasher; - table->comparator = comparator; - table->data_freer = data_freer; - - table->free_entry_list = NULL; -#if USE_OBSTACK - obstack_init (&table->entry_stack); -#endif - return table; - - fail: - free (table); - return NULL; -} - -/* Make all buckets empty, placing any chained entries on the free list. - Apply the user-specified function data_freer (if any) to the datas of any - affected entries. */ - -void -hash_clear (Hash_table *table) -{ - struct hash_entry *bucket; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - struct hash_entry *cursor; - struct hash_entry *next; - - /* Free the bucket overflow. */ - for (cursor = bucket->next; cursor; cursor = next) - { - if (table->data_freer) - (*table->data_freer) (cursor->data); - cursor->data = NULL; - - next = cursor->next; - /* Relinking is done one entry at a time, as it is to be expected - that overflows are either rare or short. */ - cursor->next = table->free_entry_list; - table->free_entry_list = cursor; - } - - /* Free the bucket head. */ - if (table->data_freer) - (*table->data_freer) (bucket->data); - bucket->data = NULL; - bucket->next = NULL; - } - } - - table->n_buckets_used = 0; - table->n_entries = 0; -} - -/* Reclaim all storage associated with a hash table. If a data_freer - function has been supplied by the user when the hash table was created, - this function applies it to the data of each entry before freeing that - entry. */ - -void -hash_free (Hash_table *table) -{ - struct hash_entry *bucket; - struct hash_entry *cursor; - struct hash_entry *next; - - /* Call the user data_freer function. */ - if (table->data_freer && table->n_entries) - { - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - if (bucket->data) - { - for (cursor = bucket; cursor; cursor = cursor->next) - { - (*table->data_freer) (cursor->data); - } - } - } - } - -#if USE_OBSTACK - - obstack_free (&table->entry_stack, NULL); - -#else - - /* Free all bucket overflowed entries. */ - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - for (cursor = bucket->next; cursor; cursor = next) - { - next = cursor->next; - free (cursor); - } - } - - /* Also reclaim the internal list of previously freed entries. */ - for (cursor = table->free_entry_list; cursor; cursor = next) - { - next = cursor->next; - free (cursor); - } - -#endif - - /* Free the remainder of the hash table structure. */ - free (table->bucket); - free (table); -} - -/* Insertion and deletion. */ - -/* Get a new hash entry for a bucket overflow, possibly by reclying a - previously freed one. If this is not possible, allocate a new one. */ - -static struct hash_entry * -allocate_entry (Hash_table *table) -{ - struct hash_entry *new; - - if (table->free_entry_list) - { - new = table->free_entry_list; - table->free_entry_list = new->next; - } - else - { -#if USE_OBSTACK - new = obstack_alloc (&table->entry_stack, sizeof *new); -#else - new = malloc (sizeof *new); -#endif - } - - return new; -} - -/* Free a hash entry which was part of some bucket overflow, - saving it for later recycling. */ - -static void -free_entry (Hash_table *table, struct hash_entry *entry) -{ - entry->data = NULL; - entry->next = table->free_entry_list; - table->free_entry_list = entry; -} - -/* This private function is used to help with insertion and deletion. When - ENTRY matches an entry in the table, return a pointer to the corresponding - user data and set *BUCKET_HEAD to the head of the selected bucket. - Otherwise, return NULL. When DELETE is true and ENTRY matches an entry in - the table, unlink the matching entry. */ - -static void * -hash_find_entry (Hash_table *table, const void *entry, - struct hash_entry **bucket_head, bool delete) -{ - struct hash_entry *bucket - = table->bucket + table->hasher (entry, table->n_buckets); - struct hash_entry *cursor; - - if (! (bucket < table->bucket_limit)) - abort (); - - *bucket_head = bucket; - - /* Test for empty bucket. */ - if (bucket->data == NULL) - return NULL; - - /* See if the entry is the first in the bucket. */ - if ((*table->comparator) (entry, bucket->data)) - { - void *data = bucket->data; - - if (delete) - { - if (bucket->next) - { - struct hash_entry *next = bucket->next; - - /* Bump the first overflow entry into the bucket head, then save - the previous first overflow entry for later recycling. */ - *bucket = *next; - free_entry (table, next); - } - else - { - bucket->data = NULL; - } - } - - return data; - } - - /* Scan the bucket overflow. */ - for (cursor = bucket; cursor->next; cursor = cursor->next) - { - if ((*table->comparator) (entry, cursor->next->data)) - { - void *data = cursor->next->data; - - if (delete) - { - struct hash_entry *next = cursor->next; - - /* Unlink the entry to delete, then save the freed entry for later - recycling. */ - cursor->next = next->next; - free_entry (table, next); - } - - return data; - } - } - - /* No entry found. */ - return NULL; -} - -/* For an already existing hash table, change the number of buckets through - specifying CANDIDATE. The contents of the hash table are preserved. The - new number of buckets is automatically selected so as to _guarantee_ that - the table may receive at least CANDIDATE different user entries, including - those already in the table, before any other growth of the hash table size - occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the - exact number of buckets desired. */ - -bool -hash_rehash (Hash_table *table, size_t candidate) -{ - Hash_table *new_table; - struct hash_entry *bucket; - struct hash_entry *cursor; - struct hash_entry *next; - - new_table = hash_initialize (candidate, table->tuning, table->hasher, - table->comparator, table->data_freer); - if (new_table == NULL) - return false; - - /* Merely reuse the extra old space into the new table. */ -#if USE_OBSTACK - obstack_free (&new_table->entry_stack, NULL); - new_table->entry_stack = table->entry_stack; -#endif - new_table->free_entry_list = table->free_entry_list; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - if (bucket->data) - for (cursor = bucket; cursor; cursor = next) - { - void *data = cursor->data; - struct hash_entry *new_bucket - = (new_table->bucket - + new_table->hasher (data, new_table->n_buckets)); - - if (! (new_bucket < new_table->bucket_limit)) - abort (); - - next = cursor->next; - - if (new_bucket->data) - { - if (cursor == bucket) - { - /* Allocate or recycle an entry, when moving from a bucket - header into a bucket overflow. */ - struct hash_entry *new_entry = allocate_entry (new_table); - - if (new_entry == NULL) - return false; - - new_entry->data = data; - new_entry->next = new_bucket->next; - new_bucket->next = new_entry; - } - else - { - /* Merely relink an existing entry, when moving from a - bucket overflow into a bucket overflow. */ - cursor->next = new_bucket->next; - new_bucket->next = cursor; - } - } - else - { - /* Free an existing entry, when moving from a bucket - overflow into a bucket header. Also take care of the - simple case of moving from a bucket header into a bucket - header. */ - new_bucket->data = data; - new_table->n_buckets_used++; - if (cursor != bucket) - free_entry (new_table, cursor); - } - } - - free (table->bucket); - table->bucket = new_table->bucket; - table->bucket_limit = new_table->bucket_limit; - table->n_buckets = new_table->n_buckets; - table->n_buckets_used = new_table->n_buckets_used; - table->free_entry_list = new_table->free_entry_list; - /* table->n_entries already holds its value. */ -#if USE_OBSTACK - table->entry_stack = new_table->entry_stack; -#endif - free (new_table); - - return true; -} - -/* If ENTRY matches an entry already in the hash table, return the pointer - to the entry from the table. Otherwise, insert ENTRY and return ENTRY. - Return NULL if the storage required for insertion cannot be allocated. */ - -void * -hash_insert (Hash_table *table, const void *entry) -{ - void *data; - struct hash_entry *bucket; - - /* The caller cannot insert a NULL entry. */ - if (! entry) - abort (); - - /* If there's a matching entry already in the table, return that. */ - if ((data = hash_find_entry (table, entry, &bucket, false)) != NULL) - return data; - - /* ENTRY is not matched, it should be inserted. */ - - if (bucket->data) - { - struct hash_entry *new_entry = allocate_entry (table); - - if (new_entry == NULL) - return NULL; - - /* Add ENTRY in the overflow of the bucket. */ - - new_entry->data = (void *) entry; - new_entry->next = bucket->next; - bucket->next = new_entry; - table->n_entries++; - return (void *) entry; - } - - /* Add ENTRY right in the bucket head. */ - - bucket->data = (void *) entry; - table->n_entries++; - table->n_buckets_used++; - - /* If the growth threshold of the buckets in use has been reached, increase - the table size and rehash. There's no point in checking the number of - entries: if the hashing function is ill-conditioned, rehashing is not - likely to improve it. */ - - if (table->n_buckets_used - > table->tuning->growth_threshold * table->n_buckets) - { - /* Check more fully, before starting real work. If tuning arguments - became invalid, the second check will rely on proper defaults. */ - check_tuning (table); - if (table->n_buckets_used - > table->tuning->growth_threshold * table->n_buckets) - { - const Hash_tuning *tuning = table->tuning; - float candidate = - (tuning->is_n_buckets - ? (table->n_buckets * tuning->growth_factor) - : (table->n_buckets * tuning->growth_factor - * tuning->growth_threshold)); - - if (SIZE_MAX <= candidate) - return NULL; - - /* If the rehash fails, arrange to return NULL. */ - if (!hash_rehash (table, candidate)) - entry = NULL; - } - } - - return (void *) entry; -} - -/* If ENTRY is already in the table, remove it and return the just-deleted - data (the user may want to deallocate its storage). If ENTRY is not in the - table, don't modify the table and return NULL. */ - -void * -hash_delete (Hash_table *table, const void *entry) -{ - void *data; - struct hash_entry *bucket; - - data = hash_find_entry (table, entry, &bucket, true); - if (!data) - return NULL; - - table->n_entries--; - if (!bucket->data) - { - table->n_buckets_used--; - - /* If the shrink threshold of the buckets in use has been reached, - rehash into a smaller table. */ - - if (table->n_buckets_used - < table->tuning->shrink_threshold * table->n_buckets) - { - /* Check more fully, before starting real work. If tuning arguments - became invalid, the second check will rely on proper defaults. */ - check_tuning (table); - if (table->n_buckets_used - < table->tuning->shrink_threshold * table->n_buckets) - { - const Hash_tuning *tuning = table->tuning; - size_t candidate = - (tuning->is_n_buckets - ? table->n_buckets * tuning->shrink_factor - : (table->n_buckets * tuning->shrink_factor - * tuning->growth_threshold)); - - hash_rehash (table, candidate); - } - } - } - - return data; -} - -/* Testing. */ - -#if TESTING - -void -hash_print (const Hash_table *table) -{ - struct hash_entry const *bucket; - - for (bucket = table->bucket; bucket < table->bucket_limit; bucket++) - { - struct hash_entry *cursor; - - if (bucket) - printf ("%lu:\n", (unsigned long int) (bucket - table->bucket)); - - for (cursor = bucket; cursor; cursor = cursor->next) - { - char const *s = cursor->data; - /* FIXME */ - if (s) - printf (" %s\n", s); - } - } -} - -#endif /* TESTING */ diff --git a/src/bin/tar/lib/hash.h b/src/bin/tar/lib/hash.h deleted file mode 100644 index ab63a863fd..0000000000 --- a/src/bin/tar/lib/hash.h +++ /dev/null @@ -1,88 +0,0 @@ -/* hash - hashing table processing. - Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc. - Written by Jim Meyering , 1998. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* A generic hash table package. */ - -/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use - obstacks instead of malloc, and recompile `hash.c' with same setting. */ - -#ifndef HASH_H_ -# define HASH_H_ - -# include -# include - -typedef size_t (*Hash_hasher) (const void *, size_t); -typedef bool (*Hash_comparator) (const void *, const void *); -typedef void (*Hash_data_freer) (void *); -typedef bool (*Hash_processor) (void *, void *); - -struct hash_entry - { - void *data; - struct hash_entry *next; - }; - -struct hash_tuning - { - /* This structure is mainly used for `hash_initialize', see the block - documentation of `hash_reset_tuning' for more complete comments. */ - - float shrink_threshold; /* ratio of used buckets to trigger a shrink */ - float shrink_factor; /* ratio of new smaller size to original size */ - float growth_threshold; /* ratio of used buckets to trigger a growth */ - float growth_factor; /* ratio of new bigger size to original size */ - bool is_n_buckets; /* if CANDIDATE really means table size */ - }; - -typedef struct hash_tuning Hash_tuning; - -struct hash_table; - -typedef struct hash_table Hash_table; - -/* Information and lookup. */ -size_t hash_get_n_buckets (const Hash_table *); -size_t hash_get_n_buckets_used (const Hash_table *); -size_t hash_get_n_entries (const Hash_table *); -size_t hash_get_max_bucket_length (const Hash_table *); -bool hash_table_ok (const Hash_table *); -void hash_print_statistics (const Hash_table *, FILE *); -void *hash_lookup (const Hash_table *, const void *); - -/* Walking. */ -void *hash_get_first (const Hash_table *); -void *hash_get_next (const Hash_table *, const void *); -size_t hash_get_entries (const Hash_table *, void **, size_t); -size_t hash_do_for_each (const Hash_table *, Hash_processor, void *); - -/* Allocation and clean-up. */ -size_t hash_string (const char *, size_t); -void hash_reset_tuning (Hash_tuning *); -Hash_table *hash_initialize (size_t, const Hash_tuning *, - Hash_hasher, Hash_comparator, - Hash_data_freer); -void hash_clear (Hash_table *); -void hash_free (Hash_table *); - -/* Insertion and deletion. */ -bool hash_rehash (Hash_table *, size_t); -void *hash_insert (Hash_table *, const void *); -void *hash_delete (Hash_table *, const void *); - -#endif diff --git a/src/bin/tar/lib/human.c b/src/bin/tar/lib/human.c deleted file mode 100644 index 592f830751..0000000000 --- a/src/bin/tar/lib/human.c +++ /dev/null @@ -1,472 +0,0 @@ -/* human.c -- print human readable file size - - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert and Larry McVoy. */ - -#include - -#include "human.h" - -#include -#include -#include -#include - -#include -#include -#include - -/* The maximum length of a suffix like "KiB". */ -#define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3 - -static const char power_letter[] = -{ - 0, /* not used */ - 'K', /* kibi ('k' for kilo is a special case) */ - 'M', /* mega or mebi */ - 'G', /* giga or gibi */ - 'T', /* tera or tebi */ - 'P', /* peta or pebi */ - 'E', /* exa or exbi */ - 'Z', /* zetta or 2**70 */ - 'Y' /* yotta or 2**80 */ -}; - - -/* If INEXACT_STYLE is not human_round_to_nearest, and if easily - possible, adjust VALUE according to the style. */ - -static long double -adjust_value (int inexact_style, long double value) -{ - /* Do not use the floorl or ceill functions, as that would mean - checking for their presence and possibly linking with the - standard math library, which is a porting pain. So leave the - value alone if it is too large to easily round. */ - if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX) - { - uintmax_t u = value; - value = u + (inexact_style == human_ceiling && u != value); - } - - return value; -} - -/* Group the digits of NUMBER according to the grouping rules of the - current locale. NUMBER contains NUMBERLEN digits. Modify the - bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for - each byte inserted. Return the starting address of the modified - number. - - To group the digits, use GROUPING and THOUSANDS_SEP as in `struct - lconv' from . */ - -static char * -group_number (char *number, size_t numberlen, - char const *grouping, char const *thousands_sep) -{ - register char *d; - size_t grouplen = SIZE_MAX; - size_t thousands_seplen = strlen (thousands_sep); - size_t i = numberlen; - - /* The maximum possible value for NUMBERLEN is the number of digits - in the square of the largest uintmax_t, so double the size needed. */ - char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1]; - - memcpy (buf, number, numberlen); - d = number + numberlen; - - for (;;) - { - unsigned char g = *grouping; - - if (g) - { - grouplen = g < CHAR_MAX ? g : i; - grouping++; - } - - if (i < grouplen) - grouplen = i; - - d -= grouplen; - i -= grouplen; - memcpy (d, buf + i, grouplen); - if (i == 0) - return d; - - d -= thousands_seplen; - memcpy (d, thousands_sep, thousands_seplen); - } -} - -/* Convert N to a human readable format in BUF, using the options OPTS. - - N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must - be nonnegative. - - Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE - must be positive. - - Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling)) - to determine whether to take the ceiling or floor of any result - that cannot be expressed exactly. - - If (OPTS & human_group_digits), group the thousands digits - according to the locale, e.g., `1,000,000' in an American English - locale. - - If (OPTS & human_autoscale), deduce the output block size - automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the - output. Use powers of 1024 if (OPTS & human_base_1024), and powers - of 1000 otherwise. For example, assuming powers of 1024, 8500 - would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and - so on. Numbers smaller than the power aren't modified. - human_autoscale is normally used together with human_SI. - - If (OPTS & human_space_before_unit), use a space to separate the - number from any suffix that is appended as described below. - - If (OPTS & human_SI), append an SI prefix indicating which power is - being used. If in addition (OPTS & human_B), append "B" (if base - 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS & - human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a - power of 1024 or of 1000, depending on (OPTS & - human_base_1024). */ - -char * -human_readable (uintmax_t n, char *buf, int opts, - uintmax_t from_block_size, uintmax_t to_block_size) -{ - int inexact_style = - opts & (human_round_to_nearest | human_floor | human_ceiling); - unsigned int base = opts & human_base_1024 ? 1024 : 1000; - uintmax_t amt; - int tenths; - int exponent = -1; - int exponent_max = sizeof power_letter - 1; - char *p; - char *psuffix; - char const *integerlim; - - /* 0 means adjusted N == AMT.TENTHS; - 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05; - 2 means adjusted N == AMT.TENTHS + 0.05; - 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */ - int rounding; - - char const *decimal_point = "."; - size_t decimal_pointlen = 1; - char const *grouping = ""; - char const *thousands_sep = ""; - struct lconv const *l = localeconv (); - size_t pointlen = strlen (l->decimal_point); - if (0 < pointlen && pointlen <= MB_LEN_MAX) - { - decimal_point = l->decimal_point; - decimal_pointlen = pointlen; - } - grouping = l->grouping; - if (strlen (l->thousands_sep) <= MB_LEN_MAX) - thousands_sep = l->thousands_sep; - - psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX; - p = psuffix; - - /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE - units. If this can be done exactly with integer arithmetic, do - not use floating point operations. */ - if (to_block_size <= from_block_size) - { - if (from_block_size % to_block_size == 0) - { - uintmax_t multiplier = from_block_size / to_block_size; - amt = n * multiplier; - if (amt / multiplier == n) - { - tenths = 0; - rounding = 0; - goto use_integer_arithmetic; - } - } - } - else if (from_block_size != 0 && to_block_size % from_block_size == 0) - { - uintmax_t divisor = to_block_size / from_block_size; - uintmax_t r10 = (n % divisor) * 10; - uintmax_t r2 = (r10 % divisor) * 2; - amt = n / divisor; - tenths = r10 / divisor; - rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2); - goto use_integer_arithmetic; - } - - { - /* Either the result cannot be computed easily using uintmax_t, - or from_block_size is zero. Fall back on floating point. - FIXME: This can yield answers that are slightly off. */ - - long double dto_block_size = to_block_size; - long double damt = n * (from_block_size / dto_block_size); - size_t buflen; - size_t nonintegerlen; - - if (! (opts & human_autoscale)) - { - sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt)); - buflen = strlen (buf); - nonintegerlen = 0; - } - else - { - long double e = 1; - exponent = 0; - - do - { - e *= base; - exponent++; - } - while (e * base <= damt && exponent < exponent_max); - - damt /= e; - - sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt)); - buflen = strlen (buf); - nonintegerlen = decimal_pointlen + 1; - - if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen - || ((opts & human_suppress_point_zero) - && buf[buflen - 1] == '0')) - { - sprintf (buf, "%.0Lf", - adjust_value (inexact_style, damt * 10) / 10); - buflen = strlen (buf); - nonintegerlen = 0; - } - } - - p = psuffix - buflen; - memmove (p, buf, buflen); - integerlim = p + buflen - nonintegerlen; - } - goto do_grouping; - - use_integer_arithmetic: - { - /* The computation can be done exactly, with integer arithmetic. - - Use power of BASE notation if requested and if adjusted AMT is - large enough. */ - - if (opts & human_autoscale) - { - exponent = 0; - - if (base <= amt) - { - do - { - unsigned int r10 = (amt % base) * 10 + tenths; - unsigned int r2 = (r10 % base) * 2 + (rounding >> 1); - amt /= base; - tenths = r10 / base; - rounding = (r2 < base - ? (r2 + rounding) != 0 - : 2 + (base < r2 + rounding)); - exponent++; - } - while (base <= amt && exponent < exponent_max); - - if (amt < 10) - { - if (inexact_style == human_round_to_nearest - ? 2 < rounding + (tenths & 1) - : inexact_style == human_ceiling && 0 < rounding) - { - tenths++; - rounding = 0; - - if (tenths == 10) - { - amt++; - tenths = 0; - } - } - - if (amt < 10 - && (tenths || ! (opts & human_suppress_point_zero))) - { - *--p = '0' + tenths; - p -= decimal_pointlen; - memcpy (p, decimal_point, decimal_pointlen); - tenths = rounding = 0; - } - } - } - } - - if (inexact_style == human_round_to_nearest - ? 5 < tenths + (0 < rounding + (amt & 1)) - : inexact_style == human_ceiling && 0 < tenths + rounding) - { - amt++; - - if ((opts & human_autoscale) - && amt == base && exponent < exponent_max) - { - exponent++; - if (! (opts & human_suppress_point_zero)) - { - *--p = '0'; - p -= decimal_pointlen; - memcpy (p, decimal_point, decimal_pointlen); - } - amt = 1; - } - } - - integerlim = p; - - do - { - int digit = amt % 10; - *--p = digit + '0'; - } - while ((amt /= 10) != 0); - } - - do_grouping: - if (opts & human_group_digits) - p = group_number (p, integerlim - p, grouping, thousands_sep); - - if (opts & human_SI) - { - if (exponent < 0) - { - uintmax_t power; - exponent = 0; - for (power = 1; power < to_block_size; power *= base) - if (++exponent == exponent_max) - break; - } - - if ((exponent | (opts & human_B)) && (opts & human_space_before_unit)) - *psuffix++ = ' '; - - if (exponent) - *psuffix++ = (! (opts & human_base_1024) && exponent == 1 - ? 'k' - : power_letter[exponent]); - - if (opts & human_B) - { - if ((opts & human_base_1024) && exponent) - *psuffix++ = 'i'; - *psuffix++ = 'B'; - } - } - - *psuffix = '\0'; - - return p; -} - - -/* The default block size used for output. This number may change in - the future as disks get larger. */ -#ifndef DEFAULT_BLOCK_SIZE -# define DEFAULT_BLOCK_SIZE 1024 -#endif - -static char const *const block_size_args[] = { "human-readable", "si", 0 }; -static int const block_size_opts[] = - { - human_autoscale + human_SI + human_base_1024, - human_autoscale + human_SI - }; - -static uintmax_t -default_block_size (void) -{ - return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE; -} - -static strtol_error -humblock (char const *spec, uintmax_t *block_size, int *options) -{ - int i; - int opts = 0; - - if (! spec - && ! (spec = getenv ("BLOCK_SIZE")) - && ! (spec = getenv ("BLOCKSIZE"))) - *block_size = default_block_size (); - else - { - if (*spec == '\'') - { - opts |= human_group_digits; - spec++; - } - - if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts))) - { - opts |= block_size_opts[i]; - *block_size = 1; - } - else - { - char *ptr; - strtol_error e = xstrtoumax (spec, &ptr, 0, block_size, - "eEgGkKmMpPtTyYzZ0"); - if (e != LONGINT_OK) - { - *options = 0; - return e; - } - for (; ! ('0' <= *spec && *spec <= '9'); spec++) - if (spec == ptr) - { - opts |= human_SI; - if (ptr[-1] == 'B') - opts |= human_B; - if (ptr[-1] != 'B' || ptr[-2] == 'i') - opts |= human_base_1024; - break; - } - } - } - - *options = opts; - return LONGINT_OK; -} - -enum strtol_error -human_options (char const *spec, int *opts, uintmax_t *block_size) -{ - strtol_error e = humblock (spec, block_size, opts); - if (*block_size == 0) - { - *block_size = default_block_size (); - e = LONGINT_INVALID; - } - return e; -} diff --git a/src/bin/tar/lib/human.h b/src/bin/tar/lib/human.h deleted file mode 100644 index 95fc930042..0000000000 --- a/src/bin/tar/lib/human.h +++ /dev/null @@ -1,85 +0,0 @@ -/* human.h -- print human readable file size - - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert and Larry McVoy. */ - -#ifndef HUMAN_H_ -# define HUMAN_H_ 1 - -# include -# include -# include -# include - -# include - -/* A conservative bound on the maximum length of a human-readable string. - The output can be the square of the largest uintmax_t, so double - its size before converting to a bound. - log10 (2.0) < 146/485. Add 1 for integer division truncation. - Also, the output can have a thousands separator between every digit, - so multiply by MB_LEN_MAX + 1 and then subtract MB_LEN_MAX. - Append 1 for a space before the suffix. - Finally, append 3, the maximum length of a suffix. */ -# define LONGEST_HUMAN_READABLE \ - ((2 * sizeof (uintmax_t) * CHAR_BIT * 146 / 485 + 1) * (MB_LEN_MAX + 1) \ - - MB_LEN_MAX + 1 + 3) - -/* Options for human_readable. */ -enum -{ - /* Unless otherwise specified these options may be ORed together. */ - - /* The following three options are mutually exclusive. */ - /* Round to plus infinity (default). */ - human_ceiling = 0, - /* Round to nearest, ties to even. */ - human_round_to_nearest = 1, - /* Round to minus infinity. */ - human_floor = 2, - - /* Group digits together, e.g. `1,000,000'. This uses the - locale-defined grouping; the traditional C locale does not group, - so this has effect only if some other locale is in use. */ - human_group_digits = 4, - - /* When autoscaling, suppress ".0" at end. */ - human_suppress_point_zero = 8, - - /* Scale output and use SI-style units, ignoring the output block size. */ - human_autoscale = 16, - - /* Prefer base 1024 to base 1000. */ - human_base_1024 = 32, - - /* Prepend " " before unit symbol. */ - human_space_before_unit = 64, - - /* Append SI prefix, e.g. "k" or "M". */ - human_SI = 128, - - /* Append "B" (if base 1000) or "iB" (if base 1024) to SI prefix. */ - human_B = 256 -}; - -char *human_readable (uintmax_t, char *, int, uintmax_t, uintmax_t); - -enum strtol_error human_options (char const *, int *, uintmax_t *); - -#endif /* HUMAN_H_ */ diff --git a/src/bin/tar/lib/imaxtostr.c b/src/bin/tar/lib/imaxtostr.c deleted file mode 100644 index 5e87ad526f..0000000000 --- a/src/bin/tar/lib/imaxtostr.c +++ /dev/null @@ -1,3 +0,0 @@ -#define inttostr imaxtostr -#define inttype intmax_t -#include "inttostr.c" diff --git a/src/bin/tar/lib/intprops.h b/src/bin/tar/lib/intprops.h deleted file mode 100644 index 34f971cbaa..0000000000 --- a/src/bin/tar/lib/intprops.h +++ /dev/null @@ -1,78 +0,0 @@ -/* intprops.h -- properties of integer types - - Copyright (C) 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -/* The extra casts in the following macros work around compiler bugs, - e.g., in Cray C 5.0.3.0. */ - -/* True if the arithmetic type T is an integer type. bool counts as - an integer. */ -#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) - -/* True if negative values of the signed integer type T use two's - complement, ones' complement, or signed magnitude representation, - respectively. Much GNU code assumes two's complement, but some - people like to be portable to all possible C hosts. */ -#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) -#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) -#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) - -/* True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* The maximum and minimum values for the integer type T. These - macros have undefined behavior if T is signed and has padding bits. - If this is a problem for you, please let us know how to fix it for - your host. */ -#define TYPE_MINIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) 0 \ - : TYPE_SIGNED_MAGNITUDE (t) \ - ? ~ (t) 0 \ - : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) -#define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) - -/* Return zero if T can be determined to be an unsigned type. - Otherwise, return 1. - When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a - tighter bound. Otherwise, it overestimates the true bound by one byte - when applied to unsigned types of size 2, 4, 16, ... bytes. - The symbol signed_type_or_expr__ is private to this header file. */ -#if __GNUC__ >= 2 -# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t)) -#else -# define signed_type_or_expr__(t) 1 -#endif - -/* Bound on length of the string representing an integer type or expression T. - Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485; - add 1 for integer division truncation; add 1 more for a minus sign - if needed. */ -#define INT_STRLEN_BOUND(t) \ - ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \ - + signed_type_or_expr__ (t) + 1) - -/* Bound on buffer size needed to represent an integer type or expression T, - including the terminating null. */ -#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) diff --git a/src/bin/tar/lib/inttostr.c b/src/bin/tar/lib/inttostr.c deleted file mode 100644 index 246d658350..0000000000 --- a/src/bin/tar/lib/inttostr.c +++ /dev/null @@ -1,51 +0,0 @@ -/* inttostr.c -- convert integers to printable strings - - Copyright (C) 2001, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include - -#include "inttostr.h" - -/* Convert I to a printable string in BUF, which must be at least - INT_BUFSIZE_BOUND (INTTYPE) bytes long. Return the address of the - printable string, which need not start at BUF. */ - -char * -inttostr (inttype i, char *buf) -{ - char *p = buf + INT_STRLEN_BOUND (inttype); - *p = 0; - - if (i < 0) - { - do - *--p = '0' - i % 10; - while ((i /= 10) != 0); - - *--p = '-'; - } - else - { - do - *--p = '0' + i % 10; - while ((i /= 10) != 0); - } - - return p; -} diff --git a/src/bin/tar/lib/inttostr.h b/src/bin/tar/lib/inttostr.h deleted file mode 100644 index 31258cad35..0000000000 --- a/src/bin/tar/lib/inttostr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* inttostr.h -- convert integers to printable strings - - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include -#include - -#include "intprops.h" - -char *offtostr (off_t, char *); -char *imaxtostr (intmax_t, char *); -char *umaxtostr (uintmax_t, char *); -char *uinttostr (unsigned int, char *); diff --git a/src/bin/tar/lib/inttypes.in.h b/src/bin/tar/lib/inttypes.in.h deleted file mode 100644 index 5257275fd1..0000000000 --- a/src/bin/tar/lib/inttypes.in.h +++ /dev/null @@ -1,1096 +0,0 @@ -/* Copyright (C) 2006-2007 Free Software Foundation, Inc. - Written by Paul Eggert, Bruno Haible, Derek Price. - This file is part of gnulib. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1, 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 Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* - * ISO C 99 for platforms that lack it. - * - */ - -/* Include the original if it exists, and if this file - has not been included yet or if this file includes gnulib stdint.h - which in turn includes this file. - The include_next requires a split double-inclusion guard. */ -#if ! defined INTTYPES_H || defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H -# if @HAVE_INTTYPES_H@ -# @INCLUDE_NEXT@ @NEXT_INTTYPES_H@ -# endif -#endif - -#if ! defined INTTYPES_H && ! defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H -#define INTTYPES_H - -/* Include or the gnulib replacement. */ -#include -/* Get CHAR_BIT. */ -#include - -#if !(INT_MIN == INT32_MIN && INT_MAX == INT32_MAX) -# error "This file assumes that 'int' has exactly 32 bits. Please report your platform and compiler to ." -#endif - -/* The definition of GL_LINK_WARNING is copied here. */ - -/* 7.8.1 Macros for format specifiers */ - -#if ! defined __cplusplus || defined __STDC_FORMAT_MACROS - -# if defined _TNS_R_TARGET - /* Tandem NonStop R series and compatible platforms released before - July 2005 support %Ld but not %lld. */ -# define _LONG_LONG_FORMAT_PREFIX "L" -# else -# define _LONG_LONG_FORMAT_PREFIX "ll" -# endif - -# if !defined PRId8 || @PRI_MACROS_BROKEN@ -# undef PRId8 -# ifdef INT8_MAX -# define PRId8 "d" -# endif -# endif -# if !defined PRIi8 || @PRI_MACROS_BROKEN@ -# undef PRIi8 -# ifdef INT8_MAX -# define PRIi8 "i" -# endif -# endif -# if !defined PRIo8 || @PRI_MACROS_BROKEN@ -# undef PRIo8 -# ifdef UINT8_MAX -# define PRIo8 "o" -# endif -# endif -# if !defined PRIu8 || @PRI_MACROS_BROKEN@ -# undef PRIu8 -# ifdef UINT8_MAX -# define PRIu8 "u" -# endif -# endif -# if !defined PRIx8 || @PRI_MACROS_BROKEN@ -# undef PRIx8 -# ifdef UINT8_MAX -# define PRIx8 "x" -# endif -# endif -# if !defined PRIX8 || @PRI_MACROS_BROKEN@ -# undef PRIX8 -# ifdef UINT8_MAX -# define PRIX8 "X" -# endif -# endif -# if !defined PRId16 || @PRI_MACROS_BROKEN@ -# undef PRId16 -# ifdef INT16_MAX -# define PRId16 "d" -# endif -# endif -# if !defined PRIi16 || @PRI_MACROS_BROKEN@ -# undef PRIi16 -# ifdef INT16_MAX -# define PRIi16 "i" -# endif -# endif -# if !defined PRIo16 || @PRI_MACROS_BROKEN@ -# undef PRIo16 -# ifdef UINT16_MAX -# define PRIo16 "o" -# endif -# endif -# if !defined PRIu16 || @PRI_MACROS_BROKEN@ -# undef PRIu16 -# ifdef UINT16_MAX -# define PRIu16 "u" -# endif -# endif -# if !defined PRIx16 || @PRI_MACROS_BROKEN@ -# undef PRIx16 -# ifdef UINT16_MAX -# define PRIx16 "x" -# endif -# endif -# if !defined PRIX16 || @PRI_MACROS_BROKEN@ -# undef PRIX16 -# ifdef UINT16_MAX -# define PRIX16 "X" -# endif -# endif -# if !defined PRId32 || @PRI_MACROS_BROKEN@ -# undef PRId32 -# ifdef INT32_MAX -# define PRId32 "d" -# endif -# endif -# if !defined PRIi32 || @PRI_MACROS_BROKEN@ -# undef PRIi32 -# ifdef INT32_MAX -# define PRIi32 "i" -# endif -# endif -# if !defined PRIo32 || @PRI_MACROS_BROKEN@ -# undef PRIo32 -# ifdef UINT32_MAX -# define PRIo32 "o" -# endif -# endif -# if !defined PRIu32 || @PRI_MACROS_BROKEN@ -# undef PRIu32 -# ifdef UINT32_MAX -# define PRIu32 "u" -# endif -# endif -# if !defined PRIx32 || @PRI_MACROS_BROKEN@ -# undef PRIx32 -# ifdef UINT32_MAX -# define PRIx32 "x" -# endif -# endif -# if !defined PRIX32 || @PRI_MACROS_BROKEN@ -# undef PRIX32 -# ifdef UINT32_MAX -# define PRIX32 "X" -# endif -# endif -# ifdef INT64_MAX -# if INT64_MAX == LONG_MAX -# define _PRI64_PREFIX "l" -# elif defined _MSC_VER || defined __MINGW32__ -# define _PRI64_PREFIX "I64" -# elif @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 -# define _PRI64_PREFIX _LONG_LONG_FORMAT_PREFIX -# endif -# if !defined PRId64 || @PRI_MACROS_BROKEN@ -# undef PRId64 -# define PRId64 _PRI64_PREFIX "d" -# endif -# if !defined PRIi64 || @PRI_MACROS_BROKEN@ -# undef PRIi64 -# define PRIi64 _PRI64_PREFIX "i" -# endif -# endif -# ifdef UINT64_MAX -# if UINT64_MAX == ULONG_MAX -# define _PRIu64_PREFIX "l" -# elif defined _MSC_VER || defined __MINGW32__ -# define _PRIu64_PREFIX "I64" -# elif @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 -# define _PRIu64_PREFIX _LONG_LONG_FORMAT_PREFIX -# endif -# if !defined PRIo64 || @PRI_MACROS_BROKEN@ -# undef PRIo64 -# define PRIo64 _PRIu64_PREFIX "o" -# endif -# if !defined PRIu64 || @PRI_MACROS_BROKEN@ -# undef PRIu64 -# define PRIu64 _PRIu64_PREFIX "u" -# endif -# if !defined PRIx64 || @PRI_MACROS_BROKEN@ -# undef PRIx64 -# define PRIx64 _PRIu64_PREFIX "x" -# endif -# if !defined PRIX64 || @PRI_MACROS_BROKEN@ -# undef PRIX64 -# define PRIX64 _PRIu64_PREFIX "X" -# endif -# endif - -# if !defined PRIdLEAST8 || @PRI_MACROS_BROKEN@ -# undef PRIdLEAST8 -# define PRIdLEAST8 "d" -# endif -# if !defined PRIiLEAST8 || @PRI_MACROS_BROKEN@ -# undef PRIiLEAST8 -# define PRIiLEAST8 "i" -# endif -# if !defined PRIoLEAST8 || @PRI_MACROS_BROKEN@ -# undef PRIoLEAST8 -# define PRIoLEAST8 "o" -# endif -# if !defined PRIuLEAST8 || @PRI_MACROS_BROKEN@ -# undef PRIuLEAST8 -# define PRIuLEAST8 "u" -# endif -# if !defined PRIxLEAST8 || @PRI_MACROS_BROKEN@ -# undef PRIxLEAST8 -# define PRIxLEAST8 "x" -# endif -# if !defined PRIXLEAST8 || @PRI_MACROS_BROKEN@ -# undef PRIXLEAST8 -# define PRIXLEAST8 "X" -# endif -# if !defined PRIdLEAST16 || @PRI_MACROS_BROKEN@ -# undef PRIdLEAST16 -# define PRIdLEAST16 "d" -# endif -# if !defined PRIiLEAST16 || @PRI_MACROS_BROKEN@ -# undef PRIiLEAST16 -# define PRIiLEAST16 "i" -# endif -# if !defined PRIoLEAST16 || @PRI_MACROS_BROKEN@ -# undef PRIoLEAST16 -# define PRIoLEAST16 "o" -# endif -# if !defined PRIuLEAST16 || @PRI_MACROS_BROKEN@ -# undef PRIuLEAST16 -# define PRIuLEAST16 "u" -# endif -# if !defined PRIxLEAST16 || @PRI_MACROS_BROKEN@ -# undef PRIxLEAST16 -# define PRIxLEAST16 "x" -# endif -# if !defined PRIXLEAST16 || @PRI_MACROS_BROKEN@ -# undef PRIXLEAST16 -# define PRIXLEAST16 "X" -# endif -# if !defined PRIdLEAST32 || @PRI_MACROS_BROKEN@ -# undef PRIdLEAST32 -# define PRIdLEAST32 "d" -# endif -# if !defined PRIiLEAST32 || @PRI_MACROS_BROKEN@ -# undef PRIiLEAST32 -# define PRIiLEAST32 "i" -# endif -# if !defined PRIoLEAST32 || @PRI_MACROS_BROKEN@ -# undef PRIoLEAST32 -# define PRIoLEAST32 "o" -# endif -# if !defined PRIuLEAST32 || @PRI_MACROS_BROKEN@ -# undef PRIuLEAST32 -# define PRIuLEAST32 "u" -# endif -# if !defined PRIxLEAST32 || @PRI_MACROS_BROKEN@ -# undef PRIxLEAST32 -# define PRIxLEAST32 "x" -# endif -# if !defined PRIXLEAST32 || @PRI_MACROS_BROKEN@ -# undef PRIXLEAST32 -# define PRIXLEAST32 "X" -# endif -# ifdef INT64_MAX -# if !defined PRIdLEAST64 || @PRI_MACROS_BROKEN@ -# undef PRIdLEAST64 -# define PRIdLEAST64 PRId64 -# endif -# if !defined PRIiLEAST64 || @PRI_MACROS_BROKEN@ -# undef PRIiLEAST64 -# define PRIiLEAST64 PRIi64 -# endif -# endif -# ifdef UINT64_MAX -# if !defined PRIoLEAST64 || @PRI_MACROS_BROKEN@ -# undef PRIoLEAST64 -# define PRIoLEAST64 PRIo64 -# endif -# if !defined PRIuLEAST64 || @PRI_MACROS_BROKEN@ -# undef PRIuLEAST64 -# define PRIuLEAST64 PRIu64 -# endif -# if !defined PRIxLEAST64 || @PRI_MACROS_BROKEN@ -# undef PRIxLEAST64 -# define PRIxLEAST64 PRIx64 -# endif -# if !defined PRIXLEAST64 || @PRI_MACROS_BROKEN@ -# undef PRIXLEAST64 -# define PRIXLEAST64 PRIX64 -# endif -# endif - -# if !defined PRIdFAST8 || @PRI_MACROS_BROKEN@ -# undef PRIdFAST8 -# if INT_FAST8_MAX > INT32_MAX -# define PRIdFAST8 PRId64 -# else -# define PRIdFAST8 "d" -# endif -# endif -# if !defined PRIiFAST8 || @PRI_MACROS_BROKEN@ -# undef PRIiFAST8 -# if INT_FAST8_MAX > INT32_MAX -# define PRIiFAST8 PRIi64 -# else -# define PRIiFAST8 "i" -# endif -# endif -# if !defined PRIoFAST8 || @PRI_MACROS_BROKEN@ -# undef PRIoFAST8 -# if UINT_FAST8_MAX > UINT32_MAX -# define PRIoFAST8 PRIo64 -# else -# define PRIoFAST8 "o" -# endif -# endif -# if !defined PRIuFAST8 || @PRI_MACROS_BROKEN@ -# undef PRIuFAST8 -# if UINT_FAST8_MAX > UINT32_MAX -# define PRIuFAST8 PRIu64 -# else -# define PRIuFAST8 "u" -# endif -# endif -# if !defined PRIxFAST8 || @PRI_MACROS_BROKEN@ -# undef PRIxFAST8 -# if UINT_FAST8_MAX > UINT32_MAX -# define PRIxFAST8 PRIx64 -# else -# define PRIxFAST8 "x" -# endif -# endif -# if !defined PRIXFAST8 || @PRI_MACROS_BROKEN@ -# undef PRIXFAST8 -# if UINT_FAST8_MAX > UINT32_MAX -# define PRIXFAST8 PRIX64 -# else -# define PRIXFAST8 "X" -# endif -# endif -# if !defined PRIdFAST16 || @PRI_MACROS_BROKEN@ -# undef PRIdFAST16 -# if INT_FAST16_MAX > INT32_MAX -# define PRIdFAST16 PRId64 -# else -# define PRIdFAST16 "d" -# endif -# endif -# if !defined PRIiFAST16 || @PRI_MACROS_BROKEN@ -# undef PRIiFAST16 -# if INT_FAST16_MAX > INT32_MAX -# define PRIiFAST16 PRIi64 -# else -# define PRIiFAST16 "i" -# endif -# endif -# if !defined PRIoFAST16 || @PRI_MACROS_BROKEN@ -# undef PRIoFAST16 -# if UINT_FAST16_MAX > UINT32_MAX -# define PRIoFAST16 PRIo64 -# else -# define PRIoFAST16 "o" -# endif -# endif -# if !defined PRIuFAST16 || @PRI_MACROS_BROKEN@ -# undef PRIuFAST16 -# if UINT_FAST16_MAX > UINT32_MAX -# define PRIuFAST16 PRIu64 -# else -# define PRIuFAST16 "u" -# endif -# endif -# if !defined PRIxFAST16 || @PRI_MACROS_BROKEN@ -# undef PRIxFAST16 -# if UINT_FAST16_MAX > UINT32_MAX -# define PRIxFAST16 PRIx64 -# else -# define PRIxFAST16 "x" -# endif -# endif -# if !defined PRIXFAST16 || @PRI_MACROS_BROKEN@ -# undef PRIXFAST16 -# if UINT_FAST16_MAX > UINT32_MAX -# define PRIXFAST16 PRIX64 -# else -# define PRIXFAST16 "X" -# endif -# endif -# if !defined PRIdFAST32 || @PRI_MACROS_BROKEN@ -# undef PRIdFAST32 -# if INT_FAST32_MAX > INT32_MAX -# define PRIdFAST32 PRId64 -# else -# define PRIdFAST32 "d" -# endif -# endif -# if !defined PRIiFAST32 || @PRI_MACROS_BROKEN@ -# undef PRIiFAST32 -# if INT_FAST32_MAX > INT32_MAX -# define PRIiFAST32 PRIi64 -# else -# define PRIiFAST32 "i" -# endif -# endif -# if !defined PRIoFAST32 || @PRI_MACROS_BROKEN@ -# undef PRIoFAST32 -# if UINT_FAST32_MAX > UINT32_MAX -# define PRIoFAST32 PRIo64 -# else -# define PRIoFAST32 "o" -# endif -# endif -# if !defined PRIuFAST32 || @PRI_MACROS_BROKEN@ -# undef PRIuFAST32 -# if UINT_FAST32_MAX > UINT32_MAX -# define PRIuFAST32 PRIu64 -# else -# define PRIuFAST32 "u" -# endif -# endif -# if !defined PRIxFAST32 || @PRI_MACROS_BROKEN@ -# undef PRIxFAST32 -# if UINT_FAST32_MAX > UINT32_MAX -# define PRIxFAST32 PRIx64 -# else -# define PRIxFAST32 "x" -# endif -# endif -# if !defined PRIXFAST32 || @PRI_MACROS_BROKEN@ -# undef PRIXFAST32 -# if UINT_FAST32_MAX > UINT32_MAX -# define PRIXFAST32 PRIX64 -# else -# define PRIXFAST32 "X" -# endif -# endif -# ifdef INT64_MAX -# if !defined PRIdFAST64 || @PRI_MACROS_BROKEN@ -# undef PRIdFAST64 -# define PRIdFAST64 PRId64 -# endif -# if !defined PRIiFAST64 || @PRI_MACROS_BROKEN@ -# undef PRIiFAST64 -# define PRIiFAST64 PRIi64 -# endif -# endif -# ifdef UINT64_MAX -# if !defined PRIoFAST64 || @PRI_MACROS_BROKEN@ -# undef PRIoFAST64 -# define PRIoFAST64 PRIo64 -# endif -# if !defined PRIuFAST64 || @PRI_MACROS_BROKEN@ -# undef PRIuFAST64 -# define PRIuFAST64 PRIu64 -# endif -# if !defined PRIxFAST64 || @PRI_MACROS_BROKEN@ -# undef PRIxFAST64 -# define PRIxFAST64 PRIx64 -# endif -# if !defined PRIXFAST64 || @PRI_MACROS_BROKEN@ -# undef PRIXFAST64 -# define PRIXFAST64 PRIX64 -# endif -# endif - -# if !defined PRIdMAX || @PRI_MACROS_BROKEN@ -# undef PRIdMAX -# if INTMAX_MAX > INT32_MAX -# define PRIdMAX PRId64 -# else -# define PRIdMAX "ld" -# endif -# endif -# if !defined PRIiMAX || @PRI_MACROS_BROKEN@ -# undef PRIiMAX -# if INTMAX_MAX > INT32_MAX -# define PRIiMAX PRIi64 -# else -# define PRIiMAX "li" -# endif -# endif -# if !defined PRIoMAX || @PRI_MACROS_BROKEN@ -# undef PRIoMAX -# if UINTMAX_MAX > UINT32_MAX -# define PRIoMAX PRIo64 -# else -# define PRIoMAX "lo" -# endif -# endif -# if !defined PRIuMAX || @PRI_MACROS_BROKEN@ -# undef PRIuMAX -# if UINTMAX_MAX > UINT32_MAX -# define PRIuMAX PRIu64 -# else -# define PRIuMAX "lu" -# endif -# endif -# if !defined PRIxMAX || @PRI_MACROS_BROKEN@ -# undef PRIxMAX -# if UINTMAX_MAX > UINT32_MAX -# define PRIxMAX PRIx64 -# else -# define PRIxMAX "lx" -# endif -# endif -# if !defined PRIXMAX || @PRI_MACROS_BROKEN@ -# undef PRIXMAX -# if UINTMAX_MAX > UINT32_MAX -# define PRIXMAX PRIX64 -# else -# define PRIXMAX "lX" -# endif -# endif - -# if !defined PRIdPTR || @PRI_MACROS_BROKEN@ -# undef PRIdPTR -# ifdef INTPTR_MAX -# define PRIdPTR @PRIPTR_PREFIX@ "d" -# endif -# endif -# if !defined PRIiPTR || @PRI_MACROS_BROKEN@ -# undef PRIiPTR -# ifdef INTPTR_MAX -# define PRIiPTR @PRIPTR_PREFIX@ "i" -# endif -# endif -# if !defined PRIoPTR || @PRI_MACROS_BROKEN@ -# undef PRIoPTR -# ifdef UINTPTR_MAX -# define PRIoPTR @PRIPTR_PREFIX@ "o" -# endif -# endif -# if !defined PRIuPTR || @PRI_MACROS_BROKEN@ -# undef PRIuPTR -# ifdef UINTPTR_MAX -# define PRIuPTR @PRIPTR_PREFIX@ "u" -# endif -# endif -# if !defined PRIxPTR || @PRI_MACROS_BROKEN@ -# undef PRIxPTR -# ifdef UINTPTR_MAX -# define PRIxPTR @PRIPTR_PREFIX@ "x" -# endif -# endif -# if !defined PRIXPTR || @PRI_MACROS_BROKEN@ -# undef PRIXPTR -# ifdef UINTPTR_MAX -# define PRIXPTR @PRIPTR_PREFIX@ "X" -# endif -# endif - -# if !defined SCNd8 || @PRI_MACROS_BROKEN@ -# undef SCNd8 -# ifdef INT8_MAX -# define SCNd8 "hhd" -# endif -# endif -# if !defined SCNi8 || @PRI_MACROS_BROKEN@ -# undef SCNi8 -# ifdef INT8_MAX -# define SCNi8 "hhi" -# endif -# endif -# if !defined SCNo8 || @PRI_MACROS_BROKEN@ -# undef SCNo8 -# ifdef UINT8_MAX -# define SCNo8 "hho" -# endif -# endif -# if !defined SCNu8 || @PRI_MACROS_BROKEN@ -# undef SCNu8 -# ifdef UINT8_MAX -# define SCNu8 "hhu" -# endif -# endif -# if !defined SCNx8 || @PRI_MACROS_BROKEN@ -# undef SCNx8 -# ifdef UINT8_MAX -# define SCNx8 "hhx" -# endif -# endif -# if !defined SCNd16 || @PRI_MACROS_BROKEN@ -# undef SCNd16 -# ifdef INT16_MAX -# define SCNd16 "hd" -# endif -# endif -# if !defined SCNi16 || @PRI_MACROS_BROKEN@ -# undef SCNi16 -# ifdef INT16_MAX -# define SCNi16 "hi" -# endif -# endif -# if !defined SCNo16 || @PRI_MACROS_BROKEN@ -# undef SCNo16 -# ifdef UINT16_MAX -# define SCNo16 "ho" -# endif -# endif -# if !defined SCNu16 || @PRI_MACROS_BROKEN@ -# undef SCNu16 -# ifdef UINT16_MAX -# define SCNu16 "hu" -# endif -# endif -# if !defined SCNx16 || @PRI_MACROS_BROKEN@ -# undef SCNx16 -# ifdef UINT16_MAX -# define SCNx16 "hx" -# endif -# endif -# if !defined SCNd32 || @PRI_MACROS_BROKEN@ -# undef SCNd32 -# ifdef INT32_MAX -# define SCNd32 "d" -# endif -# endif -# if !defined SCNi32 || @PRI_MACROS_BROKEN@ -# undef SCNi32 -# ifdef INT32_MAX -# define SCNi32 "i" -# endif -# endif -# if !defined SCNo32 || @PRI_MACROS_BROKEN@ -# undef SCNo32 -# ifdef UINT32_MAX -# define SCNo32 "o" -# endif -# endif -# if !defined SCNu32 || @PRI_MACROS_BROKEN@ -# undef SCNu32 -# ifdef UINT32_MAX -# define SCNu32 "u" -# endif -# endif -# if !defined SCNx32 || @PRI_MACROS_BROKEN@ -# undef SCNx32 -# ifdef UINT32_MAX -# define SCNx32 "x" -# endif -# endif -# ifdef INT64_MAX -# if INT64_MAX == LONG_MAX -# define _SCN64_PREFIX "l" -# elif defined _MSC_VER || defined __MINGW32__ -# define _SCN64_PREFIX "I64" -# elif @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 -# define _SCN64_PREFIX _LONG_LONG_FORMAT_PREFIX -# endif -# if !defined SCNd64 || @PRI_MACROS_BROKEN@ -# undef SCNd64 -# define SCNd64 _SCN64_PREFIX "d" -# endif -# if !defined SCNi64 || @PRI_MACROS_BROKEN@ -# undef SCNi64 -# define SCNi64 _SCN64_PREFIX "i" -# endif -# endif -# ifdef UINT64_MAX -# if UINT64_MAX == ULONG_MAX -# define _SCNu64_PREFIX "l" -# elif defined _MSC_VER || defined __MINGW32__ -# define _SCNu64_PREFIX "I64" -# elif @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 -# define _SCNu64_PREFIX _LONG_LONG_FORMAT_PREFIX -# endif -# if !defined SCNo64 || @PRI_MACROS_BROKEN@ -# undef SCNo64 -# define SCNo64 _SCNu64_PREFIX "o" -# endif -# if !defined SCNu64 || @PRI_MACROS_BROKEN@ -# undef SCNu64 -# define SCNu64 _SCNu64_PREFIX "u" -# endif -# if !defined SCNx64 || @PRI_MACROS_BROKEN@ -# undef SCNx64 -# define SCNx64 _SCNu64_PREFIX "x" -# endif -# endif - -# if !defined SCNdLEAST8 || @PRI_MACROS_BROKEN@ -# undef SCNdLEAST8 -# define SCNdLEAST8 "hhd" -# endif -# if !defined SCNiLEAST8 || @PRI_MACROS_BROKEN@ -# undef SCNiLEAST8 -# define SCNiLEAST8 "hhi" -# endif -# if !defined SCNoLEAST8 || @PRI_MACROS_BROKEN@ -# undef SCNoLEAST8 -# define SCNoLEAST8 "hho" -# endif -# if !defined SCNuLEAST8 || @PRI_MACROS_BROKEN@ -# undef SCNuLEAST8 -# define SCNuLEAST8 "hhu" -# endif -# if !defined SCNxLEAST8 || @PRI_MACROS_BROKEN@ -# undef SCNxLEAST8 -# define SCNxLEAST8 "hhx" -# endif -# if !defined SCNdLEAST16 || @PRI_MACROS_BROKEN@ -# undef SCNdLEAST16 -# define SCNdLEAST16 "hd" -# endif -# if !defined SCNiLEAST16 || @PRI_MACROS_BROKEN@ -# undef SCNiLEAST16 -# define SCNiLEAST16 "hi" -# endif -# if !defined SCNoLEAST16 || @PRI_MACROS_BROKEN@ -# undef SCNoLEAST16 -# define SCNoLEAST16 "ho" -# endif -# if !defined SCNuLEAST16 || @PRI_MACROS_BROKEN@ -# undef SCNuLEAST16 -# define SCNuLEAST16 "hu" -# endif -# if !defined SCNxLEAST16 || @PRI_MACROS_BROKEN@ -# undef SCNxLEAST16 -# define SCNxLEAST16 "hx" -# endif -# if !defined SCNdLEAST32 || @PRI_MACROS_BROKEN@ -# undef SCNdLEAST32 -# define SCNdLEAST32 "d" -# endif -# if !defined SCNiLEAST32 || @PRI_MACROS_BROKEN@ -# undef SCNiLEAST32 -# define SCNiLEAST32 "i" -# endif -# if !defined SCNoLEAST32 || @PRI_MACROS_BROKEN@ -# undef SCNoLEAST32 -# define SCNoLEAST32 "o" -# endif -# if !defined SCNuLEAST32 || @PRI_MACROS_BROKEN@ -# undef SCNuLEAST32 -# define SCNuLEAST32 "u" -# endif -# if !defined SCNxLEAST32 || @PRI_MACROS_BROKEN@ -# undef SCNxLEAST32 -# define SCNxLEAST32 "x" -# endif -# ifdef INT64_MAX -# if !defined SCNdLEAST64 || @PRI_MACROS_BROKEN@ -# undef SCNdLEAST64 -# define SCNdLEAST64 SCNd64 -# endif -# if !defined SCNiLEAST64 || @PRI_MACROS_BROKEN@ -# undef SCNiLEAST64 -# define SCNiLEAST64 SCNi64 -# endif -# endif -# ifdef UINT64_MAX -# if !defined SCNoLEAST64 || @PRI_MACROS_BROKEN@ -# undef SCNoLEAST64 -# define SCNoLEAST64 SCNo64 -# endif -# if !defined SCNuLEAST64 || @PRI_MACROS_BROKEN@ -# undef SCNuLEAST64 -# define SCNuLEAST64 SCNu64 -# endif -# if !defined SCNxLEAST64 || @PRI_MACROS_BROKEN@ -# undef SCNxLEAST64 -# define SCNxLEAST64 SCNx64 -# endif -# endif - -# if !defined SCNdFAST8 || @PRI_MACROS_BROKEN@ -# undef SCNdFAST8 -# if INT_FAST8_MAX > INT32_MAX -# define SCNdFAST8 SCNd64 -# elif INT_FAST8_MAX == 0x7fff -# define SCNdFAST8 "hd" -# elif INT_FAST8_MAX == 0x7f -# define SCNdFAST8 "hhd" -# else -# define SCNdFAST8 "d" -# endif -# endif -# if !defined SCNiFAST8 || @PRI_MACROS_BROKEN@ -# undef SCNiFAST8 -# if INT_FAST8_MAX > INT32_MAX -# define SCNiFAST8 SCNi64 -# elif INT_FAST8_MAX == 0x7fff -# define SCNiFAST8 "hi" -# elif INT_FAST8_MAX == 0x7f -# define SCNiFAST8 "hhi" -# else -# define SCNiFAST8 "i" -# endif -# endif -# if !defined SCNoFAST8 || @PRI_MACROS_BROKEN@ -# undef SCNoFAST8 -# if UINT_FAST8_MAX > UINT32_MAX -# define SCNoFAST8 SCNo64 -# elif UINT_FAST8_MAX == 0xffff -# define SCNoFAST8 "ho" -# elif UINT_FAST8_MAX == 0xff -# define SCNoFAST8 "hho" -# else -# define SCNoFAST8 "o" -# endif -# endif -# if !defined SCNuFAST8 || @PRI_MACROS_BROKEN@ -# undef SCNuFAST8 -# if UINT_FAST8_MAX > UINT32_MAX -# define SCNuFAST8 SCNu64 -# elif UINT_FAST8_MAX == 0xffff -# define SCNuFAST8 "hu" -# elif UINT_FAST8_MAX == 0xff -# define SCNuFAST8 "hhu" -# else -# define SCNuFAST8 "u" -# endif -# endif -# if !defined SCNxFAST8 || @PRI_MACROS_BROKEN@ -# undef SCNxFAST8 -# if UINT_FAST8_MAX > UINT32_MAX -# define SCNxFAST8 SCNx64 -# elif UINT_FAST8_MAX == 0xffff -# define SCNxFAST8 "hx" -# elif UINT_FAST8_MAX == 0xff -# define SCNxFAST8 "hhx" -# else -# define SCNxFAST8 "x" -# endif -# endif -# if !defined SCNdFAST16 || @PRI_MACROS_BROKEN@ -# undef SCNdFAST16 -# if INT_FAST16_MAX > INT32_MAX -# define SCNdFAST16 SCNd64 -# elif INT_FAST16_MAX == 0x7fff -# define SCNdFAST16 "hd" -# else -# define SCNdFAST16 "d" -# endif -# endif -# if !defined SCNiFAST16 || @PRI_MACROS_BROKEN@ -# undef SCNiFAST16 -# if INT_FAST16_MAX > INT32_MAX -# define SCNiFAST16 SCNi64 -# elif INT_FAST16_MAX == 0x7fff -# define SCNiFAST16 "hi" -# else -# define SCNiFAST16 "i" -# endif -# endif -# if !defined SCNoFAST16 || @PRI_MACROS_BROKEN@ -# undef SCNoFAST16 -# if UINT_FAST16_MAX > UINT32_MAX -# define SCNoFAST16 SCNo64 -# elif UINT_FAST16_MAX == 0xffff -# define SCNoFAST16 "ho" -# else -# define SCNoFAST16 "o" -# endif -# endif -# if !defined SCNuFAST16 || @PRI_MACROS_BROKEN@ -# undef SCNuFAST16 -# if UINT_FAST16_MAX > UINT32_MAX -# define SCNuFAST16 SCNu64 -# elif UINT_FAST16_MAX == 0xffff -# define SCNuFAST16 "hu" -# else -# define SCNuFAST16 "u" -# endif -# endif -# if !defined SCNxFAST16 || @PRI_MACROS_BROKEN@ -# undef SCNxFAST16 -# if UINT_FAST16_MAX > UINT32_MAX -# define SCNxFAST16 SCNx64 -# elif UINT_FAST16_MAX == 0xffff -# define SCNxFAST16 "hx" -# else -# define SCNxFAST16 "x" -# endif -# endif -# if !defined SCNdFAST32 || @PRI_MACROS_BROKEN@ -# undef SCNdFAST32 -# if INT_FAST32_MAX > INT32_MAX -# define SCNdFAST32 SCNd64 -# else -# define SCNdFAST32 "d" -# endif -# endif -# if !defined SCNiFAST32 || @PRI_MACROS_BROKEN@ -# undef SCNiFAST32 -# if INT_FAST32_MAX > INT32_MAX -# define SCNiFAST32 SCNi64 -# else -# define SCNiFAST32 "i" -# endif -# endif -# if !defined SCNoFAST32 || @PRI_MACROS_BROKEN@ -# undef SCNoFAST32 -# if UINT_FAST32_MAX > UINT32_MAX -# define SCNoFAST32 SCNo64 -# else -# define SCNoFAST32 "o" -# endif -# endif -# if !defined SCNuFAST32 || @PRI_MACROS_BROKEN@ -# undef SCNuFAST32 -# if UINT_FAST32_MAX > UINT32_MAX -# define SCNuFAST32 SCNu64 -# else -# define SCNuFAST32 "u" -# endif -# endif -# if !defined SCNxFAST32 || @PRI_MACROS_BROKEN@ -# undef SCNxFAST32 -# if UINT_FAST32_MAX > UINT32_MAX -# define SCNxFAST32 SCNx64 -# else -# define SCNxFAST32 "x" -# endif -# endif -# ifdef INT64_MAX -# if !defined SCNdFAST64 || @PRI_MACROS_BROKEN@ -# undef SCNdFAST64 -# define SCNdFAST64 SCNd64 -# endif -# if !defined SCNiFAST64 || @PRI_MACROS_BROKEN@ -# undef SCNiFAST64 -# define SCNiFAST64 SCNi64 -# endif -# endif -# ifdef UINT64_MAX -# if !defined SCNoFAST64 || @PRI_MACROS_BROKEN@ -# undef SCNoFAST64 -# define SCNoFAST64 SCNo64 -# endif -# if !defined SCNuFAST64 || @PRI_MACROS_BROKEN@ -# undef SCNuFAST64 -# define SCNuFAST64 SCNu64 -# endif -# if !defined SCNxFAST64 || @PRI_MACROS_BROKEN@ -# undef SCNxFAST64 -# define SCNxFAST64 SCNx64 -# endif -# endif - -# if !defined SCNdMAX || @PRI_MACROS_BROKEN@ -# undef SCNdMAX -# if INTMAX_MAX > INT32_MAX -# define SCNdMAX SCNd64 -# else -# define SCNdMAX "ld" -# endif -# endif -# if !defined SCNiMAX || @PRI_MACROS_BROKEN@ -# undef SCNiMAX -# if INTMAX_MAX > INT32_MAX -# define SCNiMAX SCNi64 -# else -# define SCNiMAX "li" -# endif -# endif -# if !defined SCNoMAX || @PRI_MACROS_BROKEN@ -# undef SCNoMAX -# if UINTMAX_MAX > UINT32_MAX -# define SCNoMAX SCNo64 -# else -# define SCNoMAX "lo" -# endif -# endif -# if !defined SCNuMAX || @PRI_MACROS_BROKEN@ -# undef SCNuMAX -# if UINTMAX_MAX > UINT32_MAX -# define SCNuMAX SCNu64 -# else -# define SCNuMAX "lu" -# endif -# endif -# if !defined SCNxMAX || @PRI_MACROS_BROKEN@ -# undef SCNxMAX -# if UINTMAX_MAX > UINT32_MAX -# define SCNxMAX SCNx64 -# else -# define SCNxMAX "lx" -# endif -# endif - -# if !defined SCNdPTR || @PRI_MACROS_BROKEN@ -# undef SCNdPTR -# ifdef INTPTR_MAX -# define SCNdPTR @PRIPTR_PREFIX@ "d" -# endif -# endif -# if !defined SCNiPTR || @PRI_MACROS_BROKEN@ -# undef SCNiPTR -# ifdef INTPTR_MAX -# define SCNiPTR @PRIPTR_PREFIX@ "i" -# endif -# endif -# if !defined SCNoPTR || @PRI_MACROS_BROKEN@ -# undef SCNoPTR -# ifdef UINTPTR_MAX -# define SCNoPTR @PRIPTR_PREFIX@ "o" -# endif -# endif -# if !defined SCNuPTR || @PRI_MACROS_BROKEN@ -# undef SCNuPTR -# ifdef UINTPTR_MAX -# define SCNuPTR @PRIPTR_PREFIX@ "u" -# endif -# endif -# if !defined SCNxPTR || @PRI_MACROS_BROKEN@ -# undef SCNxPTR -# ifdef UINTPTR_MAX -# define SCNxPTR @PRIPTR_PREFIX@ "x" -# endif -# endif - -#endif - -/* 7.8.2 Functions for greatest-width integer types */ - -#ifdef __cplusplus -extern "C" { -#endif - -#if @GNULIB_IMAXABS@ -# if !@HAVE_DECL_IMAXABS@ -extern intmax_t imaxabs (intmax_t); -# endif -#elif defined GNULIB_POSIXCHECK -# undef imaxabs -# define imaxabs(a) \ - (GL_LINK_WARNING ("imaxabs is unportable - " \ - "use gnulib module imaxabs for portability"), \ - imaxabs (a)) -#endif - -#if @GNULIB_IMAXDIV@ -# if !@HAVE_DECL_IMAXDIV@ -typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; -extern imaxdiv_t imaxdiv (intmax_t, intmax_t); -# endif -#elif defined GNULIB_POSIXCHECK -# undef imaxdiv -# define imaxdiv(a,b) \ - (GL_LINK_WARNING ("imaxdiv is unportable - " \ - "use gnulib module imaxdiv for portability"), \ - imaxdiv (a, b)) -#endif - -#if @GNULIB_STRTOIMAX@ -# if !@HAVE_DECL_STRTOIMAX@ -extern intmax_t strtoimax (const char *, char **, int); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strtoimax -# define strtoimax(p,e,b) \ - (GL_LINK_WARNING ("strtoimax is unportable - " \ - "use gnulib module strtoimax for portability"), \ - strtoimax (p, e, b)) -#endif - -#if @GNULIB_STRTOUMAX@ -# if !@HAVE_DECL_STRTOUMAX@ -extern uintmax_t strtoumax (const char *, char **, int); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strtoumax -# define strtoumax(p,e,b) \ - (GL_LINK_WARNING ("strtoumax is unportable - " \ - "use gnulib module strtoumax for portability"), \ - strtoumax (p, e, b)) -#endif - -/* Don't bother defining or declaring wcstoimax and wcstoumax, since - wide-character functions like this are hardly ever useful. */ - -#ifdef __cplusplus -} -#endif - -#endif /* !defined INTTYPES_H && !defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H */ diff --git a/src/bin/tar/lib/lchown.c b/src/bin/tar/lib/lchown.c deleted file mode 100644 index 4ed4742116..0000000000 --- a/src/bin/tar/lib/lchown.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Provide a stub lchown function for systems that lack it. - - Copyright (C) 1998, 1999, 2002, 2004, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -/* If the system chown does not follow symlinks, we don't want it - replaced by gnulib's chown, which does follow symlinks. */ -#if CHOWN_MODIFIES_SYMLINK -# define REPLACE_CHOWN 0 -#endif -#include - -#include -#include - -/* Some systems don't have EOPNOTSUPP. */ -#ifndef EOPNOTSUPP -# ifdef ENOTSUP -# define EOPNOTSUPP ENOTSUP -# else -/* Some systems don't have ENOTSUP either. */ -# define EOPNOTSUPP EINVAL -# endif -#endif - -/* Work just like chown, except when FILE is a symbolic link. - In that case, set errno to EOPNOTSUPP and return -1. - But if autoconf tests determined that chown modifies - symlinks, then just call chown. */ - -int -lchown (const char *file, uid_t uid, gid_t gid) -{ -#if ! CHOWN_MODIFIES_SYMLINK - struct stat stats; - - if (lstat (file, &stats) == 0 && S_ISLNK (stats.st_mode)) - { - errno = EOPNOTSUPP; - return -1; - } -#endif - - return chown (file, uid, gid); -} diff --git a/src/bin/tar/lib/localcharset.c b/src/bin/tar/lib/localcharset.c deleted file mode 100644 index a0f7cca691..0000000000 --- a/src/bin/tar/lib/localcharset.c +++ /dev/null @@ -1,460 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - - Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Bruno Haible . */ - -#include - -/* Specification. */ -#include "localcharset.h" - -#include -#include -#include -#include - -#if defined _WIN32 || defined __WIN32__ -# define WIN32_NATIVE -#endif - -#if defined __EMX__ -/* Assume EMX program runs on OS/2, even if compiled under DOS. */ -# define OS2 -#endif - -#if !defined WIN32_NATIVE -# if HAVE_LANGINFO_CODESET -# include -# else -# if 0 /* see comment below */ -# include -# endif -# endif -# ifdef __CYGWIN__ -# define WIN32_LEAN_AND_MEAN -# include -# endif -#elif defined WIN32_NATIVE -# define WIN32_LEAN_AND_MEAN -# include -#endif -#if defined OS2 -# define INCL_DOS -# include -#endif - -#if ENABLE_RELOCATABLE -# include "relocatable.h" -#else -# define relocate(pathname) (pathname) -#endif - -/* Get LIBDIR. */ -#ifndef LIBDIR -# include "configmake.h" -#endif - -#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ - /* Win32, Cygwin, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#endif - -#ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -#endif - -#ifndef ISSLASH -# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) -#endif - -#if HAVE_DECL_GETC_UNLOCKED -# undef getc -# define getc getc_unlocked -#endif - -/* The following static variable is declared 'volatile' to avoid a - possible multithread problem in the function get_charset_aliases. If we - are running in a threaded environment, and if two threads initialize - 'charset_aliases' simultaneously, both will produce the same value, - and everything will be ok if the two assignments to 'charset_aliases' - are atomic. But I don't know what will happen if the two assignments mix. */ -#if __STDC__ != 1 -# define volatile /* empty */ -#endif -/* Pointer to the contents of the charset.alias file, if it has already been - read, else NULL. Its format is: - ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ -static const char * volatile charset_aliases; - -/* Return a pointer to the contents of the charset.alias file. */ -static const char * -get_charset_aliases (void) -{ - const char *cp; - - cp = charset_aliases; - if (cp == NULL) - { -#if !(defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) - FILE *fp; - const char *dir; - const char *base = "charset.alias"; - char *file_name; - - /* Make it possible to override the charset.alias location. This is - necessary for running the testsuite before "make install". */ - dir = getenv ("CHARSETALIASDIR"); - if (dir == NULL || dir[0] == '\0') - dir = relocate (LIBDIR); - - /* Concatenate dir and base into freshly allocated file_name. */ - { - size_t dir_len = strlen (dir); - size_t base_len = strlen (base); - int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); - file_name = (char *) malloc (dir_len + add_slash + base_len + 1); - if (file_name != NULL) - { - memcpy (file_name, dir, dir_len); - if (add_slash) - file_name[dir_len] = DIRECTORY_SEPARATOR; - memcpy (file_name + dir_len + add_slash, base, base_len + 1); - } - } - - if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) - /* Out of memory or file not found, treat it as empty. */ - cp = ""; - else - { - /* Parse the file's contents. */ - char *res_ptr = NULL; - size_t res_size = 0; - - for (;;) - { - int c; - char buf1[50+1]; - char buf2[50+1]; - size_t l1, l2; - char *old_res_ptr; - - c = getc (fp); - if (c == EOF) - break; - if (c == '\n' || c == ' ' || c == '\t') - continue; - if (c == '#') - { - /* Skip comment, to end of line. */ - do - c = getc (fp); - while (!(c == EOF || c == '\n')); - if (c == EOF) - break; - continue; - } - ungetc (c, fp); - if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) - break; - l1 = strlen (buf1); - l2 = strlen (buf2); - old_res_ptr = res_ptr; - if (res_size == 0) - { - res_size = l1 + 1 + l2 + 1; - res_ptr = (char *) malloc (res_size + 1); - } - else - { - res_size += l1 + 1 + l2 + 1; - res_ptr = (char *) realloc (res_ptr, res_size + 1); - } - if (res_ptr == NULL) - { - /* Out of memory. */ - res_size = 0; - if (old_res_ptr != NULL) - free (old_res_ptr); - break; - } - strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); - strcpy (res_ptr + res_size - (l2 + 1), buf2); - } - fclose (fp); - if (res_size == 0) - cp = ""; - else - { - *(res_ptr + res_size) = '\0'; - cp = res_ptr; - } - } - - if (file_name != NULL) - free (file_name); - -#else - -# if defined VMS - /* To avoid the troubles of an extra file charset.alias_vms in the - sources of many GNU packages, simply inline the aliases here. */ - /* The list of encodings is taken from the OpenVMS 7.3-1 documentation - "Compaq C Run-Time Library Reference Manual for OpenVMS systems" - section 10.7 "Handling Different Character Sets". */ - cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" - "ISO8859-2" "\0" "ISO-8859-2" "\0" - "ISO8859-5" "\0" "ISO-8859-5" "\0" - "ISO8859-7" "\0" "ISO-8859-7" "\0" - "ISO8859-8" "\0" "ISO-8859-8" "\0" - "ISO8859-9" "\0" "ISO-8859-9" "\0" - /* Japanese */ - "eucJP" "\0" "EUC-JP" "\0" - "SJIS" "\0" "SHIFT_JIS" "\0" - "DECKANJI" "\0" "DEC-KANJI" "\0" - "SDECKANJI" "\0" "EUC-JP" "\0" - /* Chinese */ - "eucTW" "\0" "EUC-TW" "\0" - "DECHANYU" "\0" "DEC-HANYU" "\0" - "DECHANZI" "\0" "GB2312" "\0" - /* Korean */ - "DECKOREAN" "\0" "EUC-KR" "\0"; -# endif - -# if defined WIN32_NATIVE || defined __CYGWIN__ - /* To avoid the troubles of installing a separate file in the same - directory as the DLL and of retrieving the DLL's directory at - runtime, simply inline the aliases here. */ - - cp = "CP936" "\0" "GBK" "\0" - "CP1361" "\0" "JOHAB" "\0" - "CP20127" "\0" "ASCII" "\0" - "CP20866" "\0" "KOI8-R" "\0" - "CP20936" "\0" "GB2312" "\0" - "CP21866" "\0" "KOI8-RU" "\0" - "CP28591" "\0" "ISO-8859-1" "\0" - "CP28592" "\0" "ISO-8859-2" "\0" - "CP28593" "\0" "ISO-8859-3" "\0" - "CP28594" "\0" "ISO-8859-4" "\0" - "CP28595" "\0" "ISO-8859-5" "\0" - "CP28596" "\0" "ISO-8859-6" "\0" - "CP28597" "\0" "ISO-8859-7" "\0" - "CP28598" "\0" "ISO-8859-8" "\0" - "CP28599" "\0" "ISO-8859-9" "\0" - "CP28605" "\0" "ISO-8859-15" "\0" - "CP38598" "\0" "ISO-8859-8" "\0" - "CP51932" "\0" "EUC-JP" "\0" - "CP51936" "\0" "GB2312" "\0" - "CP51949" "\0" "EUC-KR" "\0" - "CP51950" "\0" "EUC-TW" "\0" - "CP54936" "\0" "GB18030" "\0" - "CP65001" "\0" "UTF-8" "\0"; -# endif -#endif - - charset_aliases = cp; - } - - return cp; -} - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ - -#ifdef STATIC -STATIC -#endif -const char * -locale_charset (void) -{ - const char *codeset; - const char *aliases; - -#if !(defined WIN32_NATIVE || defined OS2) - -# if HAVE_LANGINFO_CODESET - - /* Most systems support nl_langinfo (CODESET) nowadays. */ - codeset = nl_langinfo (CODESET); - -# ifdef __CYGWIN__ - /* Cygwin 2006 does not have locales. nl_langinfo (CODESET) always - returns "US-ASCII". As long as this is not fixed, return the suffix - of the locale name from the environment variables (if present) or - the codepage as a number. */ - if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) - { - const char *locale; - static char buf[2 + 10 + 1]; - - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return - it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - } - - /* Woe32 has a function returning the locale's codepage as a number. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; - } -# endif - -# else - - /* On old systems which lack it, use setlocale or getenv. */ - const char *locale = NULL; - - /* But most old systems don't have a complete set of locales. Some - (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't - use setlocale here; it would return "C" when it doesn't support the - locale name the user has set. */ -# if 0 - locale = setlocale (LC_CTYPE, NULL); -# endif - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - } - - /* On some old systems, one used to set locale = "iso8859_1". On others, - you set it to "language_COUNTRY.charset". In any case, we resolve it - through the charset.alias file. */ - codeset = locale; - -# endif - -#elif defined WIN32_NATIVE - - static char buf[2 + 10 + 1]; - - /* Woe32 has a function returning the locale's codepage as a number. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; - -#elif defined OS2 - - const char *locale; - static char buf[2 + 10 + 1]; - ULONG cp[3]; - ULONG cplen; - - /* Allow user to override the codeset, as set in the operating system, - with standard language environment variables. */ - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - - /* Resolve through the charset.alias file. */ - codeset = locale; - } - else - { - /* OS/2 has a function returning the locale's codepage as a number. */ - if (DosQueryCp (sizeof (cp), cp, &cplen)) - codeset = ""; - else - { - sprintf (buf, "CP%u", cp[0]); - codeset = buf; - } - } - -#endif - - if (codeset == NULL) - /* The canonical name cannot be determined. */ - codeset = ""; - - /* Resolve alias. */ - for (aliases = get_charset_aliases (); - *aliases != '\0'; - aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) - if (strcmp (codeset, aliases) == 0 - || (aliases[0] == '*' && aliases[1] == '\0')) - { - codeset = aliases + strlen (aliases) + 1; - break; - } - - /* Don't return an empty string. GNU libc and GNU libiconv interpret - the empty string as denoting "the locale's character encoding", - thus GNU libiconv would call this function a second time. */ - if (codeset[0] == '\0') - codeset = "ASCII"; - - return codeset; -} diff --git a/src/bin/tar/lib/localcharset.h b/src/bin/tar/lib/localcharset.h deleted file mode 100644 index 5030210d11..0000000000 --- a/src/bin/tar/lib/localcharset.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2003 Free Software Foundation, Inc. - This file is part of the GNU CHARSET Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LOCALCHARSET_H -#define _LOCALCHARSET_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ -extern const char * locale_charset (void); - - -#ifdef __cplusplus -} -#endif - - -#endif /* _LOCALCHARSET_H */ diff --git a/src/bin/tar/lib/lstat.c b/src/bin/tar/lib/lstat.c deleted file mode 100644 index 77dd22859c..0000000000 --- a/src/bin/tar/lib/lstat.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Work around a bug of lstat on some systems - - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -/* The specification of these functions is in sys_stat.h. But we cannot - include this include file here, because on some systems, a - "#define lstat lstat64" is being used, and sys_stat.h deletes this - definition. */ - -#include -#include -#include -#include - -/* lstat works differently on Linux and Solaris systems. POSIX (see - `pathname resolution' in the glossary) requires that programs like - `ls' take into consideration the fact that FILE has a trailing slash - when FILE is a symbolic link. On Linux and Solaris 10 systems, the - lstat function already has the desired semantics (in treating - `lstat ("symlink/", sbuf)' just like `lstat ("symlink/.", sbuf)', - but on Solaris 9 and earlier it does not. - - If FILE has a trailing slash and specifies a symbolic link, - then use stat() to get more info on the referent of FILE. - If the referent is a non-directory, then set errno to ENOTDIR - and return -1. Otherwise, return stat's result. */ - -int -rpl_lstat (const char *file, struct stat *sbuf) -{ - size_t len; - int lstat_result = lstat (file, sbuf); - - if (lstat_result != 0 || !S_ISLNK (sbuf->st_mode)) - return lstat_result; - - len = strlen (file); - if (len == 0 || file[len - 1] != '/') - return 0; - - /* FILE refers to a symbolic link and the name ends with a slash. - Call stat() to get info about the link's referent. */ - - /* If stat fails, then we do the same. */ - if (stat (file, sbuf) != 0) - return -1; - - /* If FILE references a directory, return 0. */ - if (S_ISDIR (sbuf->st_mode)) - return 0; - - /* Here, we know stat succeeded and FILE references a non-directory. - But it was specified via a name including a trailing slash. - Fail with errno set to ENOTDIR to indicate the contradiction. */ - errno = ENOTDIR; - return -1; -} diff --git a/src/bin/tar/lib/lstat.h b/src/bin/tar/lib/lstat.h deleted file mode 100644 index 6a83fbf8fe..0000000000 --- a/src/bin/tar/lib/lstat.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Retrieving information about files. - Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#if !LSTAT_FOLLOWS_SLASHED_SYMLINK -extern int rpl_lstat (const char *name, struct stat *buf); -# undef lstat -# define lstat rpl_lstat -#endif diff --git a/src/bin/tar/lib/malloc.c b/src/bin/tar/lib/malloc.c deleted file mode 100644 index eba131d1f2..0000000000 --- a/src/bin/tar/lib/malloc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* malloc() function that is glibc compatible. - - Copyright (C) 1997, 1998, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering and Bruno Haible */ - -#include -/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */ -#ifdef malloc -# define NEED_MALLOC_GNU -# undef malloc -#endif - -/* Specification. */ -#include - -#include - -/* Call the system's malloc below. */ -#undef malloc - -/* Allocate an N-byte block of memory from the heap. - If N is zero, allocate a 1-byte block. */ - -void * -rpl_malloc (size_t n) -{ - void *result; - -#ifdef NEED_MALLOC_GNU - if (n == 0) - n = 1; -#endif - - result = malloc (n); - -#if !HAVE_MALLOC_POSIX - if (result == NULL) - errno = ENOMEM; -#endif - - return result; -} diff --git a/src/bin/tar/lib/malloca.c b/src/bin/tar/lib/malloca.c deleted file mode 100644 index 4145bf6df1..0000000000 --- a/src/bin/tar/lib/malloca.c +++ /dev/null @@ -1,137 +0,0 @@ -/* Safe automatic memory allocation. - Copyright (C) 2003, 2006-2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2003. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include "malloca.h" - -/* The speed critical point in this file is freea() applied to an alloca() - result: it must be fast, to match the speed of alloca(). The speed of - mmalloca() and freea() in the other case are not critical, because they - are only invoked for big memory sizes. */ - -#if HAVE_ALLOCA - -/* Store the mmalloca() results in a hash table. This is needed to reliably - distinguish a mmalloca() result and an alloca() result. - - Although it is possible that the same pointer is returned by alloca() and - by mmalloca() at different times in the same application, it does not lead - to a bug in freea(), because: - - Before a pointer returned by alloca() can point into malloc()ed memory, - the function must return, and once this has happened the programmer must - not call freea() on it anyway. - - Before a pointer returned by mmalloca() can point into the stack, it - must be freed. The only function that can free it is freea(), and - when freea() frees it, it also removes it from the hash table. */ - -#define MAGIC_NUMBER 0x1415fb4a -#define MAGIC_SIZE sizeof (int) -/* This is how the header info would look like without any alignment - considerations. */ -struct preliminary_header { void *next; char room[MAGIC_SIZE]; }; -/* But the header's size must be a multiple of sa_alignment_max. */ -#define HEADER_SIZE \ - (((sizeof (struct preliminary_header) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max) -struct header { void *next; char room[HEADER_SIZE - sizeof (struct preliminary_header) + MAGIC_SIZE]; }; -/* Verify that HEADER_SIZE == sizeof (struct header). */ -typedef int verify1[2 * (HEADER_SIZE == sizeof (struct header)) - 1]; -/* We make the hash table quite big, so that during lookups the probability - of empty hash buckets is quite high. There is no need to make the hash - table resizable, because when the hash table gets filled so much that the - lookup becomes slow, it means that the application has memory leaks. */ -#define HASH_TABLE_SIZE 257 -static void * mmalloca_results[HASH_TABLE_SIZE]; - -#endif - -void * -mmalloca (size_t n) -{ -#if HAVE_ALLOCA - /* Allocate one more word, that serves as an indicator for malloc()ed - memory, so that freea() of an alloca() result is fast. */ - size_t nplus = n + HEADER_SIZE; - - if (nplus >= n) - { - char *p = (char *) malloc (nplus); - - if (p != NULL) - { - size_t slot; - - p += HEADER_SIZE; - - /* Put a magic number into the indicator word. */ - ((int *) p)[-1] = MAGIC_NUMBER; - - /* Enter p into the hash table. */ - slot = (unsigned long) p % HASH_TABLE_SIZE; - ((struct header *) (p - HEADER_SIZE))->next = mmalloca_results[slot]; - mmalloca_results[slot] = p; - - return p; - } - } - /* Out of memory. */ - return NULL; -#else -# if !MALLOC_0_IS_NONNULL - if (n == 0) - n = 1; -# endif - return malloc (n); -#endif -} - -#if HAVE_ALLOCA -void -freea (void *p) -{ - /* mmalloca() may have returned NULL. */ - if (p != NULL) - { - /* Attempt to quickly distinguish the mmalloca() result - which has - a magic indicator word - and the alloca() result - which has an - uninitialized indicator word. It is for this test that sa_increment - additional bytes are allocated in the alloca() case. */ - if (((int *) p)[-1] == MAGIC_NUMBER) - { - /* Looks like a mmalloca() result. To see whether it really is one, - perform a lookup in the hash table. */ - size_t slot = (unsigned long) p % HASH_TABLE_SIZE; - void **chain = &mmalloca_results[slot]; - for (; *chain != NULL;) - { - if (*chain == p) - { - /* Found it. Remove it from the hash table and free it. */ - char *p_begin = (char *) p - HEADER_SIZE; - *chain = ((struct header *) p_begin)->next; - free (p_begin); - return; - } - chain = &((struct header *) ((char *) *chain - HEADER_SIZE))->next; - } - } - /* At this point, we know it was not a mmalloca() result. */ - } -} -#endif diff --git a/src/bin/tar/lib/malloca.h b/src/bin/tar/lib/malloca.h deleted file mode 100644 index 2f74b96170..0000000000 --- a/src/bin/tar/lib/malloca.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Safe automatic memory allocation. - Copyright (C) 2003-2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2003. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _MALLOCA_H -#define _MALLOCA_H - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call - alloca(N); otherwise it returns NULL. It either returns N bytes of - memory allocated on the stack, that lasts until the function returns, - or NULL. - Use of safe_alloca should be avoided: - - inside arguments of function calls - undefined behaviour, - - in inline functions - the allocation may actually last until the - calling function returns. -*/ -#if HAVE_ALLOCA -/* The OS usually guarantees only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - allocate anything larger than 4096 bytes. Also care for the possibility - of a few compiler-allocated temporary stack slots. - This must be a macro, not an inline function. */ -# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL) -#else -# define safe_alloca(N) ((void) (N), NULL) -#endif - -/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of - memory allocated on the stack, that must be freed using freea() before - the function returns. Upon failure, it returns NULL. */ -#if HAVE_ALLOCA -# define malloca(N) \ - ((N) < 4032 - sa_increment \ - ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \ - : mmalloca (N)) -#else -# define malloca(N) \ - mmalloca (N) -#endif -extern void * mmalloca (size_t n); - -/* Free a block of memory allocated through malloca(). */ -#if HAVE_ALLOCA -extern void freea (void *p); -#else -# define freea free -#endif - -/* Maybe we should also define a variant - nmalloca (size_t n, size_t s) - behaves like malloca (n * s) - If this would be useful in your application. please speak up. */ - - -#ifdef __cplusplus -} -#endif - - -/* ------------------- Auxiliary, non-public definitions ------------------- */ - -/* Determine the alignment of a type at compile time. */ -#if defined __GNUC__ -# define sa_alignof __alignof__ -#elif defined __cplusplus - template struct sa_alignof_helper { char __slot1; type __slot2; }; -# define sa_alignof(type) offsetof (sa_alignof_helper, __slot2) -#elif defined __hpux - /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof - values. */ -# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) -#elif defined _AIX - /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof - values. */ -# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8) -#else -# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2) -#endif - -enum -{ -/* The desired alignment of memory allocations is the maximum alignment - among all elementary types. */ - sa_alignment_long = sa_alignof (long), - sa_alignment_double = sa_alignof (double), -#if HAVE_LONG_LONG_INT - sa_alignment_longlong = sa_alignof (long long), -#endif - sa_alignment_longdouble = sa_alignof (long double), - sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1) -#if HAVE_LONG_LONG_INT - | (sa_alignment_longlong - 1) -#endif - | (sa_alignment_longdouble - 1) - ) + 1, -/* The increment that guarantees room for a magic word must be >= sizeof (int) - and a multiple of sa_alignment_max. */ - sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max -}; - -#endif /* _MALLOCA_H */ diff --git a/src/bin/tar/lib/malloca.valgrind b/src/bin/tar/lib/malloca.valgrind deleted file mode 100644 index 52f0a50f57..0000000000 --- a/src/bin/tar/lib/malloca.valgrind +++ /dev/null @@ -1,7 +0,0 @@ -# Suppress a valgrind message about use of uninitialized memory in freea(). -# This use is OK because it provides only a speedup. -{ - freea - Memcheck:Cond - fun:freea -} diff --git a/src/bin/tar/lib/mbchar.c b/src/bin/tar/lib/mbchar.c deleted file mode 100644 index 95373f58ba..0000000000 --- a/src/bin/tar/lib/mbchar.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2001, 2006 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - - -#include - -#include - -#include "mbchar.h" - -#if IS_BASIC_ASCII - -/* Bit table of characters in the ISO C "basic character set". */ -const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] = -{ - 0x00001a00, /* '\t' '\v' '\f' */ - 0xffffffef, /* ' '...'#' '%'...'?' */ - 0xfffffffe, /* 'A'...'Z' '[' '\\' ']' '^' '_' */ - 0x7ffffffe /* 'a'...'z' '{' '|' '}' '~' */ - /* The remaining bits are 0. */ -}; - -#endif /* IS_BASIC_ASCII */ diff --git a/src/bin/tar/lib/mbchar.h b/src/bin/tar/lib/mbchar.h deleted file mode 100644 index 213d425679..0000000000 --- a/src/bin/tar/lib/mbchar.h +++ /dev/null @@ -1,351 +0,0 @@ -/* Multibyte character data type. - Copyright (C) 2001, 2005-2007 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Bruno Haible . */ - -/* A multibyte character is a short subsequence of a char* string, - representing a single wide character. - - We use multibyte characters instead of wide characters because of - the following goals: - 1) correct multibyte handling, i.e. operate according to the LC_CTYPE - locale, - 2) ease of maintenance, i.e. the maintainer needs not know all details - of the ISO C 99 standard, - 3) don't fail grossly if the input is not in the encoding set by the - locale, because often different encodings are in use in the same - countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), - 4) fast in the case of ASCII characters, - 5) portability, i.e. don't make unportable assumptions about wchar_t. - - Multibyte characters are only accessed through the mb* macros. - - mb_ptr (mbc) - return a pointer to the beginning of the multibyte sequence. - - mb_len (mbc) - returns the number of bytes occupied by the multibyte sequence. - Always > 0. - - mb_iseq (mbc, sc) - returns true if mbc is the standard ASCII character sc. - - mb_isnul (mbc) - returns true if mbc is the nul character. - - mb_cmp (mbc1, mbc2) - returns a positive, zero, or negative value depending on whether mbc1 - sorts after, same or before mbc2. - - mb_casecmp (mbc1, mbc2) - returns a positive, zero, or negative value depending on whether mbc1 - sorts after, same or before mbc2, modulo upper/lowercase conversion. - - mb_equal (mbc1, mbc2) - returns true if mbc1 and mbc2 are equal. - - mb_caseequal (mbc1, mbc2) - returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. - - mb_isalnum (mbc) - returns true if mbc is alphanumeric. - - mb_isalpha (mbc) - returns true if mbc is alphabetic. - - mb_isascii(mbc) - returns true if mbc is plain ASCII. - - mb_isblank (mbc) - returns true if mbc is a blank. - - mb_iscntrl (mbc) - returns true if mbc is a control character. - - mb_isdigit (mbc) - returns true if mbc is a decimal digit. - - mb_isgraph (mbc) - returns true if mbc is a graphic character. - - mb_islower (mbc) - returns true if mbc is lowercase. - - mb_isprint (mbc) - returns true if mbc is a printable character. - - mb_ispunct (mbc) - returns true if mbc is a punctuation character. - - mb_isspace (mbc) - returns true if mbc is a space character. - - mb_isupper (mbc) - returns true if mbc is uppercase. - - mb_isxdigit (mbc) - returns true if mbc is a hexadecimal digit. - - mb_width (mbc) - returns the number of columns on the output device occupied by mbc. - Always >= 0. - - mb_putc (mbc, stream) - outputs mbc on stream, a byte oriented FILE stream opened for output. - - mb_setascii (&mbc, sc) - assigns the standard ASCII character sc to mbc. - - mb_copy (&destmbc, &srcmbc) - copies srcmbc to destmbc. - - Here are the function prototypes of the macros. - - extern const char * mb_ptr (const mbchar_t mbc); - extern size_t mb_len (const mbchar_t mbc); - extern bool mb_iseq (const mbchar_t mbc, char sc); - extern bool mb_isnul (const mbchar_t mbc); - extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); - extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); - extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); - extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); - extern bool mb_isalnum (const mbchar_t mbc); - extern bool mb_isalpha (const mbchar_t mbc); - extern bool mb_isascii (const mbchar_t mbc); - extern bool mb_isblank (const mbchar_t mbc); - extern bool mb_iscntrl (const mbchar_t mbc); - extern bool mb_isdigit (const mbchar_t mbc); - extern bool mb_isgraph (const mbchar_t mbc); - extern bool mb_islower (const mbchar_t mbc); - extern bool mb_isprint (const mbchar_t mbc); - extern bool mb_ispunct (const mbchar_t mbc); - extern bool mb_isspace (const mbchar_t mbc); - extern bool mb_isupper (const mbchar_t mbc); - extern bool mb_isxdigit (const mbchar_t mbc); - extern int mb_width (const mbchar_t mbc); - extern void mb_putc (const mbchar_t mbc, FILE *stream); - extern void mb_setascii (mbchar_t *new, char sc); - extern void mb_copy (mbchar_t *new, const mbchar_t *old); - */ - -#ifndef _MBCHAR_H -#define _MBCHAR_H 1 - -#include -#include - -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.1 has a bug: and must be included before - . */ -#include -#include -#include -#include - -#define MBCHAR_BUF_SIZE 24 - -struct mbchar -{ - const char *ptr; /* pointer to current character */ - size_t bytes; /* number of bytes of current character, > 0 */ - bool wc_valid; /* true if wc is a valid wide character */ - wchar_t wc; /* if wc_valid: the current character */ - char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ -}; - -/* EOF (not a real character) is represented with bytes = 0 and - wc_valid = false. */ - -typedef struct mbchar mbchar_t; - -/* Access the current character. */ -#define mb_ptr(mbc) ((mbc).ptr) -#define mb_len(mbc) ((mbc).bytes) - -/* Comparison of characters. */ -#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) -#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) -#define mb_cmp(mbc1, mbc2) \ - ((mbc1).wc_valid \ - ? ((mbc2).wc_valid \ - ? (int) (mbc1).wc - (int) (mbc2).wc \ - : -1) \ - : ((mbc2).wc_valid \ - ? 1 \ - : (mbc1).bytes == (mbc2).bytes \ - ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ - : (mbc1).bytes < (mbc2).bytes \ - ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ - : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -#define mb_casecmp(mbc1, mbc2) \ - ((mbc1).wc_valid \ - ? ((mbc2).wc_valid \ - ? (int) towlower ((mbc1).wc) - (int) towlower ((mbc2).wc) \ - : -1) \ - : ((mbc2).wc_valid \ - ? 1 \ - : (mbc1).bytes == (mbc2).bytes \ - ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ - : (mbc1).bytes < (mbc2).bytes \ - ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ - : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -#define mb_equal(mbc1, mbc2) \ - ((mbc1).wc_valid && (mbc2).wc_valid \ - ? (mbc1).wc == (mbc2).wc \ - : (mbc1).bytes == (mbc2).bytes \ - && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) -#define mb_caseequal(mbc1, mbc2) \ - ((mbc1).wc_valid && (mbc2).wc_valid \ - ? towlower ((mbc1).wc) == towlower ((mbc2).wc) \ - : (mbc1).bytes == (mbc2).bytes \ - && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) - -/* , classification. */ -#define mb_isascii(mbc) \ - ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) -#define mb_isalnum(mbc) ((mbc).wc_valid && iswalnum ((mbc).wc)) -#define mb_isalpha(mbc) ((mbc).wc_valid && iswalpha ((mbc).wc)) -#define mb_isblank(mbc) ((mbc).wc_valid && iswblank ((mbc).wc)) -#define mb_iscntrl(mbc) ((mbc).wc_valid && iswcntrl ((mbc).wc)) -#define mb_isdigit(mbc) ((mbc).wc_valid && iswdigit ((mbc).wc)) -#define mb_isgraph(mbc) ((mbc).wc_valid && iswgraph ((mbc).wc)) -#define mb_islower(mbc) ((mbc).wc_valid && iswlower ((mbc).wc)) -#define mb_isprint(mbc) ((mbc).wc_valid && iswprint ((mbc).wc)) -#define mb_ispunct(mbc) ((mbc).wc_valid && iswpunct ((mbc).wc)) -#define mb_isspace(mbc) ((mbc).wc_valid && iswspace ((mbc).wc)) -#define mb_isupper(mbc) ((mbc).wc_valid && iswupper ((mbc).wc)) -#define mb_isxdigit(mbc) ((mbc).wc_valid && iswxdigit ((mbc).wc)) - -/* Extra function. */ - -/* Unprintable characters appear as a small box of width 1. */ -#define MB_UNPRINTABLE_WIDTH 1 - -static inline int -mb_width_aux (wint_t wc) -{ - int w = wcwidth (wc); - /* For unprintable characters, arbitrarily return 0 for control characters - and MB_UNPRINTABLE_WIDTH otherwise. */ - return (w >= 0 ? w : iswcntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); -} - -#define mb_width(mbc) \ - ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) - -/* Output. */ -#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) - -/* Assignment. */ -#define mb_setascii(mbc, sc) \ - ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ - (mbc)->wc = (mbc)->buf[0] = (sc)) - -/* Copying a character. */ -static inline void -mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) -{ - if (old_mbc->ptr == &old_mbc->buf[0]) - { - memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); - new_mbc->ptr = &new_mbc->buf[0]; - } - else - new_mbc->ptr = old_mbc->ptr; - new_mbc->bytes = old_mbc->bytes; - if ((new_mbc->wc_valid = old_mbc->wc_valid)) - new_mbc->wc = old_mbc->wc; -} - - -/* is_basic(c) tests whether the single-byte character c is in the - ISO C "basic character set". - This is a convenience function, and is in this file only to share code - between mbiter_multi.h and mbfile_multi.h. */ -#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) -/* The character set is ISO-646, not EBCDIC. */ -# define IS_BASIC_ASCII 1 - -extern const unsigned int is_basic_table[]; - -static inline bool -is_basic (char c) -{ - return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31)) - & 1; -} - -#else - -static inline bool -is_basic (char c) -{ - switch (c) - { - case '\t': case '\v': case '\f': - case ' ': case '!': case '"': case '#': case '%': - case '&': case '\'': case '(': case ')': case '*': - case '+': case ',': case '-': case '.': case '/': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case ':': case ';': case '<': case '=': case '>': - case '?': - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case '[': case '\\': case ']': case '^': case '_': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': case '{': case '|': case '}': case '~': - return 1; - default: - return 0; - } -} - -#endif - -#endif /* _MBCHAR_H */ diff --git a/src/bin/tar/lib/mbscasecmp.c b/src/bin/tar/lib/mbscasecmp.c deleted file mode 100644 index 8a2f434b1d..0000000000 --- a/src/bin/tar/lib/mbscasecmp.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Case-insensitive string comparison function. - Copyright (C) 1998-1999, 2005-2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2005, - based on earlier glibc code. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -#include -#include - -#if HAVE_MBRTOWC -# include "mbuiter.h" -#endif - -#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) - -/* Compare the character strings S1 and S2, ignoring case, returning less than, - equal to or greater than zero if S1 is lexicographically less than, equal to - or greater than S2. - Note: This function may, in multibyte locales, return 0 for strings of - different lengths! */ -int -mbscasecmp (const char *s1, const char *s2) -{ - if (s1 == s2) - return 0; - - /* Be careful not to look at the entire extent of s1 or s2 until needed. - This is useful because when two strings differ, the difference is - most often already in the very few first characters. */ -#if HAVE_MBRTOWC - if (MB_CUR_MAX > 1) - { - mbui_iterator_t iter1; - mbui_iterator_t iter2; - - mbui_init (iter1, s1); - mbui_init (iter2, s2); - - while (mbui_avail (iter1) && mbui_avail (iter2)) - { - int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2)); - - if (cmp != 0) - return cmp; - - mbui_advance (iter1); - mbui_advance (iter2); - } - if (mbui_avail (iter1)) - /* s2 terminated before s1. */ - return 1; - if (mbui_avail (iter2)) - /* s1 terminated before s2. */ - return -1; - return 0; - } - else -#endif - { - const unsigned char *p1 = (const unsigned char *) s1; - const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - - do - { - c1 = TOLOWER (*p1); - c2 = TOLOWER (*p2); - - if (c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - if (UCHAR_MAX <= INT_MAX) - return c1 - c2; - else - /* On machines where 'char' and 'int' are types of the same size, the - difference of two 'unsigned char' values - including the sign bit - - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); - } -} diff --git a/src/bin/tar/lib/mbuiter.h b/src/bin/tar/lib/mbuiter.h deleted file mode 100644 index c4ceddbe64..0000000000 --- a/src/bin/tar/lib/mbuiter.h +++ /dev/null @@ -1,223 +0,0 @@ -/* Iterating through multibyte strings: macros for multi-byte encodings. - Copyright (C) 2001, 2005, 2007 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Bruno Haible . */ - -/* The macros in this file implement forward iteration through a - multi-byte string, without knowing its length a-priori. - - With these macros, an iteration loop that looks like - - char *iter; - for (iter = buf; *iter != '\0'; iter++) - { - do_something (*iter); - } - - becomes - - mbui_iterator_t iter; - for (mbui_init (iter, buf); mbui_avail (iter); mbui_advance (iter)) - { - do_something (mbui_cur_ptr (iter), mb_len (mbui_cur (iter))); - } - - The benefit of these macros over plain use of mbrtowc is: - - Handling of invalid multibyte sequences is possible without - making the code more complicated, while still preserving the - invalid multibyte sequences. - - Compared to mbiter.h, the macros here don't need to know the string's - length a-priori. The downside is that at each step, the look-ahead - that guards against overrunning the terminating '\0' is more expensive. - The mbui_* macros are therefore suitable when there is a high probability - that only the first few multibyte characters need to be inspected. - Whereas the mbi_* macros are better if usually the iteration runs - through the entire string. - - mbui_iterator_t - is a type usable for variable declarations. - - mbui_init (iter, startptr) - initializes the iterator, starting at startptr. - - mbui_avail (iter) - returns true if there are more multibyte chracters available before - the end of string is reached. In this case, mbui_cur (iter) is - initialized to the next multibyte chracter. - - mbui_advance (iter) - advances the iterator by one multibyte character. - - mbui_cur (iter) - returns the current multibyte character, of type mbchar_t. All the - macros defined in mbchar.h can be used on it. - - mbui_cur_ptr (iter) - return a pointer to the beginning of the current multibyte character. - - mbui_reloc (iter, ptrdiff) - relocates iterator when the string is moved by ptrdiff bytes. - - mbui_copy (&destiter, &srciter) - copies srciter to destiter. - - Here are the function prototypes of the macros. - - extern void mbui_init (mbui_iterator_t iter, const char *startptr); - extern bool mbui_avail (mbui_iterator_t iter); - extern void mbui_advance (mbui_iterator_t iter); - extern mbchar_t mbui_cur (mbui_iterator_t iter); - extern const char * mbui_cur_ptr (mbui_iterator_t iter); - extern void mbui_reloc (mbui_iterator_t iter, ptrdiff_t ptrdiff); - extern void mbui_copy (mbui_iterator_t *new, const mbui_iterator_t *old); - */ - -#ifndef _MBUITER_H -#define _MBUITER_H 1 - -#include -#include -#include -#include -#include - -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.1 has a bug: and must be included before - . */ -#include -#include -#include - -#include "mbchar.h" -#include "strnlen1.h" - -struct mbuiter_multi -{ - bool in_shift; /* true if next byte may not be interpreted as ASCII */ - mbstate_t state; /* if in_shift: current shift state */ - bool next_done; /* true if mbui_avail has already filled the following */ - struct mbchar cur; /* the current character: - const char *cur.ptr pointer to current character - The following are only valid after mbui_avail. - size_t cur.bytes number of bytes of current character - bool cur.wc_valid true if wc is a valid wide character - wchar_t cur.wc if wc_valid: the current character - */ -}; - -static inline void -mbuiter_multi_next (struct mbuiter_multi *iter) -{ - if (iter->next_done) - return; - if (iter->in_shift) - goto with_shift; - /* Handle most ASCII characters quickly, without calling mbrtowc(). */ - if (is_basic (*iter->cur.ptr)) - { - /* These characters are part of the basic character set. ISO C 99 - guarantees that their wide character code is identical to their - char code. */ - iter->cur.bytes = 1; - iter->cur.wc = *iter->cur.ptr; - iter->cur.wc_valid = true; - } - else - { - assert (mbsinit (&iter->state)); - iter->in_shift = true; - with_shift: - iter->cur.bytes = mbrtowc (&iter->cur.wc, iter->cur.ptr, - strnlen1 (iter->cur.ptr, MB_CUR_MAX), - &iter->state); - if (iter->cur.bytes == (size_t) -1) - { - /* An invalid multibyte sequence was encountered. */ - iter->cur.bytes = 1; - iter->cur.wc_valid = false; - /* Whether to set iter->in_shift = false and reset iter->state - or not is not very important; the string is bogus anyway. */ - } - else if (iter->cur.bytes == (size_t) -2) - { - /* An incomplete multibyte character at the end. */ - iter->cur.bytes = strlen (iter->cur.ptr); - iter->cur.wc_valid = false; - /* Whether to set iter->in_shift = false and reset iter->state - or not is not important; the string end is reached anyway. */ - } - else - { - if (iter->cur.bytes == 0) - { - /* A null wide character was encountered. */ - iter->cur.bytes = 1; - assert (*iter->cur.ptr == '\0'); - assert (iter->cur.wc == 0); - } - iter->cur.wc_valid = true; - - /* When in the initial state, we can go back treating ASCII - characters more quickly. */ - if (mbsinit (&iter->state)) - iter->in_shift = false; - } - } - iter->next_done = true; -} - -static inline void -mbuiter_multi_reloc (struct mbuiter_multi *iter, ptrdiff_t ptrdiff) -{ - iter->cur.ptr += ptrdiff; -} - -static inline void -mbuiter_multi_copy (struct mbuiter_multi *new_iter, const struct mbuiter_multi *old_iter) -{ - if ((new_iter->in_shift = old_iter->in_shift)) - memcpy (&new_iter->state, &old_iter->state, sizeof (mbstate_t)); - else - memset (&new_iter->state, 0, sizeof (mbstate_t)); - new_iter->next_done = old_iter->next_done; - mb_copy (&new_iter->cur, &old_iter->cur); -} - -/* Iteration macros. */ -typedef struct mbuiter_multi mbui_iterator_t; -#define mbui_init(iter, startptr) \ - ((iter).cur.ptr = (startptr), \ - (iter).in_shift = false, memset (&(iter).state, '\0', sizeof (mbstate_t)), \ - (iter).next_done = false) -#define mbui_avail(iter) \ - (mbuiter_multi_next (&(iter)), !mb_isnul ((iter).cur)) -#define mbui_advance(iter) \ - ((iter).cur.ptr += (iter).cur.bytes, (iter).next_done = false) - -/* Access to the current character. */ -#define mbui_cur(iter) (iter).cur -#define mbui_cur_ptr(iter) (iter).cur.ptr - -/* Relocation. */ -#define mbui_reloc(iter, ptrdiff) mbuiter_multi_reloc (&iter, ptrdiff) - -/* Copying an iterator. */ -#define mbui_copy mbuiter_multi_copy - -#endif /* _MBUITER_H */ diff --git a/src/bin/tar/lib/memchr.c b/src/bin/tar/lib/memchr.c deleted file mode 100644 index d44ad6deb5..0000000000 --- a/src/bin/tar/lib/memchr.c +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006 Free - Software Foundation, Inc. - - Based on strlen implementation by Torbjorn Granlund (tege@sics.se), - with help from Dan Sahlin (dan@sics.se) and - commentary by Jim Blandy (jimb@ai.mit.edu); - adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), - and implemented by Roland McGrath (roland@ai.mit.edu). - -NOTE: The canonical source of this file is maintained with the GNU C Library. -Bugs can be reported to bug-glibc@prep.ai.mit.edu. - -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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LIBC -# include -#endif - -#include - -#include - -#if defined _LIBC -# include -#else -# define reg_char char -#endif - -#include - -#if HAVE_BP_SYM_H || defined _LIBC -# include -#else -# define BP_SYM(sym) sym -#endif - -#undef memchr -#undef __memchr - -/* Search no more than N bytes of S for C. */ -void * -__memchr (void const *s, int c_in, size_t n) -{ - const unsigned char *char_ptr; - const unsigned long int *longword_ptr; - unsigned long int longword, magic_bits, charmask; - unsigned reg_char c; - int i; - - c = (unsigned char) c_in; - - /* Handle the first few characters by reading one character at a time. - Do this until CHAR_PTR is aligned on a longword boundary. */ - for (char_ptr = (const unsigned char *) s; - n > 0 && (size_t) char_ptr % sizeof longword != 0; - --n, ++char_ptr) - if (*char_ptr == c) - return (void *) char_ptr; - - /* All these elucidatory comments refer to 4-byte longwords, - but the theory applies equally well to any size longwords. */ - - longword_ptr = (const unsigned long int *) char_ptr; - - /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits - the "holes." Note that there is a hole just to the left of - each byte, with an extra at the end: - - bits: 01111110 11111110 11111110 11111111 - bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD - - The 1-bits make sure that carries propagate to the next 0-bit. - The 0-bits provide holes for carries to fall into. */ - - /* Set MAGIC_BITS to be this pattern of 1 and 0 bits. - Set CHARMASK to be a longword, each of whose bytes is C. */ - - magic_bits = 0xfefefefe; - charmask = c | (c << 8); - charmask |= charmask << 16; -#if 0xffffffffU < ULONG_MAX - magic_bits |= magic_bits << 32; - charmask |= charmask << 32; - if (8 < sizeof longword) - for (i = 64; i < sizeof longword * 8; i *= 2) - { - magic_bits |= magic_bits << i; - charmask |= charmask << i; - } -#endif - magic_bits = (ULONG_MAX >> 1) & (magic_bits | 1); - - /* Instead of the traditional loop which tests each character, - we will test a longword at a time. The tricky part is testing - if *any of the four* bytes in the longword in question are zero. */ - while (n >= sizeof longword) - { - /* We tentatively exit the loop if adding MAGIC_BITS to - LONGWORD fails to change any of the hole bits of LONGWORD. - - 1) Is this safe? Will it catch all the zero bytes? - Suppose there is a byte with all zeros. Any carry bits - propagating from its left will fall into the hole at its - least significant bit and stop. Since there will be no - carry from its most significant bit, the LSB of the - byte to the left will be unchanged, and the zero will be - detected. - - 2) Is this worthwhile? Will it ignore everything except - zero bytes? Suppose every byte of LONGWORD has a bit set - somewhere. There will be a carry into bit 8. If bit 8 - is set, this will carry into bit 16. If bit 8 is clear, - one of bits 9-15 must be set, so there will be a carry - into bit 16. Similarly, there will be a carry into bit - 24. If one of bits 24-30 is set, there will be a carry - into bit 31, so all of the hole bits will be changed. - - The one misfire occurs when bits 24-30 are clear and bit - 31 is set; in this case, the hole at bit 31 is not - changed. If we had access to the processor carry flag, - we could close this loophole by putting the fourth hole - at bit 32! - - So it ignores everything except 128's, when they're aligned - properly. - - 3) But wait! Aren't we looking for C, not zero? - Good point. So what we do is XOR LONGWORD with a longword, - each of whose bytes is C. This turns each byte that is C - into a zero. */ - - longword = *longword_ptr++ ^ charmask; - - /* Add MAGIC_BITS to LONGWORD. */ - if ((((longword + magic_bits) - - /* Set those bits that were unchanged by the addition. */ - ^ ~longword) - - /* Look at only the hole bits. If any of the hole bits - are unchanged, most likely one of the bytes was a - zero. */ - & ~magic_bits) != 0) - { - /* Which of the bytes was C? If none of them were, it was - a misfire; continue the search. */ - - const unsigned char *cp = (const unsigned char *) (longword_ptr - 1); - - if (cp[0] == c) - return (void *) cp; - if (cp[1] == c) - return (void *) &cp[1]; - if (cp[2] == c) - return (void *) &cp[2]; - if (cp[3] == c) - return (void *) &cp[3]; - if (4 < sizeof longword && cp[4] == c) - return (void *) &cp[4]; - if (5 < sizeof longword && cp[5] == c) - return (void *) &cp[5]; - if (6 < sizeof longword && cp[6] == c) - return (void *) &cp[6]; - if (7 < sizeof longword && cp[7] == c) - return (void *) &cp[7]; - if (8 < sizeof longword) - for (i = 8; i < sizeof longword; i++) - if (cp[i] == c) - return (void *) &cp[i]; - } - - n -= sizeof longword; - } - - char_ptr = (const unsigned char *) longword_ptr; - - while (n-- > 0) - { - if (*char_ptr == c) - return (void *) char_ptr; - else - ++char_ptr; - } - - return 0; -} -#ifdef weak_alias -weak_alias (__memchr, BP_SYM (memchr)) -#endif diff --git a/src/bin/tar/lib/mempcpy.c b/src/bin/tar/lib/mempcpy.c deleted file mode 100644 index 1c702c7f4c..0000000000 --- a/src/bin/tar/lib/mempcpy.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copy memory area and return pointer after last written byte. - Copyright (C) 2003, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -/* Copy N bytes of SRC to DEST, return pointer to bytes after the - last written byte. */ -void * -mempcpy (void *dest, const void *src, size_t n) -{ - return (char *) memcpy (dest, src, n) + n; -} diff --git a/src/bin/tar/lib/memrchr.c b/src/bin/tar/lib/memrchr.c deleted file mode 100644 index 29fd531016..0000000000 --- a/src/bin/tar/lib/memrchr.c +++ /dev/null @@ -1,190 +0,0 @@ -/* memrchr -- find the last occurrence of a byte in a memory block - - Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2005, - 2006, 2007 Free Software Foundation, Inc. - - Based on strlen implementation by Torbjorn Granlund (tege@sics.se), - with help from Dan Sahlin (dan@sics.se) and - commentary by Jim Blandy (jimb@ai.mit.edu); - adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), - and implemented by Roland McGrath (roland@ai.mit.edu). - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if defined _LIBC -# include -#else -# include -# define reg_char char -#endif - -#include -#include - -#undef __memrchr -#undef memrchr - -#ifndef weak_alias -# define __memrchr memrchr -#endif - -/* Search no more than N bytes of S for C. */ -void * -__memrchr (void const *s, int c_in, size_t n) -{ - const unsigned char *char_ptr; - const unsigned long int *longword_ptr; - unsigned long int longword, magic_bits, charmask; - unsigned reg_char c; - int i; - - c = (unsigned char) c_in; - - /* Handle the last few characters by reading one character at a time. - Do this until CHAR_PTR is aligned on a longword boundary. */ - for (char_ptr = (const unsigned char *) s + n; - n > 0 && (size_t) char_ptr % sizeof longword != 0; - --n) - if (*--char_ptr == c) - return (void *) char_ptr; - - /* All these elucidatory comments refer to 4-byte longwords, - but the theory applies equally well to any size longwords. */ - - longword_ptr = (const unsigned long int *) char_ptr; - - /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits - the "holes." Note that there is a hole just to the left of - each byte, with an extra at the end: - - bits: 01111110 11111110 11111110 11111111 - bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD - - The 1-bits make sure that carries propagate to the next 0-bit. - The 0-bits provide holes for carries to fall into. */ - - /* Set MAGIC_BITS to be this pattern of 1 and 0 bits. - Set CHARMASK to be a longword, each of whose bytes is C. */ - - magic_bits = 0xfefefefe; - charmask = c | (c << 8); - charmask |= charmask << 16; -#if 0xffffffffU < ULONG_MAX - magic_bits |= magic_bits << 32; - charmask |= charmask << 32; - if (8 < sizeof longword) - for (i = 64; i < sizeof longword * 8; i *= 2) - { - magic_bits |= magic_bits << i; - charmask |= charmask << i; - } -#endif - magic_bits = (ULONG_MAX >> 1) & (magic_bits | 1); - - /* Instead of the traditional loop which tests each character, - we will test a longword at a time. The tricky part is testing - if *any of the four* bytes in the longword in question are zero. */ - while (n >= sizeof longword) - { - /* We tentatively exit the loop if adding MAGIC_BITS to - LONGWORD fails to change any of the hole bits of LONGWORD. - - 1) Is this safe? Will it catch all the zero bytes? - Suppose there is a byte with all zeros. Any carry bits - propagating from its left will fall into the hole at its - least significant bit and stop. Since there will be no - carry from its most significant bit, the LSB of the - byte to the left will be unchanged, and the zero will be - detected. - - 2) Is this worthwhile? Will it ignore everything except - zero bytes? Suppose every byte of LONGWORD has a bit set - somewhere. There will be a carry into bit 8. If bit 8 - is set, this will carry into bit 16. If bit 8 is clear, - one of bits 9-15 must be set, so there will be a carry - into bit 16. Similarly, there will be a carry into bit - 24. If one of bits 24-30 is set, there will be a carry - into bit 31, so all of the hole bits will be changed. - - The one misfire occurs when bits 24-30 are clear and bit - 31 is set; in this case, the hole at bit 31 is not - changed. If we had access to the processor carry flag, - we could close this loophole by putting the fourth hole - at bit 32! - - So it ignores everything except 128's, when they're aligned - properly. - - 3) But wait! Aren't we looking for C, not zero? - Good point. So what we do is XOR LONGWORD with a longword, - each of whose bytes is C. This turns each byte that is C - into a zero. */ - - longword = *--longword_ptr ^ charmask; - - /* Add MAGIC_BITS to LONGWORD. */ - if ((((longword + magic_bits) - - /* Set those bits that were unchanged by the addition. */ - ^ ~longword) - - /* Look at only the hole bits. If any of the hole bits - are unchanged, most likely one of the bytes was a - zero. */ - & ~magic_bits) != 0) - { - /* Which of the bytes was C? If none of them were, it was - a misfire; continue the search. */ - - const unsigned char *cp = (const unsigned char *) longword_ptr; - - if (8 < sizeof longword) - for (i = sizeof longword - 1; 8 <= i; i--) - if (cp[i] == c) - return (void *) &cp[i]; - if (7 < sizeof longword && cp[7] == c) - return (void *) &cp[7]; - if (6 < sizeof longword && cp[6] == c) - return (void *) &cp[6]; - if (5 < sizeof longword && cp[5] == c) - return (void *) &cp[5]; - if (4 < sizeof longword && cp[4] == c) - return (void *) &cp[4]; - if (cp[3] == c) - return (void *) &cp[3]; - if (cp[2] == c) - return (void *) &cp[2]; - if (cp[1] == c) - return (void *) &cp[1]; - if (cp[0] == c) - return (void *) cp; - } - - n -= sizeof longword; - } - - char_ptr = (const unsigned char *) longword_ptr; - - while (n-- > 0) - { - if (*--char_ptr == c) - return (void *) char_ptr; - } - - return 0; -} -#ifdef weak_alias -weak_alias (__memrchr, memrchr) -#endif diff --git a/src/bin/tar/lib/memset.c b/src/bin/tar/lib/memset.c deleted file mode 100644 index 890cbf12d0..0000000000 --- a/src/bin/tar/lib/memset.c +++ /dev/null @@ -1,28 +0,0 @@ -/* memset.c -- set an area of memory to a given value - Copyright (C) 1991, 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -void * -memset (void *str, int c, size_t len) -{ - register char *st = str; - - while (len-- > 0) - *st++ = c; - return str; -} diff --git a/src/bin/tar/lib/mkdirat.c b/src/bin/tar/lib/mkdirat.c deleted file mode 100644 index da0b262bf6..0000000000 --- a/src/bin/tar/lib/mkdirat.c +++ /dev/null @@ -1,43 +0,0 @@ -/* fd-relative mkdir - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -#include "openat.h" - -#include - -#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ -#include "save-cwd.h" -#include "openat-priv.h" - -/* Solaris 10 has no function like this. - Create a subdirectory, FILE, with mode MODE, in the directory - open on descriptor FD. If possible, do it without changing the - working directory. Otherwise, resort to using save_cwd/fchdir, - then mkdir/restore_cwd. If either the save_cwd or the restore_cwd - fails, then give a diagnostic and exit nonzero. */ - -#define AT_FUNC_NAME mkdirat -#define AT_FUNC_F1 mkdir -#define AT_FUNC_F2 mkdir -#define AT_FUNC_USE_F1_COND 1 -#define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode -#define AT_FUNC_POST_FILE_ARGS , mode -#include "at-func.c" diff --git a/src/bin/tar/lib/mkdtemp.c b/src/bin/tar/lib/mkdtemp.c deleted file mode 100644 index 36b6c7577e..0000000000 --- a/src/bin/tar/lib/mkdtemp.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 1999, 2001-2003, 2006-2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Extracted from misc/mkdtemp.c. */ - -#include - -/* Specification. */ -#include - -#include "tempname.h" - -/* Generate a unique temporary directory from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the filename unique. - The directory is created, mode 700, and its name is returned. - (This function comes from OpenBSD.) */ -char * -mkdtemp (char *template) -{ - if (gen_tempname (template, GT_DIR)) - return NULL; - else - return template; -} diff --git a/src/bin/tar/lib/mktime.c b/src/bin/tar/lib/mktime.c deleted file mode 100644 index a91fb20e68..0000000000 --- a/src/bin/tar/lib/mktime.c +++ /dev/null @@ -1,663 +0,0 @@ -/* Convert a `struct tm' to a time_t value. - Copyright (C) 1993-1999, 2002-2005, 2006, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Paul Eggert . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Define this to have a standalone program to test this implementation of - mktime. */ -/* #define DEBUG 1 */ - -#ifndef _LIBC -# include -#endif - -/* Assume that leap seconds are possible, unless told otherwise. - If the host has a `zic' command with a `-L leapsecondfilename' option, - then it supports leap seconds; otherwise it probably doesn't. */ -#ifndef LEAP_SECONDS_POSSIBLE -# define LEAP_SECONDS_POSSIBLE 1 -#endif - -#include - -#include - -#include /* For the real memcpy prototype. */ - -#if DEBUG -# include -# include -/* Make it work even if the system's libc has its own mktime routine. */ -# define mktime my_mktime -#endif /* DEBUG */ - -/* Shift A right by B bits portably, by dividing A by 2**B and - truncating towards minus infinity. A and B should be free of side - effects, and B should be in the range 0 <= B <= INT_BITS - 2, where - INT_BITS is the number of useful bits in an int. GNU code can - assume that INT_BITS is at least 32. - - ISO C99 says that A >> B is implementation-defined if A < 0. Some - implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift - right in the usual way when A < 0, so SHR falls back on division if - ordinary A >> B doesn't seem to be the usual signed shift. */ -#define SHR(a, b) \ - (-1 >> 1 == -1 \ - ? (a) >> (b) \ - : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) - -/* The extra casts in the following macros work around compiler bugs, - e.g., in Cray C 5.0.3.0. */ - -/* True if the arithmetic type T is an integer type. bool counts as - an integer. */ -#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) - -/* True if negative values of the signed integer type T use two's - complement, ones' complement, or signed magnitude representation, - respectively. Much GNU code assumes two's complement, but some - people like to be portable to all possible C hosts. */ -#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) -#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) -#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) - -/* True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* The maximum and minimum values for the integer type T. These - macros have undefined behavior if T is signed and has padding bits. - If this is a problem for you, please let us know how to fix it for - your host. */ -#define TYPE_MINIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) 0 \ - : TYPE_SIGNED_MAGNITUDE (t) \ - ? ~ (t) 0 \ - : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) -#define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) - -#ifndef TIME_T_MIN -# define TIME_T_MIN TYPE_MINIMUM (time_t) -#endif -#ifndef TIME_T_MAX -# define TIME_T_MAX TYPE_MAXIMUM (time_t) -#endif -#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) - -/* Verify a requirement at compile-time (unlike assert, which is runtime). */ -#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } - -verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); -verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int)); -/* The code also assumes that signed integer overflow silently wraps - around, but this assumption can't be stated without causing a - diagnostic on some hosts. */ - -#define EPOCH_YEAR 1970 -#define TM_YEAR_BASE 1900 -verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); - -/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ -static inline int -leapyear (long int year) -{ - /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. - Also, work even if YEAR is negative. */ - return - ((year & 3) == 0 - && (year % 100 != 0 - || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3))); -} - -/* How many days come before each month (0-12). */ -#ifndef _LIBC -static -#endif -const unsigned short int __mon_yday[2][13] = - { - /* Normal years. */ - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - /* Leap years. */ - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } - }; - - -#ifndef _LIBC -/* Portable standalone applications should supply a that - declares a POSIX-compliant localtime_r, for the benefit of older - implementations that lack localtime_r or have a nonstandard one. - See the gnulib time_r module for one way to implement this. */ -# undef __localtime_r -# define __localtime_r localtime_r -# define __mktime_internal mktime_internal -#endif - -/* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - - (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks - were not adjusted between the time stamps. - - The YEAR values uses the same numbering as TP->tm_year. Values - need not be in the usual range. However, YEAR1 must not be less - than 2 * INT_MIN or greater than 2 * INT_MAX. - - The result may overflow. It is the caller's responsibility to - detect overflow. */ - -static inline time_t -ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1, - int year0, int yday0, int hour0, int min0, int sec0) -{ - verify (C99_integer_division, -1 / 2 == 0); - verify (long_int_year_and_yday_are_wide_enough, - INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX); - - /* Compute intervening leap days correctly even if year is negative. - Take care to avoid integer overflow here. */ - int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3); - int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3); - int a100 = a4 / 25 - (a4 % 25 < 0); - int b100 = b4 / 25 - (b4 % 25 < 0); - int a400 = SHR (a100, 2); - int b400 = SHR (b100, 2); - int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); - - /* Compute the desired time in time_t precision. Overflow might - occur here. */ - time_t tyear1 = year1; - time_t years = tyear1 - year0; - time_t days = 365 * years + yday1 - yday0 + intervening_leap_days; - time_t hours = 24 * days + hour1 - hour0; - time_t minutes = 60 * hours + min1 - min0; - time_t seconds = 60 * minutes + sec1 - sec0; - return seconds; -} - - -/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), - assuming that *T corresponds to *TP and that no clock adjustments - occurred between *TP and the desired time. - If TP is null, return a value not equal to *T; this avoids false matches. - If overflow occurs, yield the minimal or maximal value, except do not - yield a value equal to *T. */ -static time_t -guess_time_tm (long int year, long int yday, int hour, int min, int sec, - const time_t *t, const struct tm *tp) -{ - if (tp) - { - time_t d = ydhms_diff (year, yday, hour, min, sec, - tp->tm_year, tp->tm_yday, - tp->tm_hour, tp->tm_min, tp->tm_sec); - time_t t1 = *t + d; - if ((t1 < *t) == (TYPE_SIGNED (time_t) ? d < 0 : TIME_T_MAX / 2 < d)) - return t1; - } - - /* Overflow occurred one way or another. Return the nearest result - that is actually in range, except don't report a zero difference - if the actual difference is nonzero, as that would cause a false - match; and don't oscillate between two values, as that would - confuse the spring-forward gap detector. */ - return (*t < TIME_T_MIDPOINT - ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN) - : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX)); -} - -/* Use CONVERT to convert *T to a broken down time in *TP. - If *T is out of range for conversion, adjust it so that - it is the nearest in-range value and then convert that. */ -static struct tm * -ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), - time_t *t, struct tm *tp) -{ - struct tm *r = convert (t, tp); - - if (!r && *t) - { - time_t bad = *t; - time_t ok = 0; - - /* BAD is a known unconvertible time_t, and OK is a known good one. - Use binary search to narrow the range between BAD and OK until - they differ by 1. */ - while (bad != ok + (bad < 0 ? -1 : 1)) - { - time_t mid = *t = (bad < 0 - ? bad + ((ok - bad) >> 1) - : ok + ((bad - ok) >> 1)); - r = convert (t, tp); - if (r) - ok = mid; - else - bad = mid; - } - - if (!r && ok) - { - /* The last conversion attempt failed; - revert to the most recent successful attempt. */ - *t = ok; - r = convert (t, tp); - } - } - - return r; -} - - -/* Convert *TP to a time_t value, inverting - the monotonic and mostly-unit-linear conversion function CONVERT. - Use *OFFSET to keep track of a guess at the offset of the result, - compared to what the result would be for UTC without leap seconds. - If *OFFSET's guess is correct, only one CONVERT call is needed. - This function is external because it is used also by timegm.c. */ -time_t -__mktime_internal (struct tm *tp, - struct tm *(*convert) (const time_t *, struct tm *), - time_t *offset) -{ - time_t t, gt, t0, t1, t2; - struct tm tm; - - /* The maximum number of probes (calls to CONVERT) should be enough - to handle any combinations of time zone rule changes, solar time, - leap seconds, and oscillations around a spring-forward gap. - POSIX.1 prohibits leap seconds, but some hosts have them anyway. */ - int remaining_probes = 6; - - /* Time requested. Copy it in case CONVERT modifies *TP; this can - occur if TP is localtime's returned value and CONVERT is localtime. */ - int sec = tp->tm_sec; - int min = tp->tm_min; - int hour = tp->tm_hour; - int mday = tp->tm_mday; - int mon = tp->tm_mon; - int year_requested = tp->tm_year; - int isdst = tp->tm_isdst; - - /* 1 if the previous probe was DST. */ - int dst2; - - /* Ensure that mon is in range, and set year accordingly. */ - int mon_remainder = mon % 12; - int negative_mon_remainder = mon_remainder < 0; - int mon_years = mon / 12 - negative_mon_remainder; - long int lyear_requested = year_requested; - long int year = lyear_requested + mon_years; - - /* The other values need not be in range: - the remaining code handles minor overflows correctly, - assuming int and time_t arithmetic wraps around. - Major overflows are caught at the end. */ - - /* Calculate day of year from year, month, and day of month. - The result need not be in range. */ - int mon_yday = ((__mon_yday[leapyear (year)] - [mon_remainder + 12 * negative_mon_remainder]) - - 1); - long int lmday = mday; - long int yday = mon_yday + lmday; - - time_t guessed_offset = *offset; - - int sec_requested = sec; - - if (LEAP_SECONDS_POSSIBLE) - { - /* Handle out-of-range seconds specially, - since ydhms_tm_diff assumes every minute has 60 seconds. */ - if (sec < 0) - sec = 0; - if (59 < sec) - sec = 59; - } - - /* Invert CONVERT by probing. First assume the same offset as last - time. */ - - t0 = ydhms_diff (year, yday, hour, min, sec, - EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset); - - if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3) - { - /* time_t isn't large enough to rule out overflows, so check - for major overflows. A gross check suffices, since if t0 - has overflowed, it is off by a multiple of TIME_T_MAX - - TIME_T_MIN + 1. So ignore any component of the difference - that is bounded by a small value. */ - - /* Approximate log base 2 of the number of time units per - biennium. A biennium is 2 years; use this unit instead of - years to avoid integer overflow. For example, 2 average - Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds, - which is 63113904 seconds, and rint (log2 (63113904)) is - 26. */ - int ALOG2_SECONDS_PER_BIENNIUM = 26; - int ALOG2_MINUTES_PER_BIENNIUM = 20; - int ALOG2_HOURS_PER_BIENNIUM = 14; - int ALOG2_DAYS_PER_BIENNIUM = 10; - int LOG2_YEARS_PER_BIENNIUM = 1; - - int approx_requested_biennia = - (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM) - - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM) - + SHR (mday, ALOG2_DAYS_PER_BIENNIUM) - + SHR (hour, ALOG2_HOURS_PER_BIENNIUM) - + SHR (min, ALOG2_MINUTES_PER_BIENNIUM) - + (LEAP_SECONDS_POSSIBLE - ? 0 - : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM))); - - int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); - int diff = approx_biennia - approx_requested_biennia; - int abs_diff = diff < 0 ? - diff : diff; - - /* IRIX 4.0.5 cc miscaculates TIME_T_MIN / 3: it erroneously - gives a positive value of 715827882. Setting a variable - first then doing math on it seems to work. - (ghazi@caip.rutgers.edu) */ - time_t time_t_max = TIME_T_MAX; - time_t time_t_min = TIME_T_MIN; - time_t overflow_threshold = - (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM; - - if (overflow_threshold < abs_diff) - { - /* Overflow occurred. Try repairing it; this might work if - the time zone offset is enough to undo the overflow. */ - time_t repaired_t0 = -1 - t0; - approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); - diff = approx_biennia - approx_requested_biennia; - abs_diff = diff < 0 ? - diff : diff; - if (overflow_threshold < abs_diff) - return -1; - guessed_offset += repaired_t0 - t0; - t0 = repaired_t0; - } - } - - /* Repeatedly use the error to improve the guess. */ - - for (t = t1 = t2 = t0, dst2 = 0; - (gt = guess_time_tm (year, yday, hour, min, sec, &t, - ranged_convert (convert, &t, &tm)), - t != gt); - t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0) - if (t == t1 && t != t2 - && (tm.tm_isdst < 0 - || (isdst < 0 - ? dst2 <= (tm.tm_isdst != 0) - : (isdst != 0) != (tm.tm_isdst != 0)))) - /* We can't possibly find a match, as we are oscillating - between two values. The requested time probably falls - within a spring-forward gap of size GT - T. Follow the common - practice in this case, which is to return a time that is GT - T - away from the requested time, preferring a time whose - tm_isdst differs from the requested value. (If no tm_isdst - was requested and only one of the two values has a nonzero - tm_isdst, prefer that value.) In practice, this is more - useful than returning -1. */ - goto offset_found; - else if (--remaining_probes == 0) - return -1; - - /* We have a match. Check whether tm.tm_isdst has the requested - value, if any. */ - if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst) - { - /* tm.tm_isdst has the wrong value. Look for a neighboring - time with the right value, and use its UTC offset. - - Heuristic: probe the adjacent timestamps in both directions, - looking for the desired isdst. This should work for all real - time zone histories in the tz database. */ - - /* Distance between probes when looking for a DST boundary. In - tzdata2003a, the shortest period of DST is 601200 seconds - (e.g., America/Recife starting 2000-10-08 01:00), and the - shortest period of non-DST surrounded by DST is 694800 - seconds (Africa/Tunis starting 1943-04-17 01:00). Use the - minimum of these two values, so we don't miss these short - periods when probing. */ - int stride = 601200; - - /* The longest period of DST in tzdata2003a is 536454000 seconds - (e.g., America/Jujuy starting 1946-10-01 01:00). The longest - period of non-DST is much longer, but it makes no real sense - to search for more than a year of non-DST, so use the DST - max. */ - int duration_max = 536454000; - - /* Search in both directions, so the maximum distance is half - the duration; add the stride to avoid off-by-1 problems. */ - int delta_bound = duration_max / 2 + stride; - - int delta, direction; - - for (delta = stride; delta < delta_bound; delta += stride) - for (direction = -1; direction <= 1; direction += 2) - { - time_t ot = t + delta * direction; - if ((ot < t) == (direction < 0)) - { - struct tm otm; - ranged_convert (convert, &ot, &otm); - if (otm.tm_isdst == isdst) - { - /* We found the desired tm_isdst. - Extrapolate back to the desired time. */ - t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); - ranged_convert (convert, &t, &tm); - goto offset_found; - } - } - } - } - - offset_found: - *offset = guessed_offset + t - t0; - - if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec) - { - /* Adjust time to reflect the tm_sec requested, not the normalized value. - Also, repair any damage from a false match due to a leap second. */ - int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; - t1 = t + sec_requested; - t2 = t1 + sec_adjustment; - if (((t1 < t) != (sec_requested < 0)) - | ((t2 < t1) != (sec_adjustment < 0)) - | ! convert (&t2, &tm)) - return -1; - t = t2; - } - - *tp = tm; - return t; -} - - -/* FIXME: This should use a signed type wide enough to hold any UTC - offset in seconds. 'int' should be good enough for GNU code. We - can't fix this unilaterally though, as other modules invoke - __mktime_internal. */ -static time_t localtime_offset; - -/* Convert *TP to a time_t value. */ -time_t -mktime (struct tm *tp) -{ -#ifdef _LIBC - /* POSIX.1 8.1.1 requires that whenever mktime() is called, the - time zone names contained in the external variable `tzname' shall - be set as if the tzset() function had been called. */ - __tzset (); -#endif - - return __mktime_internal (tp, __localtime_r, &localtime_offset); -} - -#ifdef weak_alias -weak_alias (mktime, timelocal) -#endif - -#ifdef _LIBC -libc_hidden_def (mktime) -libc_hidden_weak (timelocal) -#endif - -#if DEBUG - -static int -not_equal_tm (const struct tm *a, const struct tm *b) -{ - return ((a->tm_sec ^ b->tm_sec) - | (a->tm_min ^ b->tm_min) - | (a->tm_hour ^ b->tm_hour) - | (a->tm_mday ^ b->tm_mday) - | (a->tm_mon ^ b->tm_mon) - | (a->tm_year ^ b->tm_year) - | (a->tm_yday ^ b->tm_yday) - | (a->tm_isdst ^ b->tm_isdst)); -} - -static void -print_tm (const struct tm *tp) -{ - if (tp) - printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d", - tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec, - tp->tm_yday, tp->tm_wday, tp->tm_isdst); - else - printf ("0"); -} - -static int -check_result (time_t tk, struct tm tmk, time_t tl, const struct tm *lt) -{ - if (tk != tl || !lt || not_equal_tm (&tmk, lt)) - { - printf ("mktime ("); - print_tm (lt); - printf (")\nyields ("); - print_tm (&tmk); - printf (") == %ld, should be %ld\n", (long int) tk, (long int) tl); - return 1; - } - - return 0; -} - -int -main (int argc, char **argv) -{ - int status = 0; - struct tm tm, tmk, tml; - struct tm *lt; - time_t tk, tl, tl1; - char trailer; - - if ((argc == 3 || argc == 4) - && (sscanf (argv[1], "%d-%d-%d%c", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer) - == 3) - && (sscanf (argv[2], "%d:%d:%d%c", - &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer) - == 3)) - { - tm.tm_year -= TM_YEAR_BASE; - tm.tm_mon--; - tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); - tmk = tm; - tl = mktime (&tmk); - lt = localtime (&tl); - if (lt) - { - tml = *lt; - lt = &tml; - } - printf ("mktime returns %ld == ", (long int) tl); - print_tm (&tmk); - printf ("\n"); - status = check_result (tl, tmk, tl, lt); - } - else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0)) - { - time_t from = atol (argv[1]); - time_t by = atol (argv[2]); - time_t to = atol (argv[3]); - - if (argc == 4) - for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) - { - lt = localtime (&tl); - if (lt) - { - tmk = tml = *lt; - tk = mktime (&tmk); - status |= check_result (tk, tmk, tl, &tml); - } - else - { - printf ("localtime (%ld) yields 0\n", (long int) tl); - status = 1; - } - tl1 = tl + by; - if ((tl1 < tl) != (by < 0)) - break; - } - else - for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) - { - /* Null benchmark. */ - lt = localtime (&tl); - if (lt) - { - tmk = tml = *lt; - tk = tl; - status |= check_result (tk, tmk, tl, &tml); - } - else - { - printf ("localtime (%ld) yields 0\n", (long int) tl); - status = 1; - } - tl1 = tl + by; - if ((tl1 < tl) != (by < 0)) - break; - } - } - else - printf ("Usage:\ -\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\ -\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\ -\t%s FROM BY TO - # Do not test those values (for benchmark).\n", - argv[0], argv[0], argv[0]); - - return status; -} - -#endif /* DEBUG */ - -/* -Local Variables: -compile-command: "gcc -DDEBUG -Wall -W -O -g mktime.c -o mktime" -End: -*/ diff --git a/src/bin/tar/lib/modechange.c b/src/bin/tar/lib/modechange.c deleted file mode 100644 index e1f7ceb77c..0000000000 --- a/src/bin/tar/lib/modechange.c +++ /dev/null @@ -1,386 +0,0 @@ -/* modechange.c -- file mode manipulation - - Copyright (C) 1989, 1990, 1997, 1998, 1999, 2001, 2003, 2004, 2005, - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie */ - -/* The ASCII mode string is compiled into an array 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. */ - -#include - -#include "modechange.h" -#include -#include "stat-macros.h" -#include "xalloc.h" -#include - -/* The traditional octal values corresponding to each mode bit. */ -#define SUID 04000 -#define SGID 02000 -#define SVTX 01000 -#define RUSR 00400 -#define WUSR 00200 -#define XUSR 00100 -#define RGRP 00040 -#define WGRP 00020 -#define XGRP 00010 -#define ROTH 00004 -#define WOTH 00002 -#define XOTH 00001 -#define ALLM 07777 /* all octal mode bits */ - -/* Convert OCTAL, which uses one of the traditional octal values, to - an internal mode_t value. */ -static mode_t -octal_to_mode (unsigned int octal) -{ - /* Help the compiler optimize the usual case where mode_t uses - the traditional octal representation. */ - return ((S_ISUID == SUID && S_ISGID == SGID && S_ISVTX == SVTX - && S_IRUSR == RUSR && S_IWUSR == WUSR && S_IXUSR == XUSR - && S_IRGRP == RGRP && S_IWGRP == WGRP && S_IXGRP == XGRP - && S_IROTH == ROTH && S_IWOTH == WOTH && S_IXOTH == XOTH) - ? octal - : (mode_t) ((octal & SUID ? S_ISUID : 0) - | (octal & SGID ? S_ISGID : 0) - | (octal & SVTX ? S_ISVTX : 0) - | (octal & RUSR ? S_IRUSR : 0) - | (octal & WUSR ? S_IWUSR : 0) - | (octal & XUSR ? S_IXUSR : 0) - | (octal & RGRP ? S_IRGRP : 0) - | (octal & WGRP ? S_IWGRP : 0) - | (octal & XGRP ? S_IXGRP : 0) - | (octal & ROTH ? S_IROTH : 0) - | (octal & WOTH ? S_IWOTH : 0) - | (octal & XOTH ? S_IXOTH : 0))); -} - -/* Special operations flags. */ -enum - { - /* For the sentinel at the end of the mode changes array. */ - MODE_DONE, - - /* The typical case. */ - MODE_ORDINARY_CHANGE, - - /* In addition to the typical case, affect the execute bits if at - least one execute bit is set already, or if the file is a - directory. */ - MODE_X_IF_ANY_X, - - /* Instead of the typical case, 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. */ - MODE_COPY_EXISTING - }; - -/* Description of a mode change. */ -struct mode_change -{ - char op; /* One of "=+-". */ - char flag; /* Special operations flag. */ - mode_t affected; /* Set for u, g, o, or a. */ - mode_t value; /* Bits to add/remove. */ - mode_t mentioned; /* Bits explicitly mentioned. */ -}; - -/* Return a mode_change array with the specified `=ddd'-style - mode change operation, where NEW_MODE is `ddd' and MENTIONED - contains the bits explicitly mentioned in the mode are MENTIONED. */ - -static struct mode_change * -make_node_op_equals (mode_t new_mode, mode_t mentioned) -{ - struct mode_change *p = xmalloc (2 * sizeof *p); - p->op = '='; - p->flag = MODE_ORDINARY_CHANGE; - p->affected = CHMOD_MODE_BITS; - p->value = new_mode; - p->mentioned = mentioned; - p[1].flag = MODE_DONE; - return p; -} - -/* Return a pointer to an array 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...]...][,...] - - Return NULL if `mode_string' does not contain a valid - representation of file mode change operations. */ - -struct mode_change * -mode_compile (char const *mode_string) -{ - /* The array of mode-change directives to be returned. */ - struct mode_change *mc; - size_t used = 0; - - if ('0' <= *mode_string && *mode_string < '8') - { - unsigned int octal_mode = 0; - mode_t mode; - mode_t mentioned; - - do - { - octal_mode = 8 * octal_mode + *mode_string++ - '0'; - if (ALLM < octal_mode) - return NULL; - } - while ('0' <= *mode_string && *mode_string < '8'); - - if (*mode_string) - return NULL; - - mode = octal_to_mode (octal_mode); - mentioned = (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO; - return make_node_op_equals (mode, mentioned); - } - - /* Allocate enough space to hold the result. */ - { - size_t needed = 1; - char const *p; - for (p = mode_string; *p; p++) - needed += (*p == '=' || *p == '+' || *p == '-'); - mc = xnmalloc (needed, sizeof *mc); - } - - /* One loop iteration for each `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'. */ - for (;; mode_string++) - { - /* Which bits in the mode are operated on. */ - mode_t affected = 0; - - /* Turn on all the bits in `affected' for each group given. */ - for (;; mode_string++) - switch (*mode_string) - { - default: - goto invalid; - case 'u': - affected |= S_ISUID | S_IRWXU; - break; - case 'g': - affected |= S_ISGID | S_IRWXG; - break; - case 'o': - affected |= S_ISVTX | S_IRWXO; - break; - case 'a': - affected |= CHMOD_MODE_BITS; - break; - case '=': case '+': case '-': - goto no_more_affected; - } - no_more_affected:; - - do - { - char op = *mode_string++; - mode_t value; - char flag = MODE_COPY_EXISTING; - struct mode_change *change; - - switch (*mode_string++) - { - case 'u': - /* Set the affected bits to the value of the `u' bits - on the same file. */ - value = S_IRWXU; - break; - case 'g': - /* Set the affected bits to the value of the `g' bits - on the same file. */ - value = S_IRWXG; - break; - case 'o': - /* Set the affected bits to the value of the `o' bits - on the same file. */ - value = S_IRWXO; - break; - - default: - value = 0; - flag = MODE_ORDINARY_CHANGE; - - for (mode_string--;; mode_string++) - switch (*mode_string) - { - case 'r': - value |= S_IRUSR | S_IRGRP | S_IROTH; - break; - case 'w': - value |= S_IWUSR | S_IWGRP | S_IWOTH; - break; - case 'x': - value |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - case 'X': - flag = MODE_X_IF_ANY_X; - break; - case 's': - /* Set the setuid/gid bits if `u' or `g' is selected. */ - value |= S_ISUID | S_ISGID; - break; - case 't': - /* Set the "save text image" bit if `o' is selected. */ - value |= S_ISVTX; - break; - default: - goto no_more_values; - } - no_more_values:; - } - - change = &mc[used++]; - change->op = op; - change->flag = flag; - change->affected = affected; - change->value = value; - change->mentioned = (affected ? affected & value : value); - } - while (*mode_string == '=' || *mode_string == '+' - || *mode_string == '-'); - - if (*mode_string != ',') - break; - } - - if (*mode_string == 0) - { - mc[used].flag = MODE_DONE; - return mc; - } - -invalid: - free (mc); - return NULL; -} - -/* Return a file mode change operation that sets permissions to match those - of REF_FILE. Return NULL (setting errno) if REF_FILE can't be accessed. */ - -struct mode_change * -mode_create_from_ref (const char *ref_file) -{ - struct stat ref_stats; - - if (stat (ref_file, &ref_stats) != 0) - return NULL; - return make_node_op_equals (ref_stats.st_mode, CHMOD_MODE_BITS); -} - -/* Return the file mode bits of OLDMODE (which is the mode of a - directory if DIR), assuming the umask is UMASK_VALUE, adjusted as - indicated by the list of change operations CHANGES. If DIR, the - type 'X' change affects the returned value even if no execute bits - were set in OLDMODE, and set user and group ID bits are preserved - unless CHANGES mentioned them. If PMODE_BITS is not null, store into - *PMODE_BITS a mask denoting file mode bits that are affected by - CHANGES. - - The returned value and *PMODE_BITS contain only file mode bits. - For example, they have the S_IFMT bits cleared on a standard - Unix-like host. */ - -mode_t -mode_adjust (mode_t oldmode, bool dir, mode_t umask_value, - struct mode_change const *changes, mode_t *pmode_bits) -{ - /* The adjusted mode. */ - mode_t newmode = oldmode & CHMOD_MODE_BITS; - - /* File mode bits that CHANGES cares about. */ - mode_t mode_bits = 0; - - for (; changes->flag != MODE_DONE; changes++) - { - mode_t affected = changes->affected; - mode_t omit_change = - (dir ? S_ISUID | S_ISGID : 0) & ~ changes->mentioned; - mode_t value = changes->value; - - switch (changes->flag) - { - case MODE_ORDINARY_CHANGE: - break; - - case MODE_COPY_EXISTING: - /* Isolate in `value' the bits in `newmode' to copy. */ - value &= newmode; - - /* Copy the isolated bits to the other two parts. */ - value |= ((value & (S_IRUSR | S_IRGRP | S_IROTH) - ? S_IRUSR | S_IRGRP | S_IROTH : 0) - | (value & (S_IWUSR | S_IWGRP | S_IWOTH) - ? S_IWUSR | S_IWGRP | S_IWOTH : 0) - | (value & (S_IXUSR | S_IXGRP | S_IXOTH) - ? S_IXUSR | S_IXGRP | S_IXOTH : 0)); - break; - - case MODE_X_IF_ANY_X: - /* Affect the execute bits if execute bits are already set - or if the file is a directory. */ - if ((newmode & (S_IXUSR | S_IXGRP | S_IXOTH)) | dir) - value |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - } - - /* If WHO was specified, limit the change to the affected bits. - Otherwise, apply the umask. Either way, omit changes as - requested. */ - value &= (affected ? affected : ~umask_value) & ~ omit_change; - - switch (changes->op) - { - case '=': - /* If WHO was specified, preserve the previous values of - bits that are not affected by this change operation. - Otherwise, clear all the bits. */ - { - mode_t preserved = (affected ? ~affected : 0) | omit_change; - mode_bits |= CHMOD_MODE_BITS & ~preserved; - newmode = (newmode & preserved) | value; - break; - } - - case '+': - mode_bits |= value; - newmode |= value; - break; - - case '-': - mode_bits |= value; - newmode &= ~value; - break; - } - } - - if (pmode_bits) - *pmode_bits = mode_bits; - return newmode; -} diff --git a/src/bin/tar/lib/modechange.h b/src/bin/tar/lib/modechange.h deleted file mode 100644 index 76e0178de2..0000000000 --- a/src/bin/tar/lib/modechange.h +++ /dev/null @@ -1,31 +0,0 @@ -/* modechange.h -- definitions for file mode manipulation - - Copyright (C) 1989, 1990, 1997, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if ! defined MODECHANGE_H_ -# define MODECHANGE_H_ - -# include -# include - -struct mode_change *mode_compile (const char *); -struct mode_change *mode_create_from_ref (const char *); -mode_t mode_adjust (mode_t, bool, mode_t, struct mode_change const *, - mode_t *); - -#endif diff --git a/src/bin/tar/lib/obstack.c b/src/bin/tar/lib/obstack.c deleted file mode 100644 index 5cd0b7a6d0..0000000000 --- a/src/bin/tar/lib/obstack.c +++ /dev/null @@ -1,431 +0,0 @@ -/* obstack.c - subroutines used implicitly by object stack macros - - Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef _LIBC -# include -# include -#else -# include -# include "obstack.h" -#endif - -/* NOTE BEFORE MODIFYING THIS FILE: This version number must be - incremented whenever callers compiled using an old obstack.h can no - longer properly call the functions in this obstack.c. */ -#define OBSTACK_INTERFACE_VERSION 1 - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself, and the installed library - supports the same library interface we do. 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. */ - -#include /* Random thing to get __GNU_LIBRARY__. */ -#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 -# include -# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#include - -#ifndef ELIDE_CODE - -# include - -/* Determine default alignment. */ -union fooround -{ - uintmax_t i; - long double d; - void *p; -}; -struct fooalign -{ - char c; - union fooround u; -}; -/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT. - But in fact it might be less smart and round addresses to as much as - DEFAULT_ROUNDING. So we prepare for it to do that. */ -enum - { - DEFAULT_ALIGNMENT = offsetof (struct fooalign, u), - DEFAULT_ROUNDING = sizeof (union fooround) - }; - -/* When we copy a long block of data, this is the unit to do it with. - On some machines, copying successive ints does not work; - in such a case, redefine COPYING_UNIT to `long' (if that works) - or `char' as a last resort. */ -# ifndef COPYING_UNIT -# define COPYING_UNIT int -# endif - - -/* The functions allocating more room by calling `obstack_chunk_alloc' - jump to the handler pointed to by `obstack_alloc_failed_handler'. - This can be set to a user defined function which should either - abort gracefully or use longjump - but shouldn't return. This - variable by default points to the internal function - `print_and_abort'. */ -static void print_and_abort (void); -void (*obstack_alloc_failed_handler) (void) = print_and_abort; - -/* Exit value used when `print_and_abort' is used. */ -# include -# ifdef _LIBC -int obstack_exit_failure = EXIT_FAILURE; -# else -# include "exitfail.h" -# define obstack_exit_failure exit_failure -# endif - -# ifdef _LIBC -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) -/* A looong time ago (before 1994, anyway; we're not sure) this global variable - was used by non-GNU-C macros to avoid multiple evaluation. The GNU C - library still exports it because somebody might use it. */ -struct obstack *_obstack_compat; -compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); -# endif -# endif - -/* Define a macro that either calls functions with the traditional malloc/free - calling interface, or calls functions with the mmalloc/mfree interface - (that adds an extra first argument), based on the state of use_extra_arg. - For free, do not use ?:, since some compilers, like the MIPS compilers, - do not allow (expr) ? void : void. */ - -# define CALL_CHUNKFUN(h, size) \ - (((h) -> use_extra_arg) \ - ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ - : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) - -# define CALL_FREEFUN(h, old_chunk) \ - do { \ - if ((h) -> use_extra_arg) \ - (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ - else \ - (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ - } while (0) - - -/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default). - Objects start on multiples of ALIGNMENT (0 means use default). - CHUNKFUN is the function to use to allocate chunks, - and FREEFUN the function to free them. - - Return nonzero if successful, calls obstack_alloc_failed_handler if - allocation fails. */ - -int -_obstack_begin (struct obstack *h, - int size, int alignment, - void *(*chunkfun) (long), - void (*freefun) (void *)) -{ - register struct _obstack_chunk *chunk; /* points to new chunk */ - - if (alignment == 0) - alignment = DEFAULT_ALIGNMENT; - if (size == 0) - /* Default size is what GNU malloc can fit in a 4096-byte block. */ - { - /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. - Use the values for range checking, because if range checking is off, - the extra bytes won't be missed terribly, but if range checking is on - and we used a larger request, a whole extra 4096 bytes would be - allocated. - - These number are irrelevant to the new GNU malloc. I suspect it is - less sensitive to the size of the request. */ - int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) - + 4 + DEFAULT_ROUNDING - 1) - & ~(DEFAULT_ROUNDING - 1)); - size = 4096 - extra; - } - - h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun; - h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; - h->chunk_size = size; - h->alignment_mask = alignment - 1; - h->use_extra_arg = 0; - - chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); - if (!chunk) - (*obstack_alloc_failed_handler) (); - h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, - alignment - 1); - h->chunk_limit = chunk->limit - = (char *) chunk + h->chunk_size; - chunk->prev = 0; - /* The initial chunk now contains no empty object. */ - h->maybe_empty_object = 0; - h->alloc_failed = 0; - return 1; -} - -int -_obstack_begin_1 (struct obstack *h, int size, int alignment, - void *(*chunkfun) (void *, long), - void (*freefun) (void *, void *), - void *arg) -{ - register struct _obstack_chunk *chunk; /* points to new chunk */ - - if (alignment == 0) - alignment = DEFAULT_ALIGNMENT; - if (size == 0) - /* Default size is what GNU malloc can fit in a 4096-byte block. */ - { - /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc. - Use the values for range checking, because if range checking is off, - the extra bytes won't be missed terribly, but if range checking is on - and we used a larger request, a whole extra 4096 bytes would be - allocated. - - These number are irrelevant to the new GNU malloc. I suspect it is - less sensitive to the size of the request. */ - int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1)) - + 4 + DEFAULT_ROUNDING - 1) - & ~(DEFAULT_ROUNDING - 1)); - size = 4096 - extra; - } - - h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun; - h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun; - h->chunk_size = size; - h->alignment_mask = alignment - 1; - h->extra_arg = arg; - h->use_extra_arg = 1; - - chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size); - if (!chunk) - (*obstack_alloc_failed_handler) (); - h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents, - alignment - 1); - h->chunk_limit = chunk->limit - = (char *) chunk + h->chunk_size; - chunk->prev = 0; - /* The initial chunk now contains no empty object. */ - h->maybe_empty_object = 0; - h->alloc_failed = 0; - return 1; -} - -/* Allocate a new current chunk for the obstack *H - on the assumption that LENGTH bytes need to be added - to the current object, or a new object of length LENGTH allocated. - Copies any partial object from the end of the old chunk - to the beginning of the new one. */ - -void -_obstack_newchunk (struct obstack *h, int length) -{ - register struct _obstack_chunk *old_chunk = h->chunk; - register struct _obstack_chunk *new_chunk; - register long new_size; - register long obj_size = h->next_free - h->object_base; - register long i; - long already; - char *object_base; - - /* Compute size for new chunk. */ - new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100; - if (new_size < h->chunk_size) - new_size = h->chunk_size; - - /* Allocate and initialize the new chunk. */ - new_chunk = CALL_CHUNKFUN (h, new_size); - if (!new_chunk) - (*obstack_alloc_failed_handler) (); - h->chunk = new_chunk; - new_chunk->prev = old_chunk; - new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; - - /* Compute an aligned object_base in the new chunk */ - object_base = - __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask); - - /* Move the existing object to the new chunk. - Word at a time is fast and is safe if the object - is sufficiently aligned. */ - if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) - { - for (i = obj_size / sizeof (COPYING_UNIT) - 1; - i >= 0; i--) - ((COPYING_UNIT *)object_base)[i] - = ((COPYING_UNIT *)h->object_base)[i]; - /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT, - but that can cross a page boundary on a machine - which does not do strict alignment for COPYING_UNITS. */ - already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); - } - else - already = 0; - /* Copy remaining bytes one by one. */ - for (i = already; i < obj_size; i++) - object_base[i] = h->object_base[i]; - - /* If the object just copied was the only data in OLD_CHUNK, - free that chunk and remove it from the chain. - But not if that chunk might contain an empty object. */ - if (! h->maybe_empty_object - && (h->object_base - == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents, - h->alignment_mask))) - { - new_chunk->prev = old_chunk->prev; - CALL_FREEFUN (h, old_chunk); - } - - h->object_base = object_base; - h->next_free = h->object_base + obj_size; - /* The new chunk certainly contains no empty object yet. */ - h->maybe_empty_object = 0; -} -# ifdef _LIBC -libc_hidden_def (_obstack_newchunk) -# endif - -/* Return nonzero if object OBJ has been allocated from obstack H. - This is here for debugging. - If you use it in a program, you are probably losing. */ - -/* Suppress -Wmissing-prototypes warning. We don't want to declare this in - obstack.h because it is just for debugging. */ -int _obstack_allocated_p (struct obstack *h, void *obj); - -int -_obstack_allocated_p (struct obstack *h, void *obj) -{ - register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk *plp; /* point to previous chunk if any */ - - lp = (h)->chunk; - /* We use >= rather than > since the object cannot be exactly at - the beginning of the chunk but might be an empty object exactly - at the end of an adjacent chunk. */ - while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) - { - plp = lp->prev; - lp = plp; - } - return lp != 0; -} - -/* Free objects in obstack H, including OBJ and everything allocate - more recently than OBJ. If OBJ is zero, free everything in H. */ - -# undef obstack_free - -void -__obstack_free (struct obstack *h, void *obj) -{ - register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk *plp; /* point to previous chunk if any */ - - lp = h->chunk; - /* We use >= because there cannot be an object at the beginning of a chunk. - But there can be an empty object at that address - at the end of another chunk. */ - while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj)) - { - plp = lp->prev; - CALL_FREEFUN (h, lp); - lp = plp; - /* If we switch chunks, we can't tell whether the new current - chunk contains an empty object, so assume that it may. */ - h->maybe_empty_object = 1; - } - if (lp) - { - h->object_base = h->next_free = (char *) (obj); - h->chunk_limit = lp->limit; - h->chunk = lp; - } - else if (obj != 0) - /* obj is not in any of the chunks! */ - abort (); -} - -# ifdef _LIBC -/* Older versions of libc used a function _obstack_free intended to be - called by non-GCC compilers. */ -strong_alias (obstack_free, _obstack_free) -# endif - -int -_obstack_memory_used (struct obstack *h) -{ - register struct _obstack_chunk* lp; - register int nbytes = 0; - - for (lp = h->chunk; lp != 0; lp = lp->prev) - { - nbytes += lp->limit - (char *) lp; - } - return nbytes; -} - -/* Define the error handler. */ -# ifdef _LIBC -# include -# else -# include "gettext.h" -# endif -# ifndef _ -# define _(msgid) gettext (msgid) -# endif - -# ifdef _LIBC -# include -# endif - -# ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -# define __attribute__(Spec) /* empty */ -# endif -# endif - -static void -__attribute__ ((noreturn)) -print_and_abort (void) -{ - /* Don't change any of these strings. Yes, it would be possible to add - the newline to the string and use fputs or so. But this must not - happen because the "memory exhausted" message appears in other places - like this and the translation should be reused instead of creating - a very similar string which requires a separate translation. */ -# ifdef _LIBC - (void) __fxprintf (NULL, "%s\n", _("memory exhausted")); -# else - fprintf (stderr, "%s\n", _("memory exhausted")); -# endif - exit (obstack_exit_failure); -} - -#endif /* !ELIDE_CODE */ diff --git a/src/bin/tar/lib/obstack.h b/src/bin/tar/lib/obstack.h deleted file mode 100644 index 3315dfe617..0000000000 --- a/src/bin/tar/lib/obstack.h +++ /dev/null @@ -1,513 +0,0 @@ -/* obstack.h - object stack macros - Copyright (C) 1988-1994,1996-1999,2003,2004,2005,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Summary: - -All the apparent functions defined here are macros. The idea -is that you would use these pre-tested macros to solve a -very specific set of problems, and they would run fast. -Caution: no side-effects in arguments please!! They may be -evaluated MANY times!! - -These macros operate a stack of objects. Each object starts life -small, and may grow to maturity. (Consider building a word syllable -by syllable.) An object can move while it is growing. Once it has -been "finished" it never changes address again. So the "top of the -stack" is typically an immature growing object, while the rest of the -stack is of mature, fixed size and fixed address objects. - -These routines grab large chunks of memory, using a function you -supply, called `obstack_chunk_alloc'. On occasion, they free chunks, -by calling `obstack_chunk_free'. You must define them and declare -them before using any obstack macros. - -Each independent stack is represented by a `struct obstack'. -Each of the obstack macros expects a pointer to such a structure -as the first argument. - -One motivation for this package is the problem of growing char strings -in symbol tables. Unless you are "fascist pig with a read-only mind" ---Gosper's immortal quote from HAKMEM item 154, out of context--you -would not like to put any arbitrary upper limit on the length of your -symbols. - -In practice this often means you will build many short symbols and a -few long symbols. At the time you are reading a symbol you don't know -how long it is. One traditional method is to read a symbol into a -buffer, realloc()ating the buffer every time you try to read a symbol -that is longer than the buffer. This is beaut, but you still will -want to copy the symbol from the buffer to a more permanent -symbol-table entry say about half the time. - -With obstacks, you can work differently. Use one obstack for all symbol -names. As you read a symbol, grow the name in the obstack gradually. -When the name is complete, finalize it. Then, if the symbol exists already, -free the newly read name. - -The way we do this is to take a large chunk, allocating memory from -low addresses. When you want to build a symbol in the chunk you just -add chars above the current "high water mark" in the chunk. When you -have finished adding chars, because you got to the end of the symbol, -you know how long the chars are, and you can create a new object. -Mostly the chars will not burst over the highest address of the chunk, -because you would typically expect a chunk to be (say) 100 times as -long as an average object. - -In case that isn't clear, when we have enough chars to make up -the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) -so we just point to it where it lies. No moving of chars is -needed and this is the second win: potentially long strings need -never be explicitly shuffled. Once an object is formed, it does not -change its address during its lifetime. - -When the chars burst over a chunk boundary, we allocate a larger -chunk, and then copy the partly formed object from the end of the old -chunk to the beginning of the new larger chunk. We then carry on -accreting characters to the end of the object as we normally would. - -A special macro is provided to add a single char at a time to a -growing object. This allows the use of register variables, which -break the ordinary 'growth' macro. - -Summary: - We allocate large chunks. - We carve out one object at a time from the current chunk. - Once carved, an object never moves. - We are free to append data of any size to the currently - growing object. - Exactly one object is growing in an obstack at any one time. - You can run one obstack per control block. - You may have as many control blocks as you dare. - Because of the way we do it, you can `unwind' an obstack - back to a previous state. (You may remove objects much - as you would with a stack.) -*/ - - -/* Don't do the contents of this file more than once. */ - -#ifndef _OBSTACK_H -#define _OBSTACK_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is - defined, as with GNU C, use that; that way we don't pollute the - namespace with 's symbols. Otherwise, include - and use ptrdiff_t. */ - -#ifdef __PTRDIFF_TYPE__ -# define PTR_INT_TYPE __PTRDIFF_TYPE__ -#else -# include -# define PTR_INT_TYPE ptrdiff_t -#endif - -/* If B is the base of an object addressed by P, return the result of - aligning P to the next multiple of A + 1. B and P must be of type - char *. A + 1 must be a power of 2. */ - -#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) - -/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case - where pointers can be converted to integers, aligned as integers, - and converted back again. If PTR_INT_TYPE is narrower than a - pointer (e.g., the AS/400), play it safe and compute the alignment - relative to B. Otherwise, use the faster strategy of computing the - alignment relative to 0. */ - -#define __PTR_ALIGN(B, P, A) \ - __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \ - P, A) - -#include - -struct _obstack_chunk /* Lives at front of each chunk. */ -{ - char *limit; /* 1 past end of this chunk */ - struct _obstack_chunk *prev; /* address of prior chunk or NULL */ - char contents[4]; /* objects begin here */ -}; - -struct obstack /* control current object in current chunk */ -{ - long chunk_size; /* preferred size to allocate chunks in */ - struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ - char *object_base; /* address of object we are building */ - char *next_free; /* where to add next char to current object */ - char *chunk_limit; /* address of char after current chunk */ - union - { - PTR_INT_TYPE tempint; - void *tempptr; - } temp; /* Temporary for some macros. */ - int alignment_mask; /* Mask of alignment for each object. */ - /* These prototypes vary based on `use_extra_arg', and we use - casts to the prototypeless function type in all assignments, - but having prototypes here quiets -Wstrict-prototypes. */ - struct _obstack_chunk *(*chunkfun) (void *, long); - void (*freefun) (void *, struct _obstack_chunk *); - void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ - unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ - unsigned maybe_empty_object:1;/* There is a possibility that the current - chunk contains a zero-length object. This - prevents freeing the chunk if we allocate - a bigger chunk to replace it. */ - unsigned alloc_failed:1; /* No longer used, as we now call the failed - handler on error, but retained for binary - compatibility. */ -}; - -/* Declare the external functions we use; they are in obstack.c. */ - -extern void _obstack_newchunk (struct obstack *, int); -extern int _obstack_begin (struct obstack *, int, int, - void *(*) (long), void (*) (void *)); -extern int _obstack_begin_1 (struct obstack *, int, int, - void *(*) (void *, long), - void (*) (void *, void *), void *); -extern int _obstack_memory_used (struct obstack *); - -/* The default name of the function for freeing a chunk is 'obstack_free', - but gnulib users can override this by defining '__obstack_free'. */ -#ifndef __obstack_free -# define __obstack_free obstack_free -#endif -extern void __obstack_free (struct obstack *obstack, void *block); - - -/* Error handler called when `obstack_chunk_alloc' failed to allocate - more memory. This can be set to a user defined function which - should either abort gracefully or use longjump - but shouldn't - return. The default action is to print a message and abort. */ -extern void (*obstack_alloc_failed_handler) (void); - -/* Exit value used when `print_and_abort' is used. */ -extern int obstack_exit_failure; - -/* Pointer to beginning of object being allocated or to be allocated next. - Note that this might not be the final address of the object - because a new chunk might be needed to hold the final size. */ - -#define obstack_base(h) ((void *) (h)->object_base) - -/* Size for allocating ordinary chunks. */ - -#define obstack_chunk_size(h) ((h)->chunk_size) - -/* Pointer to next byte not yet allocated in current chunk. */ - -#define obstack_next_free(h) ((h)->next_free) - -/* Mask specifying low bits that should be clear in address of an object. */ - -#define obstack_alignment_mask(h) ((h)->alignment_mask) - -/* To prevent prototype warnings provide complete argument list. */ -#define obstack_init(h) \ - _obstack_begin ((h), 0, 0, \ - (void *(*) (long)) obstack_chunk_alloc, \ - (void (*) (void *)) obstack_chunk_free) - -#define obstack_begin(h, size) \ - _obstack_begin ((h), (size), 0, \ - (void *(*) (long)) obstack_chunk_alloc, \ - (void (*) (void *)) obstack_chunk_free) - -#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ - _obstack_begin ((h), (size), (alignment), \ - (void *(*) (long)) (chunkfun), \ - (void (*) (void *)) (freefun)) - -#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ - _obstack_begin_1 ((h), (size), (alignment), \ - (void *(*) (void *, long)) (chunkfun), \ - (void (*) (void *, void *)) (freefun), (arg)) - -#define obstack_chunkfun(h, newchunkfun) \ - ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) - -#define obstack_freefun(h, newfreefun) \ - ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) - -#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) - -#define obstack_blank_fast(h,n) ((h)->next_free += (n)) - -#define obstack_memory_used(h) _obstack_memory_used (h) - -#if defined __GNUC__ && defined __STDC__ && __STDC__ -/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and - does not implement __extension__. But that compiler doesn't define - __GNUC_MINOR__. */ -# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) -# define __extension__ -# endif - -/* For GNU C, if not -traditional, - we can define these macros to compute all args only once - without using a global variable. - Also, we can avoid using the `temp' slot, to make faster code. */ - -# define obstack_object_size(OBSTACK) \ - __extension__ \ - ({ struct obstack const *__o = (OBSTACK); \ - (unsigned) (__o->next_free - __o->object_base); }) - -# define obstack_room(OBSTACK) \ - __extension__ \ - ({ struct obstack const *__o = (OBSTACK); \ - (unsigned) (__o->chunk_limit - __o->next_free); }) - -# define obstack_make_room(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ - _obstack_newchunk (__o, __len); \ - (void) 0; }) - -# define obstack_empty_p(OBSTACK) \ - __extension__ \ - ({ struct obstack const *__o = (OBSTACK); \ - (__o->chunk->prev == 0 \ - && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \ - __o->chunk->contents, \ - __o->alignment_mask)); }) - -# define obstack_grow(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len > __o->chunk_limit) \ - _obstack_newchunk (__o, __len); \ - memcpy (__o->next_free, where, __len); \ - __o->next_free += __len; \ - (void) 0; }) - -# define obstack_grow0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, __len + 1); \ - memcpy (__o->next_free, where, __len); \ - __o->next_free += __len; \ - *(__o->next_free)++ = 0; \ - (void) 0; }) - -# define obstack_1grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + 1 > __o->chunk_limit) \ - _obstack_newchunk (__o, 1); \ - obstack_1grow_fast (__o, datum); \ - (void) 0; }) - -/* These assume that the obstack alignment is good enough for pointers - or ints, and that the data added so far to the current object - shares that much alignment. */ - -# define obstack_ptr_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (void *)); \ - obstack_ptr_grow_fast (__o, datum); }) \ - -# define obstack_int_grow(OBSTACK,datum) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (int) > __o->chunk_limit) \ - _obstack_newchunk (__o, sizeof (int)); \ - obstack_int_grow_fast (__o, datum); }) - -# define obstack_ptr_grow_fast(OBSTACK,aptr) \ -__extension__ \ -({ struct obstack *__o1 = (OBSTACK); \ - *(const void **) __o1->next_free = (aptr); \ - __o1->next_free += sizeof (const void *); \ - (void) 0; }) - -# define obstack_int_grow_fast(OBSTACK,aint) \ -__extension__ \ -({ struct obstack *__o1 = (OBSTACK); \ - *(int *) __o1->next_free = (aint); \ - __o1->next_free += sizeof (int); \ - (void) 0; }) - -# define obstack_blank(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ - _obstack_newchunk (__o, __len); \ - obstack_blank_fast (__o, __len); \ - (void) 0; }) - -# define obstack_alloc(OBSTACK,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_blank (__h, (length)); \ - obstack_finish (__h); }) - -# define obstack_copy(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow (__h, (where), (length)); \ - obstack_finish (__h); }) - -# define obstack_copy0(OBSTACK,where,length) \ -__extension__ \ -({ struct obstack *__h = (OBSTACK); \ - obstack_grow0 (__h, (where), (length)); \ - obstack_finish (__h); }) - -/* The local variable is named __o1 to avoid a name conflict - when obstack_blank is called. */ -# define obstack_finish(OBSTACK) \ -__extension__ \ -({ struct obstack *__o1 = (OBSTACK); \ - void *__value = (void *) __o1->object_base; \ - if (__o1->next_free == __value) \ - __o1->maybe_empty_object = 1; \ - __o1->next_free \ - = __PTR_ALIGN (__o1->object_base, __o1->next_free, \ - __o1->alignment_mask); \ - if (__o1->next_free - (char *)__o1->chunk \ - > __o1->chunk_limit - (char *)__o1->chunk) \ - __o1->next_free = __o1->chunk_limit; \ - __o1->object_base = __o1->next_free; \ - __value; }) - -# define obstack_free(OBSTACK, OBJ) \ -__extension__ \ -({ struct obstack *__o = (OBSTACK); \ - void *__obj = (OBJ); \ - if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ - __o->next_free = __o->object_base = (char *)__obj; \ - else (__obstack_free) (__o, __obj); }) - -#else /* not __GNUC__ or not __STDC__ */ - -# define obstack_object_size(h) \ - (unsigned) ((h)->next_free - (h)->object_base) - -# define obstack_room(h) \ - (unsigned) ((h)->chunk_limit - (h)->next_free) - -# define obstack_empty_p(h) \ - ((h)->chunk->prev == 0 \ - && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \ - (h)->chunk->contents, \ - (h)->alignment_mask)) - -/* Note that the call to _obstack_newchunk is enclosed in (..., 0) - so that we can avoid having void expressions - in the arms of the conditional expression. - Casting the third operand to void was tried before, - but some compilers won't accept it. */ - -# define obstack_make_room(h,length) \ -( (h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0)) - -# define obstack_grow(h,where,length) \ -( (h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp.tempint), \ - (h)->next_free += (h)->temp.tempint) - -# define obstack_grow0(h,where,length) \ -( (h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp.tempint), \ - (h)->next_free += (h)->temp.tempint, \ - *((h)->next_free)++ = 0) - -# define obstack_1grow(h,datum) \ -( (((h)->next_free + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), 1), 0) : 0), \ - obstack_1grow_fast (h, datum)) - -# define obstack_ptr_grow(h,datum) \ -( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ - obstack_ptr_grow_fast (h, datum)) - -# define obstack_int_grow(h,datum) \ -( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ - obstack_int_grow_fast (h, datum)) - -# define obstack_ptr_grow_fast(h,aptr) \ - (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) - -# define obstack_int_grow_fast(h,aint) \ - (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint)) - -# define obstack_blank(h,length) \ -( (h)->temp.tempint = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ - obstack_blank_fast (h, (h)->temp.tempint)) - -# define obstack_alloc(h,length) \ - (obstack_blank ((h), (length)), obstack_finish ((h))) - -# define obstack_copy(h,where,length) \ - (obstack_grow ((h), (where), (length)), obstack_finish ((h))) - -# define obstack_copy0(h,where,length) \ - (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) - -# define obstack_finish(h) \ -( ((h)->next_free == (h)->object_base \ - ? (((h)->maybe_empty_object = 1), 0) \ - : 0), \ - (h)->temp.tempptr = (h)->object_base, \ - (h)->next_free \ - = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ - (h)->alignment_mask), \ - (((h)->next_free - (char *) (h)->chunk \ - > (h)->chunk_limit - (char *) (h)->chunk) \ - ? ((h)->next_free = (h)->chunk_limit) : 0), \ - (h)->object_base = (h)->next_free, \ - (h)->temp.tempptr) - -# define obstack_free(h,obj) \ -( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ - ((((h)->temp.tempint > 0 \ - && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ - ? (int) ((h)->next_free = (h)->object_base \ - = (h)->temp.tempint + (char *) (h)->chunk) \ - : (((__obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0))) - -#endif /* not __GNUC__ or not __STDC__ */ - -#ifdef __cplusplus -} /* C++ */ -#endif - -#endif /* obstack.h */ diff --git a/src/bin/tar/lib/offtostr.c b/src/bin/tar/lib/offtostr.c deleted file mode 100644 index 45196e28a4..0000000000 --- a/src/bin/tar/lib/offtostr.c +++ /dev/null @@ -1,3 +0,0 @@ -#define inttostr offtostr -#define inttype off_t -#include "inttostr.c" diff --git a/src/bin/tar/lib/open-safer.c b/src/bin/tar/lib/open-safer.c deleted file mode 100644 index 04a72eb7b6..0000000000 --- a/src/bin/tar/lib/open-safer.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Invoke open, but avoid some glitches. - - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -#include "fcntl-safer.h" - -#include -#include -#include "unistd-safer.h" - -int -open_safer (char const *file, int flags, ...) -{ - mode_t mode = 0; - - if (flags & O_CREAT) - { - va_list ap; - va_start (ap, flags); - - /* Assume mode_t promotes to int if and only if it is smaller. - This assumption isn't guaranteed by the C standard, but we - don't know of any real-world counterexamples. */ - mode = (sizeof (mode_t) < sizeof (int) - ? va_arg (ap, int) - : va_arg (ap, mode_t)); - - va_end (ap); - } - - return fd_safer (open (file, flags, mode)); -} diff --git a/src/bin/tar/lib/openat-die.c b/src/bin/tar/lib/openat-die.c deleted file mode 100644 index 7a285700d5..0000000000 --- a/src/bin/tar/lib/openat-die.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Report a save- or restore-cwd failure in our openat replacement and then exit. - - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include - -#include "error.h" -#include "exitfail.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -void -openat_save_fail (int errno) -{ - error (exit_failure, errno, - _("unable to record current working directory")); - - /* The `noreturn' attribute cannot be applied to error, since it returns - when its first argument is 0. To help compilers understand that this - function does not return, call abort. Also, the abort is a - safety feature if exit_failure is 0 (which shouldn't happen). */ - abort (); -} - -void -openat_restore_fail (int errno) -{ - error (exit_failure, errno, - _("failed to return to initial working directory")); - - /* As above. */ - abort (); -} diff --git a/src/bin/tar/lib/openat-priv.h b/src/bin/tar/lib/openat-priv.h deleted file mode 100644 index 2d98821f55..0000000000 --- a/src/bin/tar/lib/openat-priv.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Internals for openat-like functions. - - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include -#include - -#define OPENAT_BUFFER_SIZE 512 -char *openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file); - -/* Some systems don't have ENOSYS. */ -#ifndef ENOSYS -# ifdef ENOTSUP -# define ENOSYS ENOTSUP -# else -/* Some systems don't have ENOTSUP either. */ -# define ENOSYS EINVAL -# endif -#endif - -/* Some systems don't have EOPNOTSUPP. */ -#ifndef EOPNOTSUPP -# ifdef ENOTSUP -# define EOPNOTSUPP ENOTSUP -# else -/* Some systems don't have ENOTSUP either. */ -# define EOPNOTSUPP EINVAL -# endif -#endif - -/* Trying to access a BUILD_PROC_NAME file will fail on systems without - /proc support, and even on systems *with* ProcFS support. Return - nonzero if the failure may be legitimate, e.g., because /proc is not - readable, or the particular .../fd/N directory is not present. */ -#define EXPECTED_ERRNO(Errno) \ - ((Errno) == ENOTDIR || (Errno) == ENOENT \ - || (Errno) == EPERM || (Errno) == EACCES \ - || (Errno) == ENOSYS /* Solaris 8 */ \ - || (Errno) == EOPNOTSUPP /* FreeBSD */) diff --git a/src/bin/tar/lib/openat-proc.c b/src/bin/tar/lib/openat-proc.c deleted file mode 100644 index ff2fff0033..0000000000 --- a/src/bin/tar/lib/openat-proc.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Create /proc/self/fd-related names for subfiles of open directories. - - Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -#include "openat-priv.h" - -#include -#include -#include - -#include -#include - -#include "dirname.h" -#include "intprops.h" -#include "same-inode.h" -#include "xalloc.h" - -/* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef open -#undef close - -#define PROC_SELF_FD_FORMAT "/proc/self/fd/%d/%s" - -#define PROC_SELF_FD_NAME_SIZE_BOUND(len) \ - (sizeof PROC_SELF_FD_FORMAT - sizeof "%d%s" \ - + INT_STRLEN_BOUND (int) + (len) + 1) - - -/* Set BUF to the expansion of PROC_SELF_FD_FORMAT, using FD and FILE - respectively for %d and %s. If successful, return BUF if the - result fits in BUF, dynamically allocated memory otherwise. But - return NULL if /proc is not reliable. */ -char * -openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) -{ - static int proc_status = 0; - - if (! proc_status) - { - /* Set PROC_STATUS to a positive value if /proc/self/fd is - reliable, and a negative value otherwise. Solaris 10 - /proc/self/fd mishandles "..", and any file name might expand - to ".." after symbolic link expansion, so avoid /proc/self/fd - if it mishandles "..". Solaris 10 has openat, but this - problem is exhibited on code that built on Solaris 8 and - running on Solaris 10. */ - - int proc_self_fd = open ("/proc/self/fd", O_RDONLY); - if (proc_self_fd < 0) - proc_status = -1; - else - { - struct stat proc_self_fd_dotdot_st; - struct stat proc_self_st; - char dotdot_buf[PROC_SELF_FD_NAME_SIZE_BOUND (sizeof ".." - 1)]; - sprintf (dotdot_buf, PROC_SELF_FD_FORMAT, proc_self_fd, ".."); - proc_status = - ((stat (dotdot_buf, &proc_self_fd_dotdot_st) == 0 - && stat ("/proc/self", &proc_self_st) == 0 - && SAME_INODE (proc_self_fd_dotdot_st, proc_self_st)) - ? 1 : -1); - close (proc_self_fd); - } - } - - if (proc_status < 0) - return NULL; - else - { - size_t bufsize = PROC_SELF_FD_NAME_SIZE_BOUND (strlen (file)); - char *result = (bufsize < OPENAT_BUFFER_SIZE ? buf : xmalloc (bufsize)); - sprintf (result, PROC_SELF_FD_FORMAT, fd, file); - return result; - } -} diff --git a/src/bin/tar/lib/openat.c b/src/bin/tar/lib/openat.c deleted file mode 100644 index 25eedbb056..0000000000 --- a/src/bin/tar/lib/openat.c +++ /dev/null @@ -1,269 +0,0 @@ -/* provide a replacement openat function - Copyright (C) 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -#include "openat.h" - -#include -#include - -#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ -#include "fcntl--.h" -#include "lstat.h" -#include "openat-priv.h" -#include "save-cwd.h" - -/* Replacement for Solaris' openat function. - - First, try to simulate it via open ("/proc/self/fd/FD/FILE"). - Failing that, simulate it by doing save_cwd/fchdir/open/restore_cwd. - If either the save_cwd or the restore_cwd fails (relatively unlikely), - then give a diagnostic and exit nonzero. - Otherwise, upon failure, set errno and return -1, as openat does. - Upon successful completion, return a file descriptor. */ -int -openat (int fd, char const *file, int flags, ...) -{ - mode_t mode = 0; - - if (flags & O_CREAT) - { - va_list arg; - va_start (arg, flags); - - /* If mode_t is narrower than int, use the promoted type (int), - not mode_t. Use sizeof to guess whether mode_t is narrower; - we don't know of any practical counterexamples. */ - mode = (sizeof (mode_t) < sizeof (int) - ? va_arg (arg, int) - : va_arg (arg, mode_t)); - - va_end (arg); - } - - return openat_permissive (fd, file, flags, mode, NULL); -} - -/* Like openat (FD, FILE, FLAGS, MODE), but if CWD_ERRNO is - nonnull, set *CWD_ERRNO to an errno value if unable to save - or restore the initial working directory. This is needed only - the first time remove.c's remove_dir opens a command-line - directory argument. - - If a previous attempt to restore the current working directory - failed, then we must not even try to access a `.'-relative name. - It is the caller's responsibility not to call this function - in that case. */ - -int -openat_permissive (int fd, char const *file, int flags, mode_t mode, - int *cwd_errno) -{ - struct saved_cwd saved_cwd; - int saved_errno; - int err; - bool save_ok; - - if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file)) - return open (file, flags, mode); - - { - char buf[OPENAT_BUFFER_SIZE]; - char *proc_file = openat_proc_name (buf, fd, file); - if (proc_file) - { - int open_result = open (proc_file, flags, mode); - int open_errno = errno; - if (proc_file != buf) - free (proc_file); - /* If the syscall succeeds, or if it fails with an unexpected - errno value, then return right away. Otherwise, fall through - and resort to using save_cwd/restore_cwd. */ - if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) - { - errno = open_errno; - return open_result; - } - } - } - - save_ok = (save_cwd (&saved_cwd) == 0); - if (! save_ok) - { - if (! cwd_errno) - openat_save_fail (errno); - *cwd_errno = errno; - } - - err = fchdir (fd); - saved_errno = errno; - - if (! err) - { - err = open (file, flags, mode); - saved_errno = errno; - if (save_ok && restore_cwd (&saved_cwd) != 0) - { - if (! cwd_errno) - openat_restore_fail (errno); - *cwd_errno = errno; - } - } - - free_cwd (&saved_cwd); - errno = saved_errno; - return err; -} - -/* Return true if our openat implementation must resort to - using save_cwd and restore_cwd. */ -bool -openat_needs_fchdir (void) -{ - bool needs_fchdir = true; - int fd = open ("/", O_RDONLY); - - if (0 <= fd) - { - char buf[OPENAT_BUFFER_SIZE]; - char *proc_file = openat_proc_name (buf, fd, "."); - if (proc_file) - { - needs_fchdir = false; - if (proc_file != buf) - free (proc_file); - } - close (fd); - } - - return needs_fchdir; -} - -#if !HAVE_FDOPENDIR - -/* Replacement for Solaris' function by the same name. - - First, try to simulate it via opendir ("/proc/self/fd/FD"). Failing - that, simulate it by doing save_cwd/fchdir/opendir(".")/restore_cwd. - If either the save_cwd or the restore_cwd fails (relatively unlikely), - then give a diagnostic and exit nonzero. - Otherwise, this function works just like Solaris' fdopendir. - - W A R N I N G: - Unlike the other fd-related functions here, this one - effectively consumes its FD parameter. The caller should not - close or otherwise manipulate FD if this function returns successfully. */ -DIR * -fdopendir (int fd) -{ - struct saved_cwd saved_cwd; - int saved_errno; - DIR *dir; - - char buf[OPENAT_BUFFER_SIZE]; - char *proc_file = openat_proc_name (buf, fd, "."); - if (proc_file) - { - dir = opendir (proc_file); - saved_errno = errno; - } - else - { - dir = NULL; - saved_errno = EOPNOTSUPP; - } - - /* If the syscall fails with an expected errno value, resort to - save_cwd/restore_cwd. */ - if (! dir && EXPECTED_ERRNO (saved_errno)) - { - if (save_cwd (&saved_cwd) != 0) - openat_save_fail (errno); - - if (fchdir (fd) != 0) - { - dir = NULL; - saved_errno = errno; - } - else - { - dir = opendir ("."); - saved_errno = errno; - - if (restore_cwd (&saved_cwd) != 0) - openat_restore_fail (errno); - } - - free_cwd (&saved_cwd); - } - - if (dir) - close (fd); - if (proc_file != buf) - free (proc_file); - errno = saved_errno; - return dir; -} - -#endif - -/* Replacement for Solaris' function by the same name. - - First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE"). - Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd. - If either the save_cwd or the restore_cwd fails (relatively unlikely), - then give a diagnostic and exit nonzero. - Otherwise, this function works just like Solaris' fstatat. */ - -#define AT_FUNC_NAME fstatat -#define AT_FUNC_F1 lstat -#define AT_FUNC_F2 stat -#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW -#define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag -#define AT_FUNC_POST_FILE_ARGS , st -#include "at-func.c" -#undef AT_FUNC_NAME -#undef AT_FUNC_F1 -#undef AT_FUNC_F2 -#undef AT_FUNC_USE_F1_COND -#undef AT_FUNC_POST_FILE_PARAM_DECLS -#undef AT_FUNC_POST_FILE_ARGS - -/* Replacement for Solaris' function by the same name. - - First, try to simulate it via (unlink|rmdir) ("/proc/self/fd/FD/FILE"). - Failing that, simulate it via save_cwd/fchdir/(unlink|rmdir)/restore_cwd. - If either the save_cwd or the restore_cwd fails (relatively unlikely), - then give a diagnostic and exit nonzero. - Otherwise, this function works just like Solaris' unlinkat. */ - -#define AT_FUNC_NAME unlinkat -#define AT_FUNC_F1 rmdir -#define AT_FUNC_F2 unlink -#define AT_FUNC_USE_F1_COND flag == AT_REMOVEDIR -#define AT_FUNC_POST_FILE_PARAM_DECLS , int flag -#define AT_FUNC_POST_FILE_ARGS /* empty */ -#include "at-func.c" -#undef AT_FUNC_NAME -#undef AT_FUNC_F1 -#undef AT_FUNC_F2 -#undef AT_FUNC_USE_F1_COND -#undef AT_FUNC_POST_FILE_PARAM_DECLS -#undef AT_FUNC_POST_FILE_ARGS diff --git a/src/bin/tar/lib/openat.h b/src/bin/tar/lib/openat.h deleted file mode 100644 index f8333f0843..0000000000 --- a/src/bin/tar/lib/openat.h +++ /dev/null @@ -1,127 +0,0 @@ -/* provide a replacement openat function - Copyright (C) 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering */ - -#include - -#include -#include -#include -#include -#include - -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) /* empty */ -# endif -#endif - -#ifndef ATTRIBUTE_NORETURN -# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -#endif - -/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its - value exceeds INT_MAX, so its use as an int doesn't conform to the - C standard, and GCC and Sun C complain in some cases. If the bug - is present, undef AT_FDCWD here, so it can be redefined below. */ -#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553 -# undef AT_FDCWD -#endif - -/* Use the same bit pattern as Solaris 9, but with the proper - signedness. The bit pattern is important, in case this actually is - Solaris with the above workaround. */ -#ifndef AT_FDCWD -# define AT_FDCWD (-3041965) -#endif - -/* Use the same values as Solaris 9. This shouldn't matter, but - there's no real reason to differ. */ -#ifndef AT_SYMLINK_NOFOLLOW -# define AT_SYMLINK_NOFOLLOW 4096 -# define AT_REMOVEDIR 1 -#endif - -#ifdef __OPENAT_PREFIX - -# undef openat -# define __OPENAT_CONCAT(x, y) x ## y -# define __OPENAT_XCONCAT(x, y) __OPENAT_CONCAT (x, y) -# define __OPENAT_ID(y) __OPENAT_XCONCAT (__OPENAT_PREFIX, y) -# define openat __OPENAT_ID (openat) -int openat (int fd, char const *file, int flags, /* mode_t mode */ ...); -int openat_permissive (int fd, char const *file, int flags, mode_t mode, - int *cwd_errno); -# if ! HAVE_FDOPENDIR -# define fdopendir __OPENAT_ID (fdopendir) -# endif -DIR *fdopendir (int fd); -# define fstatat __OPENAT_ID (fstatat) -int fstatat (int fd, char const *file, struct stat *st, int flag); -# define unlinkat __OPENAT_ID (unlinkat) -int unlinkat (int fd, char const *file, int flag); -bool openat_needs_fchdir (void); - -#else - -# define openat_permissive(Fd, File, Flags, Mode, Cwd_errno) \ - openat (Fd, File, Flags, Mode) -# define openat_needs_fchdir() false - -#endif - -#if HAVE_OPENAT && ! LSTAT_FOLLOWS_SLASHED_SYMLINK -int rpl_fstatat (int fd, char const *file, struct stat *st, int flag); -# if !COMPILING_FSTATAT -# undef fstatat -# define fstatat rpl_fstatat -# endif -#endif - -int mkdirat (int fd, char const *file, mode_t mode); -void openat_restore_fail (int) ATTRIBUTE_NORETURN; -void openat_save_fail (int) ATTRIBUTE_NORETURN; -int fchmodat (int fd, char const *file, mode_t mode, int flag); -int fchownat (int fd, char const *file, uid_t owner, gid_t group, int flag); - -/* Using these function names makes application code - slightly more readable than it would be with - fchownat (..., 0) or fchownat (..., AT_SYMLINK_NOFOLLOW). */ -static inline int -chownat (int fd, char const *file, uid_t owner, gid_t group) -{ - return fchownat (fd, file, owner, group, 0); -} - -static inline int -lchownat (int fd, char const *file, uid_t owner, gid_t group) -{ - return fchownat (fd, file, owner, group, AT_SYMLINK_NOFOLLOW); -} - -static inline int -chmodat (int fd, char const *file, mode_t mode) -{ - return fchmodat (fd, file, mode, 0); -} - -static inline int -lchmodat (int fd, char const *file, mode_t mode) -{ - return fchmodat (fd, file, mode, AT_SYMLINK_NOFOLLOW); -} diff --git a/src/bin/tar/lib/pathmax.h b/src/bin/tar/lib/pathmax.h deleted file mode 100644 index 6941e457e3..0000000000 --- a/src/bin/tar/lib/pathmax.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Define PATH_MAX somehow. Requires sys/types.h. - Copyright (C) 1992, 1999, 2001, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _PATHMAX_H -# define _PATHMAX_H - -# include - -# include - -# ifndef _POSIX_PATH_MAX -# define _POSIX_PATH_MAX 256 -# 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 -# 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 */ diff --git a/src/bin/tar/lib/paxerror.c b/src/bin/tar/lib/paxerror.c deleted file mode 100644 index b4edb68b90..0000000000 --- a/src/bin/tar/lib/paxerror.c +++ /dev/null @@ -1,365 +0,0 @@ -/* Miscellaneous error functions - - Copyright (C) 2005, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include -#include - -/* Decode MODE from its binary form in a stat structure, and encode it - into a 9-byte string STRING, terminated with a NUL. */ - -void -pax_decode_mode (mode_t mode, char *string) -{ - *string++ = mode & S_IRUSR ? 'r' : '-'; - *string++ = mode & S_IWUSR ? 'w' : '-'; - *string++ = (mode & S_ISUID - ? (mode & S_IXUSR ? 's' : 'S') - : (mode & S_IXUSR ? 'x' : '-')); - *string++ = mode & S_IRGRP ? 'r' : '-'; - *string++ = mode & S_IWGRP ? 'w' : '-'; - *string++ = (mode & S_ISGID - ? (mode & S_IXGRP ? 's' : 'S') - : (mode & S_IXGRP ? 'x' : '-')); - *string++ = mode & S_IROTH ? 'r' : '-'; - *string++ = mode & S_IWOTH ? 'w' : '-'; - *string++ = (mode & S_ISVTX - ? (mode & S_IXOTH ? 't' : 'T') - : (mode & S_IXOTH ? 'x' : '-')); - *string = '\0'; -} - -/* Report an error associated with the system call CALL and the - optional name NAME. */ -void -call_arg_error (char const *call, char const *name) -{ - int e = errno; - /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. - Directly translating this to another language will not work, first because - %s itself is not translated. - Translate it as `%s: Function %s failed'. */ - ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call)); -} - -/* Report a fatal error associated with the system call CALL and - the optional file name NAME. */ -void -call_arg_fatal (char const *call, char const *name) -{ - int e = errno; - /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. - Directly translating this to another language will not work, first because - %s itself is not translated. - Translate it as `%s: Function %s failed'. */ - FATAL_ERROR ((0, e, _("%s: Cannot %s"), quotearg_colon (name), call)); -} - -/* Report a warning associated with the system call CALL and - the optional file name NAME. */ -void -call_arg_warn (char const *call, char const *name) -{ - int e = errno; - /* TRANSLATORS: %s after `Cannot' is a function name, e.g. `Cannot open'. - Directly translating this to another language will not work, first because - %s itself is not translated. - Translate it as `%s: Function %s failed'. */ - WARN ((0, e, _("%s: Warning: Cannot %s"), quotearg_colon (name), call)); -} - -void -chmod_error_details (char const *name, mode_t mode) -{ - int e = errno; - char buf[10]; - pax_decode_mode (mode, buf); - ERROR ((0, e, _("%s: Cannot change mode to %s"), - quotearg_colon (name), buf)); -} - -void -chown_error_details (char const *name, uid_t uid, gid_t gid) -{ - int e = errno; - ERROR ((0, e, _("%s: Cannot change ownership to uid %lu, gid %lu"), - quotearg_colon (name), (unsigned long) uid, (unsigned long) gid)); -} - -void -close_error (char const *name) -{ - call_arg_error ("close", name); -} - -void -close_warn (char const *name) -{ - call_arg_warn ("close", name); -} - -void -exec_fatal (char const *name) -{ - call_arg_fatal ("exec", name); -} - -void -link_error (char const *target, char const *source) -{ - int e = errno; - ERROR ((0, e, _("%s: Cannot hard link to %s"), - quotearg_colon (source), quote_n (1, target))); -} - -void -mkdir_error (char const *name) -{ - call_arg_error ("mkdir", name); -} - -void -mkfifo_error (char const *name) -{ - call_arg_error ("mkfifo", name); -} - -void -mknod_error (char const *name) -{ - call_arg_error ("mknod", name); -} - -void -open_error (char const *name) -{ - call_arg_error ("open", name); -} - -void -open_fatal (char const *name) -{ - call_arg_fatal ("open", name); -} - -void -open_warn (char const *name) -{ - call_arg_warn ("open", name); -} - -void -read_error (char const *name) -{ - call_arg_error ("read", name); -} - -void -read_error_details (char const *name, off_t offset, size_t size) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - ERROR ((0, e, - ngettext ("%s: Read error at byte %s, while reading %lu byte", - "%s: Read error at byte %s, while reading %lu bytes", - size), - quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), - (unsigned long) size)); -} - -void -read_warn_details (char const *name, off_t offset, size_t size) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - WARN ((0, e, - ngettext ("%s: Warning: Read error at byte %s, while reading %lu byte", - "%s: Warning: Read error at byte %s, while reading %lu bytes", - size), - quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), - (unsigned long) size)); -} - -void -read_fatal (char const *name) -{ - call_arg_fatal ("read", name); -} - -void -read_fatal_details (char const *name, off_t offset, size_t size) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - FATAL_ERROR ((0, e, - ngettext ("%s: Read error at byte %s, while reading %lu byte", - "%s: Read error at byte %s, while reading %lu bytes", - size), - quotearg_colon (name), STRINGIFY_BIGINT (offset, buf), - (unsigned long) size)); -} - -void -readlink_error (char const *name) -{ - call_arg_error ("readlink", name); -} - -void -readlink_warn (char const *name) -{ - call_arg_warn ("readlink", name); -} - -void -rmdir_error (char const *name) -{ - call_arg_error ("rmdir", name); -} - -void -savedir_error (char const *name) -{ - call_arg_error ("savedir", name); -} - -void -savedir_warn (char const *name) -{ - call_arg_warn ("savedir", name); -} - -void -seek_error (char const *name) -{ - call_arg_error ("seek", name); -} - -void -seek_error_details (char const *name, off_t offset) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - ERROR ((0, e, _("%s: Cannot seek to %s"), - quotearg_colon (name), - STRINGIFY_BIGINT (offset, buf))); -} - -void -seek_warn (char const *name) -{ - call_arg_warn ("seek", name); -} - -void -seek_warn_details (char const *name, off_t offset) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - int e = errno; - WARN ((0, e, _("%s: Warning: Cannot seek to %s"), - quotearg_colon (name), - STRINGIFY_BIGINT (offset, buf))); -} - -void -symlink_error (char const *contents, char const *name) -{ - int e = errno; - ERROR ((0, e, _("%s: Cannot create symlink to %s"), - quotearg_colon (name), quote_n (1, contents))); -} - -void -stat_fatal (char const *name) -{ - call_arg_fatal ("stat", name); -} - -void -stat_error (char const *name) -{ - call_arg_error ("stat", name); -} - -void -stat_warn (char const *name) -{ - call_arg_warn ("stat", name); -} - -void -truncate_error (char const *name) -{ - call_arg_error ("truncate", name); -} - -void -truncate_warn (char const *name) -{ - call_arg_warn ("truncate", name); -} - -void -unlink_error (char const *name) -{ - call_arg_error ("unlink", name); -} - -void -utime_error (char const *name) -{ - call_arg_error ("utime", name); -} - -void -waitpid_error (char const *name) -{ - call_arg_error ("waitpid", name); -} - -void -write_error (char const *name) -{ - call_arg_error ("write", name); -} - -void -write_error_details (char const *name, size_t status, size_t size) -{ - if (status == 0) - write_error (name); - else - ERROR ((0, 0, - ngettext ("%s: Wrote only %lu of %lu byte", - "%s: Wrote only %lu of %lu bytes", - size), - name, (unsigned long int) status, (unsigned long int) size)); -} - -void -write_fatal (char const *name) -{ - call_arg_fatal ("write", name); -} - -void -chdir_fatal (char const *name) -{ - call_arg_fatal ("chdir", name); -} diff --git a/src/bin/tar/lib/paxexit.c b/src/bin/tar/lib/paxexit.c deleted file mode 100644 index 1a2e5b511b..0000000000 --- a/src/bin/tar/lib/paxexit.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Miscellaneous error functions - - Copyright (C) 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include - -int exit_status = PAXEXIT_SUCCESS; - -void -pax_exit () -{ - exit (exit_status); -} diff --git a/src/bin/tar/lib/paxlib.h b/src/bin/tar/lib/paxlib.h deleted file mode 100644 index 2fa396a227..0000000000 --- a/src/bin/tar/lib/paxlib.h +++ /dev/null @@ -1,115 +0,0 @@ -/* This file is part of GNU paxutils - - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, - 2005, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef _paxlib_h_ -#define _paxlib_h_ - -#include -#include - -/* Error reporting functions and definitions */ - -/* Exit status for paxutils app. Let's try to keep this list as simple as - possible. tar -d option strongly invites a status different for unequal - comparison and other errors. */ -#define PAXEXIT_SUCCESS 0 -#define PAXEXIT_DIFFERS 1 -#define PAXEXIT_FAILURE 2 - -/* Both WARN and ERROR write a message on stderr and continue processing, - however ERROR manages so tar will exit unsuccessfully. FATAL_ERROR - writes a message on stderr and aborts immediately, with another message - line telling so. USAGE_ERROR works like FATAL_ERROR except that the - other message line suggests trying --help. All four macros accept a - single argument of the form ((0, errno, _("FORMAT"), Args...)). errno - is zero when the error is not being detected by the system. */ - -#define WARN(Args) \ - error Args -#define ERROR(Args) \ - (error Args, exit_status = PAXEXIT_FAILURE) -#define FATAL_ERROR(Args) \ - (error Args, fatal_exit ()) -#define USAGE_ERROR(Args) \ - (error Args, usage (PAXEXIT_FAILURE)) - -extern int exit_status; - -void pax_decode_mode (mode_t mode, char *string); -void call_arg_error (char const *call, char const *name); -void call_arg_fatal (char const *call, char const *name) __attribute__ ((noreturn)); -void call_arg_warn (char const *call, char const *name); -void chmod_error_details (char const *name, mode_t mode); -void chown_error_details (char const *name, uid_t uid, gid_t gid); - -void decode_mode (mode_t, char *); - -void chdir_fatal (char const *) __attribute__ ((noreturn)); -void chmod_error_details (char const *, mode_t); -void chown_error_details (char const *, uid_t, gid_t); -void close_error (char const *); -void close_warn (char const *); -void exec_fatal (char const *) __attribute__ ((noreturn)); -void link_error (char const *, char const *); -void mkdir_error (char const *); -void mkfifo_error (char const *); -void mknod_error (char const *); -void open_error (char const *); -void open_fatal (char const *) __attribute__ ((noreturn)); -void open_warn (char const *); -void read_error (char const *); -void read_error_details (char const *, off_t, size_t); -void read_fatal (char const *) __attribute__ ((noreturn)); -void read_fatal_details (char const *, off_t, size_t) __attribute__ ((noreturn)); -void read_warn_details (char const *, off_t, size_t); -void readlink_error (char const *); -void readlink_warn (char const *); -void rmdir_error (char const *); -void savedir_error (char const *); -void savedir_warn (char const *); -void seek_error (char const *); -void seek_error_details (char const *, off_t); -void seek_warn (char const *); -void seek_warn_details (char const *, off_t); -void stat_fatal (char const *); -void stat_error (char const *); -void stat_warn (char const *); -void symlink_error (char const *, char const *); -void truncate_error (char const *); -void truncate_warn (char const *); -void unlink_error (char const *); -void utime_error (char const *); -void waitpid_error (char const *); -void write_error (char const *); - -void pax_exit (void); -void fatal_exit (void) __attribute__ ((noreturn)); - -#define STRINGIFY_BIGINT(i, b) umaxtostr (i, b) - - -/* Name-related functions */ -bool hash_string_insert (Hash_table **table, char const *string); -bool hash_string_lookup (Hash_table const *table, char const *string); - -bool removed_prefixes_p (void); -char *safer_name_suffix (char const *file_name, bool link_target, bool absolute_names); - -#endif diff --git a/src/bin/tar/lib/paxnames.c b/src/bin/tar/lib/paxnames.c deleted file mode 100644 index 80fa83ebab..0000000000 --- a/src/bin/tar/lib/paxnames.c +++ /dev/null @@ -1,179 +0,0 @@ -/* This file is part of GNU paxutils - Copyright (C) 2005, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include - - -/* Hash tables of strings. */ - -/* Calculate the hash of a string. */ -static size_t -hash_string_hasher (void const *name, size_t n_buckets) -{ - return hash_string (name, n_buckets); -} - -/* Compare two strings for equality. */ -static bool -hash_string_compare (void const *name1, void const *name2) -{ - return strcmp (name1, name2) == 0; -} - -/* Return zero if TABLE contains a LEN-character long prefix of STRING, - otherwise, insert a newly allocated copy of this prefix to TABLE and - return 1. If RETURN_PREFIX is not NULL, point it to the allocated - copy. */ -static bool -hash_string_insert_prefix (Hash_table **table, char const *string, size_t len, - const char **return_prefix) -{ - Hash_table *t = *table; - char *s; - char *e; - - if (len) - { - s = xmalloc (len + 1); - memcpy (s, string, len); - s[len] = 0; - } - else - s = xstrdup (string); - - if (! ((t - || (*table = t = hash_initialize (0, 0, hash_string_hasher, - hash_string_compare, 0))) - && (e = hash_insert (t, s)))) - xalloc_die (); - - if (e == s) - { - if (return_prefix) - *return_prefix = s; - return 1; - } - else - { - free (s); - return 0; - } -} - -/* Return zero if TABLE contains a copy of STRING; otherwise, insert a - copy of STRING to TABLE and return 1. */ -bool -hash_string_insert (Hash_table **table, char const *string) -{ - return hash_string_insert_prefix (table, string, 0, NULL); -} - -/* Return 1 if TABLE contains STRING. */ -bool -hash_string_lookup (Hash_table const *table, char const *string) -{ - return table && hash_lookup (table, string); -} - - -static Hash_table *prefix_table[2]; - -/* Return true if file names of some members in the archive were stripped off - their leading components. We could have used - return prefix_table[0] || prefix_table[1] - but the following seems to be safer: */ -bool -removed_prefixes_p (void) -{ - return (prefix_table[0] && hash_get_n_entries (prefix_table[0]) != 0) - || (prefix_table[1] && hash_get_n_entries (prefix_table[1]) != 0); -} - -/* Return a safer suffix of FILE_NAME, or "." if it has no safer - suffix. Check for fully specified file names and other atrocities. - Warn the user if we do not return NAME. If LINK_TARGET is 1, - FILE_NAME is the target of a hard link, not a member name. - If ABSOLUTE_NAMES is 0, strip filesystem prefix from the file name. */ - -char * -safer_name_suffix (char const *file_name, bool link_target, - bool absolute_names) -{ - char const *p; - - if (absolute_names) - p = file_name; - else - { - /* Skip file system prefixes, leading file name components that contain - "..", and leading slashes. */ - - size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name); - - for (p = file_name + prefix_len; *p; ) - { - if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) - prefix_len = p + 2 - file_name; - - do - { - char c = *p++; - if (ISSLASH (c)) - break; - } - while (*p); - } - - for (p = file_name + prefix_len; ISSLASH (*p); p++) - continue; - prefix_len = p - file_name; - - if (prefix_len) - { - const char *prefix; - if (hash_string_insert_prefix (&prefix_table[link_target], file_name, - prefix_len, &prefix)) - { - static char const *const diagnostic[] = - { - N_("Removing leading `%s' from member names"), - N_("Removing leading `%s' from hard link targets") - }; - WARN ((0, 0, _(diagnostic[link_target]), prefix)); - } - } - } - - if (! *p) - { - if (p == file_name) - { - static char const *const diagnostic[] = - { - N_("Substituting `.' for empty member name"), - N_("Substituting `.' for empty hard link target") - }; - WARN ((0, 0, "%s", _(diagnostic[link_target]))); - } - - p = "."; - } - - return (char *) p; -} diff --git a/src/bin/tar/lib/pipe-safer.c b/src/bin/tar/lib/pipe-safer.c deleted file mode 100644 index e4431b33a4..0000000000 --- a/src/bin/tar/lib/pipe-safer.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Invoke pipe, but avoid some glitches. - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -#include "unistd-safer.h" - -#include -#include - -/* Like pipe, but ensure that neither of the file descriptors is - STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO. Fail with ENOSYS on - platforms that lack pipe. */ - -int -pipe_safer (int fd[2]) -{ -#if HAVE_PIPE - if (pipe (fd) == 0) - { - int i; - for (i = 0; i < 2; i++) - { - fd[i] = fd_safer (fd[i]); - if (fd[i] < 0) - { - int e = errno; - close (fd[1 - i]); - errno = e; - return -1; - } - } - - return 0; - } -#else - errno = ENOSYS; -#endif - - return -1; -} diff --git a/src/bin/tar/lib/prepargs.c b/src/bin/tar/lib/prepargs.c deleted file mode 100644 index 1b6b0ce6dd..0000000000 --- a/src/bin/tar/lib/prepargs.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Parse arguments from a string and prepend them to an argv. - Copyright 1999, 2000, 2001, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ - -/* Written by Paul Eggert . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "prepargs.h" -#include -#include - -#if HAVE_STRING_H -# include -#endif - -#include - -/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given - as an argument to macros like "isspace". */ -#ifdef STDC_HEADERS -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) ((c) <= 0177) -#endif - -#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) - -/* Find the white-space-separated options specified by OPTIONS, and - using BUF to store copies of these options, set ARGV[0], ARGV[1], - etc. to the option copies. Return the number N of options found. - Do not set ARGV[N]. If ARGV is null, do not store ARGV[0] - etc. Backslash can be used to escape whitespace (and backslashes). */ -static int -prepend_args (char const *options, char *buf, char **argv) -{ - char const *o = options; - char *b = buf; - int n = 0; - - for (;;) - { - while (ISSPACE ((unsigned char) *o)) - o++; - if (!*o) - return n; - if (argv) - argv[n] = b; - n++; - - do - if ((*b++ = *o++) == '\\' && *o) - b[-1] = *o++; - while (*o && ! ISSPACE ((unsigned char) *o)); - - *b++ = '\0'; - } -} - -/* Prepend the whitespace-separated options in OPTIONS to the argument - vector of a main program with argument count *PARGC and argument - vector *PARGV. */ -void -prepend_default_options (char const *options, int *pargc, char ***pargv) -{ - if (options) - { - char *buf = xmalloc (strlen (options) + 1); - int prepended = prepend_args (options, buf, (char **) 0); - int argc = *pargc; - char * const *argv = *pargv; - char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp); - *pargc = prepended + argc; - *pargv = pp; - *pp++ = *argv++; - pp += prepend_args (options, buf, pp); - while ((*pp++ = *argv++)) - continue; - } -} diff --git a/src/bin/tar/lib/prepargs.h b/src/bin/tar/lib/prepargs.h deleted file mode 100644 index ce93ea870c..0000000000 --- a/src/bin/tar/lib/prepargs.h +++ /dev/null @@ -1,3 +0,0 @@ -/* Parse arguments from a string and prepend them to an argv. */ - -void prepend_default_options (char const *, int *, char ***); diff --git a/src/bin/tar/lib/printf-args.c b/src/bin/tar/lib/printf-args.c deleted file mode 100644 index 4978914662..0000000000 --- a/src/bin/tar/lib/printf-args.c +++ /dev/null @@ -1,187 +0,0 @@ -/* Decomposed printf argument list. - Copyright (C) 1999, 2002-2003, 2005-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This file can be parametrized with the following macros: - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. - PRINTF_FETCHARGS Name of the function to be defined. - STATIC Set to 'static' to declare the function static. */ - -#ifndef PRINTF_FETCHARGS -# include -#endif - -/* Specification. */ -#ifndef PRINTF_FETCHARGS -# include "printf-args.h" -#endif - -#ifdef STATIC -STATIC -#endif -int -PRINTF_FETCHARGS (va_list args, arguments *a) -{ - size_t i; - argument *ap; - - for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++) - switch (ap->type) - { - case TYPE_SCHAR: - ap->a.a_schar = va_arg (args, /*signed char*/ int); - break; - case TYPE_UCHAR: - ap->a.a_uchar = va_arg (args, /*unsigned char*/ int); - break; - case TYPE_SHORT: - ap->a.a_short = va_arg (args, /*short*/ int); - break; - case TYPE_USHORT: - ap->a.a_ushort = va_arg (args, /*unsigned short*/ int); - break; - case TYPE_INT: - ap->a.a_int = va_arg (args, int); - break; - case TYPE_UINT: - ap->a.a_uint = va_arg (args, unsigned int); - break; - case TYPE_LONGINT: - ap->a.a_longint = va_arg (args, long int); - break; - case TYPE_ULONGINT: - ap->a.a_ulongint = va_arg (args, unsigned long int); - break; -#if HAVE_LONG_LONG_INT - case TYPE_LONGLONGINT: - ap->a.a_longlongint = va_arg (args, long long int); - break; - case TYPE_ULONGLONGINT: - ap->a.a_ulonglongint = va_arg (args, unsigned long long int); - break; -#endif - case TYPE_DOUBLE: - ap->a.a_double = va_arg (args, double); - break; - case TYPE_LONGDOUBLE: - ap->a.a_longdouble = va_arg (args, long double); - break; - case TYPE_CHAR: - ap->a.a_char = va_arg (args, int); - break; -#if HAVE_WINT_T - case TYPE_WIDE_CHAR: - /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by - default argument promotions", this is not the case in mingw32, - where wint_t is 'unsigned short'. */ - ap->a.a_wide_char = - (sizeof (wint_t) < sizeof (int) - ? va_arg (args, int) - : va_arg (args, wint_t)); - break; -#endif - case TYPE_STRING: - ap->a.a_string = va_arg (args, const char *); - /* A null pointer is an invalid argument for "%s", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_string == NULL) - ap->a.a_string = "(NULL)"; - break; -#if HAVE_WCHAR_T - case TYPE_WIDE_STRING: - ap->a.a_wide_string = va_arg (args, const wchar_t *); - /* A null pointer is an invalid argument for "%ls", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_wide_string == NULL) - { - static const wchar_t wide_null_string[] = - { - (wchar_t)'(', - (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L', - (wchar_t)')', - (wchar_t)0 - }; - ap->a.a_wide_string = wide_null_string; - } - break; -#endif - case TYPE_POINTER: - ap->a.a_pointer = va_arg (args, void *); - break; - case TYPE_COUNT_SCHAR_POINTER: - ap->a.a_count_schar_pointer = va_arg (args, signed char *); - break; - case TYPE_COUNT_SHORT_POINTER: - ap->a.a_count_short_pointer = va_arg (args, short *); - break; - case TYPE_COUNT_INT_POINTER: - ap->a.a_count_int_pointer = va_arg (args, int *); - break; - case TYPE_COUNT_LONGINT_POINTER: - ap->a.a_count_longint_pointer = va_arg (args, long int *); - break; -#if HAVE_LONG_LONG_INT - case TYPE_COUNT_LONGLONGINT_POINTER: - ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); - break; -#endif -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - case TYPE_U8_STRING: - ap->a.a_u8_string = va_arg (args, const uint8_t *); - /* A null pointer is an invalid argument for "%U", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_u8_string == NULL) - { - static const uint8_t u8_null_string[] = - { '(', 'N', 'U', 'L', 'L', ')', 0 }; - ap->a.a_u8_string = u8_null_string; - } - break; - case TYPE_U16_STRING: - ap->a.a_u16_string = va_arg (args, const uint16_t *); - /* A null pointer is an invalid argument for "%lU", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_u16_string == NULL) - { - static const uint16_t u16_null_string[] = - { '(', 'N', 'U', 'L', 'L', ')', 0 }; - ap->a.a_u16_string = u16_null_string; - } - break; - case TYPE_U32_STRING: - ap->a.a_u32_string = va_arg (args, const uint32_t *); - /* A null pointer is an invalid argument for "%llU", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_u32_string == NULL) - { - static const uint32_t u32_null_string[] = - { '(', 'N', 'U', 'L', 'L', ')', 0 }; - ap->a.a_u32_string = u32_null_string; - } - break; -#endif - default: - /* Unknown type. */ - return -1; - } - return 0; -} diff --git a/src/bin/tar/lib/printf-args.h b/src/bin/tar/lib/printf-args.h deleted file mode 100644 index 6f75e2aea4..0000000000 --- a/src/bin/tar/lib/printf-args.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Decomposed printf argument list. - Copyright (C) 1999, 2002-2003, 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _PRINTF_ARGS_H -#define _PRINTF_ARGS_H - -/* This file can be parametrized with the following macros: - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. - PRINTF_FETCHARGS Name of the function to be declared. - STATIC Set to 'static' to declare the function static. */ - -/* Default parameters. */ -#ifndef PRINTF_FETCHARGS -# define PRINTF_FETCHARGS printf_fetchargs -#endif - -/* Get size_t. */ -#include - -/* Get wchar_t. */ -#if HAVE_WCHAR_T -# include -#endif - -/* Get wint_t. */ -#if HAVE_WINT_T -# include -#endif - -/* Get va_list. */ -#include - - -/* Argument types */ -typedef enum -{ - TYPE_NONE, - TYPE_SCHAR, - TYPE_UCHAR, - TYPE_SHORT, - TYPE_USHORT, - TYPE_INT, - TYPE_UINT, - TYPE_LONGINT, - TYPE_ULONGINT, -#if HAVE_LONG_LONG_INT - TYPE_LONGLONGINT, - TYPE_ULONGLONGINT, -#endif - TYPE_DOUBLE, - TYPE_LONGDOUBLE, - TYPE_CHAR, -#if HAVE_WINT_T - TYPE_WIDE_CHAR, -#endif - TYPE_STRING, -#if HAVE_WCHAR_T - TYPE_WIDE_STRING, -#endif - TYPE_POINTER, - TYPE_COUNT_SCHAR_POINTER, - TYPE_COUNT_SHORT_POINTER, - TYPE_COUNT_INT_POINTER, - TYPE_COUNT_LONGINT_POINTER -#if HAVE_LONG_LONG_INT -, TYPE_COUNT_LONGLONGINT_POINTER -#endif -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ -, TYPE_U8_STRING -, TYPE_U16_STRING -, TYPE_U32_STRING -#endif -} arg_type; - -/* Polymorphic argument */ -typedef struct -{ - arg_type type; - union - { - signed char a_schar; - unsigned char a_uchar; - short a_short; - unsigned short a_ushort; - int a_int; - unsigned int a_uint; - long int a_longint; - unsigned long int a_ulongint; -#if HAVE_LONG_LONG_INT - long long int a_longlongint; - unsigned long long int a_ulonglongint; -#endif - float a_float; - double a_double; - long double a_longdouble; - int a_char; -#if HAVE_WINT_T - wint_t a_wide_char; -#endif - const char* a_string; -#if HAVE_WCHAR_T - const wchar_t* a_wide_string; -#endif - void* a_pointer; - signed char * a_count_schar_pointer; - short * a_count_short_pointer; - int * a_count_int_pointer; - long int * a_count_longint_pointer; -#if HAVE_LONG_LONG_INT - long long int * a_count_longlongint_pointer; -#endif -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - const uint8_t * a_u8_string; - const uint16_t * a_u16_string; - const uint32_t * a_u32_string; -#endif - } - a; -} -argument; - -typedef struct -{ - size_t count; - argument *arg; -} -arguments; - - -/* Fetch the arguments, putting them into a. */ -#ifdef STATIC -STATIC -#else -extern -#endif -int PRINTF_FETCHARGS (va_list args, arguments *a); - -#endif /* _PRINTF_ARGS_H */ diff --git a/src/bin/tar/lib/printf-parse.c b/src/bin/tar/lib/printf-parse.c deleted file mode 100644 index 2e67980977..0000000000 --- a/src/bin/tar/lib/printf-parse.c +++ /dev/null @@ -1,576 +0,0 @@ -/* Formatted output to strings. - Copyright (C) 1999-2000, 2002-2003, 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This file can be parametrized with the following macros: - CHAR_T The element type of the format string. - CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters - in the format string are ASCII. - DIRECTIVE Structure denoting a format directive. - Depends on CHAR_T. - DIRECTIVES Structure denoting the set of format directives of a - format string. Depends on CHAR_T. - PRINTF_PARSE Function that parses a format string. - Depends on CHAR_T. - STATIC Set to 'static' to declare the function static. - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */ - -#ifndef PRINTF_PARSE -# include -#endif - -/* Specification. */ -#ifndef PRINTF_PARSE -# include "printf-parse.h" -#endif - -/* Default parameters. */ -#ifndef PRINTF_PARSE -# define PRINTF_PARSE printf_parse -# define CHAR_T char -# define DIRECTIVE char_directive -# define DIRECTIVES char_directives -#endif - -/* Get size_t, NULL. */ -#include - -/* Get intmax_t. */ -#ifdef IN_LIBINTL -# if HAVE_STDINT_H_WITH_UINTMAX -# include -# endif -# if HAVE_INTTYPES_H_WITH_UINTMAX -# include -# endif -#else -# include -#endif - -/* malloc(), realloc(), free(). */ -#include - -/* Checked size_t computations. */ -#include "xsize.h" - -#if CHAR_T_ONLY_ASCII -/* c_isascii(). */ -# include "c-ctype.h" -#endif - -#ifdef STATIC -STATIC -#endif -int -PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) -{ - const CHAR_T *cp = format; /* pointer into format */ - size_t arg_posn = 0; /* number of regular arguments consumed */ - size_t d_allocated; /* allocated elements of d->dir */ - size_t a_allocated; /* allocated elements of a->arg */ - size_t max_width_length = 0; - size_t max_precision_length = 0; - - d->count = 0; - d_allocated = 1; - d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE)); - if (d->dir == NULL) - /* Out of memory. */ - return -1; - - a->count = 0; - a_allocated = 0; - a->arg = NULL; - -#define REGISTER_ARG(_index_,_type_) \ - { \ - size_t n = (_index_); \ - if (n >= a_allocated) \ - { \ - size_t memory_size; \ - argument *memory; \ - \ - a_allocated = xtimes (a_allocated, 2); \ - if (a_allocated <= n) \ - a_allocated = xsum (n, 1); \ - memory_size = xtimes (a_allocated, sizeof (argument)); \ - if (size_overflow_p (memory_size)) \ - /* Overflow, would lead to out of memory. */ \ - goto error; \ - memory = (argument *) (a->arg \ - ? realloc (a->arg, memory_size) \ - : malloc (memory_size)); \ - if (memory == NULL) \ - /* Out of memory. */ \ - goto error; \ - a->arg = memory; \ - } \ - while (a->count <= n) \ - a->arg[a->count++].type = TYPE_NONE; \ - if (a->arg[n].type == TYPE_NONE) \ - a->arg[n].type = (_type_); \ - else if (a->arg[n].type != (_type_)) \ - /* Ambiguous type for positional argument. */ \ - goto error; \ - } - - while (*cp != '\0') - { - CHAR_T c = *cp++; - if (c == '%') - { - size_t arg_index = ARG_NONE; - DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */ - - /* Initialize the next directive. */ - dp->dir_start = cp - 1; - dp->flags = 0; - dp->width_start = NULL; - dp->width_end = NULL; - dp->width_arg_index = ARG_NONE; - dp->precision_start = NULL; - dp->precision_end = NULL; - dp->precision_arg_index = ARG_NONE; - dp->arg_index = ARG_NONE; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - n = xsum (xtimes (n, 10), *np - '0'); - if (n == 0) - /* Positional argument 0. */ - goto error; - if (size_overflow_p (n)) - /* n too large, would lead to out of memory later. */ - goto error; - arg_index = n - 1; - cp = np + 1; - } - } - - /* Read the flags. */ - for (;;) - { - if (*cp == '\'') - { - dp->flags |= FLAG_GROUP; - cp++; - } - else if (*cp == '-') - { - dp->flags |= FLAG_LEFT; - cp++; - } - else if (*cp == '+') - { - dp->flags |= FLAG_SHOWSIGN; - cp++; - } - else if (*cp == ' ') - { - dp->flags |= FLAG_SPACE; - cp++; - } - else if (*cp == '#') - { - dp->flags |= FLAG_ALT; - cp++; - } - else if (*cp == '0') - { - dp->flags |= FLAG_ZERO; - cp++; - } - else - break; - } - - /* Parse the field width. */ - if (*cp == '*') - { - dp->width_start = cp; - cp++; - dp->width_end = cp; - if (max_width_length < 1) - max_width_length = 1; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - n = xsum (xtimes (n, 10), *np - '0'); - if (n == 0) - /* Positional argument 0. */ - goto error; - if (size_overflow_p (n)) - /* n too large, would lead to out of memory later. */ - goto error; - dp->width_arg_index = n - 1; - cp = np + 1; - } - } - if (dp->width_arg_index == ARG_NONE) - { - dp->width_arg_index = arg_posn++; - if (dp->width_arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->width_arg_index, TYPE_INT); - } - else if (*cp >= '0' && *cp <= '9') - { - size_t width_length; - - dp->width_start = cp; - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - dp->width_end = cp; - width_length = dp->width_end - dp->width_start; - if (max_width_length < width_length) - max_width_length = width_length; - } - - /* Parse the precision. */ - if (*cp == '.') - { - cp++; - if (*cp == '*') - { - dp->precision_start = cp - 1; - cp++; - dp->precision_end = cp; - if (max_precision_length < 2) - max_precision_length = 2; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - n = xsum (xtimes (n, 10), *np - '0'); - if (n == 0) - /* Positional argument 0. */ - goto error; - if (size_overflow_p (n)) - /* n too large, would lead to out of memory - later. */ - goto error; - dp->precision_arg_index = n - 1; - cp = np + 1; - } - } - if (dp->precision_arg_index == ARG_NONE) - { - dp->precision_arg_index = arg_posn++; - if (dp->precision_arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->precision_arg_index, TYPE_INT); - } - else - { - size_t precision_length; - - dp->precision_start = cp - 1; - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - dp->precision_end = cp; - precision_length = dp->precision_end - dp->precision_start; - if (max_precision_length < precision_length) - max_precision_length = precision_length; - } - } - - { - arg_type type; - - /* Parse argument type/size specifiers. */ - { - int flags = 0; - - for (;;) - { - if (*cp == 'h') - { - flags |= (1 << (flags & 1)); - cp++; - } - else if (*cp == 'L') - { - flags |= 4; - cp++; - } - else if (*cp == 'l') - { - flags += 8; - cp++; - } - else if (*cp == 'j') - { - if (sizeof (intmax_t) > sizeof (long)) - { - /* intmax_t = long long */ - flags += 16; - } - else if (sizeof (intmax_t) > sizeof (int)) - { - /* intmax_t = long */ - flags += 8; - } - cp++; - } - else if (*cp == 'z' || *cp == 'Z') - { - /* 'z' is standardized in ISO C 99, but glibc uses 'Z' - because the warning facility in gcc-2.95.2 understands - only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ - if (sizeof (size_t) > sizeof (long)) - { - /* size_t = long long */ - flags += 16; - } - else if (sizeof (size_t) > sizeof (int)) - { - /* size_t = long */ - flags += 8; - } - cp++; - } - else if (*cp == 't') - { - if (sizeof (ptrdiff_t) > sizeof (long)) - { - /* ptrdiff_t = long long */ - flags += 16; - } - else if (sizeof (ptrdiff_t) > sizeof (int)) - { - /* ptrdiff_t = long */ - flags += 8; - } - cp++; - } - else - break; - } - - /* Read the conversion character. */ - c = *cp++; - switch (c) - { - case 'd': case 'i': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ - if (flags >= 16 || (flags & 4)) - type = TYPE_LONGLONGINT; - else -#endif - /* If 'long long' exists and is the same as 'long', we parse - "lld" into TYPE_LONGINT. */ - if (flags >= 8) - type = TYPE_LONGINT; - else if (flags & 2) - type = TYPE_SCHAR; - else if (flags & 1) - type = TYPE_SHORT; - else - type = TYPE_INT; - break; - case 'o': case 'u': case 'x': case 'X': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ - if (flags >= 16 || (flags & 4)) - type = TYPE_ULONGLONGINT; - else -#endif - /* If 'unsigned long long' exists and is the same as - 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ - if (flags >= 8) - type = TYPE_ULONGINT; - else if (flags & 2) - type = TYPE_UCHAR; - else if (flags & 1) - type = TYPE_USHORT; - else - type = TYPE_UINT; - break; - case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': - case 'a': case 'A': - if (flags >= 16 || (flags & 4)) - type = TYPE_LONGDOUBLE; - else - type = TYPE_DOUBLE; - break; - case 'c': - if (flags >= 8) -#if HAVE_WINT_T - type = TYPE_WIDE_CHAR; -#else - goto error; -#endif - else - type = TYPE_CHAR; - break; -#if HAVE_WINT_T - case 'C': - type = TYPE_WIDE_CHAR; - c = 'c'; - break; -#endif - case 's': - if (flags >= 8) -#if HAVE_WCHAR_T - type = TYPE_WIDE_STRING; -#else - goto error; -#endif - else - type = TYPE_STRING; - break; -#if HAVE_WCHAR_T - case 'S': - type = TYPE_WIDE_STRING; - c = 's'; - break; -#endif - case 'p': - type = TYPE_POINTER; - break; - case 'n': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ - if (flags >= 16 || (flags & 4)) - type = TYPE_COUNT_LONGLONGINT_POINTER; - else -#endif - /* If 'long long' exists and is the same as 'long', we parse - "lln" into TYPE_COUNT_LONGINT_POINTER. */ - if (flags >= 8) - type = TYPE_COUNT_LONGINT_POINTER; - else if (flags & 2) - type = TYPE_COUNT_SCHAR_POINTER; - else if (flags & 1) - type = TYPE_COUNT_SHORT_POINTER; - else - type = TYPE_COUNT_INT_POINTER; - break; -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - case 'U': - if (flags >= 16) - type = TYPE_U32_STRING; - else if (flags >= 8) - type = TYPE_U16_STRING; - else - type = TYPE_U8_STRING; - break; -#endif - case '%': - type = TYPE_NONE; - break; - default: - /* Unknown conversion character. */ - goto error; - } - } - - if (type != TYPE_NONE) - { - dp->arg_index = arg_index; - if (dp->arg_index == ARG_NONE) - { - dp->arg_index = arg_posn++; - if (dp->arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->arg_index, type); - } - dp->conversion = c; - dp->dir_end = cp; - } - - d->count++; - if (d->count >= d_allocated) - { - size_t memory_size; - DIRECTIVE *memory; - - d_allocated = xtimes (d_allocated, 2); - memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); - if (size_overflow_p (memory_size)) - /* Overflow, would lead to out of memory. */ - goto error; - memory = (DIRECTIVE *) realloc (d->dir, memory_size); - if (memory == NULL) - /* Out of memory. */ - goto error; - d->dir = memory; - } - } -#if CHAR_T_ONLY_ASCII - else if (!c_isascii (c)) - { - /* Non-ASCII character. Not supported. */ - goto error; - } -#endif - } - d->dir[d->count].dir_start = cp; - - d->max_width_length = max_width_length; - d->max_precision_length = max_precision_length; - return 0; - -error: - if (a->arg) - free (a->arg); - if (d->dir) - free (d->dir); - return -1; -} - -#undef PRINTF_PARSE -#undef DIRECTIVES -#undef DIRECTIVE -#undef CHAR_T_ONLY_ASCII -#undef CHAR_T diff --git a/src/bin/tar/lib/printf-parse.h b/src/bin/tar/lib/printf-parse.h deleted file mode 100644 index de7fc49b6f..0000000000 --- a/src/bin/tar/lib/printf-parse.h +++ /dev/null @@ -1,179 +0,0 @@ -/* Parse printf format string. - Copyright (C) 1999, 2002-2003, 2005, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _PRINTF_PARSE_H -#define _PRINTF_PARSE_H - -/* This file can be parametrized with the following macros: - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. - STATIC Set to 'static' to declare the function static. */ - -#include "printf-args.h" - - -/* Flags */ -#define FLAG_GROUP 1 /* ' flag */ -#define FLAG_LEFT 2 /* - flag */ -#define FLAG_SHOWSIGN 4 /* + flag */ -#define FLAG_SPACE 8 /* space flag */ -#define FLAG_ALT 16 /* # flag */ -#define FLAG_ZERO 32 - -/* arg_index value indicating that no argument is consumed. */ -#define ARG_NONE (~(size_t)0) - -/* xxx_directive: A parsed directive. - xxx_directives: A parsed format string. */ - -/* A parsed directive. */ -typedef struct -{ - const char* dir_start; - const char* dir_end; - int flags; - const char* width_start; - const char* width_end; - size_t width_arg_index; - const char* precision_start; - const char* precision_end; - size_t precision_arg_index; - char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -char_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - char_directive *dir; - size_t max_width_length; - size_t max_precision_length; -} -char_directives; - -#if ENABLE_UNISTDIO - -/* A parsed directive. */ -typedef struct -{ - const uint8_t* dir_start; - const uint8_t* dir_end; - int flags; - const uint8_t* width_start; - const uint8_t* width_end; - size_t width_arg_index; - const uint8_t* precision_start; - const uint8_t* precision_end; - size_t precision_arg_index; - uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -u8_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - u8_directive *dir; - size_t max_width_length; - size_t max_precision_length; -} -u8_directives; - -/* A parsed directive. */ -typedef struct -{ - const uint16_t* dir_start; - const uint16_t* dir_end; - int flags; - const uint16_t* width_start; - const uint16_t* width_end; - size_t width_arg_index; - const uint16_t* precision_start; - const uint16_t* precision_end; - size_t precision_arg_index; - uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -u16_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - u16_directive *dir; - size_t max_width_length; - size_t max_precision_length; -} -u16_directives; - -/* A parsed directive. */ -typedef struct -{ - const uint32_t* dir_start; - const uint32_t* dir_end; - int flags; - const uint32_t* width_start; - const uint32_t* width_end; - size_t width_arg_index; - const uint32_t* precision_start; - const uint32_t* precision_end; - size_t precision_arg_index; - uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -u32_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - u32_directive *dir; - size_t max_width_length; - size_t max_precision_length; -} -u32_directives; - -#endif - - -/* Parses the format string. Fills in the number N of directives, and fills - in directives[0], ..., directives[N-1], and sets directives[N].dir_start - to the end of the format string. Also fills in the arg_type fields of the - arguments and the needed count of arguments. */ -#if ENABLE_UNISTDIO -extern int - ulc_printf_parse (const char *format, char_directives *d, arguments *a); -extern int - u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a); -extern int - u16_printf_parse (const uint16_t *format, u16_directives *d, - arguments *a); -extern int - u32_printf_parse (const uint32_t *format, u32_directives *d, - arguments *a); -#else -# ifdef STATIC -STATIC -# else -extern -# endif -int printf_parse (const char *format, char_directives *d, arguments *a); -#endif - -#endif /* _PRINTF_PARSE_H */ diff --git a/src/bin/tar/lib/quote.c b/src/bin/tar/lib/quote.c deleted file mode 100644 index 119be72ae0..0000000000 --- a/src/bin/tar/lib/quote.c +++ /dev/null @@ -1,41 +0,0 @@ -/* quote.c - quote arguments for output - - Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include - -#include "quotearg.h" -#include "quote.h" - -/* Return an unambiguous printable representation of NAME, - allocated in slot N, suitable for diagnostics. */ -char const * -quote_n (int n, char const *name) -{ - return quotearg_n_style (n, locale_quoting_style, name); -} - -/* Return an unambiguous printable representation of NAME, - suitable for diagnostics. */ -char const * -quote (char const *name) -{ - return quote_n (0, name); -} diff --git a/src/bin/tar/lib/quote.h b/src/bin/tar/lib/quote.h deleted file mode 100644 index 5400eadb65..0000000000 --- a/src/bin/tar/lib/quote.h +++ /dev/null @@ -1,22 +0,0 @@ -/* quote.h - prototypes for quote.c - - Copyright (C) 1998, 1999, 2000, 2001, 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - - -char const *quote_n (int n, char const *name); -char const *quote (char const *name); diff --git a/src/bin/tar/lib/quotearg.c b/src/bin/tar/lib/quotearg.c deleted file mode 100644 index f7f326ac50..0000000000 --- a/src/bin/tar/lib/quotearg.c +++ /dev/null @@ -1,697 +0,0 @@ -/* quotearg.c - quote arguments for output - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#include - -#include "quotearg.h" - -#include "xalloc.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gettext.h" -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -#if !HAVE_MBRTOWC -/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the - other macros are defined only for documentation and to satisfy C - syntax. */ -# undef MB_CUR_MAX -# define MB_CUR_MAX 1 -# undef mbstate_t -# define mbstate_t int -# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0) -# define iswprint(wc) isprint ((unsigned char) (wc)) -# undef HAVE_MBSINIT -#endif - -#if !defined mbsinit && !HAVE_MBSINIT -# define mbsinit(ps) 1 -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -#define INT_BITS (sizeof (int) * CHAR_BIT) - -struct quoting_options -{ - /* Basic quoting style. */ - enum quoting_style style; - - /* Quote the characters indicated by this bit vector even if the - quoting style would not normally require them to be quoted. */ - unsigned int quote_these_too[(UCHAR_MAX / INT_BITS) + 1]; -}; - -/* Names of quoting styles. */ -char const *const quoting_style_args[] = -{ - "literal", - "shell", - "shell-always", - "c", - "escape", - "locale", - "clocale", - 0 -}; - -/* Correspondences to quoting style names. */ -enum quoting_style const quoting_style_vals[] = -{ - literal_quoting_style, - shell_quoting_style, - shell_always_quoting_style, - c_quoting_style, - escape_quoting_style, - locale_quoting_style, - clocale_quoting_style -}; - -/* The default quoting options. */ -static struct quoting_options default_quoting_options; - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options * -clone_quoting_options (struct quoting_options *o) -{ - int e = errno; - struct quoting_options *p = xmemdup (o ? o : &default_quoting_options, - sizeof *o); - errno = e; - return p; -} - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style -get_quoting_style (struct quoting_options *o) -{ - return (o ? o : &default_quoting_options)->style; -} - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void -set_quoting_style (struct quoting_options *o, enum quoting_style s) -{ - (o ? o : &default_quoting_options)->style = s; -} - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int -set_char_quoting (struct quoting_options *o, char c, int i) -{ - unsigned char uc = c; - unsigned int *p = - (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; - int shift = uc % INT_BITS; - int r = (*p >> shift) & 1; - *p ^= ((i & 1) ^ r) << shift; - return r; -} - -/* MSGID approximates a quotation mark. Return its translation if it - has one; otherwise, return either it or "\"", depending on S. */ -static char const * -gettext_quote (char const *msgid, enum quoting_style s) -{ - char const *translation = _(msgid); - if (translation == msgid && s == clocale_quoting_style) - translation = "\""; - return translation; -} - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using QUOTING_STYLE and the - non-quoting-style part of O to control quoting. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE. - - This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG, - ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting - style specified by O, and O may not be null. */ - -static size_t -quotearg_buffer_restyled (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - enum quoting_style quoting_style, - struct quoting_options const *o) -{ - size_t i; - size_t len = 0; - char const *quote_string = 0; - size_t quote_string_len = 0; - bool backslash_escapes = false; - bool unibyte_locale = MB_CUR_MAX == 1; - -#define STORE(c) \ - do \ - { \ - if (len < buffersize) \ - buffer[len] = (c); \ - len++; \ - } \ - while (0) - - switch (quoting_style) - { - case c_quoting_style: - STORE ('"'); - backslash_escapes = true; - quote_string = "\""; - quote_string_len = 1; - break; - - case escape_quoting_style: - backslash_escapes = true; - break; - - case locale_quoting_style: - case clocale_quoting_style: - { - /* TRANSLATORS: - Get translations for open and closing quotation marks. - - The message catalog should translate "`" to a left - quotation mark suitable for the locale, and similarly for - "'". If the catalog has no translation, - locale_quoting_style quotes `like this', and - clocale_quoting_style quotes "like this". - - For example, an American English Unicode locale should - translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and - should translate "'" to U+201D (RIGHT DOUBLE QUOTATION - MARK). A British English Unicode locale should instead - translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and - U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. - - If you don't know what to put here, please see - - and use glyphs suitable for your language. */ - - char const *left = gettext_quote (N_("`"), quoting_style); - char const *right = gettext_quote (N_("'"), quoting_style); - for (quote_string = left; *quote_string; quote_string++) - STORE (*quote_string); - backslash_escapes = true; - quote_string = right; - quote_string_len = strlen (quote_string); - } - break; - - case shell_always_quoting_style: - STORE ('\''); - quote_string = "'"; - quote_string_len = 1; - break; - - default: - break; - } - - for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++) - { - unsigned char c; - unsigned char esc; - - if (backslash_escapes - && quote_string_len - && i + quote_string_len <= argsize - && memcmp (arg + i, quote_string, quote_string_len) == 0) - STORE ('\\'); - - c = arg[i]; - switch (c) - { - case '\0': - if (backslash_escapes) - { - STORE ('\\'); - STORE ('0'); - STORE ('0'); - c = '0'; - } - break; - - case '?': - switch (quoting_style) - { - case shell_quoting_style: - goto use_shell_always_quoting_style; - - case c_quoting_style: - if (i + 2 < argsize && arg[i + 1] == '?') - switch (arg[i + 2]) - { - case '!': case '\'': - case '(': case ')': case '-': case '/': - case '<': case '=': case '>': - /* Escape the second '?' in what would otherwise be - a trigraph. */ - c = arg[i + 2]; - i += 2; - STORE ('?'); - STORE ('\\'); - STORE ('?'); - break; - - default: - break; - } - break; - - default: - break; - } - break; - - case '\a': esc = 'a'; goto c_escape; - case '\b': esc = 'b'; goto c_escape; - case '\f': esc = 'f'; goto c_escape; - case '\n': esc = 'n'; goto c_and_shell_escape; - case '\r': esc = 'r'; goto c_and_shell_escape; - case '\t': esc = 't'; goto c_and_shell_escape; - case '\v': esc = 'v'; goto c_escape; - case '\\': esc = c; goto c_and_shell_escape; - - c_and_shell_escape: - if (quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - c_escape: - if (backslash_escapes) - { - c = esc; - goto store_escape; - } - break; - - case '{': case '}': /* sometimes special if isolated */ - if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1)) - break; - /* Fall through. */ - case '#': case '~': - if (i != 0) - break; - /* Fall through. */ - case ' ': - case '!': /* special in bash */ - case '"': case '$': case '&': - case '(': case ')': case '*': case ';': - case '<': - case '=': /* sometimes special in 0th or (with "set -k") later args */ - case '>': case '[': - case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ - case '`': case '|': - /* A shell special character. In theory, '$' and '`' could - be the first bytes of multibyte characters, which means - we should check them with mbrtowc, but in practice this - doesn't happen so it's not worth worrying about. */ - if (quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - break; - - case '\'': - switch (quoting_style) - { - case shell_quoting_style: - goto use_shell_always_quoting_style; - - case shell_always_quoting_style: - STORE ('\''); - STORE ('\\'); - STORE ('\''); - break; - - default: - break; - } - break; - - case '%': case '+': case ',': case '-': case '.': case '/': - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case ':': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': case ']': case '_': case 'a': case 'b': - case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': - case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': - case 'o': case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': - /* These characters don't cause problems, no matter what the - quoting style is. They cannot start multibyte sequences. */ - break; - - default: - /* If we have a multibyte sequence, copy it until we reach - its end, find an error, or come back to the initial shift - state. For C-like styles, if the sequence has - unprintable characters, escape the whole sequence, since - we can't easily escape single characters within it. */ - { - /* Length of multibyte sequence found so far. */ - size_t m; - - bool printable; - - if (unibyte_locale) - { - m = 1; - printable = isprint (c) != 0; - } - else - { - mbstate_t mbstate; - memset (&mbstate, 0, sizeof mbstate); - - m = 0; - printable = true; - if (argsize == SIZE_MAX) - argsize = strlen (arg); - - do - { - wchar_t w; - size_t bytes = mbrtowc (&w, &arg[i + m], - argsize - (i + m), &mbstate); - if (bytes == 0) - break; - else if (bytes == (size_t) -1) - { - printable = false; - break; - } - else if (bytes == (size_t) -2) - { - printable = false; - while (i + m < argsize && arg[i + m]) - m++; - break; - } - else - { - /* Work around a bug with older shells that "see" a '\' - that is really the 2nd byte of a multibyte character. - In practice the problem is limited to ASCII - chars >= '@' that are shell special chars. */ - if ('[' == 0x5b && quoting_style == shell_quoting_style) - { - size_t j; - for (j = 1; j < bytes; j++) - switch (arg[i + m + j]) - { - case '[': case '\\': case '^': - case '`': case '|': - goto use_shell_always_quoting_style; - - default: - break; - } - } - - if (! iswprint (w)) - printable = false; - m += bytes; - } - } - while (! mbsinit (&mbstate)); - } - - if (1 < m || (backslash_escapes && ! printable)) - { - /* Output a multibyte sequence, or an escaped - unprintable unibyte character. */ - size_t ilim = i + m; - - for (;;) - { - if (backslash_escapes && ! printable) - { - STORE ('\\'); - STORE ('0' + (c >> 6)); - STORE ('0' + ((c >> 3) & 7)); - c = '0' + (c & 7); - } - if (ilim <= i + 1) - break; - STORE (c); - c = arg[++i]; - } - - goto store_c; - } - } - } - - if (! (backslash_escapes - && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))) - goto store_c; - - store_escape: - STORE ('\\'); - - store_c: - STORE (c); - } - - if (i == 0 && quoting_style == shell_quoting_style) - goto use_shell_always_quoting_style; - - if (quote_string) - for (; *quote_string; quote_string++) - STORE (*quote_string); - - if (len < buffersize) - buffer[len] = '\0'; - return len; - - use_shell_always_quoting_style: - return quotearg_buffer_restyled (buffer, buffersize, arg, argsize, - shell_always_quoting_style, o); -} - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is SIZE_MAX, use the string length of the argument for - ARGSIZE. */ -size_t -quotearg_buffer (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o) -{ - struct quoting_options const *p = o ? o : &default_quoting_options; - int e = errno; - size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize, - p->style, p); - errno = e; - return r; -} - -/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly - allocated storage containing the quoted string. */ -char * -quotearg_alloc (char const *arg, size_t argsize, - struct quoting_options const *o) -{ - int e = errno; - size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1; - char *buf = xcharalloc (bufsize); - quotearg_buffer (buf, bufsize, arg, argsize, o); - errno = e; - return buf; -} - -/* A storage slot with size and pointer to a value. */ -struct slotvec -{ - size_t size; - char *val; -}; - -/* Preallocate a slot 0 buffer, so that the caller can always quote - one small component of a "memory exhausted" message in slot 0. */ -static char slot0[256]; -static unsigned int nslots = 1; -static struct slotvec slotvec0 = {sizeof slot0, slot0}; -static struct slotvec *slotvec = &slotvec0; - -void -quotearg_free (void) -{ - struct slotvec *sv = slotvec; - unsigned int i; - for (i = 1; i < nslots; i++) - free (sv[i].val); - if (sv[0].val != slot0) - { - free (sv[0].val); - slotvec0.size = sizeof slot0; - slotvec0.val = slot0; - } - if (sv != &slotvec0) - { - free (sv); - slotvec = &slotvec0; - } - nslots = 1; -} - -/* Use storage slot N to return a quoted version of argument ARG. - ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a - null-terminated string. - OPTIONS specifies the quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. N is deliberately declared with type "int" - to allow for future extensions (using negative values). */ -static char * -quotearg_n_options (int n, char const *arg, size_t argsize, - struct quoting_options const *options) -{ - int e = errno; - - unsigned int n0 = n; - struct slotvec *sv = slotvec; - - if (n < 0) - abort (); - - if (nslots <= n0) - { - /* FIXME: technically, the type of n1 should be `unsigned int', - but that evokes an unsuppressible warning from gcc-4.0.1 and - older. If gcc ever provides an option to suppress that warning, - revert to the original type, so that the test in xalloc_oversized - is once again performed only at compile time. */ - size_t n1 = n0 + 1; - bool preallocated = (sv == &slotvec0); - - if (xalloc_oversized (n1, sizeof *sv)) - xalloc_die (); - - slotvec = sv = xrealloc (preallocated ? NULL : sv, n1 * sizeof *sv); - if (preallocated) - *sv = slotvec0; - memset (sv + nslots, 0, (n1 - nslots) * sizeof *sv); - nslots = n1; - } - - { - size_t size = sv[n].size; - char *val = sv[n].val; - size_t qsize = quotearg_buffer (val, size, arg, argsize, options); - - if (size <= qsize) - { - sv[n].size = size = qsize + 1; - if (val != slot0) - free (val); - sv[n].val = val = xcharalloc (size); - quotearg_buffer (val, size, arg, argsize, options); - } - - errno = e; - return val; - } -} - -char * -quotearg_n (int n, char const *arg) -{ - return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options); -} - -char * -quotearg (char const *arg) -{ - return quotearg_n (0, arg); -} - -/* Return quoting options for STYLE, with no extra quoting. */ -static struct quoting_options -quoting_options_from_style (enum quoting_style style) -{ - struct quoting_options o; - o.style = style; - memset (o.quote_these_too, 0, sizeof o.quote_these_too); - return o; -} - -char * -quotearg_n_style (int n, enum quoting_style s, char const *arg) -{ - struct quoting_options const o = quoting_options_from_style (s); - return quotearg_n_options (n, arg, SIZE_MAX, &o); -} - -char * -quotearg_n_style_mem (int n, enum quoting_style s, - char const *arg, size_t argsize) -{ - struct quoting_options const o = quoting_options_from_style (s); - return quotearg_n_options (n, arg, argsize, &o); -} - -char * -quotearg_style (enum quoting_style s, char const *arg) -{ - return quotearg_n_style (0, s, arg); -} - -char * -quotearg_char (char const *arg, char ch) -{ - struct quoting_options options; - options = default_quoting_options; - set_char_quoting (&options, ch, 1); - return quotearg_n_options (0, arg, SIZE_MAX, &options); -} - -char * -quotearg_colon (char const *arg) -{ - return quotearg_char (arg, ':'); -} diff --git a/src/bin/tar/lib/quotearg.h b/src/bin/tar/lib/quotearg.h deleted file mode 100644 index 4887df3b6d..0000000000 --- a/src/bin/tar/lib/quotearg.h +++ /dev/null @@ -1,140 +0,0 @@ -/* quotearg.h - quote arguments for output - - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert */ - -#ifndef QUOTEARG_H_ -# define QUOTEARG_H_ 1 - -# include - -/* Basic quoting styles. */ -enum quoting_style - { - /* Output names as-is (ls --quoting-style=literal). */ - literal_quoting_style, - - /* Quote names for the shell if they contain shell metacharacters - or would cause ambiguous output (ls --quoting-style=shell). */ - shell_quoting_style, - - /* Quote names for the shell, even if they would normally not - require quoting (ls --quoting-style=shell-always). */ - shell_always_quoting_style, - - /* Quote names as for a C language string (ls --quoting-style=c). */ - c_quoting_style, - - /* Like c_quoting_style except omit the surrounding double-quote - characters (ls --quoting-style=escape). */ - escape_quoting_style, - - /* Like clocale_quoting_style, but quote `like this' instead of - "like this" in the default C locale (ls --quoting-style=locale). */ - locale_quoting_style, - - /* Like c_quoting_style except use quotation marks appropriate for - the locale (ls --quoting-style=clocale). */ - clocale_quoting_style - }; - -/* For now, --quoting-style=literal is the default, but this may change. */ -# ifndef DEFAULT_QUOTING_STYLE -# define DEFAULT_QUOTING_STYLE literal_quoting_style -# endif - -/* Names of quoting styles and their corresponding values. */ -extern char const *const quoting_style_args[]; -extern enum quoting_style const quoting_style_vals[]; - -struct quoting_options; - -/* The functions listed below set and use a hidden variable - that contains the default quoting style options. */ - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options *clone_quoting_options (struct quoting_options *o); - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style get_quoting_style (struct quoting_options *o); - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void set_quoting_style (struct quoting_options *o, enum quoting_style s); - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int set_char_quoting (struct quoting_options *o, char c, int i); - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ -size_t quotearg_buffer (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o); - -/* Like quotearg_buffer, except return the result in a newly allocated - buffer. It is the caller's responsibility to free the result. */ -char *quotearg_alloc (char const *arg, size_t argsize, - struct quoting_options const *o); - -/* Use storage slot N to return a quoted version of the string ARG. - Use the default quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. */ -char *quotearg_n (int n, char const *arg); - -/* Equivalent to quotearg_n (0, ARG). */ -char *quotearg (char const *arg); - -/* Use style S and storage slot N to return a quoted version of the string ARG. - This is like quotearg_n (N, ARG), except that it uses S with no other - options to specify the quoting method. */ -char *quotearg_n_style (int n, enum quoting_style s, char const *arg); - -/* Use style S and storage slot N to return a quoted version of the - argument ARG of size ARGSIZE. This is like quotearg_n_style - (N, S, ARG), except it can quote null bytes. */ -char *quotearg_n_style_mem (int n, enum quoting_style s, - char const *arg, size_t argsize); - -/* Equivalent to quotearg_n_style (0, S, ARG). */ -char *quotearg_style (enum quoting_style s, char const *arg); - -/* Like quotearg (ARG), except also quote any instances of CH. */ -char *quotearg_char (char const *arg, char ch); - -/* Equivalent to quotearg_char (ARG, ':'). */ -char *quotearg_colon (char const *arg); - -/* Free any dynamically allocated memory. */ -void quotearg_free (void); - -#endif /* !QUOTEARG_H_ */ diff --git a/src/bin/tar/lib/readlink.c b/src/bin/tar/lib/readlink.c deleted file mode 100644 index 3cbdc1c2fd..0000000000 --- a/src/bin/tar/lib/readlink.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Stub for readlink(). - Copyright (C) 2003-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -#include -#include -#include -#include - -#if !HAVE_READLINK - -/* readlink() substitute for systems that don't have a readlink() function, - such as DJGPP 2.03 and mingw32. */ - -/* The official POSIX return type of readlink() is ssize_t, but since here - we have no declaration in a public header file, we use 'int' as return - type. */ - -int -readlink (const char *path, char *buf, size_t bufsize) -{ - struct stat statbuf; - - /* In general we should use lstat() here, not stat(). But on platforms - without symbolic links lstat() - if it exists - would be equivalent to - stat(), therefore we can use stat(). This saves us a configure check. */ - if (stat (path, &statbuf) >= 0) - errno = EINVAL; - return -1; -} - -#endif diff --git a/src/bin/tar/lib/realloc.c b/src/bin/tar/lib/realloc.c deleted file mode 100644 index b1c04508c8..0000000000 --- a/src/bin/tar/lib/realloc.c +++ /dev/null @@ -1,65 +0,0 @@ -/* realloc() function that is glibc compatible. - - Copyright (C) 1997, 2003, 2004, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* written by Jim Meyering and Bruno Haible */ - -#include -/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */ -#ifdef realloc -# define NEED_REALLOC_GNU -# undef realloc -#endif - -/* Specification. */ -#include - -#include - -/* Call the system's malloc and realloc below. */ -#undef malloc -#undef realloc - -/* Change the size of an allocated block of memory P to N bytes, - with error checking. If N is zero, change it to 1. If P is NULL, - use malloc. */ - -void * -rpl_realloc (void *p, size_t n) -{ - void *result; - -#ifdef NEED_REALLOC_GNU - if (n == 0) - { - n = 1; - - /* In theory realloc might fail, so don't rely on it to free. */ - free (p); - p = NULL; - } -#endif - - result = (p == NULL ? malloc (n) : realloc (p, n)); - -#if !HAVE_REALLOC_POSIX - if (result == NULL) - errno = ENOMEM; -#endif - - return result; -} diff --git a/src/bin/tar/lib/ref-add.sin b/src/bin/tar/lib/ref-add.sin deleted file mode 100644 index bc5cc7976f..0000000000 --- a/src/bin/tar/lib/ref-add.sin +++ /dev/null @@ -1,30 +0,0 @@ -# Add this package to a list of references stored in a text file. -# -# Copyright (C) 2000 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# Written by Bruno Haible . -# -/^# Packages using this file: / { - s/# Packages using this file:// - ta - :a - s/ @PACKAGE@ / @PACKAGE@ / - tb - s/ $/ @PACKAGE@ / - :b - s/^/# Packages using this file:/ -} diff --git a/src/bin/tar/lib/ref-del.sin b/src/bin/tar/lib/ref-del.sin deleted file mode 100644 index e9301bf2ea..0000000000 --- a/src/bin/tar/lib/ref-del.sin +++ /dev/null @@ -1,25 +0,0 @@ -# Remove this package from a list of references stored in a text file. -# -# Copyright (C) 2000 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# Written by Bruno Haible . -# -/^# Packages using this file: / { - s/# Packages using this file:// - s/ @PACKAGE@ / / - s/^/# Packages using this file:/ -} diff --git a/src/bin/tar/lib/regcomp.c b/src/bin/tar/lib/regcomp.c deleted file mode 100644 index fe4d243d54..0000000000 --- a/src/bin/tar/lib/regcomp.c +++ /dev/null @@ -1,3832 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, - size_t length, reg_syntax_t syntax); -static void re_compile_fastmap_iter (regex_t *bufp, - const re_dfastate_t *init_state, - char *fastmap); -static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len); -#ifdef RE_ENABLE_I18N -static void free_charset (re_charset_t *cset); -#endif /* RE_ENABLE_I18N */ -static void free_workarea_compile (regex_t *preg); -static reg_errcode_t create_initial_state (re_dfa_t *dfa); -#ifdef RE_ENABLE_I18N -static void optimize_utf8 (re_dfa_t *dfa); -#endif -static reg_errcode_t analyze (regex_t *preg); -static reg_errcode_t preorder (bin_tree_t *root, - reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra); -static reg_errcode_t postorder (bin_tree_t *root, - reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra); -static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node); -static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node); -static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg, - bin_tree_t *node); -static reg_errcode_t calc_first (void *extra, bin_tree_t *node); -static reg_errcode_t calc_next (void *extra, bin_tree_t *node); -static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node); -static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint); -static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node, - unsigned int constraint); -static reg_errcode_t calc_eclosure (re_dfa_t *dfa); -static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, - Idx node, bool root); -static reg_errcode_t calc_inveclosure (re_dfa_t *dfa); -static Idx fetch_number (re_string_t *input, re_token_t *token, - reg_syntax_t syntax); -static int peek_token (re_token_t *token, re_string_t *input, - reg_syntax_t syntax) internal_function; -static bin_tree_t *parse (re_string_t *regexp, regex_t *preg, - reg_syntax_t syntax, reg_errcode_t *err); -static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp, - re_dfa_t *dfa, re_token_t *token, - reg_syntax_t syntax, reg_errcode_t *err); -static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, - re_token_t *token, reg_syntax_t syntax, - reg_errcode_t *err); -static reg_errcode_t parse_bracket_element (bracket_elem_t *elem, - re_string_t *regexp, - re_token_t *token, int token_len, - re_dfa_t *dfa, - reg_syntax_t syntax, - bool accept_hyphen); -static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, - re_string_t *regexp, - re_token_t *token); -#ifdef RE_ENABLE_I18N -static reg_errcode_t build_equiv_class (bitset_t sbcset, - re_charset_t *mbcset, - Idx *equiv_class_alloc, - const unsigned char *name); -static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, - bitset_t sbcset, - re_charset_t *mbcset, - Idx *char_class_alloc, - const unsigned char *class_name, - reg_syntax_t syntax); -#else /* not RE_ENABLE_I18N */ -static reg_errcode_t build_equiv_class (bitset_t sbcset, - const unsigned char *name); -static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, - bitset_t sbcset, - const unsigned char *class_name, - reg_syntax_t syntax); -#endif /* not RE_ENABLE_I18N */ -static bin_tree_t *build_charclass_op (re_dfa_t *dfa, - RE_TRANSLATE_TYPE trans, - const unsigned char *class_name, - const unsigned char *extra, - bool non_match, reg_errcode_t *err); -static bin_tree_t *create_tree (re_dfa_t *dfa, - bin_tree_t *left, bin_tree_t *right, - re_token_type_t type); -static bin_tree_t *create_token_tree (re_dfa_t *dfa, - bin_tree_t *left, bin_tree_t *right, - const re_token_t *token); -static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa); -static void free_token (re_token_t *node); -static reg_errcode_t free_tree (void *extra, bin_tree_t *node); -static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node); - -/* This table gives an error message for each of the error codes listed - in regex.h. Obviously the order here has to be same as there. - POSIX doesn't require that we do anything for REG_NOERROR, - but why not be nice? */ - -static const char __re_error_msgid[] = - { -#define REG_NOERROR_IDX 0 - gettext_noop ("Success") /* REG_NOERROR */ - "\0" -#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success") - gettext_noop ("No match") /* REG_NOMATCH */ - "\0" -#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match") - gettext_noop ("Invalid regular expression") /* REG_BADPAT */ - "\0" -#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression") - gettext_noop ("Invalid collation character") /* REG_ECOLLATE */ - "\0" -#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character") - gettext_noop ("Invalid character class name") /* REG_ECTYPE */ - "\0" -#define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name") - gettext_noop ("Trailing backslash") /* REG_EESCAPE */ - "\0" -#define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash") - gettext_noop ("Invalid back reference") /* REG_ESUBREG */ - "\0" -#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference") - gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */ - "\0" -#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^") - gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */ - "\0" -#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(") - gettext_noop ("Unmatched \\{") /* REG_EBRACE */ - "\0" -#define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{") - gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */ - "\0" -#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}") - gettext_noop ("Invalid range end") /* REG_ERANGE */ - "\0" -#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end") - gettext_noop ("Memory exhausted") /* REG_ESPACE */ - "\0" -#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted") - gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */ - "\0" -#define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression") - gettext_noop ("Premature end of regular expression") /* REG_EEND */ - "\0" -#define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression") - gettext_noop ("Regular expression too big") /* REG_ESIZE */ - "\0" -#define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big") - gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */ - }; - -static const size_t __re_error_msgid_idx[] = - { - REG_NOERROR_IDX, - REG_NOMATCH_IDX, - REG_BADPAT_IDX, - REG_ECOLLATE_IDX, - REG_ECTYPE_IDX, - REG_EESCAPE_IDX, - REG_ESUBREG_IDX, - REG_EBRACK_IDX, - REG_EPAREN_IDX, - REG_EBRACE_IDX, - REG_BADBR_IDX, - REG_ERANGE_IDX, - REG_ESPACE_IDX, - REG_BADRPT_IDX, - REG_EEND_IDX, - REG_ESIZE_IDX, - REG_ERPAREN_IDX - }; - -/* Entry points for GNU code. */ - -/* re_compile_pattern is the GNU regular expression compiler: it - compiles PATTERN (of length LENGTH) and puts the result in BUFP. - Returns 0 if the pattern was valid, otherwise an error string. - - Assumes the `allocated' (and perhaps `buffer') and `translate' fields - are set in BUFP on entry. */ - -#ifdef _LIBC -const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - size_t length; - struct re_pattern_buffer *bufp; -#else /* size_t might promote */ -const char * -re_compile_pattern (const char *pattern, size_t length, - struct re_pattern_buffer *bufp) -#endif -{ - reg_errcode_t ret; - - /* And GNU code determines whether or not to get register information - by passing null for the REGS argument to re_match, etc., not by - setting no_sub, unless RE_NO_SUB is set. */ - bufp->no_sub = !!(re_syntax_options & RE_NO_SUB); - - /* Match anchors at newline. */ - bufp->newline_anchor = 1; - - ret = re_compile_internal (bufp, pattern, length, re_syntax_options); - - if (!ret) - return NULL; - return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); -} -#ifdef _LIBC -weak_alias (__re_compile_pattern, re_compile_pattern) -#endif - -/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can - also be assigned to arbitrarily: each pattern buffer stores its own - syntax, so it can be changed between regex compilations. */ -/* This has no initializer because initialized variables in Emacs - become read-only after dumping. */ -reg_syntax_t re_syntax_options; - - -/* Specify the precise syntax of regexps for compilation. This provides - for compatibility for various utilities which historically have - different, incompatible syntaxes. - - The argument SYNTAX is a bit mask comprised of the various bits - defined in regex.h. We return the old syntax. */ - -reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; -{ - reg_syntax_t ret = re_syntax_options; - - re_syntax_options = syntax; - return ret; -} -#ifdef _LIBC -weak_alias (__re_set_syntax, re_set_syntax) -#endif - -int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; -{ - re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; - char *fastmap = bufp->fastmap; - - memset (fastmap, '\0', sizeof (char) * SBC_MAX); - re_compile_fastmap_iter (bufp, dfa->init_state, fastmap); - if (dfa->init_state != dfa->init_state_word) - re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap); - if (dfa->init_state != dfa->init_state_nl) - re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap); - if (dfa->init_state != dfa->init_state_begbuf) - re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap); - bufp->fastmap_accurate = 1; - return 0; -} -#ifdef _LIBC -weak_alias (__re_compile_fastmap, re_compile_fastmap) -#endif - -static inline void -__attribute ((always_inline)) -re_set_fastmap (char *fastmap, bool icase, int ch) -{ - fastmap[ch] = 1; - if (icase) - fastmap[tolower (ch)] = 1; -} - -/* Helper function for re_compile_fastmap. - Compile fastmap for the initial_state INIT_STATE. */ - -static void -re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, - char *fastmap) -{ - re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; - Idx node_cnt; - bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); - for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) - { - Idx node = init_state->nodes.elems[node_cnt]; - re_token_type_t type = dfa->nodes[node].type; - - if (type == CHARACTER) - { - re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); -#ifdef RE_ENABLE_I18N - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) - { - unsigned char buf[MB_LEN_MAX]; - unsigned char *p; - wchar_t wc; - mbstate_t state; - - p = buf; - *p++ = dfa->nodes[node].opr.c; - while (++node < dfa->nodes_len - && dfa->nodes[node].type == CHARACTER - && dfa->nodes[node].mb_partial) - *p++ = dfa->nodes[node].opr.c; - memset (&state, '\0', sizeof (state)); - if (mbrtowc (&wc, (const char *) buf, p - buf, - &state) == p - buf - && (__wcrtomb ((char *) buf, towlower (wc), &state) - != (size_t) -1)) - re_set_fastmap (fastmap, false, buf[0]); - } -#endif - } - else if (type == SIMPLE_BRACKET) - { - int i, ch; - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - { - int j; - bitset_word_t w = dfa->nodes[node].opr.sbcset[i]; - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - if (w & ((bitset_word_t) 1 << j)) - re_set_fastmap (fastmap, icase, ch); - } - } -#ifdef RE_ENABLE_I18N - else if (type == COMPLEX_BRACKET) - { - Idx i; - re_charset_t *cset = dfa->nodes[node].opr.mbcset; - if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes - || cset->nranges || cset->nchar_classes) - { -# ifdef _LIBC - if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0) - { - /* In this case we want to catch the bytes which are - the first byte of any collation elements. - e.g. In da_DK, we want to catch 'a' since "aa" - is a valid collation element, and don't catch - 'b' since 'b' is the only collation element - which starts from 'b'. */ - const int32_t *table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - for (i = 0; i < SBC_MAX; ++i) - if (table[i] < 0) - re_set_fastmap (fastmap, icase, i); - } -# else - if (dfa->mb_cur_max > 1) - for (i = 0; i < SBC_MAX; ++i) - if (__btowc (i) == WEOF) - re_set_fastmap (fastmap, icase, i); -# endif /* not _LIBC */ - } - for (i = 0; i < cset->nmbchars; ++i) - { - char buf[256]; - mbstate_t state; - memset (&state, '\0', sizeof (state)); - if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) - re_set_fastmap (fastmap, icase, *(unsigned char *) buf); - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) - { - if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) - != (size_t) -1) - re_set_fastmap (fastmap, false, *(unsigned char *) buf); - } - } - } -#endif /* RE_ENABLE_I18N */ - else if (type == OP_PERIOD -#ifdef RE_ENABLE_I18N - || type == OP_UTF8_PERIOD -#endif /* RE_ENABLE_I18N */ - || type == END_OF_RE) - { - memset (fastmap, '\1', sizeof (char) * SBC_MAX); - if (type == END_OF_RE) - bufp->can_be_null = 1; - return; - } - } -} - -/* Entry point for POSIX code. */ -/* regcomp takes a regular expression as a string and compiles it. - - PREG is a regex_t *. We do not expect any fields to be initialized, - since POSIX says we shouldn't. Thus, we set - - `buffer' to the compiled pattern; - `used' to the length of the compiled pattern; - `syntax' to RE_SYNTAX_POSIX_EXTENDED if the - REG_EXTENDED bit in CFLAGS is set; otherwise, to - RE_SYNTAX_POSIX_BASIC; - `newline_anchor' to REG_NEWLINE being set in CFLAGS; - `fastmap' to an allocated space for the fastmap; - `fastmap_accurate' to zero; - `re_nsub' to the number of subexpressions in PATTERN. - - PATTERN is the address of the pattern string. - - CFLAGS is a series of bits which affect compilation. - - If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we - use POSIX basic syntax. - - If REG_NEWLINE is set, then . and [^...] don't match newline. - Also, regexec will try a match beginning after every newline. - - If REG_ICASE is set, then we considers upper- and lowercase - versions of letters to be equivalent when matching. - - If REG_NOSUB is set, then when PREG is passed to regexec, that - routine will report only success or failure, and nothing about the - registers. - - It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for - the return codes and their meanings.) */ - -int -regcomp (preg, pattern, cflags) - regex_t *_Restrict_ preg; - const char *_Restrict_ pattern; - int cflags; -{ - reg_errcode_t ret; - reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED - : RE_SYNTAX_POSIX_BASIC); - - preg->buffer = NULL; - preg->allocated = 0; - preg->used = 0; - - /* Try to allocate space for the fastmap. */ - preg->fastmap = re_malloc (char, SBC_MAX); - if (BE (preg->fastmap == NULL, 0)) - return REG_ESPACE; - - syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0; - - /* If REG_NEWLINE is set, newlines are treated differently. */ - if (cflags & REG_NEWLINE) - { /* REG_NEWLINE implies neither . nor [^...] match newline. */ - syntax &= ~RE_DOT_NEWLINE; - syntax |= RE_HAT_LISTS_NOT_NEWLINE; - /* It also changes the matching behavior. */ - preg->newline_anchor = 1; - } - else - preg->newline_anchor = 0; - preg->no_sub = !!(cflags & REG_NOSUB); - preg->translate = NULL; - - ret = re_compile_internal (preg, pattern, strlen (pattern), syntax); - - /* POSIX doesn't distinguish between an unmatched open-group and an - unmatched close-group: both are REG_EPAREN. */ - if (ret == REG_ERPAREN) - ret = REG_EPAREN; - - /* We have already checked preg->fastmap != NULL. */ - if (BE (ret == REG_NOERROR, 1)) - /* Compute the fastmap now, since regexec cannot modify the pattern - buffer. This function never fails in this implementation. */ - (void) re_compile_fastmap (preg); - else - { - /* Some error occurred while compiling the expression. */ - re_free (preg->fastmap); - preg->fastmap = NULL; - } - - return (int) ret; -} -#ifdef _LIBC -weak_alias (__regcomp, regcomp) -#endif - -/* Returns a message corresponding to an error code, ERRCODE, returned - from either regcomp or regexec. We don't use PREG here. */ - -#ifdef _LIBC -size_t -regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *_Restrict_ preg; - char *_Restrict_ errbuf; - size_t errbuf_size; -#else /* size_t might promote */ -size_t -regerror (int errcode, const regex_t *_Restrict_ preg, - char *_Restrict_ errbuf, size_t errbuf_size) -#endif -{ - const char *msg; - size_t msg_size; - - if (BE (errcode < 0 - || errcode >= (int) (sizeof (__re_error_msgid_idx) - / sizeof (__re_error_msgid_idx[0])), 0)) - /* Only error codes returned by the rest of the code should be passed - to this routine. If we are given anything else, or if other regex - code generates an invalid error code, then the program has a bug. - Dump core so we can fix it. */ - abort (); - - msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); - - msg_size = strlen (msg) + 1; /* Includes the null. */ - - if (BE (errbuf_size != 0, 1)) - { - size_t cpy_size = msg_size; - if (BE (msg_size > errbuf_size, 0)) - { - cpy_size = errbuf_size - 1; - errbuf[cpy_size] = '\0'; - } - memcpy (errbuf, msg, cpy_size); - } - - return msg_size; -} -#ifdef _LIBC -weak_alias (__regerror, regerror) -#endif - - -#ifdef RE_ENABLE_I18N -/* This static array is used for the map to single-byte characters when - UTF-8 is used. Otherwise we would allocate memory just to initialize - it the same all the time. UTF-8 is the preferred encoding so this is - a worthwhile optimization. */ -static const bitset_t utf8_sb_map = -{ - /* Set the first 128 bits. */ -# if 4 * BITSET_WORD_BITS < ASCII_CHARS -# error "bitset_word_t is narrower than 32 bits" -# elif 3 * BITSET_WORD_BITS < ASCII_CHARS - BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, -# elif 2 * BITSET_WORD_BITS < ASCII_CHARS - BITSET_WORD_MAX, BITSET_WORD_MAX, -# elif 1 * BITSET_WORD_BITS < ASCII_CHARS - BITSET_WORD_MAX, -# endif - (BITSET_WORD_MAX - >> (SBC_MAX % BITSET_WORD_BITS == 0 - ? 0 - : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS)) -}; -#endif - - -static void -free_dfa_content (re_dfa_t *dfa) -{ - Idx i, j; - - if (dfa->nodes) - for (i = 0; i < dfa->nodes_len; ++i) - free_token (dfa->nodes + i); - re_free (dfa->nexts); - for (i = 0; i < dfa->nodes_len; ++i) - { - if (dfa->eclosures != NULL) - re_node_set_free (dfa->eclosures + i); - if (dfa->inveclosures != NULL) - re_node_set_free (dfa->inveclosures + i); - if (dfa->edests != NULL) - re_node_set_free (dfa->edests + i); - } - re_free (dfa->edests); - re_free (dfa->eclosures); - re_free (dfa->inveclosures); - re_free (dfa->nodes); - - if (dfa->state_table) - for (i = 0; i <= dfa->state_hash_mask; ++i) - { - struct re_state_table_entry *entry = dfa->state_table + i; - for (j = 0; j < entry->num; ++j) - { - re_dfastate_t *state = entry->array[j]; - free_state (state); - } - re_free (entry->array); - } - re_free (dfa->state_table); -#ifdef RE_ENABLE_I18N - if (dfa->sb_char != utf8_sb_map) - re_free (dfa->sb_char); -#endif - re_free (dfa->subexp_map); -#ifdef DEBUG - re_free (dfa->re_str); -#endif - - re_free (dfa); -} - - -/* Free dynamically allocated space used by PREG. */ - -void -regfree (preg) - regex_t *preg; -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - if (BE (dfa != NULL, 1)) - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - - re_free (preg->fastmap); - preg->fastmap = NULL; - - re_free (preg->translate); - preg->translate = NULL; -} -#ifdef _LIBC -weak_alias (__regfree, regfree) -#endif - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined _REGEX_RE_COMP || defined _LIBC - -/* BSD has one and only one pattern buffer. */ -static struct re_pattern_buffer re_comp_buf; - -char * -# ifdef _LIBC -/* Make these definitions weak in libc, so POSIX programs can redefine - these names if they don't use our functions, and still use - regcomp/regexec above without link errors. */ -weak_function -# endif -re_comp (s) - const char *s; -{ - reg_errcode_t ret; - char *fastmap; - - if (!s) - { - if (!re_comp_buf.buffer) - return gettext ("No previous regular expression"); - return 0; - } - - if (re_comp_buf.buffer) - { - fastmap = re_comp_buf.fastmap; - re_comp_buf.fastmap = NULL; - __regfree (&re_comp_buf); - memset (&re_comp_buf, '\0', sizeof (re_comp_buf)); - re_comp_buf.fastmap = fastmap; - } - - if (re_comp_buf.fastmap == NULL) - { - re_comp_buf.fastmap = (char *) malloc (SBC_MAX); - if (re_comp_buf.fastmap == NULL) - return (char *) gettext (__re_error_msgid - + __re_error_msgid_idx[(int) REG_ESPACE]); - } - - /* Since `re_exec' always passes NULL for the `regs' argument, we - don't need to initialize the pattern buffer fields which affect it. */ - - /* Match anchors at newlines. */ - re_comp_buf.newline_anchor = 1; - - ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options); - - if (!ret) - return NULL; - - /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ - return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); -} - -#ifdef _LIBC -libc_freeres_fn (free_mem) -{ - __regfree (&re_comp_buf); -} -#endif - -#endif /* _REGEX_RE_COMP */ - -/* Internal entry point. - Compile the regular expression PATTERN, whose length is LENGTH. - SYNTAX indicate regular expression's syntax. */ - -static reg_errcode_t -re_compile_internal (regex_t *preg, const char * pattern, size_t length, - reg_syntax_t syntax) -{ - reg_errcode_t err = REG_NOERROR; - re_dfa_t *dfa; - re_string_t regexp; - - /* Initialize the pattern buffer. */ - preg->fastmap_accurate = 0; - preg->syntax = syntax; - preg->not_bol = preg->not_eol = 0; - preg->used = 0; - preg->re_nsub = 0; - preg->can_be_null = 0; - preg->regs_allocated = REGS_UNALLOCATED; - - /* Initialize the dfa. */ - dfa = (re_dfa_t *) preg->buffer; - if (BE (preg->allocated < sizeof (re_dfa_t), 0)) - { - /* If zero allocated, but buffer is non-null, try to realloc - enough space. This loses if buffer's address is bogus, but - that is the user's responsibility. If ->buffer is NULL this - is a simple allocation. */ - dfa = re_realloc (preg->buffer, re_dfa_t, 1); - if (dfa == NULL) - return REG_ESPACE; - preg->allocated = sizeof (re_dfa_t); - preg->buffer = (unsigned char *) dfa; - } - preg->used = sizeof (re_dfa_t); - - err = init_dfa (dfa, length); - if (BE (err != REG_NOERROR, 0)) - { - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - return err; - } -#ifdef DEBUG - /* Note: length+1 will not overflow since it is checked in init_dfa. */ - dfa->re_str = re_malloc (char, length + 1); - strncpy (dfa->re_str, pattern, length + 1); -#endif - - __libc_lock_init (dfa->lock); - - err = re_string_construct (®exp, pattern, length, preg->translate, - syntax & RE_ICASE, dfa); - if (BE (err != REG_NOERROR, 0)) - { - re_compile_internal_free_return: - free_workarea_compile (preg); - re_string_destruct (®exp); - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - return err; - } - - /* Parse the regular expression, and build a structure tree. */ - preg->re_nsub = 0; - dfa->str_tree = parse (®exp, preg, syntax, &err); - if (BE (dfa->str_tree == NULL, 0)) - goto re_compile_internal_free_return; - - /* Analyze the tree and create the nfa. */ - err = analyze (preg); - if (BE (err != REG_NOERROR, 0)) - goto re_compile_internal_free_return; - -#ifdef RE_ENABLE_I18N - /* If possible, do searching in single byte encoding to speed things up. */ - if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL) - optimize_utf8 (dfa); -#endif - - /* Then create the initial state of the dfa. */ - err = create_initial_state (dfa); - - /* Release work areas. */ - free_workarea_compile (preg); - re_string_destruct (®exp); - - if (BE (err != REG_NOERROR, 0)) - { - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - } - - return err; -} - -/* Initialize DFA. We use the length of the regular expression PAT_LEN - as the initial length of some arrays. */ - -static reg_errcode_t -init_dfa (re_dfa_t *dfa, size_t pat_len) -{ - __re_size_t table_size; -#ifdef RE_ENABLE_I18N - size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); -#else - size_t max_i18n_object_size = 0; -#endif - size_t max_object_size = - MAX (sizeof (struct re_state_table_entry), - MAX (sizeof (re_token_t), - MAX (sizeof (re_node_set), - MAX (sizeof (regmatch_t), - max_i18n_object_size)))); - - memset (dfa, '\0', sizeof (re_dfa_t)); - - /* Force allocation of str_tree_storage the first time. */ - dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; - - /* Avoid overflows. The extra "/ 2" is for the table_size doubling - calculation below, and for similar doubling calculations - elsewhere. And it's <= rather than <, because some of the - doubling calculations add 1 afterwards. */ - if (BE (SIZE_MAX / max_object_size / 2 <= pat_len, 0)) - return REG_ESPACE; - - dfa->nodes_alloc = pat_len + 1; - dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc); - - /* table_size = 2 ^ ceil(log pat_len) */ - for (table_size = 1; ; table_size <<= 1) - if (table_size > pat_len) - break; - - dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); - dfa->state_hash_mask = table_size - 1; - - dfa->mb_cur_max = MB_CUR_MAX; -#ifdef _LIBC - if (dfa->mb_cur_max == 6 - && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0) - dfa->is_utf8 = 1; - dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII) - != 0); -#else - if (strcmp (locale_charset (), "UTF-8") == 0) - dfa->is_utf8 = 1; - - /* We check exhaustively in the loop below if this charset is a - superset of ASCII. */ - dfa->map_notascii = 0; -#endif - -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - if (dfa->is_utf8) - dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map; - else - { - int i, j, ch; - - dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); - if (BE (dfa->sb_char == NULL, 0)) - return REG_ESPACE; - - /* Set the bits corresponding to single byte chars. */ - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - { - wint_t wch = __btowc (ch); - if (wch != WEOF) - dfa->sb_char[i] |= (bitset_word_t) 1 << j; -# ifndef _LIBC - if (isascii (ch) && wch != ch) - dfa->map_notascii = 1; -# endif - } - } - } -#endif - - if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0)) - return REG_ESPACE; - return REG_NOERROR; -} - -/* Initialize WORD_CHAR table, which indicate which character is - "word". In this case "word" means that it is the word construction - character used by some operators like "\<", "\>", etc. */ - -static void -internal_function -init_word_char (re_dfa_t *dfa) -{ - int i, j, ch; - dfa->word_ops_used = 1; - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - if (isalnum (ch) || ch == '_') - dfa->word_char[i] |= (bitset_word_t) 1 << j; -} - -/* Free the work area which are only used while compiling. */ - -static void -free_workarea_compile (regex_t *preg) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_storage_t *storage, *next; - for (storage = dfa->str_tree_storage; storage; storage = next) - { - next = storage->next; - re_free (storage); - } - dfa->str_tree_storage = NULL; - dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; - dfa->str_tree = NULL; - re_free (dfa->org_indices); - dfa->org_indices = NULL; -} - -/* Create initial states for all contexts. */ - -static reg_errcode_t -create_initial_state (re_dfa_t *dfa) -{ - Idx first, i; - reg_errcode_t err; - re_node_set init_nodes; - - /* Initial states have the epsilon closure of the node which is - the first node of the regular expression. */ - first = dfa->str_tree->first->node_idx; - dfa->init_node = first; - err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* The back-references which are in initial states can epsilon transit, - since in this case all of the subexpressions can be null. - Then we add epsilon closures of the nodes which are the next nodes of - the back-references. */ - if (dfa->nbackref > 0) - for (i = 0; i < init_nodes.nelem; ++i) - { - Idx node_idx = init_nodes.elems[i]; - re_token_type_t type = dfa->nodes[node_idx].type; - - Idx clexp_idx; - if (type != OP_BACK_REF) - continue; - for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx) - { - re_token_t *clexp_node; - clexp_node = dfa->nodes + init_nodes.elems[clexp_idx]; - if (clexp_node->type == OP_CLOSE_SUBEXP - && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx) - break; - } - if (clexp_idx == init_nodes.nelem) - continue; - - if (type == OP_BACK_REF) - { - Idx dest_idx = dfa->edests[node_idx].elems[0]; - if (!re_node_set_contains (&init_nodes, dest_idx)) - { - re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); - i = 0; - } - } - } - - /* It must be the first time to invoke acquire_state. */ - dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); - /* We don't check ERR here, since the initial state must not be NULL. */ - if (BE (dfa->init_state == NULL, 0)) - return err; - if (dfa->init_state->has_constraint) - { - dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, - CONTEXT_WORD); - dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes, - CONTEXT_NEWLINE); - dfa->init_state_begbuf = re_acquire_state_context (&err, dfa, - &init_nodes, - CONTEXT_NEWLINE - | CONTEXT_BEGBUF); - if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) - return err; - } - else - dfa->init_state_word = dfa->init_state_nl - = dfa->init_state_begbuf = dfa->init_state; - - re_node_set_free (&init_nodes); - return REG_NOERROR; -} - -#ifdef RE_ENABLE_I18N -/* If it is possible to do searching in single byte encoding instead of UTF-8 - to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change - DFA nodes where needed. */ - -static void -optimize_utf8 (re_dfa_t *dfa) -{ - Idx node; - int i; - bool mb_chars = false; - bool has_period = false; - - for (node = 0; node < dfa->nodes_len; ++node) - switch (dfa->nodes[node].type) - { - case CHARACTER: - if (dfa->nodes[node].opr.c >= ASCII_CHARS) - mb_chars = true; - break; - case ANCHOR: - switch (dfa->nodes[node].opr.idx) - { - case LINE_FIRST: - case LINE_LAST: - case BUF_FIRST: - case BUF_LAST: - break; - default: - /* Word anchors etc. cannot be handled. */ - return; - } - break; - case OP_PERIOD: - has_period = true; - break; - case OP_BACK_REF: - case OP_ALT: - case END_OF_RE: - case OP_DUP_ASTERISK: - case OP_OPEN_SUBEXP: - case OP_CLOSE_SUBEXP: - break; - case COMPLEX_BRACKET: - return; - case SIMPLE_BRACKET: - /* Just double check. */ - { - int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0 - ? 0 - : BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS); - for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i) - { - if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0) - return; - rshift = 0; - } - } - break; - default: - abort (); - } - - if (mb_chars || has_period) - for (node = 0; node < dfa->nodes_len; ++node) - { - if (dfa->nodes[node].type == CHARACTER - && dfa->nodes[node].opr.c >= ASCII_CHARS) - dfa->nodes[node].mb_partial = 0; - else if (dfa->nodes[node].type == OP_PERIOD) - dfa->nodes[node].type = OP_UTF8_PERIOD; - } - - /* The search can be in single byte locale. */ - dfa->mb_cur_max = 1; - dfa->is_utf8 = 0; - dfa->has_mb_node = dfa->nbackref > 0 || has_period; -} -#endif - -/* Analyze the structure tree, and calculate "first", "next", "edest", - "eclosure", and "inveclosure". */ - -static reg_errcode_t -analyze (regex_t *preg) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - reg_errcode_t ret; - - /* Allocate arrays. */ - dfa->nexts = re_malloc (Idx, dfa->nodes_alloc); - dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc); - dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc); - dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc); - if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL - || dfa->eclosures == NULL, 0)) - return REG_ESPACE; - - dfa->subexp_map = re_malloc (Idx, preg->re_nsub); - if (dfa->subexp_map != NULL) - { - Idx i; - for (i = 0; i < preg->re_nsub; i++) - dfa->subexp_map[i] = i; - preorder (dfa->str_tree, optimize_subexps, dfa); - for (i = 0; i < preg->re_nsub; i++) - if (dfa->subexp_map[i] != i) - break; - if (i == preg->re_nsub) - { - free (dfa->subexp_map); - dfa->subexp_map = NULL; - } - } - - ret = postorder (dfa->str_tree, lower_subexps, preg); - if (BE (ret != REG_NOERROR, 0)) - return ret; - ret = postorder (dfa->str_tree, calc_first, dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - preorder (dfa->str_tree, calc_next, dfa); - ret = preorder (dfa->str_tree, link_nfa_nodes, dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - ret = calc_eclosure (dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - /* We only need this during the prune_impossible_nodes pass in regexec.c; - skip it if p_i_n will not run, as calc_inveclosure can be quadratic. */ - if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match) - || dfa->nbackref) - { - dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); - if (BE (dfa->inveclosures == NULL, 0)) - return REG_ESPACE; - ret = calc_inveclosure (dfa); - } - - return ret; -} - -/* Our parse trees are very unbalanced, so we cannot use a stack to - implement parse tree visits. Instead, we use parent pointers and - some hairy code in these two functions. */ -static reg_errcode_t -postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra) -{ - bin_tree_t *node, *prev; - - for (node = root; ; ) - { - /* Descend down the tree, preferably to the left (or to the right - if that's the only child). */ - while (node->left || node->right) - if (node->left) - node = node->left; - else - node = node->right; - - do - { - reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) - return err; - if (node->parent == NULL) - return REG_NOERROR; - prev = node; - node = node->parent; - } - /* Go up while we have a node that is reached from the right. */ - while (node->right == prev || node->right == NULL); - node = node->right; - } -} - -static reg_errcode_t -preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra) -{ - bin_tree_t *node; - - for (node = root; ; ) - { - reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* Go to the left node, or up and to the right. */ - if (node->left) - node = node->left; - else - { - bin_tree_t *prev = NULL; - while (node->right == prev || node->right == NULL) - { - prev = node; - node = node->parent; - if (!node) - return REG_NOERROR; - } - node = node->right; - } - } -} - -/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell - re_search_internal to map the inner one's opr.idx to this one's. Adjust - backreferences as well. Requires a preorder visit. */ -static reg_errcode_t -optimize_subexps (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - - if (node->token.type == OP_BACK_REF && dfa->subexp_map) - { - int idx = node->token.opr.idx; - node->token.opr.idx = dfa->subexp_map[idx]; - dfa->used_bkref_map |= 1 << node->token.opr.idx; - } - - else if (node->token.type == SUBEXP - && node->left && node->left->token.type == SUBEXP) - { - Idx other_idx = node->left->token.opr.idx; - - node->left = node->left->left; - if (node->left) - node->left->parent = node; - - dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx]; - if (other_idx < BITSET_WORD_BITS) - dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx); - } - - return REG_NOERROR; -} - -/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation - of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP. */ -static reg_errcode_t -lower_subexps (void *extra, bin_tree_t *node) -{ - regex_t *preg = (regex_t *) extra; - reg_errcode_t err = REG_NOERROR; - - if (node->left && node->left->token.type == SUBEXP) - { - node->left = lower_subexp (&err, preg, node->left); - if (node->left) - node->left->parent = node; - } - if (node->right && node->right->token.type == SUBEXP) - { - node->right = lower_subexp (&err, preg, node->right); - if (node->right) - node->right->parent = node; - } - - return err; -} - -static bin_tree_t * -lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *body = node->left; - bin_tree_t *op, *cls, *tree1, *tree; - - if (preg->no_sub - /* We do not optimize empty subexpressions, because otherwise we may - have bad CONCAT nodes with NULL children. This is obviously not - very common, so we do not lose much. An example that triggers - this case is the sed "script" /\(\)/x. */ - && node->left != NULL - && (node->token.opr.idx >= BITSET_WORD_BITS - || !(dfa->used_bkref_map - & ((bitset_word_t) 1 << node->token.opr.idx)))) - return node->left; - - /* Convert the SUBEXP node to the concatenation of an - OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP. */ - op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP); - cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP); - tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls; - tree = create_tree (dfa, op, tree1, CONCAT); - if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - - op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx; - op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp; - return tree; -} - -/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton - nodes. Requires a postorder visit. */ -static reg_errcode_t -calc_first (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - if (node->token.type == CONCAT) - { - node->first = node->left->first; - node->node_idx = node->left->node_idx; - } - else - { - node->first = node; - node->node_idx = re_dfa_add_node (dfa, node->token); - if (BE (node->node_idx == REG_MISSING, 0)) - return REG_ESPACE; - } - return REG_NOERROR; -} - -/* Pass 2: compute NEXT on the tree. Preorder visit. */ -static reg_errcode_t -calc_next (void *extra, bin_tree_t *node) -{ - switch (node->token.type) - { - case OP_DUP_ASTERISK: - node->left->next = node; - break; - case CONCAT: - node->left->next = node->right->first; - node->right->next = node->next; - break; - default: - if (node->left) - node->left->next = node->next; - if (node->right) - node->right->next = node->next; - break; - } - return REG_NOERROR; -} - -/* Pass 3: link all DFA nodes to their NEXT node (any order will do). */ -static reg_errcode_t -link_nfa_nodes (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - Idx idx = node->node_idx; - reg_errcode_t err = REG_NOERROR; - - switch (node->token.type) - { - case CONCAT: - break; - - case END_OF_RE: - assert (node->next == NULL); - break; - - case OP_DUP_ASTERISK: - case OP_ALT: - { - Idx left, right; - dfa->has_plural_match = 1; - if (node->left != NULL) - left = node->left->first->node_idx; - else - left = node->next->node_idx; - if (node->right != NULL) - right = node->right->first->node_idx; - else - right = node->next->node_idx; - assert (REG_VALID_INDEX (left)); - assert (REG_VALID_INDEX (right)); - err = re_node_set_init_2 (dfa->edests + idx, left, right); - } - break; - - case ANCHOR: - case OP_OPEN_SUBEXP: - case OP_CLOSE_SUBEXP: - err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx); - break; - - case OP_BACK_REF: - dfa->nexts[idx] = node->next->node_idx; - if (node->token.type == OP_BACK_REF) - re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); - break; - - default: - assert (!IS_EPSILON_NODE (node->token.type)); - dfa->nexts[idx] = node->next->node_idx; - break; - } - - return err; -} - -/* Duplicate the epsilon closure of the node ROOT_NODE. - Note that duplicated nodes have constraint INIT_CONSTRAINT in addition - to their own constraint. */ - -static reg_errcode_t -internal_function -duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, - Idx root_node, unsigned int init_constraint) -{ - Idx org_node, clone_node; - bool ok; - unsigned int constraint = init_constraint; - for (org_node = top_org_node, clone_node = top_clone_node;;) - { - Idx org_dest, clone_dest; - if (dfa->nodes[org_node].type == OP_BACK_REF) - { - /* If the back reference epsilon-transit, its destination must - also have the constraint. Then duplicate the epsilon closure - of the destination of the back reference, and store it in - edests of the back reference. */ - org_dest = dfa->nexts[org_node]; - re_node_set_empty (dfa->edests + clone_node); - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - dfa->nexts[clone_node] = dfa->nexts[org_node]; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - else if (dfa->edests[org_node].nelem == 0) - { - /* In case of the node can't epsilon-transit, don't duplicate the - destination and store the original destination as the - destination of the node. */ - dfa->nexts[clone_node] = dfa->nexts[org_node]; - break; - } - else if (dfa->edests[org_node].nelem == 1) - { - /* In case of the node can epsilon-transit, and it has only one - destination. */ - org_dest = dfa->edests[org_node].elems[0]; - re_node_set_empty (dfa->edests + clone_node); - if (dfa->nodes[org_node].type == ANCHOR) - { - /* In case of the node has another constraint, append it. */ - if (org_node == root_node && clone_node != org_node) - { - /* ...but if the node is root_node itself, it means the - epsilon closure have a loop, then tie it to the - destination of the root_node. */ - ok = re_node_set_insert (dfa->edests + clone_node, org_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - break; - } - constraint |= dfa->nodes[org_node].opr.ctx_type; - } - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - else /* dfa->edests[org_node].nelem == 2 */ - { - /* In case of the node can epsilon-transit, and it has two - destinations. In the bin_tree_t and DFA, that's '|' and '*'. */ - org_dest = dfa->edests[org_node].elems[0]; - re_node_set_empty (dfa->edests + clone_node); - /* Search for a duplicated node which satisfies the constraint. */ - clone_dest = search_duplicated_node (dfa, org_dest, constraint); - if (clone_dest == REG_MISSING) - { - /* There are no such a duplicated node, create a new one. */ - reg_errcode_t err; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - err = duplicate_node_closure (dfa, org_dest, clone_dest, - root_node, constraint); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - { - /* There are a duplicated node which satisfy the constraint, - use it to avoid infinite loop. */ - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - - org_dest = dfa->edests[org_node].elems[1]; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - org_node = org_dest; - clone_node = clone_dest; - } - return REG_NOERROR; -} - -/* Search for a node which is duplicated from the node ORG_NODE, and - satisfies the constraint CONSTRAINT. */ - -static Idx -search_duplicated_node (const re_dfa_t *dfa, Idx org_node, - unsigned int constraint) -{ - Idx idx; - for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx) - { - if (org_node == dfa->org_indices[idx] - && constraint == dfa->nodes[idx].constraint) - return idx; /* Found. */ - } - return REG_MISSING; /* Not found. */ -} - -/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT. - Return the index of the new node, or REG_MISSING if insufficient storage is - available. */ - -static Idx -duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint) -{ - Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]); - if (BE (dup_idx != REG_MISSING, 1)) - { - dfa->nodes[dup_idx].constraint = constraint; - if (dfa->nodes[org_idx].type == ANCHOR) - dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type; - dfa->nodes[dup_idx].duplicated = 1; - - /* Store the index of the original node. */ - dfa->org_indices[dup_idx] = org_idx; - } - return dup_idx; -} - -static reg_errcode_t -calc_inveclosure (re_dfa_t *dfa) -{ - Idx src, idx; - bool ok; - for (idx = 0; idx < dfa->nodes_len; ++idx) - re_node_set_init_empty (dfa->inveclosures + idx); - - for (src = 0; src < dfa->nodes_len; ++src) - { - Idx *elems = dfa->eclosures[src].elems; - for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) - { - ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); - if (BE (! ok, 0)) - return REG_ESPACE; - } - } - - return REG_NOERROR; -} - -/* Calculate "eclosure" for all the node in DFA. */ - -static reg_errcode_t -calc_eclosure (re_dfa_t *dfa) -{ - Idx node_idx; - bool incomplete; -#ifdef DEBUG - assert (dfa->nodes_len > 0); -#endif - incomplete = false; - /* For each nodes, calculate epsilon closure. */ - for (node_idx = 0; ; ++node_idx) - { - reg_errcode_t err; - re_node_set eclosure_elem; - if (node_idx == dfa->nodes_len) - { - if (!incomplete) - break; - incomplete = false; - node_idx = 0; - } - -#ifdef DEBUG - assert (dfa->eclosures[node_idx].nelem != REG_MISSING); -#endif - - /* If we have already calculated, skip it. */ - if (dfa->eclosures[node_idx].nelem != 0) - continue; - /* Calculate epsilon closure of `node_idx'. */ - err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (dfa->eclosures[node_idx].nelem == 0) - { - incomplete = true; - re_node_set_free (&eclosure_elem); - } - } - return REG_NOERROR; -} - -/* Calculate epsilon closure of NODE. */ - -static reg_errcode_t -calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) -{ - reg_errcode_t err; - unsigned int constraint; - Idx i; - bool incomplete; - bool ok; - re_node_set eclosure; - incomplete = false; - err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* This indicates that we are calculating this node now. - We reference this value to avoid infinite loop. */ - dfa->eclosures[node].nelem = REG_MISSING; - - constraint = ((dfa->nodes[node].type == ANCHOR) - ? dfa->nodes[node].opr.ctx_type : 0); - /* If the current node has constraints, duplicate all nodes. - Since they must inherit the constraints. */ - if (constraint - && dfa->edests[node].nelem - && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) - { - err = duplicate_node_closure (dfa, node, node, node, constraint); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - /* Expand each epsilon destination nodes. */ - if (IS_EPSILON_NODE(dfa->nodes[node].type)) - for (i = 0; i < dfa->edests[node].nelem; ++i) - { - re_node_set eclosure_elem; - Idx edest = dfa->edests[node].elems[i]; - /* If calculating the epsilon closure of `edest' is in progress, - return intermediate result. */ - if (dfa->eclosures[edest].nelem == REG_MISSING) - { - incomplete = true; - continue; - } - /* If we haven't calculated the epsilon closure of `edest' yet, - calculate now. Otherwise use calculated epsilon closure. */ - if (dfa->eclosures[edest].nelem == 0) - { - err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - eclosure_elem = dfa->eclosures[edest]; - /* Merge the epsilon closure of `edest'. */ - re_node_set_merge (&eclosure, &eclosure_elem); - /* If the epsilon closure of `edest' is incomplete, - the epsilon closure of this node is also incomplete. */ - if (dfa->eclosures[edest].nelem == 0) - { - incomplete = true; - re_node_set_free (&eclosure_elem); - } - } - - /* Epsilon closures include itself. */ - ok = re_node_set_insert (&eclosure, node); - if (BE (! ok, 0)) - return REG_ESPACE; - if (incomplete && !root) - dfa->eclosures[node].nelem = 0; - else - dfa->eclosures[node] = eclosure; - *new_set = eclosure; - return REG_NOERROR; -} - -/* Functions for token which are used in the parser. */ - -/* Fetch a token from INPUT. - We must not use this function inside bracket expressions. */ - -static void -internal_function -fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) -{ - re_string_skip_bytes (input, peek_token (result, input, syntax)); -} - -/* Peek a token from INPUT, and return the length of the token. - We must not use this function inside bracket expressions. */ - -static int -internal_function -peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) -{ - unsigned char c; - - if (re_string_eoi (input)) - { - token->type = END_OF_RE; - return 0; - } - - c = re_string_peek_byte (input, 0); - token->opr.c = c; - - token->word_char = 0; -#ifdef RE_ENABLE_I18N - token->mb_partial = 0; - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) - { - token->type = CHARACTER; - token->mb_partial = 1; - return 1; - } -#endif - if (c == '\\') - { - unsigned char c2; - if (re_string_cur_idx (input) + 1 >= re_string_length (input)) - { - token->type = BACK_SLASH; - return 1; - } - - c2 = re_string_peek_byte_case (input, 1); - token->opr.c = c2; - token->type = CHARACTER; -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc = re_string_wchar_at (input, - re_string_cur_idx (input) + 1); - token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; - } - else -#endif - token->word_char = IS_WORD_CHAR (c2) != 0; - - switch (c2) - { - case '|': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR)) - token->type = OP_ALT; - break; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - if (!(syntax & RE_NO_BK_REFS)) - { - token->type = OP_BACK_REF; - token->opr.idx = c2 - '1'; - } - break; - case '<': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_FIRST; - } - break; - case '>': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_LAST; - } - break; - case 'b': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_DELIM; - } - break; - case 'B': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = NOT_WORD_DELIM; - } - break; - case 'w': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_WORD; - break; - case 'W': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_NOTWORD; - break; - case 's': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_SPACE; - break; - case 'S': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_NOTSPACE; - break; - case '`': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = BUF_FIRST; - } - break; - case '\'': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = BUF_LAST; - } - break; - case '(': - if (!(syntax & RE_NO_BK_PARENS)) - token->type = OP_OPEN_SUBEXP; - break; - case ')': - if (!(syntax & RE_NO_BK_PARENS)) - token->type = OP_CLOSE_SUBEXP; - break; - case '+': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_PLUS; - break; - case '?': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_QUESTION; - break; - case '{': - if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) - token->type = OP_OPEN_DUP_NUM; - break; - case '}': - if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) - token->type = OP_CLOSE_DUP_NUM; - break; - default: - break; - } - return 2; - } - - token->type = CHARACTER; -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input)); - token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; - } - else -#endif - token->word_char = IS_WORD_CHAR (token->opr.c); - - switch (c) - { - case '\n': - if (syntax & RE_NEWLINE_ALT) - token->type = OP_ALT; - break; - case '|': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR)) - token->type = OP_ALT; - break; - case '*': - token->type = OP_DUP_ASTERISK; - break; - case '+': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_PLUS; - break; - case '?': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_QUESTION; - break; - case '{': - if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - token->type = OP_OPEN_DUP_NUM; - break; - case '}': - if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - token->type = OP_CLOSE_DUP_NUM; - break; - case '(': - if (syntax & RE_NO_BK_PARENS) - token->type = OP_OPEN_SUBEXP; - break; - case ')': - if (syntax & RE_NO_BK_PARENS) - token->type = OP_CLOSE_SUBEXP; - break; - case '[': - token->type = OP_OPEN_BRACKET; - break; - case '.': - token->type = OP_PERIOD; - break; - case '^': - if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) && - re_string_cur_idx (input) != 0) - { - char prev = re_string_peek_byte (input, -1); - if (!(syntax & RE_NEWLINE_ALT) || prev != '\n') - break; - } - token->type = ANCHOR; - token->opr.ctx_type = LINE_FIRST; - break; - case '$': - if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) && - re_string_cur_idx (input) + 1 != re_string_length (input)) - { - re_token_t next; - re_string_skip_bytes (input, 1); - peek_token (&next, input, syntax); - re_string_skip_bytes (input, -1); - if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP) - break; - } - token->type = ANCHOR; - token->opr.ctx_type = LINE_LAST; - break; - default: - break; - } - return 1; -} - -/* Peek a token from INPUT, and return the length of the token. - We must not use this function out of bracket expressions. */ - -static int -internal_function -peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) -{ - unsigned char c; - if (re_string_eoi (input)) - { - token->type = END_OF_RE; - return 0; - } - c = re_string_peek_byte (input, 0); - token->opr.c = c; - -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) - { - token->type = CHARACTER; - return 1; - } -#endif /* RE_ENABLE_I18N */ - - if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) - && re_string_cur_idx (input) + 1 < re_string_length (input)) - { - /* In this case, '\' escape a character. */ - unsigned char c2; - re_string_skip_bytes (input, 1); - c2 = re_string_peek_byte (input, 0); - token->opr.c = c2; - token->type = CHARACTER; - return 1; - } - if (c == '[') /* '[' is a special char in a bracket exps. */ - { - unsigned char c2; - int token_len; - if (re_string_cur_idx (input) + 1 < re_string_length (input)) - c2 = re_string_peek_byte (input, 1); - else - c2 = 0; - token->opr.c = c2; - token_len = 2; - switch (c2) - { - case '.': - token->type = OP_OPEN_COLL_ELEM; - break; - case '=': - token->type = OP_OPEN_EQUIV_CLASS; - break; - case ':': - if (syntax & RE_CHAR_CLASSES) - { - token->type = OP_OPEN_CHAR_CLASS; - break; - } - /* else fall through. */ - default: - token->type = CHARACTER; - token->opr.c = c; - token_len = 1; - break; - } - return token_len; - } - switch (c) - { - case '-': - token->type = OP_CHARSET_RANGE; - break; - case ']': - token->type = OP_CLOSE_BRACKET; - break; - case '^': - token->type = OP_NON_MATCH_LIST; - break; - default: - token->type = CHARACTER; - } - return 1; -} - -/* Functions for parser. */ - -/* Entry point of the parser. - Parse the regular expression REGEXP and return the structure tree. - If an error is occured, ERR is set by error code, and return NULL. - This function build the following tree, from regular expression : - CAT - / \ - / \ - EOR - - CAT means concatenation. - EOR means end of regular expression. */ - -static bin_tree_t * -parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, - reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree, *eor, *root; - re_token_t current_token; - dfa->syntax = syntax; - fetch_token (¤t_token, regexp, syntax | RE_CARET_ANCHORS_HERE); - tree = parse_reg_exp (regexp, preg, ¤t_token, syntax, 0, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - eor = create_tree (dfa, NULL, NULL, END_OF_RE); - if (tree != NULL) - root = create_tree (dfa, tree, eor, CONCAT); - else - root = eor; - if (BE (eor == NULL || root == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - return root; -} - -/* This function build the following tree, from regular expression - |: - ALT - / \ - / \ - - - ALT means alternative, which represents the operator `|'. */ - -static bin_tree_t * -parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree, *branch = NULL; - tree = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - - while (token->type == OP_ALT) - { - fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); - if (token->type != OP_ALT && token->type != END_OF_RE - && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) - { - branch = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && branch == NULL, 0)) - return NULL; - } - else - branch = NULL; - tree = create_tree (dfa, tree, branch, OP_ALT); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - return tree; -} - -/* This function build the following tree, from regular expression - : - CAT - / \ - / \ - - - CAT means concatenation. */ - -static bin_tree_t * -parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - bin_tree_t *tree, *expr; - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - tree = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - - while (token->type != OP_ALT && token->type != END_OF_RE - && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) - { - expr = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && expr == NULL, 0)) - { - return NULL; - } - if (tree != NULL && expr != NULL) - { - tree = create_tree (dfa, tree, expr, CONCAT); - if (tree == NULL) - { - *err = REG_ESPACE; - return NULL; - } - } - else if (tree == NULL) - tree = expr; - /* Otherwise expr == NULL, we don't need to create new tree. */ - } - return tree; -} - -/* This function build the following tree, from regular expression a*: - * - | - a -*/ - -static bin_tree_t * -parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree; - switch (token->type) - { - case CHARACTER: - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - while (!re_string_eoi (regexp) - && !re_string_first_byte (regexp, re_string_cur_idx (regexp))) - { - bin_tree_t *mbc_remain; - fetch_token (token, regexp, syntax); - mbc_remain = create_token_tree (dfa, NULL, NULL, token); - tree = create_tree (dfa, tree, mbc_remain, CONCAT); - if (BE (mbc_remain == NULL || tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - } -#endif - break; - case OP_OPEN_SUBEXP: - tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_OPEN_BRACKET: - tree = parse_bracket_exp (regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_BACK_REF: - if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1)) - { - *err = REG_ESUBREG; - return NULL; - } - dfa->used_bkref_map |= 1 << token->opr.idx; - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - ++dfa->nbackref; - dfa->has_mb_node = 1; - break; - case OP_OPEN_DUP_NUM: - if (syntax & RE_CONTEXT_INVALID_DUP) - { - *err = REG_BADRPT; - return NULL; - } - /* FALLTHROUGH */ - case OP_DUP_ASTERISK: - case OP_DUP_PLUS: - case OP_DUP_QUESTION: - if (syntax & RE_CONTEXT_INVALID_OPS) - { - *err = REG_BADRPT; - return NULL; - } - else if (syntax & RE_CONTEXT_INDEP_OPS) - { - fetch_token (token, regexp, syntax); - return parse_expression (regexp, preg, token, syntax, nest, err); - } - /* else fall through */ - case OP_CLOSE_SUBEXP: - if ((token->type == OP_CLOSE_SUBEXP) && - !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) - { - *err = REG_ERPAREN; - return NULL; - } - /* else fall through */ - case OP_CLOSE_DUP_NUM: - /* We treat it as a normal character. */ - - /* Then we can these characters as normal characters. */ - token->type = CHARACTER; - /* mb_partial and word_char bits should be initialized already - by peek_token. */ - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - break; - case ANCHOR: - if ((token->opr.ctx_type - & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST)) - && dfa->word_ops_used == 0) - init_word_char (dfa); - if (token->opr.ctx_type == WORD_DELIM - || token->opr.ctx_type == NOT_WORD_DELIM) - { - bin_tree_t *tree_first, *tree_last; - if (token->opr.ctx_type == WORD_DELIM) - { - token->opr.ctx_type = WORD_FIRST; - tree_first = create_token_tree (dfa, NULL, NULL, token); - token->opr.ctx_type = WORD_LAST; - } - else - { - token->opr.ctx_type = INSIDE_WORD; - tree_first = create_token_tree (dfa, NULL, NULL, token); - token->opr.ctx_type = INSIDE_NOTWORD; - } - tree_last = create_token_tree (dfa, NULL, NULL, token); - tree = create_tree (dfa, tree_first, tree_last, OP_ALT); - if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - else - { - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - /* We must return here, since ANCHORs can't be followed - by repetition operators. - eg. RE"^*" is invalid or "", - it must not be "". */ - fetch_token (token, regexp, syntax); - return tree; - case OP_PERIOD: - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - if (dfa->mb_cur_max > 1) - dfa->has_mb_node = 1; - break; - case OP_WORD: - case OP_NOTWORD: - tree = build_charclass_op (dfa, regexp->trans, - (const unsigned char *) "alnum", - (const unsigned char *) "_", - token->type == OP_NOTWORD, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_SPACE: - case OP_NOTSPACE: - tree = build_charclass_op (dfa, regexp->trans, - (const unsigned char *) "space", - (const unsigned char *) "", - token->type == OP_NOTSPACE, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_ALT: - case END_OF_RE: - return NULL; - case BACK_SLASH: - *err = REG_EESCAPE; - return NULL; - default: - /* Must not happen? */ -#ifdef DEBUG - assert (0); -#endif - return NULL; - } - fetch_token (token, regexp, syntax); - - while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS - || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) - { - tree = parse_dup_op (tree, regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - /* In BRE consecutive duplications are not allowed. */ - if ((syntax & RE_CONTEXT_INVALID_DUP) - && (token->type == OP_DUP_ASTERISK - || token->type == OP_OPEN_DUP_NUM)) - { - *err = REG_BADRPT; - return NULL; - } - } - - return tree; -} - -/* This function build the following tree, from regular expression - (): - SUBEXP - | - -*/ - -static bin_tree_t * -parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree; - size_t cur_nsub; - cur_nsub = preg->re_nsub++; - - fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); - - /* The subexpression may be a null string. */ - if (token->type == OP_CLOSE_SUBEXP) - tree = NULL; - else - { - tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); - if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) - *err = REG_EPAREN; - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } - - if (cur_nsub <= '9' - '1') - dfa->completed_bkref_map |= 1 << cur_nsub; - - tree = create_tree (dfa, tree, NULL, SUBEXP); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - tree->token.opr.idx = cur_nsub; - return tree; -} - -/* This function parse repetition operators like "*", "+", "{1,3}" etc. */ - -static bin_tree_t * -parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, - re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err) -{ - bin_tree_t *tree = NULL, *old_tree = NULL; - Idx i, start, end, start_idx = re_string_cur_idx (regexp); - re_token_t start_token = *token; - - if (token->type == OP_OPEN_DUP_NUM) - { - end = 0; - start = fetch_number (regexp, token, syntax); - if (start == REG_MISSING) - { - if (token->type == CHARACTER && token->opr.c == ',') - start = 0; /* We treat "{,m}" as "{0,m}". */ - else - { - *err = REG_BADBR; /* {} is invalid. */ - return NULL; - } - } - if (BE (start != REG_ERROR, 1)) - { - /* We treat "{n}" as "{n,n}". */ - end = ((token->type == OP_CLOSE_DUP_NUM) ? start - : ((token->type == CHARACTER && token->opr.c == ',') - ? fetch_number (regexp, token, syntax) : REG_ERROR)); - } - if (BE (start == REG_ERROR || end == REG_ERROR, 0)) - { - /* Invalid sequence. */ - if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0)) - { - if (token->type == END_OF_RE) - *err = REG_EBRACE; - else - *err = REG_BADBR; - - return NULL; - } - - /* If the syntax bit is set, rollback. */ - re_string_set_index (regexp, start_idx); - *token = start_token; - token->type = CHARACTER; - /* mb_partial and word_char bits should be already initialized by - peek_token. */ - return elem; - } - - if (BE (end != REG_MISSING && start > end, 0)) - { - /* First number greater than second. */ - *err = REG_BADBR; - return NULL; - } - } - else - { - start = (token->type == OP_DUP_PLUS) ? 1 : 0; - end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING; - } - - fetch_token (token, regexp, syntax); - - if (BE (elem == NULL, 0)) - return NULL; - if (BE (start == 0 && end == 0, 0)) - { - postorder (elem, free_tree, NULL); - return NULL; - } - - /* Extract "{n,m}" to "...{0,}". */ - if (BE (start > 0, 0)) - { - tree = elem; - for (i = 2; i <= start; ++i) - { - elem = duplicate_tree (elem, dfa); - tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) - goto parse_dup_op_espace; - } - - if (start == end) - return tree; - - /* Duplicate ELEM before it is marked optional. */ - elem = duplicate_tree (elem, dfa); - old_tree = tree; - } - else - old_tree = NULL; - - if (elem->token.type == SUBEXP) - postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx); - - tree = create_tree (dfa, elem, NULL, - (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT)); - if (BE (tree == NULL, 0)) - goto parse_dup_op_espace; - - /* This loop is actually executed only when end != REG_MISSING, - to rewrite {0,n} as ((...?)?)?... We have - already created the start+1-th copy. */ - if ((Idx) -1 < 0 || end != REG_MISSING) - for (i = start + 2; i <= end; ++i) - { - elem = duplicate_tree (elem, dfa); - tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) - goto parse_dup_op_espace; - - tree = create_tree (dfa, tree, NULL, OP_ALT); - if (BE (tree == NULL, 0)) - goto parse_dup_op_espace; - } - - if (old_tree) - tree = create_tree (dfa, old_tree, tree, CONCAT); - - return tree; - - parse_dup_op_espace: - *err = REG_ESPACE; - return NULL; -} - -/* Size of the names for collating symbol/equivalence_class/character_class. - I'm not sure, but maybe enough. */ -#define BRACKET_NAME_BUF_SIZE 32 - -#ifndef _LIBC - /* Local function for parse_bracket_exp only used in case of NOT _LIBC. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument sinse we may - update it. */ - -static reg_errcode_t -internal_function -# ifdef RE_ENABLE_I18N -build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc, - bracket_elem_t *start_elem, bracket_elem_t *end_elem) -# else /* not RE_ENABLE_I18N */ -build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, - bracket_elem_t *end_elem) -# endif /* not RE_ENABLE_I18N */ -{ - unsigned int start_ch, end_ch; - /* Equivalence Classes and Character Classes can't be a range start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) - return REG_ERANGE; - - /* We can handle no multi character collating elements without libc - support. */ - if (BE ((start_elem->type == COLL_SYM - && strlen ((char *) start_elem->opr.name) > 1) - || (end_elem->type == COLL_SYM - && strlen ((char *) end_elem->opr.name) > 1), 0)) - return REG_ECOLLATE; - -# ifdef RE_ENABLE_I18N - { - wchar_t wc; - wint_t start_wc; - wint_t end_wc; - wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; - - start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch - : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); - end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch - : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] - : 0)); - start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) - ? __btowc (start_ch) : start_elem->opr.wch); - end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) - ? __btowc (end_ch) : end_elem->opr.wch); - if (start_wc == WEOF || end_wc == WEOF) - return REG_ECOLLATE; - cmp_buf[0] = start_wc; - cmp_buf[4] = end_wc; - if (wcscoll (cmp_buf, cmp_buf + 4) > 0) - return REG_ERANGE; - - /* Got valid collation sequence values, add them as a new entry. - However, for !_LIBC we have no collation elements: if the - character set is single byte, the single byte character set - that we build below suffices. parse_bracket_exp passes - no MBCSET if dfa->mb_cur_max == 1. */ - if (mbcset) - { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - wchar_t *new_array_start, *new_array_end; - Idx new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - /* Use realloc since mbcset->range_starts and mbcset->range_ends - are NULL if *range_alloc == 0. */ - new_array_start = re_realloc (mbcset->range_starts, wchar_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, wchar_t, - new_nranges); - - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; - - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } - - mbcset->range_starts[mbcset->nranges] = start_wc; - mbcset->range_ends[mbcset->nranges++] = end_wc; - } - - /* Build the table for single byte characters. */ - for (wc = 0; wc < SBC_MAX; ++wc) - { - cmp_buf[2] = wc; - if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 - && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) - bitset_set (sbcset, wc); - } - } -# else /* not RE_ENABLE_I18N */ - { - unsigned int ch; - start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch - : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); - end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch - : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] - : 0)); - if (start_ch > end_ch) - return REG_ERANGE; - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ++ch) - if (start_ch <= ch && ch <= end_ch) - bitset_set (sbcset, ch); - } -# endif /* not RE_ENABLE_I18N */ - return REG_NOERROR; -} -#endif /* not _LIBC */ - -#ifndef _LIBC -/* Helper function for parse_bracket_exp only used in case of NOT _LIBC.. - Build the collating element which is represented by NAME. - The result are written to MBCSET and SBCSET. - COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a - pointer argument since we may update it. */ - -static reg_errcode_t -internal_function -build_collating_symbol (bitset_t sbcset, -# ifdef RE_ENABLE_I18N - re_charset_t *mbcset, Idx *coll_sym_alloc, -# endif - const unsigned char *name) -{ - size_t name_len = strlen ((const char *) name); - if (BE (name_len != 1, 0)) - return REG_ECOLLATE; - else - { - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } -} -#endif /* not _LIBC */ - -/* This function parse bracket expression like "[abc]", "[a-c]", - "[[.a-a.]]" etc. */ - -static bin_tree_t * -parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, - reg_syntax_t syntax, reg_errcode_t *err) -{ -#ifdef _LIBC - const unsigned char *collseqmb; - const char *collseqwc; - uint32_t nrules; - int32_t table_size; - const int32_t *symb_table; - const unsigned char *extra; - - /* Local function for parse_bracket_exp used in _LIBC environement. - Seek the collating symbol entry correspondings to NAME. - Return the index of the symbol in the SYMB_TABLE. */ - - auto inline int32_t - __attribute ((always_inline)) - seek_collating_symbol_entry (name, name_len) - const unsigned char *name; - size_t name_len; - { - int32_t hash = elem_hash ((const char *) name, name_len); - int32_t elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - int32_t second = hash % (table_size - 2) + 1; - - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - /* Compare the length of the name. */ - && name_len == extra[symb_table[2 * elem + 1]] - /* Compare the name. */ - && memcmp (name, &extra[symb_table[2 * elem + 1] + 1], - name_len) == 0) - { - /* Yep, this is the entry. */ - break; - } - - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } - return elem; - } - - /* Local function for parse_bracket_exp used in _LIBC environement. - Look up the collation sequence value of BR_ELEM. - Return the value if succeeded, UINT_MAX otherwise. */ - - auto inline unsigned int - __attribute ((always_inline)) - lookup_collation_sequence_value (br_elem) - bracket_elem_t *br_elem; - { - if (br_elem->type == SB_CHAR) - { - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - return collseqmb[br_elem->opr.ch]; - else - { - wint_t wc = __btowc (br_elem->opr.ch); - return __collseq_table_lookup (collseqwc, wc); - } - } - else if (br_elem->type == MB_CHAR) - { - return __collseq_table_lookup (collseqwc, br_elem->opr.wch); - } - else if (br_elem->type == COLL_SYM) - { - size_t sym_name_len = strlen ((char *) br_elem->opr.name); - if (nrules != 0) - { - int32_t elem, idx; - elem = seek_collating_symbol_entry (br_elem->opr.name, - sym_name_len); - if (symb_table[2 * elem] != 0) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - /* Skip the byte sequence of the collating element. */ - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - /* Skip the multibyte collation sequence value. */ - idx += sizeof (unsigned int); - /* Skip the wide char sequence of the collating element. */ - idx += sizeof (unsigned int) * - (1 + *(unsigned int *) (extra + idx)); - /* Return the collation sequence value. */ - return *(unsigned int *) (extra + idx); - } - else if (symb_table[2 * elem] == 0 && sym_name_len == 1) - { - /* No valid character. Match it as a single byte - character. */ - return collseqmb[br_elem->opr.name[0]]; - } - } - else if (sym_name_len == 1) - return collseqmb[br_elem->opr.name[0]]; - } - return UINT_MAX; - } - - /* Local function for parse_bracket_exp used in _LIBC environement. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument sinse we may - update it. */ - - auto inline reg_errcode_t - __attribute ((always_inline)) - build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem) - re_charset_t *mbcset; - Idx *range_alloc; - bitset_t sbcset; - bracket_elem_t *start_elem, *end_elem; - { - unsigned int ch; - uint32_t start_collseq; - uint32_t end_collseq; - - /* Equivalence Classes and Character Classes can't be a range - start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) - return REG_ERANGE; - - start_collseq = lookup_collation_sequence_value (start_elem); - end_collseq = lookup_collation_sequence_value (end_elem); - /* Check start/end collation sequence values. */ - if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0)) - return REG_ECOLLATE; - if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0)) - return REG_ERANGE; - - /* Got valid collation sequence values, add them as a new entry. - However, if we have no collation elements, and the character set - is single byte, the single byte character set that we - build below suffices. */ - if (nrules > 0 || dfa->mb_cur_max > 1) - { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - uint32_t *new_array_start; - uint32_t *new_array_end; - Idx new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - new_array_start = re_realloc (mbcset->range_starts, uint32_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, uint32_t, - new_nranges); - - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; - - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } - - mbcset->range_starts[mbcset->nranges] = start_collseq; - mbcset->range_ends[mbcset->nranges++] = end_collseq; - } - - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ch++) - { - uint32_t ch_collseq; - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - ch_collseq = collseqmb[ch]; - else - ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); - if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) - bitset_set (sbcset, ch); - } - return REG_NOERROR; - } - - /* Local function for parse_bracket_exp used in _LIBC environement. - Build the collating element which is represented by NAME. - The result are written to MBCSET and SBCSET. - COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a - pointer argument sinse we may update it. */ - - auto inline reg_errcode_t - __attribute ((always_inline)) - build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name) - re_charset_t *mbcset; - Idx *coll_sym_alloc; - bitset_t sbcset; - const unsigned char *name; - { - int32_t elem, idx; - size_t name_len = strlen ((const char *) name); - if (nrules != 0) - { - elem = seek_collating_symbol_entry (name, name_len); - if (symb_table[2 * elem] != 0) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - } - else if (symb_table[2 * elem] == 0 && name_len == 1) - { - /* No valid character, treat it as a normal - character. */ - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } - else - return REG_ECOLLATE; - - /* Got valid collation sequence, add it as a new entry. */ - /* Check the space of the arrays. */ - if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->ncoll_syms is 0. */ - Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; - /* Use realloc since mbcset->coll_syms is NULL - if *alloc == 0. */ - int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, - new_coll_sym_alloc); - if (BE (new_coll_syms == NULL, 0)) - return REG_ESPACE; - mbcset->coll_syms = new_coll_syms; - *coll_sym_alloc = new_coll_sym_alloc; - } - mbcset->coll_syms[mbcset->ncoll_syms++] = idx; - return REG_NOERROR; - } - else - { - if (BE (name_len != 1, 0)) - return REG_ECOLLATE; - else - { - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } - } - } -#endif - - re_token_t br_token; - re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; - Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; - Idx equiv_class_alloc = 0, char_class_alloc = 0; -#endif /* not RE_ENABLE_I18N */ - bool non_match = false; - bin_tree_t *work_tree; - int token_len; - bool first_round = true; -#ifdef _LIBC - collseqmb = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); - nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules) - { - /* - if (MB_CUR_MAX > 1) - */ - collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); - table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); - } -#endif - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else - if (BE (sbcset == NULL, 0)) -#endif /* RE_ENABLE_I18N */ - { - *err = REG_ESPACE; - return NULL; - } - - token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_BADPAT; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_NON_MATCH_LIST) - { -#ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ - non_match = true; - if (syntax & RE_HAT_LISTS_NOT_NEWLINE) - bitset_set (sbcset, '\n'); - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_BADPAT; - goto parse_bracket_exp_free_return; - } - } - - /* We treat the first ']' as a normal character. */ - if (token->type == OP_CLOSE_BRACKET) - token->type = CHARACTER; - - while (1) - { - bracket_elem_t start_elem, end_elem; - unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE]; - unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE]; - reg_errcode_t ret; - int token_len2 = 0; - bool is_range_exp = false; - re_token_t token2; - - start_elem.opr.name = start_name_buf; - ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa, - syntax, first_round); - if (BE (ret != REG_NOERROR, 0)) - { - *err = ret; - goto parse_bracket_exp_free_return; - } - first_round = false; - - /* Get information about the next token. We need it in any case. */ - token_len = peek_token_bracket (token, regexp, syntax); - - /* Do not check for ranges if we know they are not allowed. */ - if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) - { - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_CHARSET_RANGE) - { - re_string_skip_bytes (regexp, token_len); /* Skip '-'. */ - token_len2 = peek_token_bracket (&token2, regexp, syntax); - if (BE (token2.type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token2.type == OP_CLOSE_BRACKET) - { - /* We treat the last '-' as a normal character. */ - re_string_skip_bytes (regexp, -token_len); - token->type = CHARACTER; - } - else - is_range_exp = true; - } - } - - if (is_range_exp == true) - { - end_elem.opr.name = end_name_buf; - ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2, - dfa, syntax, true); - if (BE (ret != REG_NOERROR, 0)) - { - *err = ret; - goto parse_bracket_exp_free_return; - } - - token_len = peek_token_bracket (token, regexp, syntax); - -#ifdef _LIBC - *err = build_range_exp (sbcset, mbcset, &range_alloc, - &start_elem, &end_elem); -#else -# ifdef RE_ENABLE_I18N - *err = build_range_exp (sbcset, - dfa->mb_cur_max > 1 ? mbcset : NULL, - &range_alloc, &start_elem, &end_elem); -# else - *err = build_range_exp (sbcset, &start_elem, &end_elem); -# endif -#endif /* RE_ENABLE_I18N */ - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - } - else - { - switch (start_elem.type) - { - case SB_CHAR: - bitset_set (sbcset, start_elem.opr.ch); - break; -#ifdef RE_ENABLE_I18N - case MB_CHAR: - /* Check whether the array has enough space. */ - if (BE (mbchar_alloc == mbcset->nmbchars, 0)) - { - wchar_t *new_mbchars; - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nmbchars is 0. */ - mbchar_alloc = 2 * mbcset->nmbchars + 1; - /* Use realloc since array is NULL if *alloc == 0. */ - new_mbchars = re_realloc (mbcset->mbchars, wchar_t, - mbchar_alloc); - if (BE (new_mbchars == NULL, 0)) - goto parse_bracket_exp_espace; - mbcset->mbchars = new_mbchars; - } - mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; - break; -#endif /* RE_ENABLE_I18N */ - case EQUIV_CLASS: - *err = build_equiv_class (sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &equiv_class_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - case COLL_SYM: - *err = build_collating_symbol (sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &coll_sym_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - case CHAR_CLASS: - *err = build_charclass (regexp->trans, sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &char_class_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name, syntax); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - default: - assert (0); - break; - } - } - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_CLOSE_BRACKET) - break; - } - - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - - /* If it is non-matching list. */ - if (non_match) - bitset_not (sbcset); - -#ifdef RE_ENABLE_I18N - /* Ensure only single byte characters are set. */ - if (dfa->mb_cur_max > 1) - bitset_mask (sbcset, dfa->sb_char); - - if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes - || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes - || mbcset->non_match))) - { - bin_tree_t *mbc_tree; - int sbc_idx; - /* Build a tree for complex bracket. */ - dfa->has_mb_node = 1; - br_token.type = COMPLEX_BRACKET; - br_token.opr.mbcset = mbcset; - mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) - goto parse_bracket_exp_espace; - for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx) - if (sbcset[sbc_idx]) - break; - /* If there are no bits set in sbcset, there is no point - of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */ - if (sbc_idx < BITSET_WORDS) - { - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - - /* Then join them by ALT node. */ - work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - } - else - { - re_free (sbcset); - work_tree = mbc_tree; - } - } - else -#endif /* not RE_ENABLE_I18N */ - { -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - } - return work_tree; - - parse_bracket_exp_espace: - *err = REG_ESPACE; - parse_bracket_exp_free_return: - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - return NULL; -} - -/* Parse an element in the bracket expression. */ - -static reg_errcode_t -parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp, - re_token_t *token, int token_len, re_dfa_t *dfa, - reg_syntax_t syntax, bool accept_hyphen) -{ -#ifdef RE_ENABLE_I18N - int cur_char_size; - cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); - if (cur_char_size > 1) - { - elem->type = MB_CHAR; - elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp)); - re_string_skip_bytes (regexp, cur_char_size); - return REG_NOERROR; - } -#endif /* RE_ENABLE_I18N */ - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS - || token->type == OP_OPEN_EQUIV_CLASS) - return parse_bracket_symbol (elem, regexp, token); - if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen) - { - /* A '-' must only appear as anything but a range indicator before - the closing bracket. Everything else is an error. */ - re_token_t token2; - (void) peek_token_bracket (&token2, regexp, syntax); - if (token2.type != OP_CLOSE_BRACKET) - /* The actual error value is not standardized since this whole - case is undefined. But ERANGE makes good sense. */ - return REG_ERANGE; - } - elem->type = SB_CHAR; - elem->opr.ch = token->opr.c; - return REG_NOERROR; -} - -/* Parse a bracket symbol in the bracket expression. Bracket symbols are - such as [::], [..], and - [==]. */ - -static reg_errcode_t -parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, - re_token_t *token) -{ - unsigned char ch, delim = token->opr.c; - int i = 0; - if (re_string_eoi(regexp)) - return REG_EBRACK; - for (;; ++i) - { - if (i >= BRACKET_NAME_BUF_SIZE) - return REG_EBRACK; - if (token->type == OP_OPEN_CHAR_CLASS) - ch = re_string_fetch_byte_case (regexp); - else - ch = re_string_fetch_byte (regexp); - if (re_string_eoi(regexp)) - return REG_EBRACK; - if (ch == delim && re_string_peek_byte (regexp, 0) == ']') - break; - elem->opr.name[i] = ch; - } - re_string_skip_bytes (regexp, 1); - elem->opr.name[i] = '\0'; - switch (token->type) - { - case OP_OPEN_COLL_ELEM: - elem->type = COLL_SYM; - break; - case OP_OPEN_EQUIV_CLASS: - elem->type = EQUIV_CLASS; - break; - case OP_OPEN_CHAR_CLASS: - elem->type = CHAR_CLASS; - break; - default: - break; - } - return REG_NOERROR; -} - - /* Helper function for parse_bracket_exp. - Build the equivalence class which is represented by NAME. - The result are written to MBCSET and SBCSET. - EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes, - is a pointer argument sinse we may update it. */ - -static reg_errcode_t -#ifdef RE_ENABLE_I18N -build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, - Idx *equiv_class_alloc, const unsigned char *name) -#else /* not RE_ENABLE_I18N */ -build_equiv_class (bitset_t sbcset, const unsigned char *name) -#endif /* not RE_ENABLE_I18N */ -{ -#ifdef _LIBC - uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules != 0) - { - const int32_t *table, *indirect; - const unsigned char *weights, *extra, *cp; - unsigned char char_buf[2]; - int32_t idx1, idx2; - unsigned int ch; - size_t len; - /* This #include defines a local function! */ -# include - /* Calculate the index for equivalence class. */ - cp = name; - table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_INDIRECTMB); - idx1 = findidx (&cp); - if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0)) - /* This isn't a valid character. */ - return REG_ECOLLATE; - - /* Build single byte matcing table for this equivalence class. */ - char_buf[1] = (unsigned char) '\0'; - len = weights[idx1]; - for (ch = 0; ch < SBC_MAX; ++ch) - { - char_buf[0] = ch; - cp = char_buf; - idx2 = findidx (&cp); -/* - idx2 = table[ch]; -*/ - if (idx2 == 0) - /* This isn't a valid character. */ - continue; - if (len == weights[idx2]) - { - int cnt = 0; - while (cnt <= len && - weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt]) - ++cnt; - - if (cnt > len) - bitset_set (sbcset, ch); - } - } - /* Check whether the array has enough space. */ - if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nequiv_classes is 0. */ - Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1; - /* Use realloc since the array is NULL if *alloc == 0. */ - int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes, - int32_t, - new_equiv_class_alloc); - if (BE (new_equiv_classes == NULL, 0)) - return REG_ESPACE; - mbcset->equiv_classes = new_equiv_classes; - *equiv_class_alloc = new_equiv_class_alloc; - } - mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1; - } - else -#endif /* _LIBC */ - { - if (BE (strlen ((const char *) name) != 1, 0)) - return REG_ECOLLATE; - bitset_set (sbcset, *name); - } - return REG_NOERROR; -} - - /* Helper function for parse_bracket_exp. - Build the character class which is represented by NAME. - The result are written to MBCSET and SBCSET. - CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes, - is a pointer argument sinse we may update it. */ - -static reg_errcode_t -#ifdef RE_ENABLE_I18N -build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, - re_charset_t *mbcset, Idx *char_class_alloc, - const unsigned char *class_name, reg_syntax_t syntax) -#else /* not RE_ENABLE_I18N */ -build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, - const unsigned char *class_name, reg_syntax_t syntax) -#endif /* not RE_ENABLE_I18N */ -{ - int i; - const char *name = (const char *) class_name; - - /* In case of REG_ICASE "upper" and "lower" match the both of - upper and lower cases. */ - if ((syntax & RE_ICASE) - && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0)) - name = "alpha"; - -#ifdef RE_ENABLE_I18N - /* Check the space of the arrays. */ - if (BE (*char_class_alloc == mbcset->nchar_classes, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nchar_classes is 0. */ - Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1; - /* Use realloc since array is NULL if *alloc == 0. */ - wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t, - new_char_class_alloc); - if (BE (new_char_classes == NULL, 0)) - return REG_ESPACE; - mbcset->char_classes = new_char_classes; - *char_class_alloc = new_char_class_alloc; - } - mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name); -#endif /* RE_ENABLE_I18N */ - -#define BUILD_CHARCLASS_LOOP(ctype_func) \ - do { \ - if (BE (trans != NULL, 0)) \ - { \ - for (i = 0; i < SBC_MAX; ++i) \ - if (ctype_func (i)) \ - bitset_set (sbcset, trans[i]); \ - } \ - else \ - { \ - for (i = 0; i < SBC_MAX; ++i) \ - if (ctype_func (i)) \ - bitset_set (sbcset, i); \ - } \ - } while (0) - - if (strcmp (name, "alnum") == 0) - BUILD_CHARCLASS_LOOP (isalnum); - else if (strcmp (name, "cntrl") == 0) - BUILD_CHARCLASS_LOOP (iscntrl); - else if (strcmp (name, "lower") == 0) - BUILD_CHARCLASS_LOOP (islower); - else if (strcmp (name, "space") == 0) - BUILD_CHARCLASS_LOOP (isspace); - else if (strcmp (name, "alpha") == 0) - BUILD_CHARCLASS_LOOP (isalpha); - else if (strcmp (name, "digit") == 0) - BUILD_CHARCLASS_LOOP (isdigit); - else if (strcmp (name, "print") == 0) - BUILD_CHARCLASS_LOOP (isprint); - else if (strcmp (name, "upper") == 0) - BUILD_CHARCLASS_LOOP (isupper); - else if (strcmp (name, "blank") == 0) - BUILD_CHARCLASS_LOOP (isblank); - else if (strcmp (name, "graph") == 0) - BUILD_CHARCLASS_LOOP (isgraph); - else if (strcmp (name, "punct") == 0) - BUILD_CHARCLASS_LOOP (ispunct); - else if (strcmp (name, "xdigit") == 0) - BUILD_CHARCLASS_LOOP (isxdigit); - else - return REG_ECTYPE; - - return REG_NOERROR; -} - -static bin_tree_t * -build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, - const unsigned char *class_name, - const unsigned char *extra, bool non_match, - reg_errcode_t *err) -{ - re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; - Idx alloc = 0; -#endif /* not RE_ENABLE_I18N */ - reg_errcode_t ret; - re_token_t br_token; - bin_tree_t *tree; - - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ - -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else /* not RE_ENABLE_I18N */ - if (BE (sbcset == NULL, 0)) -#endif /* not RE_ENABLE_I18N */ - { - *err = REG_ESPACE; - return NULL; - } - - if (non_match) - { -#ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ - } - - /* We don't care the syntax in this case. */ - ret = build_charclass (trans, sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &alloc, -#endif /* RE_ENABLE_I18N */ - class_name, 0); - - if (BE (ret != REG_NOERROR, 0)) - { - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - *err = ret; - return NULL; - } - /* \w match '_' also. */ - for (; *extra; extra++) - bitset_set (sbcset, *extra); - - /* If it is non-matching list. */ - if (non_match) - bitset_not (sbcset); - -#ifdef RE_ENABLE_I18N - /* Ensure only single byte characters are set. */ - if (dfa->mb_cur_max > 1) - bitset_mask (sbcset, dfa->sb_char); -#endif - - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (tree == NULL, 0)) - goto build_word_op_espace; - -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - bin_tree_t *mbc_tree; - /* Build a tree for complex bracket. */ - br_token.type = COMPLEX_BRACKET; - br_token.opr.mbcset = mbcset; - dfa->has_mb_node = 1; - mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) - goto build_word_op_espace; - /* Then join them by ALT node. */ - tree = create_tree (dfa, tree, mbc_tree, OP_ALT); - if (BE (mbc_tree != NULL, 1)) - return tree; - } - else - { - free_charset (mbcset); - return tree; - } -#else /* not RE_ENABLE_I18N */ - return tree; -#endif /* not RE_ENABLE_I18N */ - - build_word_op_espace: - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - *err = REG_ESPACE; - return NULL; -} - -/* This is intended for the expressions like "a{1,3}". - Fetch a number from `input', and return the number. - Return REG_MISSING if the number field is empty like "{,1}". - Return REG_ERROR if an error occurred. */ - -static Idx -fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) -{ - Idx num = REG_MISSING; - unsigned char c; - while (1) - { - fetch_token (token, input, syntax); - c = token->opr.c; - if (BE (token->type == END_OF_RE, 0)) - return REG_ERROR; - if (token->type == OP_CLOSE_DUP_NUM || c == ',') - break; - num = ((token->type != CHARACTER || c < '0' || '9' < c - || num == REG_ERROR) - ? REG_ERROR - : ((num == REG_MISSING) ? c - '0' : num * 10 + c - '0')); - num = (num > RE_DUP_MAX) ? REG_ERROR : num; - } - return num; -} - -#ifdef RE_ENABLE_I18N -static void -free_charset (re_charset_t *cset) -{ - re_free (cset->mbchars); -# ifdef _LIBC - re_free (cset->coll_syms); - re_free (cset->equiv_classes); - re_free (cset->range_starts); - re_free (cset->range_ends); -# endif - re_free (cset->char_classes); - re_free (cset); -} -#endif /* RE_ENABLE_I18N */ - -/* Functions for binary tree operation. */ - -/* Create a tree node. */ - -static bin_tree_t * -create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, - re_token_type_t type) -{ - re_token_t t; - t.type = type; - return create_token_tree (dfa, left, right, &t); -} - -static bin_tree_t * -create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, - const re_token_t *token) -{ - bin_tree_t *tree; - if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0)) - { - bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1); - - if (storage == NULL) - return NULL; - storage->next = dfa->str_tree_storage; - dfa->str_tree_storage = storage; - dfa->str_tree_storage_idx = 0; - } - tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++]; - - tree->parent = NULL; - tree->left = left; - tree->right = right; - tree->token = *token; - tree->token.duplicated = 0; - tree->token.opt_subexp = 0; - tree->first = NULL; - tree->next = NULL; - tree->node_idx = REG_MISSING; - - if (left != NULL) - left->parent = tree; - if (right != NULL) - right->parent = tree; - return tree; -} - -/* Mark the tree SRC as an optional subexpression. - To be called from preorder or postorder. */ - -static reg_errcode_t -mark_opt_subexp (void *extra, bin_tree_t *node) -{ - Idx idx = (Idx) (long) extra; - if (node->token.type == SUBEXP && node->token.opr.idx == idx) - node->token.opt_subexp = 1; - - return REG_NOERROR; -} - -/* Free the allocated memory inside NODE. */ - -static void -free_token (re_token_t *node) -{ -#ifdef RE_ENABLE_I18N - if (node->type == COMPLEX_BRACKET && node->duplicated == 0) - free_charset (node->opr.mbcset); - else -#endif /* RE_ENABLE_I18N */ - if (node->type == SIMPLE_BRACKET && node->duplicated == 0) - re_free (node->opr.sbcset); -} - -/* Worker function for tree walking. Free the allocated memory inside NODE - and its children. */ - -static reg_errcode_t -free_tree (void *extra, bin_tree_t *node) -{ - free_token (&node->token); - return REG_NOERROR; -} - - -/* Duplicate the node SRC, and return new node. This is a preorder - visit similar to the one implemented by the generic visitor, but - we need more infrastructure to maintain two parallel trees --- so, - it's easier to duplicate. */ - -static bin_tree_t * -duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa) -{ - const bin_tree_t *node; - bin_tree_t *dup_root; - bin_tree_t **p_new = &dup_root, *dup_node = root->parent; - - for (node = root; ; ) - { - /* Create a new tree and link it back to the current parent. */ - *p_new = create_token_tree (dfa, NULL, NULL, &node->token); - if (*p_new == NULL) - return NULL; - (*p_new)->parent = dup_node; - (*p_new)->token.duplicated = 1; - dup_node = *p_new; - - /* Go to the left node, or up and to the right. */ - if (node->left) - { - node = node->left; - p_new = &dup_node->left; - } - else - { - const bin_tree_t *prev = NULL; - while (node->right == prev || node->right == NULL) - { - prev = node; - node = node->parent; - dup_node = dup_node->parent; - if (!node) - return dup_root; - } - node = node->right; - p_new = &dup_node->right; - } - } -} diff --git a/src/bin/tar/lib/regex.c b/src/bin/tar/lib/regex.c deleted file mode 100644 index d4eb726b29..0000000000 --- a/src/bin/tar/lib/regex.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Make sure noone compiles this code with a C++ compiler. */ -#if defined __cplusplus && defined _LIBC -# error "This is C code, use a C compiler" -#endif - -#ifdef _LIBC -/* We have to keep the namespace clean. */ -# define regfree(preg) __regfree (preg) -# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) -# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) -# define regerror(errcode, preg, errbuf, errbuf_size) \ - __regerror(errcode, preg, errbuf, errbuf_size) -# define re_set_registers(bu, re, nu, st, en) \ - __re_set_registers (bu, re, nu, st, en) -# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ - __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) -# define re_match(bufp, string, size, pos, regs) \ - __re_match (bufp, string, size, pos, regs) -# define re_search(bufp, string, size, startpos, range, regs) \ - __re_search (bufp, string, size, startpos, range, regs) -# define re_compile_pattern(pattern, length, bufp) \ - __re_compile_pattern (pattern, length, bufp) -# define re_set_syntax(syntax) __re_set_syntax (syntax) -# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ - __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) -# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) - -# include "../locale/localeinfo.h" -#endif - -/* On some systems, limits.h sets RE_DUP_MAX to a lower value than - GNU regex allows. Include it before , which correctly - #undefs RE_DUP_MAX and sets it to the right value. */ -#include - -#include -#include "regex_internal.h" - -#include "regex_internal.c" -#include "regcomp.c" -#include "regexec.c" - -/* Binary backward compatibility. */ -#if _LIBC -# include -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) -link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.") -int re_max_failures = 2000; -# endif -#endif diff --git a/src/bin/tar/lib/regex.h b/src/bin/tar/lib/regex.h deleted file mode 100644 index 7a79ca3724..0000000000 --- a/src/bin/tar/lib/regex.h +++ /dev/null @@ -1,675 +0,0 @@ -/* Definitions for data structures and routines for the regular - expression library. - Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _REGEX_H -#define _REGEX_H 1 - -#include - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Define __USE_GNU_REGEX to declare GNU extensions that violate the - POSIX name space rules. */ -#undef __USE_GNU_REGEX -#if (defined _GNU_SOURCE \ - || (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE \ - && !defined _XOPEN_SOURCE)) -# define __USE_GNU_REGEX 1 -#endif - -#ifdef _REGEX_LARGE_OFFSETS - -/* Use types and values that are wide enough to represent signed and - unsigned byte offsets in memory. This currently works only when - the regex code is used outside of the GNU C library; it is not yet - supported within glibc itself, and glibc users should not define - _REGEX_LARGE_OFFSETS. */ - -/* The type of the offset of a byte within a string. - For historical reasons POSIX 1003.1-2004 requires that regoff_t be - at least as wide as off_t. However, many common POSIX platforms set - regoff_t to the more-sensible ssize_t and the Open Group has - signalled its intention to change the requirement to be that - regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN - 60 (2005-08-25). We don't know of any hosts where ssize_t or - ptrdiff_t is wider than ssize_t, so ssize_t is safe. */ -typedef ssize_t regoff_t; - -/* The type of nonnegative object indexes. Traditionally, GNU regex - uses 'int' for these. Code that uses __re_idx_t should work - regardless of whether the type is signed. */ -typedef size_t __re_idx_t; - -/* The type of object sizes. */ -typedef size_t __re_size_t; - -/* The type of object sizes, in places where the traditional code - uses unsigned long int. */ -typedef size_t __re_long_size_t; - -#else - -/* Use types that are binary-compatible with the traditional GNU regex - implementation, which mishandles strings longer than INT_MAX. */ - -typedef int regoff_t; -typedef int __re_idx_t; -typedef unsigned int __re_size_t; -typedef unsigned long int __re_long_size_t; - -#endif - -/* The following two types have to be signed and unsigned integer type - wide enough to hold a value of a pointer. For most ANSI compilers - ptrdiff_t and size_t should be likely OK. Still size of these two - types is 2 for Microsoft C. Ugh... */ -typedef long int s_reg_t; -typedef unsigned long int active_reg_t; - -/* 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 long int reg_syntax_t; - -#ifdef __USE_GNU_REGEX - -/* 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 ((unsigned long int) 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 \ matches . - If not set, then \ 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) - -/* If this bit is set, succeed as soon as we match the whole pattern, - without further backtracking. */ -# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) - -/* If this bit is set, do not process the GNU regex operators. - If not set, then the GNU regex operators are recognized. */ -# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) - -/* If this bit is set, turn on internal regex debugging. - If not set, and debugging was on, turn it off. - This only works if regex.c is compiled -DDEBUG. - We define this bit always, so that all that's needed to turn on - debugging is to recompile regex.c; the calling code can always have - this bit set, and it won't affect anything in the normal case. */ -# define RE_DEBUG (RE_NO_GNU_OPS << 1) - -/* If this bit is set, a syntactically invalid interval is treated as - a string of ordinary characters. For example, the ERE 'a{1' is - treated as 'a\{1'. */ -# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) - -/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only - for ^, because it is difficult to scan the regex backwards to find - whether ^ should be special. */ -# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1) - -/* If this bit is set, then \{ cannot be first in an bre or - immediately after an alternation or begin-group operator. */ -# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1) - -/* If this bit is set, then no_sub will be set to 1 during - re_compile_pattern. */ -# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1) - -#endif /* defined __USE_GNU_REGEX */ - -/* 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; - -#ifdef __USE_GNU_REGEX -/* 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_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ - | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) - -# define RE_SYNTAX_GNU_AWK \ - ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ - & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS \ - | RE_CONTEXT_INVALID_OPS )) - -# define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INTERVALS | RE_NO_GNU_OPS) - -# 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 \ - | RE_INVALID_INTERVAL_ORD) - -/* 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 | RE_CONTEXT_INVALID_DUP) - -/* 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_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is - removed 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]]] */ - -#endif /* defined __USE_GNU_REGEX */ - -#ifdef __USE_GNU_REGEX - -/* Maximum number of duplicates an interval can allow. POSIX-conforming - systems might define this in , but we want our - value, so remove any previous define. */ -# ifdef RE_DUP_MAX -# undef RE_DUP_MAX -# endif - -/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored - the counter as a 2-byte signed integer. This is no longer true, so - RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to - ((SIZE_MAX - 2) / 10 - 1) if _REGEX_LARGE_OFFSETS is defined. - However, there would be a huge performance problem if someone - actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains - its historical value. */ -# define RE_DUP_MAX (0x7fff) - -#endif /* defined __USE_GNU_REGEX */ - - -/* 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 (1 << 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 (1 << 2) - -/* 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 (1 << 3) - - -/* 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) - -/* Use PMATCH[0] to delimit the start and end of the search in the - buffer. */ -#define REG_STARTEND (1 << 2) - - -/* If any error codes are removed, changed, or added, update the - `__re_error_msgid' table in regcomp.c. */ - -typedef enum -{ - _REG_ENOSYS = -1, /* This will never happen for this implementation. */ - _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, /* Invalid collating element. */ - _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; - -#ifdef _XOPEN_SOURCE -# define REG_ENOSYS _REG_ENOSYS -#endif -#define REG_NOERROR _REG_NOERROR -#define REG_NOMATCH _REG_NOMATCH -#define REG_BADPAT _REG_BADPAT -#define REG_ECOLLATE _REG_ECOLLATE -#define REG_ECTYPE _REG_ECTYPE -#define REG_EESCAPE _REG_EESCAPE -#define REG_ESUBREG _REG_ESUBREG -#define REG_EBRACK _REG_EBRACK -#define REG_EPAREN _REG_EPAREN -#define REG_EBRACE _REG_EBRACE -#define REG_BADBR _REG_BADBR -#define REG_ERANGE _REG_ERANGE -#define REG_ESPACE _REG_ESPACE -#define REG_BADRPT _REG_BADRPT -#define REG_EEND _REG_EEND -#define REG_ESIZE _REG_ESIZE -#define REG_ERPAREN _REG_ERPAREN - -/* struct re_pattern_buffer normally uses member names like `buffer' - that POSIX does not allow. In POSIX mode these members have names - with leading `re_' (e.g., `re_buffer'). */ -#ifdef __USE_GNU_REGEX -# define _REG_RE_NAME(id) id -# define _REG_RM_NAME(id) id -#else -# define _REG_RE_NAME(id) re_##id -# define _REG_RM_NAME(id) rm_##id -#endif - -/* The user can specify the type of the re_translate member by - defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned - char *. This pollutes the POSIX name space, so in POSIX mode just - use unsigned char *. */ -#ifdef __USE_GNU_REGEX -# ifndef RE_TRANSLATE_TYPE -# define RE_TRANSLATE_TYPE unsigned char * -# endif -# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE -#else -# define REG_TRANSLATE_TYPE unsigned char * -#endif - -/* 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 -{ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are sometimes used as - array indexes. */ - unsigned char *_REG_RE_NAME (buffer); - - /* Number of bytes to which `buffer' points. */ - __re_long_size_t _REG_RE_NAME (allocated); - - /* Number of bytes actually used in `buffer'. */ - __re_long_size_t _REG_RE_NAME (used); - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t _REG_RE_NAME (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 *_REG_RE_NAME (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. */ - REG_TRANSLATE_TYPE _REG_RE_NAME (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 int _REG_RE_NAME (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. */ -#ifdef __USE_GNU_REGEX -# define REGS_UNALLOCATED 0 -# define REGS_REALLOCATE 1 -# define REGS_FIXED 2 -#endif - unsigned int _REG_RE_NAME (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 int _REG_RE_NAME (fastmap_accurate) : 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ - unsigned int _REG_RE_NAME (no_sub) : 1; - - /* If set, a beginning-of-line anchor doesn't match at the beginning - of the string. */ - unsigned int _REG_RE_NAME (not_bol) : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned int _REG_RE_NAME (not_eol) : 1; - - /* If true, an anchor at a newline matches. */ - unsigned int _REG_RE_NAME (newline_anchor) : 1; - -/* [[[end pattern_buffer]]] */ -}; - -typedef struct re_pattern_buffer regex_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 -{ - __re_size_t _REG_RM_NAME (num_regs); - regoff_t *_REG_RM_NAME (start); - regoff_t *_REG_RM_NAME (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. */ -#if !defined RE_NREGS && defined __USE_GNU_REGEX -# 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. */ - -/* 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 (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 (const char *__pattern, size_t __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 (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 regoff_t re_search (struct re_pattern_buffer *__buffer, - const char *__string, __re_idx_t __length, - __re_idx_t __start, regoff_t __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 regoff_t re_search_2 (struct re_pattern_buffer *__buffer, - const char *__string1, __re_idx_t __length1, - const char *__string2, __re_idx_t __length2, - __re_idx_t __start, regoff_t __range, - struct re_registers *__regs, - __re_idx_t __stop); - - -/* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern regoff_t re_match (struct re_pattern_buffer *__buffer, - const char *__string, __re_idx_t __length, - __re_idx_t __start, struct re_registers *__regs); - - -/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, - const char *__string1, __re_idx_t __length1, - const char *__string2, __re_idx_t __length2, - __re_idx_t __start, struct re_registers *__regs, - __re_idx_t __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 (struct re_pattern_buffer *__buffer, - struct re_registers *__regs, - __re_size_t __num_regs, - regoff_t *__starts, regoff_t *__ends); - -#if defined _REGEX_RE_COMP || defined _LIBC -# ifndef _CRAY -/* 4.2 bsd compatibility. */ -extern char *re_comp (const char *); -extern int re_exec (const char *); -# endif -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". - Other compilers use __restrict, __restrict__, and _Restrict, and - 'configure' might #define 'restrict' to those words, so pick a - different name. */ -#ifndef _Restrict_ -# if 199901L <= __STDC_VERSION__ -# define _Restrict_ restrict -# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__) -# define _Restrict_ __restrict -# else -# define _Restrict_ -# endif -#endif -/* gcc 3.1 and up support the [restrict] syntax. Don't trust - sys/cdefs.h's definition of __restrict_arr, though, as it - mishandles gcc -ansi -pedantic. */ -#ifndef _Restrict_arr_ -# if ((199901L <= __STDC_VERSION__ \ - || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ - && !__STRICT_ANSI__)) \ - && !defined __GNUG__) -# define _Restrict_arr_ _Restrict_ -# else -# define _Restrict_arr_ -# endif -#endif - -/* POSIX compatibility. */ -extern int regcomp (regex_t *_Restrict_ __preg, - const char *_Restrict_ __pattern, - int __cflags); - -extern int regexec (const regex_t *_Restrict_ __preg, - const char *_Restrict_ __string, size_t __nmatch, - regmatch_t __pmatch[_Restrict_arr_], - int __eflags); - -extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, - char *_Restrict_ __errbuf, size_t __errbuf_size); - -extern void regfree (regex_t *__preg); - - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif /* regex.h */ diff --git a/src/bin/tar/lib/regex_internal.c b/src/bin/tar/lib/regex_internal.c deleted file mode 100644 index 21298889a3..0000000000 --- a/src/bin/tar/lib/regex_internal.c +++ /dev/null @@ -1,1741 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -static void re_string_construct_common (const char *str, Idx len, - re_string_t *pstr, - RE_TRANSLATE_TYPE trans, bool icase, - const re_dfa_t *dfa) internal_function; -static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, - const re_node_set *nodes, - re_hashval_t hash) internal_function; -static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, - const re_node_set *nodes, - unsigned int context, - re_hashval_t hash) internal_function; - -/* Functions for string operation. */ - -/* This function allocate the buffers. It is necessary to call - re_string_reconstruct before using the object. */ - -static reg_errcode_t -internal_function -re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, - RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) -{ - reg_errcode_t ret; - Idx init_buf_len; - - /* Ensure at least one character fits into the buffers. */ - if (init_len < dfa->mb_cur_max) - init_len = dfa->mb_cur_max; - init_buf_len = (len + 1 < init_len) ? len + 1: init_len; - re_string_construct_common (str, len, pstr, trans, icase, dfa); - - ret = re_string_realloc_buffers (pstr, init_buf_len); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - pstr->word_char = dfa->word_char; - pstr->word_ops_used = dfa->word_ops_used; - pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; - pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len; - pstr->valid_raw_len = pstr->valid_len; - return REG_NOERROR; -} - -/* This function allocate the buffers, and initialize them. */ - -static reg_errcode_t -internal_function -re_string_construct (re_string_t *pstr, const char *str, Idx len, - RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) -{ - reg_errcode_t ret; - memset (pstr, '\0', sizeof (re_string_t)); - re_string_construct_common (str, len, pstr, trans, icase, dfa); - - if (len > 0) - { - ret = re_string_realloc_buffers (pstr, len + 1); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; - - if (icase) - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - while (1) - { - ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - if (pstr->valid_raw_len >= len) - break; - if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) - break; - ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - } - else -#endif /* RE_ENABLE_I18N */ - build_upper_buffer (pstr); - } - else - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - build_wcs_buffer (pstr); - else -#endif /* RE_ENABLE_I18N */ - { - if (trans != NULL) - re_string_translate_buffer (pstr); - else - { - pstr->valid_len = pstr->bufs_len; - pstr->valid_raw_len = pstr->bufs_len; - } - } - } - - return REG_NOERROR; -} - -/* Helper functions for re_string_allocate, and re_string_construct. */ - -static reg_errcode_t -internal_function -re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) -{ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - wint_t *new_wcs; - - /* Avoid overflow. */ - size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); - if (BE (SIZE_MAX / max_object_size < new_buf_len, 0)) - return REG_ESPACE; - - new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); - if (BE (new_wcs == NULL, 0)) - return REG_ESPACE; - pstr->wcs = new_wcs; - if (pstr->offsets != NULL) - { - Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len); - if (BE (new_offsets == NULL, 0)) - return REG_ESPACE; - pstr->offsets = new_offsets; - } - } -#endif /* RE_ENABLE_I18N */ - if (pstr->mbs_allocated) - { - unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, - new_buf_len); - if (BE (new_mbs == NULL, 0)) - return REG_ESPACE; - pstr->mbs = new_mbs; - } - pstr->bufs_len = new_buf_len; - return REG_NOERROR; -} - - -static void -internal_function -re_string_construct_common (const char *str, Idx len, re_string_t *pstr, - RE_TRANSLATE_TYPE trans, bool icase, - const re_dfa_t *dfa) -{ - pstr->raw_mbs = (const unsigned char *) str; - pstr->len = len; - pstr->raw_len = len; - pstr->trans = trans; - pstr->icase = icase; - pstr->mbs_allocated = (trans != NULL || icase); - pstr->mb_cur_max = dfa->mb_cur_max; - pstr->is_utf8 = dfa->is_utf8; - pstr->map_notascii = dfa->map_notascii; - pstr->stop = pstr->len; - pstr->raw_stop = pstr->stop; -} - -#ifdef RE_ENABLE_I18N - -/* Build wide character buffer PSTR->WCS. - If the byte sequence of the string are: - (0), (1), (0), (1), - Then wide character buffer will be: - , WEOF , , WEOF , - We use WEOF for padding, they indicate that the position isn't - a first byte of a multibyte character. - - Note that this function assumes PSTR->VALID_LEN elements are already - built and starts from PSTR->VALID_LEN. */ - -static void -internal_function -build_wcs_buffer (re_string_t *pstr) -{ -#ifdef _LIBC - unsigned char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); -#else - unsigned char buf[64]; -#endif - mbstate_t prev_st; - Idx byte_idx, end_idx, remain_len; - size_t mbclen; - - /* Build the buffers from pstr->valid_len to either pstr->len or - pstr->bufs_len. */ - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - for (byte_idx = pstr->valid_len; byte_idx < end_idx;) - { - wchar_t wc; - const char *p; - - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - /* Apply the translation if we need. */ - if (BE (pstr->trans != NULL, 0)) - { - int i, ch; - - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) - { - ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i]; - buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch]; - } - p = (const char *) buf; - } - else - p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; - mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -2, 0)) - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0)) - { - /* We treat these cases as a singlebyte character. */ - mbclen = 1; - wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - if (BE (pstr->trans != NULL, 0)) - wc = pstr->trans[wc]; - pstr->cur_state = prev_st; - } - - /* Write wide character and padding. */ - pstr->wcs[byte_idx++] = wc; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = byte_idx; -} - -/* Build wide character buffer PSTR->WCS like build_wcs_buffer, - but for REG_ICASE. */ - -static reg_errcode_t -internal_function -build_wcs_upper_buffer (re_string_t *pstr) -{ - mbstate_t prev_st; - Idx src_idx, byte_idx, end_idx, remain_len; - size_t mbclen; -#ifdef _LIBC - char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); -#else - char buf[64]; -#endif - - byte_idx = pstr->valid_len; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - /* The following optimization assumes that ASCII characters can be - mapped to wide characters with a simple cast. */ - if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed) - { - while (byte_idx < end_idx) - { - wchar_t wc; - - if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) - && mbsinit (&pstr->cur_state)) - { - /* In case of a singlebyte character. */ - pstr->mbs[byte_idx] - = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]); - /* The next step uses the assumption that wchar_t is encoded - ASCII-safe: all ASCII values can be converted like this. */ - pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; - ++byte_idx; - continue; - } - - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - mbclen = mbrtowc (&wc, - ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx - + byte_idx), remain_len, &pstr->cur_state); - if (BE (mbclen < (size_t) -2, 1)) - { - wchar_t wcu = wc; - if (iswlower (wc)) - { - size_t mbcdlen; - - wcu = towupper (wc); - mbcdlen = wcrtomb (buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) - memcpy (pstr->mbs + byte_idx, buf, mbclen); - else - { - src_idx = byte_idx; - goto offsets_needed; - } - } - else - memcpy (pstr->mbs + byte_idx, - pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen); - pstr->wcs[byte_idx++] = wcu; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - else if (mbclen == (size_t) -1 || mbclen == 0) - { - /* It is an invalid character or '\0'. Just use the byte. */ - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - pstr->mbs[byte_idx] = ch; - /* And also cast it to wide char. */ - pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) - pstr->cur_state = prev_st; - } - else - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = byte_idx; - return REG_NOERROR; - } - else - for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;) - { - wchar_t wc; - const char *p; - offsets_needed: - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - if (BE (pstr->trans != NULL, 0)) - { - int i, ch; - - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) - { - ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i]; - buf[i] = pstr->trans[ch]; - } - p = (const char *) buf; - } - else - p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; - mbclen = mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen < (size_t) -2, 1)) - { - wchar_t wcu = wc; - if (iswlower (wc)) - { - size_t mbcdlen; - - wcu = towupper (wc); - mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) - memcpy (pstr->mbs + byte_idx, buf, mbclen); - else if (mbcdlen != (size_t) -1) - { - size_t i; - - if (byte_idx + mbcdlen > pstr->bufs_len) - { - pstr->cur_state = prev_st; - break; - } - - if (pstr->offsets == NULL) - { - pstr->offsets = re_malloc (Idx, pstr->bufs_len); - - if (pstr->offsets == NULL) - return REG_ESPACE; - } - if (!pstr->offsets_needed) - { - for (i = 0; i < (size_t) byte_idx; ++i) - pstr->offsets[i] = i; - pstr->offsets_needed = 1; - } - - memcpy (pstr->mbs + byte_idx, buf, mbcdlen); - pstr->wcs[byte_idx] = wcu; - pstr->offsets[byte_idx] = src_idx; - for (i = 1; i < mbcdlen; ++i) - { - pstr->offsets[byte_idx + i] - = src_idx + (i < mbclen ? i : mbclen - 1); - pstr->wcs[byte_idx + i] = WEOF; - } - pstr->len += mbcdlen - mbclen; - if (pstr->raw_stop > src_idx) - pstr->stop += mbcdlen - mbclen; - end_idx = (pstr->bufs_len > pstr->len) - ? pstr->len : pstr->bufs_len; - byte_idx += mbcdlen; - src_idx += mbclen; - continue; - } - else - memcpy (pstr->mbs + byte_idx, p, mbclen); - } - else - memcpy (pstr->mbs + byte_idx, p, mbclen); - - if (BE (pstr->offsets_needed != 0, 0)) - { - size_t i; - for (i = 0; i < mbclen; ++i) - pstr->offsets[byte_idx + i] = src_idx + i; - } - src_idx += mbclen; - - pstr->wcs[byte_idx++] = wcu; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - else if (mbclen == (size_t) -1 || mbclen == 0) - { - /* It is an invalid character or '\0'. Just use the byte. */ - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; - - if (BE (pstr->trans != NULL, 0)) - ch = pstr->trans [ch]; - pstr->mbs[byte_idx] = ch; - - if (BE (pstr->offsets_needed != 0, 0)) - pstr->offsets[byte_idx] = src_idx; - ++src_idx; - - /* And also cast it to wide char. */ - pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) - pstr->cur_state = prev_st; - } - else - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = src_idx; - return REG_NOERROR; -} - -/* Skip characters until the index becomes greater than NEW_RAW_IDX. - Return the index. */ - -static Idx -internal_function -re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) -{ - mbstate_t prev_st; - Idx rawbuf_idx; - size_t mbclen; - wint_t wc = WEOF; - - /* Skip the characters which are not necessary to check. */ - for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len; - rawbuf_idx < new_raw_idx;) - { - wchar_t wc2; - Idx remain_len; - remain_len = pstr->len - rawbuf_idx; - prev_st = pstr->cur_state; - mbclen = mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, - remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) - { - /* We treat these cases as a single byte character. */ - if (mbclen == 0 || remain_len == 0) - wc = L'\0'; - else - wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx); - mbclen = 1; - pstr->cur_state = prev_st; - } - else - wc = wc2; - /* Then proceed the next character. */ - rawbuf_idx += mbclen; - } - *last_wc = wc; - return rawbuf_idx; -} -#endif /* RE_ENABLE_I18N */ - -/* Build the buffer PSTR->MBS, and apply the translation if we need. - This function is used in case of REG_ICASE. */ - -static void -internal_function -build_upper_buffer (re_string_t *pstr) -{ - Idx char_idx, end_idx; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) - { - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; - if (BE (pstr->trans != NULL, 0)) - ch = pstr->trans[ch]; - if (islower (ch)) - pstr->mbs[char_idx] = toupper (ch); - else - pstr->mbs[char_idx] = ch; - } - pstr->valid_len = char_idx; - pstr->valid_raw_len = char_idx; -} - -/* Apply TRANS to the buffer in PSTR. */ - -static void -internal_function -re_string_translate_buffer (re_string_t *pstr) -{ - Idx buf_idx, end_idx; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) - { - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx]; - pstr->mbs[buf_idx] = pstr->trans[ch]; - } - - pstr->valid_len = buf_idx; - pstr->valid_raw_len = buf_idx; -} - -/* This function re-construct the buffers. - Concretely, convert to wide character in case of pstr->mb_cur_max > 1, - convert to upper case in case of REG_ICASE, apply translation. */ - -static reg_errcode_t -internal_function -re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) -{ - Idx offset; - - if (BE (pstr->raw_mbs_idx <= idx, 0)) - offset = idx - pstr->raw_mbs_idx; - else - { - /* Reset buffer. */ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); -#endif /* RE_ENABLE_I18N */ - pstr->len = pstr->raw_len; - pstr->stop = pstr->raw_stop; - pstr->valid_len = 0; - pstr->raw_mbs_idx = 0; - pstr->valid_raw_len = 0; - pstr->offsets_needed = 0; - pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF - : CONTEXT_NEWLINE | CONTEXT_BEGBUF); - if (!pstr->mbs_allocated) - pstr->mbs = (unsigned char *) pstr->raw_mbs; - offset = idx; - } - - if (BE (offset != 0, 1)) - { - /* Should the already checked characters be kept? */ - if (BE (offset < pstr->valid_raw_len, 1)) - { - /* Yes, move them to the front of the buffer. */ -#ifdef RE_ENABLE_I18N - if (BE (pstr->offsets_needed, 0)) - { - Idx low = 0, high = pstr->valid_len, mid; - do - { - mid = (high + low) / 2; - if (pstr->offsets[mid] > offset) - high = mid; - else if (pstr->offsets[mid] < offset) - low = mid + 1; - else - break; - } - while (low < high); - if (pstr->offsets[mid] < offset) - ++mid; - pstr->tip_context = re_string_context_at (pstr, mid - 1, - eflags); - /* This can be quite complicated, so handle specially - only the common and easy case where the character with - different length representation of lower and upper - case is present at or after offset. */ - if (pstr->valid_len > offset - && mid == offset && pstr->offsets[mid] == offset) - { - memmove (pstr->wcs, pstr->wcs + offset, - (pstr->valid_len - offset) * sizeof (wint_t)); - memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset); - pstr->valid_len -= offset; - pstr->valid_raw_len -= offset; - for (low = 0; low < pstr->valid_len; low++) - pstr->offsets[low] = pstr->offsets[low + offset] - offset; - } - else - { - /* Otherwise, just find out how long the partial multibyte - character at offset is and fill it with WEOF/255. */ - pstr->len = pstr->raw_len - idx + offset; - pstr->stop = pstr->raw_stop - idx + offset; - pstr->offsets_needed = 0; - while (mid > 0 && pstr->offsets[mid - 1] == offset) - --mid; - while (mid < pstr->valid_len) - if (pstr->wcs[mid] != WEOF) - break; - else - ++mid; - if (mid == pstr->valid_len) - pstr->valid_len = 0; - else - { - pstr->valid_len = pstr->offsets[mid] - offset; - if (pstr->valid_len) - { - for (low = 0; low < pstr->valid_len; ++low) - pstr->wcs[low] = WEOF; - memset (pstr->mbs, 255, pstr->valid_len); - } - } - pstr->valid_raw_len = pstr->valid_len; - } - } - else -#endif - { - pstr->tip_context = re_string_context_at (pstr, offset - 1, - eflags); -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - memmove (pstr->wcs, pstr->wcs + offset, - (pstr->valid_len - offset) * sizeof (wint_t)); -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) - memmove (pstr->mbs, pstr->mbs + offset, - pstr->valid_len - offset); - pstr->valid_len -= offset; - pstr->valid_raw_len -= offset; -#if DEBUG - assert (pstr->valid_len > 0); -#endif - } - } - else - { - /* No, skip all characters until IDX. */ - Idx prev_valid_len = pstr->valid_len; - -#ifdef RE_ENABLE_I18N - if (BE (pstr->offsets_needed, 0)) - { - pstr->len = pstr->raw_len - idx + offset; - pstr->stop = pstr->raw_stop - idx + offset; - pstr->offsets_needed = 0; - } -#endif - pstr->valid_len = 0; -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - Idx wcs_idx; - wint_t wc = WEOF; - - if (pstr->is_utf8) - { - const unsigned char *raw, *p, *end; - - /* Special case UTF-8. Multi-byte chars start with any - byte other than 0x80 - 0xbf. */ - raw = pstr->raw_mbs + pstr->raw_mbs_idx; - end = raw + (offset - pstr->mb_cur_max); - if (end < pstr->raw_mbs) - end = pstr->raw_mbs; - p = raw + offset - 1; -#ifdef _LIBC - /* We know the wchar_t encoding is UCS4, so for the simple - case, ASCII characters, skip the conversion step. */ - if (isascii (*p) && BE (pstr->trans == NULL, 1)) - { - memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); - /* pstr->valid_len = 0; */ - wc = (wchar_t) *p; - } - else -#endif - for (; p >= end; --p) - if ((*p & 0xc0) != 0x80) - { - mbstate_t cur_state; - wchar_t wc2; - Idx mlen = raw + pstr->len - p; - unsigned char buf[6]; - size_t mbclen; - - if (BE (pstr->trans != NULL, 0)) - { - int i = mlen < 6 ? mlen : 6; - while (--i >= 0) - buf[i] = pstr->trans[p[i]]; - } - /* XXX Don't use mbrtowc, we know which conversion - to use (UTF-8 -> UCS4). */ - memset (&cur_state, 0, sizeof (cur_state)); - mbclen = mbrtowc (&wc2, (const char *) p, mlen, - &cur_state); - if (raw + offset - p <= mbclen - && mbclen < (size_t) -2) - { - memset (&pstr->cur_state, '\0', - sizeof (mbstate_t)); - pstr->valid_len = mbclen - (raw + offset - p); - wc = wc2; - } - break; - } - } - - if (wc == WEOF) - pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx; - if (wc == WEOF) - pstr->tip_context - = re_string_context_at (pstr, prev_valid_len - 1, eflags); - else - pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) - && IS_WIDE_WORD_CHAR (wc)) - ? CONTEXT_WORD - : ((IS_WIDE_NEWLINE (wc) - && pstr->newline_anchor) - ? CONTEXT_NEWLINE : 0)); - if (BE (pstr->valid_len, 0)) - { - for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) - pstr->wcs[wcs_idx] = WEOF; - if (pstr->mbs_allocated) - memset (pstr->mbs, 255, pstr->valid_len); - } - pstr->valid_raw_len = pstr->valid_len; - } - else -#endif /* RE_ENABLE_I18N */ - { - int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; - pstr->valid_raw_len = 0; - if (pstr->trans) - c = pstr->trans[c]; - pstr->tip_context = (bitset_contain (pstr->word_char, c) - ? CONTEXT_WORD - : ((IS_NEWLINE (c) && pstr->newline_anchor) - ? CONTEXT_NEWLINE : 0)); - } - } - if (!BE (pstr->mbs_allocated, 0)) - pstr->mbs += offset; - } - pstr->raw_mbs_idx = idx; - pstr->len -= offset; - pstr->stop -= offset; - - /* Then build the buffers. */ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - if (pstr->icase) - { - reg_errcode_t ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - else - build_wcs_buffer (pstr); - } - else -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) - { - if (pstr->icase) - build_upper_buffer (pstr); - else if (pstr->trans != NULL) - re_string_translate_buffer (pstr); - } - else - pstr->valid_len = pstr->len; - - pstr->cur_idx = 0; - return REG_NOERROR; -} - -static unsigned char -internal_function __attribute ((pure)) -re_string_peek_byte_case (const re_string_t *pstr, Idx idx) -{ - int ch; - Idx off; - - /* Handle the common (easiest) cases first. */ - if (BE (!pstr->mbs_allocated, 1)) - return re_string_peek_byte (pstr, idx); - -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1 - && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) - return re_string_peek_byte (pstr, idx); -#endif - - off = pstr->cur_idx + idx; -#ifdef RE_ENABLE_I18N - if (pstr->offsets_needed) - off = pstr->offsets[off]; -#endif - - ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; - -#ifdef RE_ENABLE_I18N - /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I - this function returns CAPITAL LETTER I instead of first byte of - DOTLESS SMALL LETTER I. The latter would confuse the parser, - since peek_byte_case doesn't advance cur_idx in any way. */ - if (pstr->offsets_needed && !isascii (ch)) - return re_string_peek_byte (pstr, idx); -#endif - - return ch; -} - -static unsigned char -internal_function __attribute ((pure)) -re_string_fetch_byte_case (re_string_t *pstr) -{ - if (BE (!pstr->mbs_allocated, 1)) - return re_string_fetch_byte (pstr); - -#ifdef RE_ENABLE_I18N - if (pstr->offsets_needed) - { - Idx off; - int ch; - - /* For tr_TR.UTF-8 [[:islower:]] there is - [[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip - in that case the whole multi-byte character and return - the original letter. On the other side, with - [[: DOTLESS SMALL LETTER I return [[:I, as doing - anything else would complicate things too much. */ - - if (!re_string_first_byte (pstr, pstr->cur_idx)) - return re_string_fetch_byte (pstr); - - off = pstr->offsets[pstr->cur_idx]; - ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; - - if (! isascii (ch)) - return re_string_fetch_byte (pstr); - - re_string_skip_bytes (pstr, - re_string_char_size_at (pstr, pstr->cur_idx)); - return ch; - } -#endif - - return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; -} - -static void -internal_function -re_string_destruct (re_string_t *pstr) -{ -#ifdef RE_ENABLE_I18N - re_free (pstr->wcs); - re_free (pstr->offsets); -#endif /* RE_ENABLE_I18N */ - if (pstr->mbs_allocated) - re_free (pstr->mbs); -} - -/* Return the context at IDX in INPUT. */ - -static unsigned int -internal_function -re_string_context_at (const re_string_t *input, Idx idx, int eflags) -{ - int c; - if (BE (! REG_VALID_INDEX (idx), 0)) - /* In this case, we use the value stored in input->tip_context, - since we can't know the character in input->mbs[-1] here. */ - return input->tip_context; - if (BE (idx == input->len, 0)) - return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF - : CONTEXT_NEWLINE | CONTEXT_ENDBUF); -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc; - Idx wc_idx = idx; - while(input->wcs[wc_idx] == WEOF) - { -#ifdef DEBUG - /* It must not happen. */ - assert (REG_VALID_INDEX (wc_idx)); -#endif - --wc_idx; - if (! REG_VALID_INDEX (wc_idx)) - return input->tip_context; - } - wc = input->wcs[wc_idx]; - if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) - return CONTEXT_WORD; - return (IS_WIDE_NEWLINE (wc) && input->newline_anchor - ? CONTEXT_NEWLINE : 0); - } - else -#endif - { - c = re_string_byte_at (input, idx); - if (bitset_contain (input->word_char, c)) - return CONTEXT_WORD; - return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0; - } -} - -/* Functions for set operation. */ - -static reg_errcode_t -internal_function -re_node_set_alloc (re_node_set *set, Idx size) -{ - set->alloc = size; - set->nelem = 0; - set->elems = re_malloc (Idx, size); - if (BE (set->elems == NULL, 0)) - return REG_ESPACE; - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -re_node_set_init_1 (re_node_set *set, Idx elem) -{ - set->alloc = 1; - set->nelem = 1; - set->elems = re_malloc (Idx, 1); - if (BE (set->elems == NULL, 0)) - { - set->alloc = set->nelem = 0; - return REG_ESPACE; - } - set->elems[0] = elem; - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) -{ - set->alloc = 2; - set->elems = re_malloc (Idx, 2); - if (BE (set->elems == NULL, 0)) - return REG_ESPACE; - if (elem1 == elem2) - { - set->nelem = 1; - set->elems[0] = elem1; - } - else - { - set->nelem = 2; - if (elem1 < elem2) - { - set->elems[0] = elem1; - set->elems[1] = elem2; - } - else - { - set->elems[0] = elem2; - set->elems[1] = elem1; - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -re_node_set_init_copy (re_node_set *dest, const re_node_set *src) -{ - dest->nelem = src->nelem; - if (src->nelem > 0) - { - dest->alloc = dest->nelem; - dest->elems = re_malloc (Idx, dest->alloc); - if (BE (dest->elems == NULL, 0)) - { - dest->alloc = dest->nelem = 0; - return REG_ESPACE; - } - memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); - } - else - re_node_set_init_empty (dest); - return REG_NOERROR; -} - -/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. - Note: We assume dest->elems is NULL, when dest->alloc is 0. */ - -static reg_errcode_t -internal_function -re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, - const re_node_set *src2) -{ - Idx i1, i2, is, id, delta, sbase; - if (src1->nelem == 0 || src2->nelem == 0) - return REG_NOERROR; - - /* We need dest->nelem + 2 * elems_in_intersection; this is a - conservative estimate. */ - if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) - { - Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; - Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); - if (BE (new_elems == NULL, 0)) - return REG_ESPACE; - dest->elems = new_elems; - dest->alloc = new_alloc; - } - - /* Find the items in the intersection of SRC1 and SRC2, and copy - into the top of DEST those that are not already in DEST itself. */ - sbase = dest->nelem + src1->nelem + src2->nelem; - i1 = src1->nelem - 1; - i2 = src2->nelem - 1; - id = dest->nelem - 1; - for (;;) - { - if (src1->elems[i1] == src2->elems[i2]) - { - /* Try to find the item in DEST. Maybe we could binary search? */ - while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) - --id; - - if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) - dest->elems[--sbase] = src1->elems[i1]; - - if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) - break; - } - - /* Lower the highest of the two items. */ - else if (src1->elems[i1] < src2->elems[i2]) - { - if (! REG_VALID_INDEX (--i2)) - break; - } - else - { - if (! REG_VALID_INDEX (--i1)) - break; - } - } - - id = dest->nelem - 1; - is = dest->nelem + src1->nelem + src2->nelem - 1; - delta = is - sbase + 1; - - /* Now copy. When DELTA becomes zero, the remaining - DEST elements are already in place; this is more or - less the same loop that is in re_node_set_merge. */ - dest->nelem += delta; - if (delta > 0 && REG_VALID_INDEX (id)) - for (;;) - { - if (dest->elems[is] > dest->elems[id]) - { - /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; - if (delta == 0) - break; - } - else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; - if (! REG_VALID_INDEX (--id)) - break; - } - } - - /* Copy remaining SRC elements. */ - memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx)); - - return REG_NOERROR; -} - -/* Calculate the union set of the sets SRC1 and SRC2. And store it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ - -static reg_errcode_t -internal_function -re_node_set_init_union (re_node_set *dest, const re_node_set *src1, - const re_node_set *src2) -{ - Idx i1, i2, id; - if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) - { - dest->alloc = src1->nelem + src2->nelem; - dest->elems = re_malloc (Idx, dest->alloc); - if (BE (dest->elems == NULL, 0)) - return REG_ESPACE; - } - else - { - if (src1 != NULL && src1->nelem > 0) - return re_node_set_init_copy (dest, src1); - else if (src2 != NULL && src2->nelem > 0) - return re_node_set_init_copy (dest, src2); - else - re_node_set_init_empty (dest); - return REG_NOERROR; - } - for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;) - { - if (src1->elems[i1] > src2->elems[i2]) - { - dest->elems[id++] = src2->elems[i2++]; - continue; - } - if (src1->elems[i1] == src2->elems[i2]) - ++i2; - dest->elems[id++] = src1->elems[i1++]; - } - if (i1 < src1->nelem) - { - memcpy (dest->elems + id, src1->elems + i1, - (src1->nelem - i1) * sizeof (Idx)); - id += src1->nelem - i1; - } - else if (i2 < src2->nelem) - { - memcpy (dest->elems + id, src2->elems + i2, - (src2->nelem - i2) * sizeof (Idx)); - id += src2->nelem - i2; - } - dest->nelem = id; - return REG_NOERROR; -} - -/* Calculate the union set of the sets DEST and SRC. And store it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ - -static reg_errcode_t -internal_function -re_node_set_merge (re_node_set *dest, const re_node_set *src) -{ - Idx is, id, sbase, delta; - if (src == NULL || src->nelem == 0) - return REG_NOERROR; - if (dest->alloc < 2 * src->nelem + dest->nelem) - { - Idx new_alloc = 2 * (src->nelem + dest->alloc); - Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc); - if (BE (new_buffer == NULL, 0)) - return REG_ESPACE; - dest->elems = new_buffer; - dest->alloc = new_alloc; - } - - if (BE (dest->nelem == 0, 0)) - { - dest->nelem = src->nelem; - memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); - return REG_NOERROR; - } - - /* Copy into the top of DEST the items of SRC that are not - found in DEST. Maybe we could binary search in DEST? */ - for (sbase = dest->nelem + 2 * src->nelem, - is = src->nelem - 1, id = dest->nelem - 1; - REG_VALID_INDEX (is) && REG_VALID_INDEX (id); ) - { - if (dest->elems[id] == src->elems[is]) - is--, id--; - else if (dest->elems[id] < src->elems[is]) - dest->elems[--sbase] = src->elems[is--]; - else /* if (dest->elems[id] > src->elems[is]) */ - --id; - } - - if (REG_VALID_INDEX (is)) - { - /* If DEST is exhausted, the remaining items of SRC must be unique. */ - sbase -= is + 1; - memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx)); - } - - id = dest->nelem - 1; - is = dest->nelem + 2 * src->nelem - 1; - delta = is - sbase + 1; - if (delta == 0) - return REG_NOERROR; - - /* Now copy. When DELTA becomes zero, the remaining - DEST elements are already in place. */ - dest->nelem += delta; - for (;;) - { - if (dest->elems[is] > dest->elems[id]) - { - /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; - if (delta == 0) - break; - } - else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; - if (! REG_VALID_INDEX (--id)) - { - /* Copy remaining SRC elements. */ - memcpy (dest->elems, dest->elems + sbase, - delta * sizeof (Idx)); - break; - } - } - } - - return REG_NOERROR; -} - -/* Insert the new element ELEM to the re_node_set* SET. - SET should not already have ELEM. - Return true if successful. */ - -static bool -internal_function -re_node_set_insert (re_node_set *set, Idx elem) -{ - Idx idx; - /* In case the set is empty. */ - if (set->alloc == 0) - return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1); - - if (BE (set->nelem, 0) == 0) - { - /* We already guaranteed above that set->alloc != 0. */ - set->elems[0] = elem; - ++set->nelem; - return true; - } - - /* Realloc if we need. */ - if (set->alloc == set->nelem) - { - Idx *new_elems; - set->alloc = set->alloc * 2; - new_elems = re_realloc (set->elems, Idx, set->alloc); - if (BE (new_elems == NULL, 0)) - return false; - set->elems = new_elems; - } - - /* Move the elements which follows the new element. Test the - first element separately to skip a check in the inner loop. */ - if (elem < set->elems[0]) - { - idx = 0; - for (idx = set->nelem; idx > 0; idx--) - set->elems[idx] = set->elems[idx - 1]; - } - else - { - for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) - set->elems[idx] = set->elems[idx - 1]; - } - - /* Insert the new element. */ - set->elems[idx] = elem; - ++set->nelem; - return true; -} - -/* Insert the new element ELEM to the re_node_set* SET. - SET should not already have any element greater than or equal to ELEM. - Return true if successful. */ - -static bool -internal_function -re_node_set_insert_last (re_node_set *set, Idx elem) -{ - /* Realloc if we need. */ - if (set->alloc == set->nelem) - { - Idx *new_elems; - set->alloc = (set->alloc + 1) * 2; - new_elems = re_realloc (set->elems, Idx, set->alloc); - if (BE (new_elems == NULL, 0)) - return false; - set->elems = new_elems; - } - - /* Insert the new element. */ - set->elems[set->nelem++] = elem; - return true; -} - -/* Compare two node sets SET1 and SET2. - Return true if SET1 and SET2 are equivalent. */ - -static bool -internal_function __attribute ((pure)) -re_node_set_compare (const re_node_set *set1, const re_node_set *set2) -{ - Idx i; - if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) - return false; - for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) - if (set1->elems[i] != set2->elems[i]) - return false; - return true; -} - -/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ - -static Idx -internal_function __attribute ((pure)) -re_node_set_contains (const re_node_set *set, Idx elem) -{ - __re_size_t idx, right, mid; - if (! REG_VALID_NONZERO_INDEX (set->nelem)) - return 0; - - /* Binary search the element. */ - idx = 0; - right = set->nelem - 1; - while (idx < right) - { - mid = (idx + right) / 2; - if (set->elems[mid] < elem) - idx = mid + 1; - else - right = mid; - } - return set->elems[idx] == elem ? idx + 1 : 0; -} - -static void -internal_function -re_node_set_remove_at (re_node_set *set, Idx idx) -{ - if (idx < 0 || idx >= set->nelem) - return; - --set->nelem; - for (; idx < set->nelem; idx++) - set->elems[idx] = set->elems[idx + 1]; -} - - -/* Add the token TOKEN to dfa->nodes, and return the index of the token. - Or return REG_MISSING if an error occurred. */ - -static Idx -internal_function -re_dfa_add_node (re_dfa_t *dfa, re_token_t token) -{ - if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) - { - size_t new_nodes_alloc = dfa->nodes_alloc * 2; - Idx *new_nexts, *new_indices; - re_node_set *new_edests, *new_eclosures; - re_token_t *new_nodes; - size_t max_object_size = - MAX (sizeof (re_token_t), - MAX (sizeof (re_node_set), - sizeof (Idx))); - - /* Avoid overflows. */ - if (BE (SIZE_MAX / 2 / max_object_size < dfa->nodes_alloc, 0)) - return REG_MISSING; - - new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); - if (BE (new_nodes == NULL, 0)) - return REG_MISSING; - dfa->nodes = new_nodes; - new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); - new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); - new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); - new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); - if (BE (new_nexts == NULL || new_indices == NULL - || new_edests == NULL || new_eclosures == NULL, 0)) - return REG_MISSING; - dfa->nexts = new_nexts; - dfa->org_indices = new_indices; - dfa->edests = new_edests; - dfa->eclosures = new_eclosures; - dfa->nodes_alloc = new_nodes_alloc; - } - dfa->nodes[dfa->nodes_len] = token; - dfa->nodes[dfa->nodes_len].constraint = 0; -#ifdef RE_ENABLE_I18N - { - int type = token.type; - dfa->nodes[dfa->nodes_len].accept_mb = - (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET; - } -#endif - dfa->nexts[dfa->nodes_len] = REG_MISSING; - re_node_set_init_empty (dfa->edests + dfa->nodes_len); - re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); - return dfa->nodes_len++; -} - -static inline re_hashval_t -internal_function -calc_state_hash (const re_node_set *nodes, unsigned int context) -{ - re_hashval_t hash = nodes->nelem + context; - Idx i; - for (i = 0 ; i < nodes->nelem ; i++) - hash += nodes->elems[i]; - return hash; -} - -/* Search for the state whose node_set is equivalent to NODES. - Return the pointer to the state, if we found it in the DFA. - Otherwise create the new one and return it. In case of an error - return NULL and set the error code in ERR. - Note: - We assume NULL as the invalid state, then it is possible that - return value is NULL and ERR is REG_NOERROR. - - We never return non-NULL value in case of any errors, it is for - optimization. */ - -static re_dfastate_t * -internal_function -re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, - const re_node_set *nodes) -{ - re_hashval_t hash; - re_dfastate_t *new_state; - struct re_state_table_entry *spot; - Idx i; -#ifdef lint - /* Suppress bogus uninitialized-variable warnings. */ - *err = REG_NOERROR; -#endif - if (BE (nodes->nelem == 0, 0)) - { - *err = REG_NOERROR; - return NULL; - } - hash = calc_state_hash (nodes, 0); - spot = dfa->state_table + (hash & dfa->state_hash_mask); - - for (i = 0 ; i < spot->num ; i++) - { - re_dfastate_t *state = spot->array[i]; - if (hash != state->hash) - continue; - if (re_node_set_compare (&state->nodes, nodes)) - return state; - } - - /* There are no appropriate state in the dfa, create the new one. */ - new_state = create_ci_newstate (dfa, nodes, hash); - if (BE (new_state == NULL, 0)) - *err = REG_ESPACE; - - return new_state; -} - -/* Search for the state whose node_set is equivalent to NODES and - whose context is equivalent to CONTEXT. - Return the pointer to the state, if we found it in the DFA. - Otherwise create the new one and return it. In case of an error - return NULL and set the error code in ERR. - Note: - We assume NULL as the invalid state, then it is possible that - return value is NULL and ERR is REG_NOERROR. - - We never return non-NULL value in case of any errors, it is for - optimization. */ - -static re_dfastate_t * -internal_function -re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, - const re_node_set *nodes, unsigned int context) -{ - re_hashval_t hash; - re_dfastate_t *new_state; - struct re_state_table_entry *spot; - Idx i; -#ifdef lint - /* Suppress bogus uninitialized-variable warnings. */ - *err = REG_NOERROR; -#endif - if (nodes->nelem == 0) - { - *err = REG_NOERROR; - return NULL; - } - hash = calc_state_hash (nodes, context); - spot = dfa->state_table + (hash & dfa->state_hash_mask); - - for (i = 0 ; i < spot->num ; i++) - { - re_dfastate_t *state = spot->array[i]; - if (state->hash == hash - && state->context == context - && re_node_set_compare (state->entrance_nodes, nodes)) - return state; - } - /* There are no appropriate state in `dfa', create the new one. */ - new_state = create_cd_newstate (dfa, nodes, context, hash); - if (BE (new_state == NULL, 0)) - *err = REG_ESPACE; - - return new_state; -} - -/* Finish initialization of the new state NEWSTATE, and using its hash value - HASH put in the appropriate bucket of DFA's state table. Return value - indicates the error code if failed. */ - -static reg_errcode_t -register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, - re_hashval_t hash) -{ - struct re_state_table_entry *spot; - reg_errcode_t err; - Idx i; - - newstate->hash = hash; - err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - for (i = 0; i < newstate->nodes.nelem; i++) - { - Idx elem = newstate->nodes.elems[i]; - if (!IS_EPSILON_NODE (dfa->nodes[elem].type)) - if (BE (! re_node_set_insert_last (&newstate->non_eps_nodes, elem), 0)) - return REG_ESPACE; - } - - spot = dfa->state_table + (hash & dfa->state_hash_mask); - if (BE (spot->alloc <= spot->num, 0)) - { - Idx new_alloc = 2 * spot->num + 2; - re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, - new_alloc); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - spot->array = new_array; - spot->alloc = new_alloc; - } - spot->array[spot->num++] = newstate; - return REG_NOERROR; -} - -static void -free_state (re_dfastate_t *state) -{ - re_node_set_free (&state->non_eps_nodes); - re_node_set_free (&state->inveclosure); - if (state->entrance_nodes != &state->nodes) - { - re_node_set_free (state->entrance_nodes); - re_free (state->entrance_nodes); - } - re_node_set_free (&state->nodes); - re_free (state->word_trtable); - re_free (state->trtable); - re_free (state); -} - -/* Create the new state which is independ of contexts. - Return the new state if succeeded, otherwise return NULL. */ - -static re_dfastate_t * -internal_function -create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, - re_hashval_t hash) -{ - Idx i; - reg_errcode_t err; - re_dfastate_t *newstate; - - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) - return NULL; - err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_free (newstate); - return NULL; - } - - newstate->entrance_nodes = &newstate->nodes; - for (i = 0 ; i < nodes->nelem ; i++) - { - re_token_t *node = dfa->nodes + nodes->elems[i]; - re_token_type_t type = node->type; - if (type == CHARACTER && !node->constraint) - continue; -#ifdef RE_ENABLE_I18N - newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ - - /* If the state has the halt node, the state is a halt state. */ - if (type == END_OF_RE) - newstate->halt = 1; - else if (type == OP_BACK_REF) - newstate->has_backref = 1; - else if (type == ANCHOR || node->constraint) - newstate->has_constraint = 1; - } - err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) - { - free_state (newstate); - newstate = NULL; - } - return newstate; -} - -/* Create the new state which is depend on the context CONTEXT. - Return the new state if succeeded, otherwise return NULL. */ - -static re_dfastate_t * -internal_function -create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, - unsigned int context, re_hashval_t hash) -{ - Idx i, nctx_nodes = 0; - reg_errcode_t err; - re_dfastate_t *newstate; - - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) - return NULL; - err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_free (newstate); - return NULL; - } - - newstate->context = context; - newstate->entrance_nodes = &newstate->nodes; - - for (i = 0 ; i < nodes->nelem ; i++) - { - unsigned int constraint = 0; - re_token_t *node = dfa->nodes + nodes->elems[i]; - re_token_type_t type = node->type; - if (node->constraint) - constraint = node->constraint; - - if (type == CHARACTER && !constraint) - continue; -#ifdef RE_ENABLE_I18N - newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ - - /* If the state has the halt node, the state is a halt state. */ - if (type == END_OF_RE) - newstate->halt = 1; - else if (type == OP_BACK_REF) - newstate->has_backref = 1; - else if (type == ANCHOR) - constraint = node->opr.ctx_type; - - if (constraint) - { - if (newstate->entrance_nodes == &newstate->nodes) - { - newstate->entrance_nodes = re_malloc (re_node_set, 1); - if (BE (newstate->entrance_nodes == NULL, 0)) - { - free_state (newstate); - return NULL; - } - re_node_set_init_copy (newstate->entrance_nodes, nodes); - nctx_nodes = 0; - newstate->has_constraint = 1; - } - - if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context)) - { - re_node_set_remove_at (&newstate->nodes, i - nctx_nodes); - ++nctx_nodes; - } - } - } - err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) - { - free_state (newstate); - newstate = NULL; - } - return newstate; -} diff --git a/src/bin/tar/lib/regex_internal.h b/src/bin/tar/lib/regex_internal.h deleted file mode 100644 index 5c07f9366f..0000000000 --- a/src/bin/tar/lib/regex_internal.h +++ /dev/null @@ -1,857 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _REGEX_INTERNAL_H -#define _REGEX_INTERNAL_H 1 - -#include -#include -#include -#include -#include -#include - -#ifdef _LIBC -# include -#else -# include "localcharset.h" -#endif -#if defined HAVE_LOCALE_H || defined _LIBC -# include -#endif - -#include -#include -#include -#if defined _LIBC -# include -#else -# define __libc_lock_init(NAME) do { } while (0) -# define __libc_lock_lock(NAME) do { } while (0) -# define __libc_lock_unlock(NAME) do { } while (0) -#endif - -/* In case that the system doesn't have isblank(). */ -#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) -# define isblank(ch) ((ch) == ' ' || (ch) == '\t') -#endif - -#ifdef _LIBC -# ifndef _RE_DEFINE_LOCALE_FUNCTIONS -# define _RE_DEFINE_LOCALE_FUNCTIONS 1 -# include -# include -# include -# endif -#endif - -/* This is for other GNU distributions with internationalized messages. */ -#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC -# include -# ifdef _LIBC -# undef gettext -# define gettext(msgid) \ - INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES) -# endif -#else -# define gettext(msgid) (msgid) -#endif - -#ifndef gettext_noop -/* This define is so xgettext can find the internationalizable - strings. */ -# define gettext_noop(String) String -#endif - -/* For loser systems without the definition. */ -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCRTOMB && HAVE_MBRTOWC && HAVE_WCSCOLL) || _LIBC -# define RE_ENABLE_I18N -#endif - -#if __GNUC__ >= 3 -# define BE(expr, val) __builtin_expect (expr, val) -#else -# define BE(expr, val) (expr) -# ifdef _LIBC -# define inline -# endif -#endif - -/* Number of ASCII characters. */ -#define ASCII_CHARS 0x80 - -/* Number of single byte characters. */ -#define SBC_MAX (UCHAR_MAX + 1) - -#define COLL_ELEM_LEN_MAX 8 - -/* The character which represents newline. */ -#define NEWLINE_CHAR '\n' -#define WIDE_NEWLINE_CHAR L'\n' - -/* Rename to standard API for using out of glibc. */ -#ifndef _LIBC -# define __wctype wctype -# define __iswctype iswctype -# define __btowc btowc -# define __wcrtomb wcrtomb -# define __regfree regfree -# define attribute_hidden -#endif /* not _LIBC */ - -#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -# define __attribute(arg) __attribute__ (arg) -#else -# define __attribute(arg) -#endif - -typedef __re_idx_t Idx; - -/* Special return value for failure to match. */ -#define REG_MISSING ((Idx) -1) - -/* Special return value for internal error. */ -#define REG_ERROR ((Idx) -2) - -/* Test whether N is a valid index, and is not one of the above. */ -#ifdef _REGEX_LARGE_OFFSETS -# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR) -#else -# define REG_VALID_INDEX(n) (0 <= (n)) -#endif - -/* Test whether N is a valid nonzero index. */ -#ifdef _REGEX_LARGE_OFFSETS -# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1)) -#else -# define REG_VALID_NONZERO_INDEX(n) (0 < (n)) -#endif - -/* A hash value, suitable for computing hash tables. */ -typedef __re_size_t re_hashval_t; - -/* An integer used to represent a set of bits. It must be unsigned, - and must be at least as wide as unsigned int. */ -typedef unsigned long int bitset_word_t; -/* All bits set in a bitset_word_t. */ -#define BITSET_WORD_MAX ULONG_MAX - -/* Number of bits in a bitset_word_t. For portability to hosts with - padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)'; - instead, deduce it directly from BITSET_WORD_MAX. Avoid - greater-than-32-bit integers and unconditional shifts by more than - 31 bits, as they're not portable. */ -#if BITSET_WORD_MAX == 0xffffffff -# define BITSET_WORD_BITS 32 -#elif BITSET_WORD_MAX >> 31 >> 5 == 1 -# define BITSET_WORD_BITS 36 -#elif BITSET_WORD_MAX >> 31 >> 16 == 1 -# define BITSET_WORD_BITS 48 -#elif BITSET_WORD_MAX >> 31 >> 28 == 1 -# define BITSET_WORD_BITS 60 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1 -# define BITSET_WORD_BITS 64 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1 -# define BITSET_WORD_BITS 72 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1 -# define BITSET_WORD_BITS 128 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1 -# define BITSET_WORD_BITS 256 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1 -# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */ -# if BITSET_WORD_BITS <= SBC_MAX -# error "Invalid SBC_MAX" -# endif -#elif BITSET_WORD_MAX == (0xffffffff + 2) * 0xffffffff -/* Work around a bug in 64-bit PGC (before version 6.1-2), where the - preprocessor mishandles large unsigned values as if they were signed. */ -# define BITSET_WORD_BITS 64 -#else -# error "Add case for new bitset_word_t size" -#endif - -/* Number of bitset_word_t values in a bitset_t. */ -#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS) - -typedef bitset_word_t bitset_t[BITSET_WORDS]; -typedef bitset_word_t *re_bitset_ptr_t; -typedef const bitset_word_t *re_const_bitset_ptr_t; - -#define PREV_WORD_CONSTRAINT 0x0001 -#define PREV_NOTWORD_CONSTRAINT 0x0002 -#define NEXT_WORD_CONSTRAINT 0x0004 -#define NEXT_NOTWORD_CONSTRAINT 0x0008 -#define PREV_NEWLINE_CONSTRAINT 0x0010 -#define NEXT_NEWLINE_CONSTRAINT 0x0020 -#define PREV_BEGBUF_CONSTRAINT 0x0040 -#define NEXT_ENDBUF_CONSTRAINT 0x0080 -#define WORD_DELIM_CONSTRAINT 0x0100 -#define NOT_WORD_DELIM_CONSTRAINT 0x0200 - -typedef enum -{ - INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, - WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, - WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, - INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, - LINE_FIRST = PREV_NEWLINE_CONSTRAINT, - LINE_LAST = NEXT_NEWLINE_CONSTRAINT, - BUF_FIRST = PREV_BEGBUF_CONSTRAINT, - BUF_LAST = NEXT_ENDBUF_CONSTRAINT, - WORD_DELIM = WORD_DELIM_CONSTRAINT, - NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT -} re_context_type; - -typedef struct -{ - Idx alloc; - Idx nelem; - Idx *elems; -} re_node_set; - -typedef enum -{ - NON_TYPE = 0, - - /* Node type, These are used by token, node, tree. */ - CHARACTER = 1, - END_OF_RE = 2, - SIMPLE_BRACKET = 3, - OP_BACK_REF = 4, - OP_PERIOD = 5, -#ifdef RE_ENABLE_I18N - COMPLEX_BRACKET = 6, - OP_UTF8_PERIOD = 7, -#endif /* RE_ENABLE_I18N */ - - /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used - when the debugger shows values of this enum type. */ -#define EPSILON_BIT 8 - OP_OPEN_SUBEXP = EPSILON_BIT | 0, - OP_CLOSE_SUBEXP = EPSILON_BIT | 1, - OP_ALT = EPSILON_BIT | 2, - OP_DUP_ASTERISK = EPSILON_BIT | 3, - ANCHOR = EPSILON_BIT | 4, - - /* Tree type, these are used only by tree. */ - CONCAT = 16, - SUBEXP = 17, - - /* Token type, these are used only by token. */ - OP_DUP_PLUS = 18, - OP_DUP_QUESTION, - OP_OPEN_BRACKET, - OP_CLOSE_BRACKET, - OP_CHARSET_RANGE, - OP_OPEN_DUP_NUM, - OP_CLOSE_DUP_NUM, - OP_NON_MATCH_LIST, - OP_OPEN_COLL_ELEM, - OP_CLOSE_COLL_ELEM, - OP_OPEN_EQUIV_CLASS, - OP_CLOSE_EQUIV_CLASS, - OP_OPEN_CHAR_CLASS, - OP_CLOSE_CHAR_CLASS, - OP_WORD, - OP_NOTWORD, - OP_SPACE, - OP_NOTSPACE, - BACK_SLASH - -} re_token_type_t; - -#ifdef RE_ENABLE_I18N -typedef struct -{ - /* Multibyte characters. */ - wchar_t *mbchars; - - /* Collating symbols. */ -# ifdef _LIBC - int32_t *coll_syms; -# endif - - /* Equivalence classes. */ -# ifdef _LIBC - int32_t *equiv_classes; -# endif - - /* Range expressions. */ -# ifdef _LIBC - uint32_t *range_starts; - uint32_t *range_ends; -# else /* not _LIBC */ - wchar_t *range_starts; - wchar_t *range_ends; -# endif /* not _LIBC */ - - /* Character classes. */ - wctype_t *char_classes; - - /* If this character set is the non-matching list. */ - unsigned int non_match : 1; - - /* # of multibyte characters. */ - Idx nmbchars; - - /* # of collating symbols. */ - Idx ncoll_syms; - - /* # of equivalence classes. */ - Idx nequiv_classes; - - /* # of range expressions. */ - Idx nranges; - - /* # of character classes. */ - Idx nchar_classes; -} re_charset_t; -#endif /* RE_ENABLE_I18N */ - -typedef struct -{ - union - { - unsigned char c; /* for CHARACTER */ - re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; /* for COMPLEX_BRACKET */ -#endif /* RE_ENABLE_I18N */ - Idx idx; /* for BACK_REF */ - re_context_type ctx_type; /* for ANCHOR */ - } opr; -#if __GNUC__ >= 2 && !__STRICT_ANSI__ - re_token_type_t type : 8; -#else - re_token_type_t type; -#endif - unsigned int constraint : 10; /* context constraint */ - unsigned int duplicated : 1; - unsigned int opt_subexp : 1; -#ifdef RE_ENABLE_I18N - unsigned int accept_mb : 1; - /* These 2 bits can be moved into the union if needed (e.g. if running out - of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */ - unsigned int mb_partial : 1; -#endif - unsigned int word_char : 1; -} re_token_t; - -#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT) - -struct re_string_t -{ - /* Indicate the raw buffer which is the original string passed as an - argument of regexec(), re_search(), etc.. */ - const unsigned char *raw_mbs; - /* Store the multibyte string. In case of "case insensitive mode" like - REG_ICASE, upper cases of the string are stored, otherwise MBS points - the same address that RAW_MBS points. */ - unsigned char *mbs; -#ifdef RE_ENABLE_I18N - /* Store the wide character string which is corresponding to MBS. */ - wint_t *wcs; - Idx *offsets; - mbstate_t cur_state; -#endif - /* Index in RAW_MBS. Each character mbs[i] corresponds to - raw_mbs[raw_mbs_idx + i]. */ - Idx raw_mbs_idx; - /* The length of the valid characters in the buffers. */ - Idx valid_len; - /* The corresponding number of bytes in raw_mbs array. */ - Idx valid_raw_len; - /* The length of the buffers MBS and WCS. */ - Idx bufs_len; - /* The index in MBS, which is updated by re_string_fetch_byte. */ - Idx cur_idx; - /* length of RAW_MBS array. */ - Idx raw_len; - /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */ - Idx len; - /* End of the buffer may be shorter than its length in the cases such - as re_match_2, re_search_2. Then, we use STOP for end of the buffer - instead of LEN. */ - Idx raw_stop; - /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */ - Idx stop; - - /* The context of mbs[0]. We store the context independently, since - the context of mbs[0] may be different from raw_mbs[0], which is - the beginning of the input string. */ - unsigned int tip_context; - /* The translation passed as a part of an argument of re_compile_pattern. */ - RE_TRANSLATE_TYPE trans; - /* Copy of re_dfa_t's word_char. */ - re_const_bitset_ptr_t word_char; - /* true if REG_ICASE. */ - unsigned char icase; - unsigned char is_utf8; - unsigned char map_notascii; - unsigned char mbs_allocated; - unsigned char offsets_needed; - unsigned char newline_anchor; - unsigned char word_ops_used; - int mb_cur_max; -}; -typedef struct re_string_t re_string_t; - - -struct re_dfa_t; -typedef struct re_dfa_t re_dfa_t; - -#ifndef _LIBC -# ifdef __i386__ -# define internal_function __attribute ((regparm (3), stdcall)) -# else -# define internal_function -# endif -#endif - -static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, - Idx new_buf_len) - internal_function; -#ifdef RE_ENABLE_I18N -static void build_wcs_buffer (re_string_t *pstr) internal_function; -static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr) - internal_function; -#endif /* RE_ENABLE_I18N */ -static void build_upper_buffer (re_string_t *pstr) internal_function; -static void re_string_translate_buffer (re_string_t *pstr) internal_function; -static unsigned int re_string_context_at (const re_string_t *input, Idx idx, - int eflags) - internal_function __attribute ((pure)); -#define re_string_peek_byte(pstr, offset) \ - ((pstr)->mbs[(pstr)->cur_idx + offset]) -#define re_string_fetch_byte(pstr) \ - ((pstr)->mbs[(pstr)->cur_idx++]) -#define re_string_first_byte(pstr, idx) \ - ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF) -#define re_string_is_single_byte_char(pstr, idx) \ - ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \ - || (pstr)->wcs[(idx) + 1] != WEOF)) -#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx) -#define re_string_cur_idx(pstr) ((pstr)->cur_idx) -#define re_string_get_buffer(pstr) ((pstr)->mbs) -#define re_string_length(pstr) ((pstr)->len) -#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx]) -#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) -#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) - -#include - -#ifndef _LIBC -# if HAVE_ALLOCA -/* The OS usually guarantees only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - allocate anything larger than 4096 bytes. Also care for the possibility - of a few compiler-allocated temporary stack slots. */ -# define __libc_use_alloca(n) ((n) < 4032) -# else -/* alloca is implemented with malloc, so just use malloc. */ -# define __libc_use_alloca(n) 0 -# endif -#endif - -#ifndef MAX -# define MAX(a,b) ((a) < (b) ? (b) : (a)) -#endif - -#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) -#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) -#define re_free(p) free (p) - -struct bin_tree_t -{ - struct bin_tree_t *parent; - struct bin_tree_t *left; - struct bin_tree_t *right; - struct bin_tree_t *first; - struct bin_tree_t *next; - - re_token_t token; - - /* `node_idx' is the index in dfa->nodes, if `type' == 0. - Otherwise `type' indicate the type of this node. */ - Idx node_idx; -}; -typedef struct bin_tree_t bin_tree_t; - -#define BIN_TREE_STORAGE_SIZE \ - ((1024 - sizeof (void *)) / sizeof (bin_tree_t)) - -struct bin_tree_storage_t -{ - struct bin_tree_storage_t *next; - bin_tree_t data[BIN_TREE_STORAGE_SIZE]; -}; -typedef struct bin_tree_storage_t bin_tree_storage_t; - -#define CONTEXT_WORD 1 -#define CONTEXT_NEWLINE (CONTEXT_WORD << 1) -#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1) -#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1) - -#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD) -#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE) -#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF) -#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF) -#define IS_ORDINARY_CONTEXT(c) ((c) == 0) - -#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_') -#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR) -#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_') -#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR) - -#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \ - ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ - || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ - || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\ - || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context))) - -#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \ - ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ - || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ - || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \ - || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context))) - -struct re_dfastate_t -{ - re_hashval_t hash; - re_node_set nodes; - re_node_set non_eps_nodes; - re_node_set inveclosure; - re_node_set *entrance_nodes; - struct re_dfastate_t **trtable, **word_trtable; - unsigned int context : 4; - unsigned int halt : 1; - /* If this state can accept `multi byte'. - Note that we refer to multibyte characters, and multi character - collating elements as `multi byte'. */ - unsigned int accept_mb : 1; - /* If this state has backreference node(s). */ - unsigned int has_backref : 1; - unsigned int has_constraint : 1; -}; -typedef struct re_dfastate_t re_dfastate_t; - -struct re_state_table_entry -{ - Idx num; - Idx alloc; - re_dfastate_t **array; -}; - -/* Array type used in re_sub_match_last_t and re_sub_match_top_t. */ - -typedef struct -{ - Idx next_idx; - Idx alloc; - re_dfastate_t **array; -} state_array_t; - -/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */ - -typedef struct -{ - Idx node; - Idx str_idx; /* The position NODE match at. */ - state_array_t path; -} re_sub_match_last_t; - -/* Store information about the node NODE whose type is OP_OPEN_SUBEXP. - And information about the node, whose type is OP_CLOSE_SUBEXP, - corresponding to NODE is stored in LASTS. */ - -typedef struct -{ - Idx str_idx; - Idx node; - state_array_t *path; - Idx alasts; /* Allocation size of LASTS. */ - Idx nlasts; /* The number of LASTS. */ - re_sub_match_last_t **lasts; -} re_sub_match_top_t; - -struct re_backref_cache_entry -{ - Idx node; - Idx str_idx; - Idx subexp_from; - Idx subexp_to; - char more; - char unused; - unsigned short int eps_reachable_subexps_map; -}; - -typedef struct -{ - /* The string object corresponding to the input string. */ - re_string_t input; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - const re_dfa_t *const dfa; -#else - const re_dfa_t *dfa; -#endif - /* EFLAGS of the argument of regexec. */ - int eflags; - /* Where the matching ends. */ - Idx match_last; - Idx last_node; - /* The state log used by the matcher. */ - re_dfastate_t **state_log; - Idx state_log_top; - /* Back reference cache. */ - Idx nbkref_ents; - Idx abkref_ents; - struct re_backref_cache_entry *bkref_ents; - int max_mb_elem_len; - Idx nsub_tops; - Idx asub_tops; - re_sub_match_top_t **sub_tops; -} re_match_context_t; - -typedef struct -{ - re_dfastate_t **sifted_states; - re_dfastate_t **limited_states; - Idx last_node; - Idx last_str_idx; - re_node_set limits; -} re_sift_context_t; - -struct re_fail_stack_ent_t -{ - Idx idx; - Idx node; - regmatch_t *regs; - re_node_set eps_via_nodes; -}; - -struct re_fail_stack_t -{ - Idx num; - Idx alloc; - struct re_fail_stack_ent_t *stack; -}; - -struct re_dfa_t -{ - re_token_t *nodes; - size_t nodes_alloc; - size_t nodes_len; - Idx *nexts; - Idx *org_indices; - re_node_set *edests; - re_node_set *eclosures; - re_node_set *inveclosures; - struct re_state_table_entry *state_table; - re_dfastate_t *init_state; - re_dfastate_t *init_state_word; - re_dfastate_t *init_state_nl; - re_dfastate_t *init_state_begbuf; - bin_tree_t *str_tree; - bin_tree_storage_t *str_tree_storage; - re_bitset_ptr_t sb_char; - int str_tree_storage_idx; - - /* number of subexpressions `re_nsub' is in regex_t. */ - re_hashval_t state_hash_mask; - Idx init_node; - Idx nbackref; /* The number of backreference in this dfa. */ - - /* Bitmap expressing which backreference is used. */ - bitset_word_t used_bkref_map; - bitset_word_t completed_bkref_map; - - unsigned int has_plural_match : 1; - /* If this dfa has "multibyte node", which is a backreference or - a node which can accept multibyte character or multi character - collating element. */ - unsigned int has_mb_node : 1; - unsigned int is_utf8 : 1; - unsigned int map_notascii : 1; - unsigned int word_ops_used : 1; - int mb_cur_max; - bitset_t word_char; - reg_syntax_t syntax; - Idx *subexp_map; -#ifdef DEBUG - char* re_str; -#endif -#ifdef _LIBC - __libc_lock_define (, lock) -#endif -}; - -#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set)) -#define re_node_set_remove(set,id) \ - (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1)) -#define re_node_set_empty(p) ((p)->nelem = 0) -#define re_node_set_free(set) re_free ((set)->elems) - - -typedef enum -{ - SB_CHAR, - MB_CHAR, - EQUIV_CLASS, - COLL_SYM, - CHAR_CLASS -} bracket_elem_type; - -typedef struct -{ - bracket_elem_type type; - union - { - unsigned char ch; - unsigned char *name; - wchar_t wch; - } opr; -} bracket_elem_t; - - -/* Inline functions for bitset_t operation. */ - -static inline void -bitset_set (bitset_t set, Idx i) -{ - set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; -} - -static inline void -bitset_clear (bitset_t set, Idx i) -{ - set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); -} - -static inline bool -bitset_contain (const bitset_t set, Idx i) -{ - return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; -} - -static inline void -bitset_empty (bitset_t set) -{ - memset (set, '\0', sizeof (bitset_t)); -} - -static inline void -bitset_set_all (bitset_t set) -{ - memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); - if (SBC_MAX % BITSET_WORD_BITS != 0) - set[BITSET_WORDS - 1] = - ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; -} - -static inline void -bitset_copy (bitset_t dest, const bitset_t src) -{ - memcpy (dest, src, sizeof (bitset_t)); -} - -static inline void -bitset_not (bitset_t set) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i) - set[bitset_i] = ~set[bitset_i]; - if (SBC_MAX % BITSET_WORD_BITS != 0) - set[BITSET_WORDS - 1] = - ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1) - & ~set[BITSET_WORDS - 1]); -} - -static inline void -bitset_merge (bitset_t dest, const bitset_t src) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) - dest[bitset_i] |= src[bitset_i]; -} - -static inline void -bitset_mask (bitset_t dest, const bitset_t src) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) - dest[bitset_i] &= src[bitset_i]; -} - -#ifdef RE_ENABLE_I18N -/* Inline functions for re_string. */ -static inline int -internal_function __attribute ((pure)) -re_string_char_size_at (const re_string_t *pstr, Idx idx) -{ - int byte_idx; - if (pstr->mb_cur_max == 1) - return 1; - for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx) - if (pstr->wcs[idx + byte_idx] != WEOF) - break; - return byte_idx; -} - -static inline wint_t -internal_function __attribute ((pure)) -re_string_wchar_at (const re_string_t *pstr, Idx idx) -{ - if (pstr->mb_cur_max == 1) - return (wint_t) pstr->mbs[idx]; - return (wint_t) pstr->wcs[idx]; -} - -static int -internal_function __attribute ((pure)) -re_string_elem_size_at (const re_string_t *pstr, Idx idx) -{ -# ifdef _LIBC - const unsigned char *p, *extra; - const int32_t *table, *indirect; - int32_t tmp; -# include - uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - - if (nrules != 0) - { - table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_INDIRECTMB); - p = pstr->mbs + idx; - tmp = findidx (&p); - return p - pstr->mbs - idx; - } - else -# endif /* _LIBC */ - return 1; -} -#endif /* RE_ENABLE_I18N */ - -#endif /* _REGEX_INTERNAL_H */ diff --git a/src/bin/tar/lib/regexec.c b/src/bin/tar/lib/regexec.c deleted file mode 100644 index b136570820..0000000000 --- a/src/bin/tar/lib/regexec.c +++ /dev/null @@ -1,4399 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, - Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, - Idx n) internal_function; -static void match_ctx_clean (re_match_context_t *mctx) internal_function; -static void match_ctx_free (re_match_context_t *cache) internal_function; -static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node, - Idx str_idx, Idx from, Idx to) - internal_function; -static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) - internal_function; -static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node, - Idx str_idx) internal_function; -static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop, - Idx node, Idx str_idx) - internal_function; -static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, - re_dfastate_t **limited_sts, Idx last_node, - Idx last_str_idx) - internal_function; -static reg_errcode_t re_search_internal (const regex_t *preg, - const char *string, Idx length, - Idx start, Idx last_start, Idx stop, - size_t nmatch, regmatch_t pmatch[], - int eflags) internal_function; -static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp, - const char *string1, Idx length1, - const char *string2, Idx length2, - Idx start, regoff_t range, - struct re_registers *regs, - Idx stop, bool ret_len) internal_function; -static regoff_t re_search_stub (struct re_pattern_buffer *bufp, - const char *string, Idx length, Idx start, - regoff_t range, Idx stop, - struct re_registers *regs, - bool ret_len) internal_function; -static unsigned int re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, - Idx nregs, int regs_allocated) - internal_function; -static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx) - internal_function; -static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match, - Idx *p_match_first) internal_function; -static Idx check_halt_state_context (const re_match_context_t *mctx, - const re_dfastate_t *state, Idx idx) - internal_function; -static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, - regmatch_t *prev_idx_match, Idx cur_node, - Idx cur_idx, Idx nmatch) internal_function; -static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, - Idx str_idx, Idx dest_node, Idx nregs, - regmatch_t *regs, - re_node_set *eps_via_nodes) - internal_function; -static reg_errcode_t set_regs (const regex_t *preg, - const re_match_context_t *mctx, - size_t nmatch, regmatch_t *pmatch, - bool fl_backtrack) internal_function; -static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) - internal_function; - -#ifdef RE_ENABLE_I18N -static int sift_states_iter_mb (const re_match_context_t *mctx, - re_sift_context_t *sctx, - Idx node_idx, Idx str_idx, Idx max_str_idx) - internal_function; -#endif /* RE_ENABLE_I18N */ -static reg_errcode_t sift_states_backward (const re_match_context_t *mctx, - re_sift_context_t *sctx) - internal_function; -static reg_errcode_t build_sifted_states (const re_match_context_t *mctx, - re_sift_context_t *sctx, Idx str_idx, - re_node_set *cur_dest) - internal_function; -static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx, - re_sift_context_t *sctx, - Idx str_idx, - re_node_set *dest_nodes) - internal_function; -static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa, - re_node_set *dest_nodes, - const re_node_set *candidates) - internal_function; -static bool check_dst_limits (const re_match_context_t *mctx, - const re_node_set *limits, - Idx dst_node, Idx dst_idx, Idx src_node, - Idx src_idx) internal_function; -static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, - int boundaries, Idx subexp_idx, - Idx from_node, Idx bkref_idx) - internal_function; -static int check_dst_limits_calc_pos (const re_match_context_t *mctx, - Idx limit, Idx subexp_idx, - Idx node, Idx str_idx, - Idx bkref_idx) internal_function; -static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa, - re_node_set *dest_nodes, - const re_node_set *candidates, - re_node_set *limits, - struct re_backref_cache_entry *bkref_ents, - Idx str_idx) internal_function; -static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx, - re_sift_context_t *sctx, - Idx str_idx, const re_node_set *candidates) - internal_function; -static reg_errcode_t merge_state_array (const re_dfa_t *dfa, - re_dfastate_t **dst, - re_dfastate_t **src, Idx num) - internal_function; -static re_dfastate_t *find_recover_state (reg_errcode_t *err, - re_match_context_t *mctx) internal_function; -static re_dfastate_t *transit_state (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *state) internal_function; -static re_dfastate_t *merge_state_with_log (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *next_state) - internal_function; -static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx, - re_node_set *cur_nodes, - Idx str_idx) internal_function; -#if 0 -static re_dfastate_t *transit_state_sb (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; -#endif -#ifdef RE_ENABLE_I18N -static reg_errcode_t transit_state_mb (re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; -#endif /* RE_ENABLE_I18N */ -static reg_errcode_t transit_state_bkref (re_match_context_t *mctx, - const re_node_set *nodes) - internal_function; -static reg_errcode_t get_subexp (re_match_context_t *mctx, - Idx bkref_node, Idx bkref_str_idx) - internal_function; -static reg_errcode_t get_subexp_sub (re_match_context_t *mctx, - const re_sub_match_top_t *sub_top, - re_sub_match_last_t *sub_last, - Idx bkref_node, Idx bkref_str) - internal_function; -static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, - Idx subexp_idx, int type) internal_function; -static reg_errcode_t check_arrival (re_match_context_t *mctx, - state_array_t *path, Idx top_node, - Idx top_str, Idx last_node, Idx last_str, - int type) internal_function; -static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx, - Idx str_idx, - re_node_set *cur_nodes, - re_node_set *next_nodes) - internal_function; -static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa, - re_node_set *cur_nodes, - Idx ex_subexp, int type) - internal_function; -static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa, - re_node_set *dst_nodes, - Idx target, Idx ex_subexp, - int type) internal_function; -static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx, - re_node_set *cur_nodes, Idx cur_str, - Idx subexp_num, int type) - internal_function; -static bool build_trtable (const re_dfa_t *dfa, - re_dfastate_t *state) internal_function; -#ifdef RE_ENABLE_I18N -static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, - const re_string_t *input, Idx idx) - internal_function; -# ifdef _LIBC -static unsigned int find_collation_sequence_value (const unsigned char *mbs, - size_t name_len) - internal_function; -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ -static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa, - const re_dfastate_t *state, - re_node_set *states_node, - bitset_t *states_ch) internal_function; -static bool check_node_accept (const re_match_context_t *mctx, - const re_token_t *node, Idx idx) - internal_function; -static reg_errcode_t extend_buffers (re_match_context_t *mctx) - internal_function; - -/* Entry point for POSIX code. */ - -/* regexec searches for a given pattern, specified by PREG, in the - string STRING. - - If NMATCH is zero or REG_NOSUB was set in the cflags argument to - `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at - least NMATCH elements, and we set them to the offsets of the - corresponding matched substrings. - - EFLAGS specifies `execution flags' which affect matching: if - REG_NOTBOL is set, then ^ does not match at the beginning of the - string; if REG_NOTEOL is set, then $ does not match at the end. - - We return 0 if we find a match and REG_NOMATCH if not. */ - -int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *_Restrict_ preg; - const char *_Restrict_ string; - size_t nmatch; - regmatch_t pmatch[_Restrict_arr_]; - int eflags; -{ - reg_errcode_t err; - Idx start, length; -#ifdef _LIBC - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; -#endif - - if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND)) - return REG_BADPAT; - - if (eflags & REG_STARTEND) - { - start = pmatch[0].rm_so; - length = pmatch[0].rm_eo; - } - else - { - start = 0; - length = strlen (string); - } - - __libc_lock_lock (dfa->lock); - if (preg->no_sub) - err = re_search_internal (preg, string, length, start, length, - length, 0, NULL, eflags); - else - err = re_search_internal (preg, string, length, start, length, - length, nmatch, pmatch, eflags); - __libc_lock_unlock (dfa->lock); - return err != REG_NOERROR; -} - -#ifdef _LIBC -# include -versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); - -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) -__typeof__ (__regexec) __compat_regexec; - -int -attribute_compat_text_section -__compat_regexec (const regex_t *_Restrict_ preg, - const char *_Restrict_ string, size_t nmatch, - regmatch_t pmatch[], int eflags) -{ - return regexec (preg, string, nmatch, pmatch, - eflags & (REG_NOTBOL | REG_NOTEOL)); -} -compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); -# endif -#endif - -/* Entry points for GNU code. */ - -/* re_match, re_search, re_match_2, re_search_2 - - The former two functions operate on STRING with length LENGTH, - while the later two operate on concatenation of STRING1 and STRING2 - with lengths LENGTH1 and LENGTH2, respectively. - - re_match() matches the compiled pattern in BUFP against the string, - starting at index START. - - re_search() first tries matching at index START, then it tries to match - starting from index START + 1, and so on. The last start position tried - is START + RANGE. (Thus RANGE = 0 forces re_search to operate the same - way as re_match().) - - The parameter STOP of re_{match,search}_2 specifies that no match exceeding - the first STOP characters of the concatenation of the strings should be - concerned. - - If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match - and all groups is stored in REGS. (For the "_2" variants, the offsets are - computed relative to the concatenation, not relative to the individual - strings.) - - On success, re_match* functions return the length of the match, re_search* - return the position of the start of the match. Return value -1 means no - match was found and -2 indicates an internal error. */ - -regoff_t -re_match (bufp, string, length, start, regs) - struct re_pattern_buffer *bufp; - const char *string; - Idx length, start; - struct re_registers *regs; -{ - return re_search_stub (bufp, string, length, start, 0, length, regs, true); -} -#ifdef _LIBC -weak_alias (__re_match, re_match) -#endif - -regoff_t -re_search (bufp, string, length, start, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - Idx length, start; - regoff_t range; - struct re_registers *regs; -{ - return re_search_stub (bufp, string, length, start, range, length, regs, - false); -} -#ifdef _LIBC -weak_alias (__re_search, re_search) -#endif - -regoff_t -re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - Idx length1, length2, start, stop; - struct re_registers *regs; -{ - return re_search_2_stub (bufp, string1, length1, string2, length2, - start, 0, regs, stop, true); -} -#ifdef _LIBC -weak_alias (__re_match_2, re_match_2) -#endif - -regoff_t -re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - Idx length1, length2, start, stop; - regoff_t range; - struct re_registers *regs; -{ - return re_search_2_stub (bufp, string1, length1, string2, length2, - start, range, regs, stop, false); -} -#ifdef _LIBC -weak_alias (__re_search_2, re_search_2) -#endif - -static regoff_t -internal_function -re_search_2_stub (struct re_pattern_buffer *bufp, - const char *string1, Idx length1, - const char *string2, Idx length2, - Idx start, regoff_t range, struct re_registers *regs, - Idx stop, bool ret_len) -{ - const char *str; - regoff_t rval; - Idx len = length1 + length2; - char *s = NULL; - - if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0)) - return -2; - - /* Concatenate the strings. */ - if (length2 > 0) - if (length1 > 0) - { - s = re_malloc (char, len); - - if (BE (s == NULL, 0)) - return -2; -#ifdef _LIBC - memcpy (__mempcpy (s, string1, length1), string2, length2); -#else - memcpy (s, string1, length1); - memcpy (s + length1, string2, length2); -#endif - str = s; - } - else - str = string2; - else - str = string1; - - rval = re_search_stub (bufp, str, len, start, range, stop, regs, - ret_len); - re_free (s); - return rval; -} - -/* The parameters have the same meaning as those of re_search. - Additional parameters: - If RET_LEN is true the length of the match is returned (re_match style); - otherwise the position of the match is returned. */ - -static regoff_t -internal_function -re_search_stub (struct re_pattern_buffer *bufp, - const char *string, Idx length, - Idx start, regoff_t range, Idx stop, struct re_registers *regs, - bool ret_len) -{ - reg_errcode_t result; - regmatch_t *pmatch; - Idx nregs; - regoff_t rval; - int eflags = 0; -#ifdef _LIBC - re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; -#endif - Idx last_start = start + range; - - /* Check for out-of-range. */ - if (BE (start < 0 || start > length, 0)) - return -1; - if (BE (length < last_start || (0 <= range && last_start < start), 0)) - last_start = length; - else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0)) - last_start = 0; - - __libc_lock_lock (dfa->lock); - - eflags |= (bufp->not_bol) ? REG_NOTBOL : 0; - eflags |= (bufp->not_eol) ? REG_NOTEOL : 0; - - /* Compile fastmap if we haven't yet. */ - if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate) - re_compile_fastmap (bufp); - - if (BE (bufp->no_sub, 0)) - regs = NULL; - - /* We need at least 1 register. */ - if (regs == NULL) - nregs = 1; - else if (BE (bufp->regs_allocated == REGS_FIXED - && regs->num_regs <= bufp->re_nsub, 0)) - { - nregs = regs->num_regs; - if (BE (nregs < 1, 0)) - { - /* Nothing can be copied to regs. */ - regs = NULL; - nregs = 1; - } - } - else - nregs = bufp->re_nsub + 1; - pmatch = re_malloc (regmatch_t, nregs); - if (BE (pmatch == NULL, 0)) - { - rval = -2; - goto out; - } - - result = re_search_internal (bufp, string, length, start, last_start, stop, - nregs, pmatch, eflags); - - rval = 0; - - /* I hope we needn't fill ther regs with -1's when no match was found. */ - if (result != REG_NOERROR) - rval = -1; - else if (regs != NULL) - { - /* If caller wants register contents data back, copy them. */ - bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs, - bufp->regs_allocated); - if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0)) - rval = -2; - } - - if (BE (rval == 0, 1)) - { - if (ret_len) - { - assert (pmatch[0].rm_so == start); - rval = pmatch[0].rm_eo - start; - } - else - rval = pmatch[0].rm_so; - } - re_free (pmatch); - out: - __libc_lock_unlock (dfa->lock); - return rval; -} - -static unsigned int -internal_function -re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, - int regs_allocated) -{ - int rval = REGS_REALLOCATE; - Idx i; - Idx need_regs = nregs + 1; - /* We need one extra element beyond `num_regs' for the `-1' marker GNU code - uses. */ - - /* Have the register data arrays been allocated? */ - if (regs_allocated == REGS_UNALLOCATED) - { /* No. So allocate them with malloc. */ - regs->start = re_malloc (regoff_t, need_regs); - if (BE (regs->start == NULL, 0)) - return REGS_UNALLOCATED; - regs->end = re_malloc (regoff_t, need_regs); - if (BE (regs->end == NULL, 0)) - { - re_free (regs->start); - return REGS_UNALLOCATED; - } - regs->num_regs = need_regs; - } - else if (regs_allocated == REGS_REALLOCATE) - { /* Yes. If we need more elements than were already - allocated, reallocate them. If we need fewer, just - leave it alone. */ - if (BE (need_regs > regs->num_regs, 0)) - { - regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs); - regoff_t *new_end; - if (BE (new_start == NULL, 0)) - return REGS_UNALLOCATED; - new_end = re_realloc (regs->end, regoff_t, need_regs); - if (BE (new_end == NULL, 0)) - { - re_free (new_start); - return REGS_UNALLOCATED; - } - regs->start = new_start; - regs->end = new_end; - regs->num_regs = need_regs; - } - } - else - { - assert (regs_allocated == REGS_FIXED); - /* This function may not be called with REGS_FIXED and nregs too big. */ - assert (regs->num_regs >= nregs); - rval = REGS_FIXED; - } - - /* Copy the regs. */ - for (i = 0; i < nregs; ++i) - { - regs->start[i] = pmatch[i].rm_so; - regs->end[i] = pmatch[i].rm_eo; - } - for ( ; i < regs->num_regs; ++i) - regs->start[i] = regs->end[i] = -1; - - return rval; -} - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use - this memory for recording register information. STARTS and ENDS - must be allocated using the malloc library routine, 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. */ - -void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - __re_size_t num_regs; - regoff_t *starts, *ends; -{ - if (num_regs) - { - bufp->regs_allocated = REGS_REALLOCATE; - regs->num_regs = num_regs; - regs->start = starts; - regs->end = ends; - } - else - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; - regs->start = regs->end = NULL; - } -} -#ifdef _LIBC -weak_alias (__re_set_registers, re_set_registers) -#endif - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined _REGEX_RE_COMP || defined _LIBC -int -# ifdef _LIBC -weak_function -# endif -re_exec (s) - const char *s; -{ - return 0 == regexec (&re_comp_buf, s, 0, NULL, 0); -} -#endif /* _REGEX_RE_COMP */ - -/* Internal entry point. */ - -/* Searches for a compiled pattern PREG in the string STRING, whose - length is LENGTH. NMATCH, PMATCH, and EFLAGS have the same - meaning as with regexec. LAST_START is START + RANGE, where - START and RANGE have the same meaning as with re_search. - Return REG_NOERROR if we find a match, and REG_NOMATCH if not, - otherwise return the error code. - Note: We assume front end functions already check ranges. - (0 <= LAST_START && LAST_START <= LENGTH) */ - -static reg_errcode_t -internal_function -re_search_internal (const regex_t *preg, - const char *string, Idx length, - Idx start, Idx last_start, Idx stop, - size_t nmatch, regmatch_t pmatch[], - int eflags) -{ - reg_errcode_t err; - const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; - Idx left_lim, right_lim; - int incr; - bool fl_longest_match; - int match_kind; - Idx match_first; - Idx match_last = REG_MISSING; - Idx extra_nmatch; - bool sb; - int ch; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - re_match_context_t mctx = { .dfa = dfa }; -#else - re_match_context_t mctx; -#endif - char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate - && start != last_start && !preg->can_be_null) - ? preg->fastmap : NULL); - RE_TRANSLATE_TYPE t = preg->translate; - -#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) - memset (&mctx, '\0', sizeof (re_match_context_t)); - mctx.dfa = dfa; -#endif - - extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0; - nmatch -= extra_nmatch; - - /* Check if the DFA haven't been compiled. */ - if (BE (preg->used == 0 || dfa->init_state == NULL - || dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) - return REG_NOMATCH; - -#ifdef DEBUG - /* We assume front-end functions already check them. */ - assert (0 <= last_start && last_start <= length); -#endif - - /* If initial states with non-begbuf contexts have no elements, - the regex must be anchored. If preg->newline_anchor is set, - we'll never use init_state_nl, so do not check it. */ - if (dfa->init_state->nodes.nelem == 0 - && dfa->init_state_word->nodes.nelem == 0 - && (dfa->init_state_nl->nodes.nelem == 0 - || !preg->newline_anchor)) - { - if (start != 0 && last_start != 0) - return REG_NOMATCH; - start = last_start = 0; - } - - /* We must check the longest matching, if nmatch > 0. */ - fl_longest_match = (nmatch != 0 || dfa->nbackref); - - err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1, - preg->translate, preg->syntax & RE_ICASE, dfa); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - mctx.input.stop = stop; - mctx.input.raw_stop = stop; - mctx.input.newline_anchor = preg->newline_anchor; - - err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* We will log all the DFA states through which the dfa pass, - if nmatch > 1, or this dfa has "multibyte node", which is a - back-reference or a node which can accept multibyte character or - multi character collating element. */ - if (nmatch > 1 || dfa->has_mb_node) - { - /* Avoid overflow. */ - if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0)) - { - err = REG_ESPACE; - goto free_return; - } - - mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1); - if (BE (mctx.state_log == NULL, 0)) - { - err = REG_ESPACE; - goto free_return; - } - } - else - mctx.state_log = NULL; - - match_first = start; - mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF - : CONTEXT_NEWLINE | CONTEXT_BEGBUF; - - /* Check incrementally whether of not the input string match. */ - incr = (last_start < start) ? -1 : 1; - left_lim = (last_start < start) ? last_start : start; - right_lim = (last_start < start) ? start : last_start; - sb = dfa->mb_cur_max == 1; - match_kind = - (fastmap - ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0) - | (start <= last_start ? 2 : 0) - | (t != NULL ? 1 : 0)) - : 8); - - for (;; match_first += incr) - { - err = REG_NOMATCH; - if (match_first < left_lim || right_lim < match_first) - goto free_return; - - /* Advance as rapidly as possible through the string, until we - find a plausible place to start matching. This may be done - with varying efficiency, so there are various possibilities: - only the most common of them are specialized, in order to - save on code size. We use a switch statement for speed. */ - switch (match_kind) - { - case 8: - /* No fastmap. */ - break; - - case 7: - /* Fastmap with single-byte translation, match forward. */ - while (BE (match_first < right_lim, 1) - && !fastmap[t[(unsigned char) string[match_first]]]) - ++match_first; - goto forward_match_found_start_or_reached_end; - - case 6: - /* Fastmap without translation, match forward. */ - while (BE (match_first < right_lim, 1) - && !fastmap[(unsigned char) string[match_first]]) - ++match_first; - - forward_match_found_start_or_reached_end: - if (BE (match_first == right_lim, 0)) - { - ch = match_first >= length - ? 0 : (unsigned char) string[match_first]; - if (!fastmap[t ? t[ch] : ch]) - goto free_return; - } - break; - - case 4: - case 5: - /* Fastmap without multi-byte translation, match backwards. */ - while (match_first >= left_lim) - { - ch = match_first >= length - ? 0 : (unsigned char) string[match_first]; - if (fastmap[t ? t[ch] : ch]) - break; - --match_first; - } - if (match_first < left_lim) - goto free_return; - break; - - default: - /* In this case, we can't determine easily the current byte, - since it might be a component byte of a multibyte - character. Then we use the constructed buffer instead. */ - for (;;) - { - /* If MATCH_FIRST is out of the valid range, reconstruct the - buffers. */ - __re_size_t offset = match_first - mctx.input.raw_mbs_idx; - if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0)) - { - err = re_string_reconstruct (&mctx.input, match_first, - eflags); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - offset = match_first - mctx.input.raw_mbs_idx; - } - /* If MATCH_FIRST is out of the buffer, leave it as '\0'. - Note that MATCH_FIRST must not be smaller than 0. */ - ch = (match_first >= length - ? 0 : re_string_byte_at (&mctx.input, offset)); - if (fastmap[ch]) - break; - match_first += incr; - if (match_first < left_lim || match_first > right_lim) - { - err = REG_NOMATCH; - goto free_return; - } - } - break; - } - - /* Reconstruct the buffers so that the matcher can assume that - the matching starts from the beginning of the buffer. */ - err = re_string_reconstruct (&mctx.input, match_first, eflags); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - -#ifdef RE_ENABLE_I18N - /* Don't consider this char as a possible match start if it part, - yet isn't the head, of a multibyte character. */ - if (!sb && !re_string_first_byte (&mctx.input, 0)) - continue; -#endif - - /* It seems to be appropriate one, then use the matcher. */ - /* We assume that the matching starts from 0. */ - mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0; - match_last = check_matching (&mctx, fl_longest_match, - start <= last_start ? &match_first : NULL); - if (match_last != REG_MISSING) - { - if (BE (match_last == REG_ERROR, 0)) - { - err = REG_ESPACE; - goto free_return; - } - else - { - mctx.match_last = match_last; - if ((!preg->no_sub && nmatch > 1) || dfa->nbackref) - { - re_dfastate_t *pstate = mctx.state_log[match_last]; - mctx.last_node = check_halt_state_context (&mctx, pstate, - match_last); - } - if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match) - || dfa->nbackref) - { - err = prune_impossible_nodes (&mctx); - if (err == REG_NOERROR) - break; - if (BE (err != REG_NOMATCH, 0)) - goto free_return; - match_last = REG_MISSING; - } - else - break; /* We found a match. */ - } - } - - match_ctx_clean (&mctx); - } - -#ifdef DEBUG - assert (match_last != REG_MISSING); - assert (err == REG_NOERROR); -#endif - - /* Set pmatch[] if we need. */ - if (nmatch > 0) - { - Idx reg_idx; - - /* Initialize registers. */ - for (reg_idx = 1; reg_idx < nmatch; ++reg_idx) - pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1; - - /* Set the points where matching start/end. */ - pmatch[0].rm_so = 0; - pmatch[0].rm_eo = mctx.match_last; - /* FIXME: This function should fail if mctx.match_last exceeds - the maximum possible regoff_t value. We need a new error - code REG_OVERFLOW. */ - - if (!preg->no_sub && nmatch > 1) - { - err = set_regs (preg, &mctx, nmatch, pmatch, - dfa->has_plural_match && dfa->nbackref > 0); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - - /* At last, add the offset to the each registers, since we slided - the buffers so that we could assume that the matching starts - from 0. */ - for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) - if (pmatch[reg_idx].rm_so != -1) - { -#ifdef RE_ENABLE_I18N - if (BE (mctx.input.offsets_needed != 0, 0)) - { - pmatch[reg_idx].rm_so = - (pmatch[reg_idx].rm_so == mctx.input.valid_len - ? mctx.input.valid_raw_len - : mctx.input.offsets[pmatch[reg_idx].rm_so]); - pmatch[reg_idx].rm_eo = - (pmatch[reg_idx].rm_eo == mctx.input.valid_len - ? mctx.input.valid_raw_len - : mctx.input.offsets[pmatch[reg_idx].rm_eo]); - } -#else - assert (mctx.input.offsets_needed == 0); -#endif - pmatch[reg_idx].rm_so += match_first; - pmatch[reg_idx].rm_eo += match_first; - } - for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx) - { - pmatch[nmatch + reg_idx].rm_so = -1; - pmatch[nmatch + reg_idx].rm_eo = -1; - } - - if (dfa->subexp_map) - for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++) - if (dfa->subexp_map[reg_idx] != reg_idx) - { - pmatch[reg_idx + 1].rm_so - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so; - pmatch[reg_idx + 1].rm_eo - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo; - } - } - - free_return: - re_free (mctx.state_log); - if (dfa->nbackref) - match_ctx_free (&mctx); - re_string_destruct (&mctx.input); - return err; -} - -static reg_errcode_t -internal_function -prune_impossible_nodes (re_match_context_t *mctx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx halt_node, match_last; - reg_errcode_t ret; - re_dfastate_t **sifted_states; - re_dfastate_t **lim_states = NULL; - re_sift_context_t sctx; -#ifdef DEBUG - assert (mctx->state_log != NULL); -#endif - match_last = mctx->match_last; - halt_node = mctx->last_node; - - /* Avoid overflow. */ - if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0)) - return REG_ESPACE; - - sifted_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (sifted_states == NULL, 0)) - { - ret = REG_ESPACE; - goto free_return; - } - if (dfa->nbackref) - { - lim_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (lim_states == NULL, 0)) - { - ret = REG_ESPACE; - goto free_return; - } - while (1) - { - memset (lim_states, '\0', - sizeof (re_dfastate_t *) * (match_last + 1)); - sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, - match_last); - ret = sift_states_backward (mctx, &sctx); - re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - if (sifted_states[0] != NULL || lim_states[0] != NULL) - break; - do - { - --match_last; - if (! REG_VALID_INDEX (match_last)) - { - ret = REG_NOMATCH; - goto free_return; - } - } while (mctx->state_log[match_last] == NULL - || !mctx->state_log[match_last]->halt); - halt_node = check_halt_state_context (mctx, - mctx->state_log[match_last], - match_last); - } - ret = merge_state_array (dfa, sifted_states, lim_states, - match_last + 1); - re_free (lim_states); - lim_states = NULL; - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - } - else - { - sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last); - ret = sift_states_backward (mctx, &sctx); - re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - } - re_free (mctx->state_log); - mctx->state_log = sifted_states; - sifted_states = NULL; - mctx->last_node = halt_node; - mctx->match_last = match_last; - ret = REG_NOERROR; - free_return: - re_free (sifted_states); - re_free (lim_states); - return ret; -} - -/* Acquire an initial state and return it. - We must select appropriate initial state depending on the context, - since initial states may have constraints like "\<", "^", etc.. */ - -static inline re_dfastate_t * -__attribute ((always_inline)) internal_function -acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, - Idx idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - if (dfa->init_state->has_constraint) - { - unsigned int context; - context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags); - if (IS_WORD_CONTEXT (context)) - return dfa->init_state_word; - else if (IS_ORDINARY_CONTEXT (context)) - return dfa->init_state; - else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context)) - return dfa->init_state_begbuf; - else if (IS_NEWLINE_CONTEXT (context)) - return dfa->init_state_nl; - else if (IS_BEGBUF_CONTEXT (context)) - { - /* It is relatively rare case, then calculate on demand. */ - return re_acquire_state_context (err, dfa, - dfa->init_state->entrance_nodes, - context); - } - else - /* Must not happen? */ - return dfa->init_state; - } - else - return dfa->init_state; -} - -/* Check whether the regular expression match input string INPUT or not, - and return the index where the matching end. Return REG_MISSING if - there is no match, and return REG_ERROR in case of an error. - FL_LONGEST_MATCH means we want the POSIX longest matching. - If P_MATCH_FIRST is not NULL, and the match fails, it is set to the - next place where we may want to try matching. - Note that the matcher assume that the maching starts from the current - index of the buffer. */ - -static Idx -internal_function -check_matching (re_match_context_t *mctx, bool fl_longest_match, - Idx *p_match_first) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx match = 0; - Idx match_last = REG_MISSING; - Idx cur_str_idx = re_string_cur_idx (&mctx->input); - re_dfastate_t *cur_state; - bool at_init_state = p_match_first != NULL; - Idx next_start_idx = cur_str_idx; - - err = REG_NOERROR; - cur_state = acquire_init_state_context (&err, mctx, cur_str_idx); - /* An initial state must not be NULL (invalid). */ - if (BE (cur_state == NULL, 0)) - { - assert (err == REG_ESPACE); - return REG_ERROR; - } - - if (mctx->state_log != NULL) - { - mctx->state_log[cur_str_idx] = cur_state; - - /* Check OP_OPEN_SUBEXP in the initial state in case that we use them - later. E.g. Processing back references. */ - if (BE (dfa->nbackref, 0)) - { - at_init_state = false; - err = check_subexp_matching_top (mctx, &cur_state->nodes, 0); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (cur_state->has_backref) - { - err = transit_state_bkref (mctx, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - } - - /* If the RE accepts NULL string. */ - if (BE (cur_state->halt, 0)) - { - if (!cur_state->has_constraint - || check_halt_state_context (mctx, cur_state, cur_str_idx)) - { - if (!fl_longest_match) - return cur_str_idx; - else - { - match_last = cur_str_idx; - match = 1; - } - } - } - - while (!re_string_eoi (&mctx->input)) - { - re_dfastate_t *old_state = cur_state; - Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1; - - if (BE (next_char_idx >= mctx->input.bufs_len, 0) - || (BE (next_char_idx >= mctx->input.valid_len, 0) - && mctx->input.valid_len < mctx->input.len)) - { - err = extend_buffers (mctx); - if (BE (err != REG_NOERROR, 0)) - { - assert (err == REG_ESPACE); - return REG_ERROR; - } - } - - cur_state = transit_state (&err, mctx, cur_state); - if (mctx->state_log != NULL) - cur_state = merge_state_with_log (&err, mctx, cur_state); - - if (cur_state == NULL) - { - /* Reached the invalid state or an error. Try to recover a valid - state using the state log, if available and if we have not - already found a valid (even if not the longest) match. */ - if (BE (err != REG_NOERROR, 0)) - return REG_ERROR; - - if (mctx->state_log == NULL - || (match && !fl_longest_match) - || (cur_state = find_recover_state (&err, mctx)) == NULL) - break; - } - - if (BE (at_init_state, 0)) - { - if (old_state == cur_state) - next_start_idx = next_char_idx; - else - at_init_state = false; - } - - if (cur_state->halt) - { - /* Reached a halt state. - Check the halt state can satisfy the current context. */ - if (!cur_state->has_constraint - || check_halt_state_context (mctx, cur_state, - re_string_cur_idx (&mctx->input))) - { - /* We found an appropriate halt state. */ - match_last = re_string_cur_idx (&mctx->input); - match = 1; - - /* We found a match, do not modify match_first below. */ - p_match_first = NULL; - if (!fl_longest_match) - break; - } - } - } - - if (p_match_first) - *p_match_first += next_start_idx; - - return match_last; -} - -/* Check NODE match the current context. */ - -static bool -internal_function -check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context) -{ - re_token_type_t type = dfa->nodes[node].type; - unsigned int constraint = dfa->nodes[node].constraint; - if (type != END_OF_RE) - return false; - if (!constraint) - return true; - if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context)) - return false; - return true; -} - -/* Check the halt state STATE match the current context. - Return 0 if not match, if the node, STATE has, is a halt node and - match the context, return the node. */ - -static Idx -internal_function -check_halt_state_context (const re_match_context_t *mctx, - const re_dfastate_t *state, Idx idx) -{ - Idx i; - unsigned int context; -#ifdef DEBUG - assert (state->halt); -#endif - context = re_string_context_at (&mctx->input, idx, mctx->eflags); - for (i = 0; i < state->nodes.nelem; ++i) - if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context)) - return state->nodes.elems[i]; - return 0; -} - -/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA - corresponding to the DFA). - Return the destination node, and update EPS_VIA_NODES; - return REG_MISSING in case of errors. */ - -static Idx -internal_function -proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, - Idx *pidx, Idx node, re_node_set *eps_via_nodes, - struct re_fail_stack_t *fs) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx i; - bool ok; - if (IS_EPSILON_NODE (dfa->nodes[node].type)) - { - re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; - re_node_set *edests = &dfa->edests[node]; - Idx dest_node; - ok = re_node_set_insert (eps_via_nodes, node); - if (BE (! ok, 0)) - return REG_ERROR; - /* Pick up a valid destination, or return REG_MISSING if none - is found. */ - for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i) - { - Idx candidate = edests->elems[i]; - if (!re_node_set_contains (cur_nodes, candidate)) - continue; - if (dest_node == REG_MISSING) - dest_node = candidate; - - else - { - /* In order to avoid infinite loop like "(a*)*", return the second - epsilon-transition if the first was already considered. */ - if (re_node_set_contains (eps_via_nodes, dest_node)) - return candidate; - - /* Otherwise, push the second epsilon-transition on the fail stack. */ - else if (fs != NULL - && push_fail_stack (fs, *pidx, candidate, nregs, regs, - eps_via_nodes)) - return REG_ERROR; - - /* We know we are going to exit. */ - break; - } - } - return dest_node; - } - else - { - Idx naccepted = 0; - re_token_type_t type = dfa->nodes[node].type; - -#ifdef RE_ENABLE_I18N - if (dfa->nodes[node].accept_mb) - naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx); - else -#endif /* RE_ENABLE_I18N */ - if (type == OP_BACK_REF) - { - Idx subexp_idx = dfa->nodes[node].opr.idx + 1; - naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; - if (fs != NULL) - { - if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1) - return REG_MISSING; - else if (naccepted) - { - char *buf = (char *) re_string_get_buffer (&mctx->input); - if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, - naccepted) != 0) - return REG_MISSING; - } - } - - if (naccepted == 0) - { - Idx dest_node; - ok = re_node_set_insert (eps_via_nodes, node); - if (BE (! ok, 0)) - return REG_ERROR; - dest_node = dfa->edests[node].elems[0]; - if (re_node_set_contains (&mctx->state_log[*pidx]->nodes, - dest_node)) - return dest_node; - } - } - - if (naccepted != 0 - || check_node_accept (mctx, dfa->nodes + node, *pidx)) - { - Idx dest_node = dfa->nexts[node]; - *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted; - if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL - || !re_node_set_contains (&mctx->state_log[*pidx]->nodes, - dest_node))) - return REG_MISSING; - re_node_set_empty (eps_via_nodes); - return dest_node; - } - } - return REG_MISSING; -} - -static reg_errcode_t -internal_function -push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, - Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) -{ - reg_errcode_t err; - Idx num = fs->num++; - if (fs->num == fs->alloc) - { - struct re_fail_stack_ent_t *new_array; - new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) - * fs->alloc * 2)); - if (new_array == NULL) - return REG_ESPACE; - fs->alloc *= 2; - fs->stack = new_array; - } - fs->stack[num].idx = str_idx; - fs->stack[num].node = dest_node; - fs->stack[num].regs = re_malloc (regmatch_t, nregs); - if (fs->stack[num].regs == NULL) - return REG_ESPACE; - memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); - err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); - return err; -} - -static Idx -internal_function -pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, - regmatch_t *regs, re_node_set *eps_via_nodes) -{ - Idx num = --fs->num; - assert (REG_VALID_INDEX (num)); - *pidx = fs->stack[num].idx; - memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); - re_node_set_free (eps_via_nodes); - re_free (fs->stack[num].regs); - *eps_via_nodes = fs->stack[num].eps_via_nodes; - return fs->stack[num].node; -} - -/* Set the positions where the subexpressions are starts/ends to registers - PMATCH. - Note: We assume that pmatch[0] is already set, and - pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */ - -static reg_errcode_t -internal_function -set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, - regmatch_t *pmatch, bool fl_backtrack) -{ - const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; - Idx idx, cur_node; - re_node_set eps_via_nodes; - struct re_fail_stack_t *fs; - struct re_fail_stack_t fs_body = { 0, 2, NULL }; - regmatch_t *prev_idx_match; - bool prev_idx_match_malloced = false; - -#ifdef DEBUG - assert (nmatch > 1); - assert (mctx->state_log != NULL); -#endif - if (fl_backtrack) - { - fs = &fs_body; - fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc); - if (fs->stack == NULL) - return REG_ESPACE; - } - else - fs = NULL; - - cur_node = dfa->init_node; - re_node_set_init_empty (&eps_via_nodes); - - if (__libc_use_alloca (nmatch * sizeof (regmatch_t))) - prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t)); - else - { - prev_idx_match = re_malloc (regmatch_t, nmatch); - if (prev_idx_match == NULL) - { - free_fail_stack_return (fs); - return REG_ESPACE; - } - prev_idx_match_malloced = true; - } - memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); - - for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) - { - update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); - - if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) - { - Idx reg_idx; - if (fs) - { - for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) - if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) - break; - if (reg_idx == nmatch) - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return free_fail_stack_return (fs); - } - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); - } - else - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return REG_NOERROR; - } - } - - /* Proceed to next node. */ - cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, - &eps_via_nodes, fs); - - if (BE (! REG_VALID_INDEX (cur_node), 0)) - { - if (BE (cur_node == REG_ERROR, 0)) - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - free_fail_stack_return (fs); - return REG_ESPACE; - } - if (fs) - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); - else - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return REG_NOMATCH; - } - } - } - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return free_fail_stack_return (fs); -} - -static reg_errcode_t -internal_function -free_fail_stack_return (struct re_fail_stack_t *fs) -{ - if (fs) - { - Idx fs_idx; - for (fs_idx = 0; fs_idx < fs->num; ++fs_idx) - { - re_node_set_free (&fs->stack[fs_idx].eps_via_nodes); - re_free (fs->stack[fs_idx].regs); - } - re_free (fs->stack); - } - return REG_NOERROR; -} - -static void -internal_function -update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, - regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch) -{ - int type = dfa->nodes[cur_node].type; - if (type == OP_OPEN_SUBEXP) - { - Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; - - /* We are at the first node of this sub expression. */ - if (reg_num < nmatch) - { - pmatch[reg_num].rm_so = cur_idx; - pmatch[reg_num].rm_eo = -1; - } - } - else if (type == OP_CLOSE_SUBEXP) - { - Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; - if (reg_num < nmatch) - { - /* We are at the last node of this sub expression. */ - if (pmatch[reg_num].rm_so < cur_idx) - { - pmatch[reg_num].rm_eo = cur_idx; - /* This is a non-empty match or we are not inside an optional - subexpression. Accept this right away. */ - memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); - } - else - { - if (dfa->nodes[cur_node].opt_subexp - && prev_idx_match[reg_num].rm_so != -1) - /* We transited through an empty match for an optional - subexpression, like (a?)*, and this is not the subexp's - first match. Copy back the old content of the registers - so that matches of an inner subexpression are undone as - well, like in ((a?))*. */ - memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch); - else - /* We completed a subexpression, but it may be part of - an optional one, so do not update PREV_IDX_MATCH. */ - pmatch[reg_num].rm_eo = cur_idx; - } - } - } -} - -/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0 - and sift the nodes in each states according to the following rules. - Updated state_log will be wrote to STATE_LOG. - - Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if... - 1. When STR_IDX == MATCH_LAST(the last index in the state_log): - If `a' isn't the LAST_NODE and `a' can't epsilon transit to - the LAST_NODE, we throw away the node `a'. - 2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts - string `s' and transit to `b': - i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw - away the node `a'. - ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is - thrown away, we throw away the node `a'. - 3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b': - i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the - node `a'. - ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away, - we throw away the node `a'. */ - -#define STATE_NODE_CONTAINS(state,node) \ - ((state) != NULL && re_node_set_contains (&(state)->nodes, node)) - -static reg_errcode_t -internal_function -sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) -{ - reg_errcode_t err; - int null_cnt = 0; - Idx str_idx = sctx->last_str_idx; - re_node_set cur_dest; - -#ifdef DEBUG - assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL); -#endif - - /* Build sifted state_log[str_idx]. It has the nodes which can epsilon - transit to the last_node and the last_node itself. */ - err = re_node_set_init_1 (&cur_dest, sctx->last_node); - if (BE (err != REG_NOERROR, 0)) - return err; - err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* Then check each states in the state_log. */ - while (str_idx > 0) - { - /* Update counters. */ - null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0; - if (null_cnt > mctx->max_mb_elem_len) - { - memset (sctx->sifted_states, '\0', - sizeof (re_dfastate_t *) * str_idx); - re_node_set_free (&cur_dest); - return REG_NOERROR; - } - re_node_set_empty (&cur_dest); - --str_idx; - - if (mctx->state_log[str_idx]) - { - err = build_sifted_states (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - - /* Add all the nodes which satisfy the following conditions: - - It can epsilon transit to a node in CUR_DEST. - - It is in CUR_SRC. - And update state_log. */ - err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - err = REG_NOERROR; - free_return: - re_node_set_free (&cur_dest); - return err; -} - -static reg_errcode_t -internal_function -build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx str_idx, re_node_set *cur_dest) -{ - const re_dfa_t *const dfa = mctx->dfa; - const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes; - Idx i; - - /* Then build the next sifted state. - We build the next sifted state on `cur_dest', and update - `sifted_states[str_idx]' with `cur_dest'. - Note: - `cur_dest' is the sifted state from `state_log[str_idx + 1]'. - `cur_src' points the node_set of the old `state_log[str_idx]' - (with the epsilon nodes pre-filtered out). */ - for (i = 0; i < cur_src->nelem; i++) - { - Idx prev_node = cur_src->elems[i]; - int naccepted = 0; - bool ok; - -#ifdef DEBUG - re_token_type_t type = dfa->nodes[prev_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N - /* If the node may accept `multi byte'. */ - if (dfa->nodes[prev_node].accept_mb) - naccepted = sift_states_iter_mb (mctx, sctx, prev_node, - str_idx, sctx->last_str_idx); -#endif /* RE_ENABLE_I18N */ - - /* We don't check backreferences here. - See update_cur_sifted_state(). */ - if (!naccepted - && check_node_accept (mctx, dfa->nodes + prev_node, str_idx) - && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1], - dfa->nexts[prev_node])) - naccepted = 1; - - if (naccepted == 0) - continue; - - if (sctx->limits.nelem) - { - Idx to_idx = str_idx + naccepted; - if (check_dst_limits (mctx, &sctx->limits, - dfa->nexts[prev_node], to_idx, - prev_node, str_idx)) - continue; - } - ok = re_node_set_insert (cur_dest, prev_node); - if (BE (! ok, 0)) - return REG_ESPACE; - } - - return REG_NOERROR; -} - -/* Helper functions. */ - -static reg_errcode_t -internal_function -clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) -{ - Idx top = mctx->state_log_top; - - if (next_state_log_idx >= mctx->input.bufs_len - || (next_state_log_idx >= mctx->input.valid_len - && mctx->input.valid_len < mctx->input.len)) - { - reg_errcode_t err; - err = extend_buffers (mctx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (top < next_state_log_idx) - { - memset (mctx->state_log + top + 1, '\0', - sizeof (re_dfastate_t *) * (next_state_log_idx - top)); - mctx->state_log_top = next_state_log_idx; - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, - re_dfastate_t **src, Idx num) -{ - Idx st_idx; - reg_errcode_t err; - for (st_idx = 0; st_idx < num; ++st_idx) - { - if (dst[st_idx] == NULL) - dst[st_idx] = src[st_idx]; - else if (src[st_idx] != NULL) - { - re_node_set merged_set; - err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes, - &src[st_idx]->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - dst[st_idx] = re_acquire_state (&err, dfa, &merged_set); - re_node_set_free (&merged_set); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -update_cur_sifted_state (const re_match_context_t *mctx, - re_sift_context_t *sctx, Idx str_idx, - re_node_set *dest_nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err = REG_NOERROR; - const re_node_set *candidates; - candidates = ((mctx->state_log[str_idx] == NULL) ? NULL - : &mctx->state_log[str_idx]->nodes); - - if (dest_nodes->nelem == 0) - sctx->sifted_states[str_idx] = NULL; - else - { - if (candidates) - { - /* At first, add the nodes which can epsilon transit to a node in - DEST_NODE. */ - err = add_epsilon_src_nodes (dfa, dest_nodes, candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* Then, check the limitations in the current sift_context. */ - if (sctx->limits.nelem) - { - err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits, - mctx->bkref_ents, str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - - sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (candidates && mctx->state_log[str_idx]->has_backref) - { - err = sift_states_bkref (mctx, sctx, str_idx, candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, - const re_node_set *candidates) -{ - reg_errcode_t err = REG_NOERROR; - Idx i; - - re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (!state->inveclosure.alloc) - { - err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - for (i = 0; i < dest_nodes->nelem; i++) - re_node_set_merge (&state->inveclosure, - dfa->inveclosures + dest_nodes->elems[i]); - } - return re_node_set_add_intersect (dest_nodes, candidates, - &state->inveclosure); -} - -static reg_errcode_t -internal_function -sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, - const re_node_set *candidates) -{ - Idx ecl_idx; - reg_errcode_t err; - re_node_set *inv_eclosure = dfa->inveclosures + node; - re_node_set except_nodes; - re_node_set_init_empty (&except_nodes); - for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) - { - Idx cur_node = inv_eclosure->elems[ecl_idx]; - if (cur_node == node) - continue; - if (IS_EPSILON_NODE (dfa->nodes[cur_node].type)) - { - Idx edst1 = dfa->edests[cur_node].elems[0]; - Idx edst2 = ((dfa->edests[cur_node].nelem > 1) - ? dfa->edests[cur_node].elems[1] : REG_MISSING); - if ((!re_node_set_contains (inv_eclosure, edst1) - && re_node_set_contains (dest_nodes, edst1)) - || (REG_VALID_NONZERO_INDEX (edst2) - && !re_node_set_contains (inv_eclosure, edst2) - && re_node_set_contains (dest_nodes, edst2))) - { - err = re_node_set_add_intersect (&except_nodes, candidates, - dfa->inveclosures + cur_node); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&except_nodes); - return err; - } - } - } - } - for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) - { - Idx cur_node = inv_eclosure->elems[ecl_idx]; - if (!re_node_set_contains (&except_nodes, cur_node)) - { - Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1; - re_node_set_remove_at (dest_nodes, idx); - } - } - re_node_set_free (&except_nodes); - return REG_NOERROR; -} - -static bool -internal_function -check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits, - Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx lim_idx, src_pos, dst_pos; - - Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx); - Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx); - for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) - { - Idx subexp_idx; - struct re_backref_cache_entry *ent; - ent = mctx->bkref_ents + limits->elems[lim_idx]; - subexp_idx = dfa->nodes[ent->node].opr.idx; - - dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], - subexp_idx, dst_node, dst_idx, - dst_bkref_idx); - src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], - subexp_idx, src_node, src_idx, - src_bkref_idx); - - /* In case of: - ( ) - ( ) - ( ) */ - if (src_pos == dst_pos) - continue; /* This is unrelated limitation. */ - else - return true; - } - return false; -} - -static int -internal_function -check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, - Idx subexp_idx, Idx from_node, Idx bkref_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - const re_node_set *eclosures = dfa->eclosures + from_node; - Idx node_idx; - - /* Else, we are on the boundary: examine the nodes on the epsilon - closure. */ - for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx) - { - Idx node = eclosures->elems[node_idx]; - switch (dfa->nodes[node].type) - { - case OP_BACK_REF: - if (bkref_idx != REG_MISSING) - { - struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx; - do - { - Idx dst; - int cpos; - - if (ent->node != node) - continue; - - if (subexp_idx < BITSET_WORD_BITS - && !(ent->eps_reachable_subexps_map - & ((bitset_word_t) 1 << subexp_idx))) - continue; - - /* Recurse trying to reach the OP_OPEN_SUBEXP and - OP_CLOSE_SUBEXP cases below. But, if the - destination node is the same node as the source - node, don't recurse because it would cause an - infinite loop: a regex that exhibits this behavior - is ()\1*\1* */ - dst = dfa->edests[node].elems[0]; - if (dst == from_node) - { - if (boundaries & 1) - return -1; - else /* if (boundaries & 2) */ - return 0; - } - - cpos = - check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, - dst, bkref_idx); - if (cpos == -1 /* && (boundaries & 1) */) - return -1; - if (cpos == 0 && (boundaries & 2)) - return 0; - - if (subexp_idx < BITSET_WORD_BITS) - ent->eps_reachable_subexps_map - &= ~((bitset_word_t) 1 << subexp_idx); - } - while (ent++->more); - } - break; - - case OP_OPEN_SUBEXP: - if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx) - return -1; - break; - - case OP_CLOSE_SUBEXP: - if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx) - return 0; - break; - - default: - break; - } - } - - return (boundaries & 2) ? 1 : 0; -} - -static int -internal_function -check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit, - Idx subexp_idx, Idx from_node, Idx str_idx, - Idx bkref_idx) -{ - struct re_backref_cache_entry *lim = mctx->bkref_ents + limit; - int boundaries; - - /* If we are outside the range of the subexpression, return -1 or 1. */ - if (str_idx < lim->subexp_from) - return -1; - - if (lim->subexp_to < str_idx) - return 1; - - /* If we are within the subexpression, return 0. */ - boundaries = (str_idx == lim->subexp_from); - boundaries |= (str_idx == lim->subexp_to) << 1; - if (boundaries == 0) - return 0; - - /* Else, examine epsilon closure. */ - return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, - from_node, bkref_idx); -} - -/* Check the limitations of sub expressions LIMITS, and remove the nodes - which are against limitations from DEST_NODES. */ - -static reg_errcode_t -internal_function -check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, - const re_node_set *candidates, re_node_set *limits, - struct re_backref_cache_entry *bkref_ents, Idx str_idx) -{ - reg_errcode_t err; - Idx node_idx, lim_idx; - - for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) - { - Idx subexp_idx; - struct re_backref_cache_entry *ent; - ent = bkref_ents + limits->elems[lim_idx]; - - if (str_idx <= ent->subexp_from || ent->str_idx < str_idx) - continue; /* This is unrelated limitation. */ - - subexp_idx = dfa->nodes[ent->node].opr.idx; - if (ent->subexp_to == str_idx) - { - Idx ops_node = REG_MISSING; - Idx cls_node = REG_MISSING; - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - Idx node = dest_nodes->elems[node_idx]; - re_token_type_t type = dfa->nodes[node].type; - if (type == OP_OPEN_SUBEXP - && subexp_idx == dfa->nodes[node].opr.idx) - ops_node = node; - else if (type == OP_CLOSE_SUBEXP - && subexp_idx == dfa->nodes[node].opr.idx) - cls_node = node; - } - - /* Check the limitation of the open subexpression. */ - /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */ - if (REG_VALID_INDEX (ops_node)) - { - err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - /* Check the limitation of the close subexpression. */ - if (REG_VALID_INDEX (cls_node)) - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - Idx node = dest_nodes->elems[node_idx]; - if (!re_node_set_contains (dfa->inveclosures + node, - cls_node) - && !re_node_set_contains (dfa->eclosures + node, - cls_node)) - { - /* It is against this limitation. - Remove it form the current sifted state. */ - err = sub_epsilon_src_nodes (dfa, node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - --node_idx; - } - } - } - else /* (ent->subexp_to != str_idx) */ - { - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - Idx node = dest_nodes->elems[node_idx]; - re_token_type_t type = dfa->nodes[node].type; - if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP) - { - if (subexp_idx != dfa->nodes[node].opr.idx) - continue; - /* It is against this limitation. - Remove it form the current sifted state. */ - err = sub_epsilon_src_nodes (dfa, node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx str_idx, const re_node_set *candidates) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx node_idx, node; - re_sift_context_t local_sctx; - Idx first_idx = search_cur_bkref_entry (mctx, str_idx); - - if (first_idx == REG_MISSING) - return REG_NOERROR; - - local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */ - - for (node_idx = 0; node_idx < candidates->nelem; ++node_idx) - { - Idx enabled_idx; - re_token_type_t type; - struct re_backref_cache_entry *entry; - node = candidates->elems[node_idx]; - type = dfa->nodes[node].type; - /* Avoid infinite loop for the REs like "()\1+". */ - if (node == sctx->last_node && str_idx == sctx->last_str_idx) - continue; - if (type != OP_BACK_REF) - continue; - - entry = mctx->bkref_ents + first_idx; - enabled_idx = first_idx; - do - { - Idx subexp_len; - Idx to_idx; - Idx dst_node; - bool ok; - re_dfastate_t *cur_state; - - if (entry->node != node) - continue; - subexp_len = entry->subexp_to - entry->subexp_from; - to_idx = str_idx + subexp_len; - dst_node = (subexp_len ? dfa->nexts[node] - : dfa->edests[node].elems[0]); - - if (to_idx > sctx->last_str_idx - || sctx->sifted_states[to_idx] == NULL - || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node) - || check_dst_limits (mctx, &sctx->limits, node, - str_idx, dst_node, to_idx)) - continue; - - if (local_sctx.sifted_states == NULL) - { - local_sctx = *sctx; - err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - local_sctx.last_node = node; - local_sctx.last_str_idx = str_idx; - ok = re_node_set_insert (&local_sctx.limits, enabled_idx); - if (BE (! ok, 0)) - { - err = REG_ESPACE; - goto free_return; - } - cur_state = local_sctx.sifted_states[str_idx]; - err = sift_states_backward (mctx, &local_sctx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - if (sctx->limited_states != NULL) - { - err = merge_state_array (dfa, sctx->limited_states, - local_sctx.sifted_states, - str_idx + 1); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - local_sctx.sifted_states[str_idx] = cur_state; - re_node_set_remove (&local_sctx.limits, enabled_idx); - - /* mctx->bkref_ents may have changed, reload the pointer. */ - entry = mctx->bkref_ents + enabled_idx; - } - while (enabled_idx++, entry++->more); - } - err = REG_NOERROR; - free_return: - if (local_sctx.sifted_states != NULL) - { - re_node_set_free (&local_sctx.limits); - } - - return err; -} - - -#ifdef RE_ENABLE_I18N -static int -internal_function -sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx node_idx, Idx str_idx, Idx max_str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - int naccepted; - /* Check the node can accept `multi byte'. */ - naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx); - if (naccepted > 0 && str_idx + naccepted <= max_str_idx && - !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted], - dfa->nexts[node_idx])) - /* The node can't accept the `multi byte', or the - destination was already thrown away, then the node - could't accept the current input `multi byte'. */ - naccepted = 0; - /* Otherwise, it is sure that the node could accept - `naccepted' bytes input. */ - return naccepted; -} -#endif /* RE_ENABLE_I18N */ - - -/* Functions for state transition. */ - -/* Return the next state to which the current state STATE will transit by - accepting the current input byte, and update STATE_LOG if necessary. - If STATE can accept a multibyte char/collating element/back reference - update the destination of STATE_LOG. */ - -static re_dfastate_t * -internal_function -transit_state (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *state) -{ - re_dfastate_t **trtable; - unsigned char ch; - -#ifdef RE_ENABLE_I18N - /* If the current state can accept multibyte. */ - if (BE (state->accept_mb, 0)) - { - *err = transit_state_mb (mctx, state); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } -#endif /* RE_ENABLE_I18N */ - - /* Then decide the next state with the single byte. */ -#if 0 - if (0) - /* don't use transition table */ - return transit_state_sb (err, mctx, state); -#endif - - /* Use transition table */ - ch = re_string_fetch_byte (&mctx->input); - for (;;) - { - trtable = state->trtable; - if (BE (trtable != NULL, 1)) - return trtable[ch]; - - trtable = state->word_trtable; - if (BE (trtable != NULL, 1)) - { - unsigned int context; - context - = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input) - 1, - mctx->eflags); - if (IS_WORD_CONTEXT (context)) - return trtable[ch + SBC_MAX]; - else - return trtable[ch]; - } - - if (!build_trtable (mctx->dfa, state)) - { - *err = REG_ESPACE; - return NULL; - } - - /* Retry, we now have a transition table. */ - } -} - -/* Update the state_log if we need */ -static re_dfastate_t * -internal_function -merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *next_state) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx cur_idx = re_string_cur_idx (&mctx->input); - - if (cur_idx > mctx->state_log_top) - { - mctx->state_log[cur_idx] = next_state; - mctx->state_log_top = cur_idx; - } - else if (mctx->state_log[cur_idx] == 0) - { - mctx->state_log[cur_idx] = next_state; - } - else - { - re_dfastate_t *pstate; - unsigned int context; - re_node_set next_nodes, *log_nodes, *table_nodes = NULL; - /* If (state_log[cur_idx] != 0), it implies that cur_idx is - the destination of a multibyte char/collating element/ - back reference. Then the next state is the union set of - these destinations and the results of the transition table. */ - pstate = mctx->state_log[cur_idx]; - log_nodes = pstate->entrance_nodes; - if (next_state != NULL) - { - table_nodes = next_state->entrance_nodes; - *err = re_node_set_init_union (&next_nodes, table_nodes, - log_nodes); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } - else - next_nodes = *log_nodes; - /* Note: We already add the nodes of the initial state, - then we don't need to add them here. */ - - context = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input) - 1, - mctx->eflags); - next_state = mctx->state_log[cur_idx] - = re_acquire_state_context (err, dfa, &next_nodes, context); - /* We don't need to check errors here, since the return value of - this function is next_state and ERR is already set. */ - - if (table_nodes != NULL) - re_node_set_free (&next_nodes); - } - - if (BE (dfa->nbackref, 0) && next_state != NULL) - { - /* Check OP_OPEN_SUBEXP in the current state in case that we use them - later. We must check them here, since the back references in the - next state might use them. */ - *err = check_subexp_matching_top (mctx, &next_state->nodes, - cur_idx); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - - /* If the next state has back references. */ - if (next_state->has_backref) - { - *err = transit_state_bkref (mctx, &next_state->nodes); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - next_state = mctx->state_log[cur_idx]; - } - } - - return next_state; -} - -/* Skip bytes in the input that correspond to part of a - multi-byte match, then look in the log for a state - from which to restart matching. */ -static re_dfastate_t * -internal_function -find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) -{ - re_dfastate_t *cur_state; - do - { - Idx max = mctx->state_log_top; - Idx cur_str_idx = re_string_cur_idx (&mctx->input); - - do - { - if (++cur_str_idx > max) - return NULL; - re_string_skip_bytes (&mctx->input, 1); - } - while (mctx->state_log[cur_str_idx] == NULL); - - cur_state = merge_state_with_log (err, mctx, NULL); - } - while (*err == REG_NOERROR && cur_state == NULL); - return cur_state; -} - -/* Helper functions for transit_state. */ - -/* From the node set CUR_NODES, pick up the nodes whose types are - OP_OPEN_SUBEXP and which have corresponding back references in the regular - expression. And register them to use them later for evaluating the - correspoding back references. */ - -static reg_errcode_t -internal_function -check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, - Idx str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx node_idx; - reg_errcode_t err; - - /* TODO: This isn't efficient. - Because there might be more than one nodes whose types are - OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all - nodes. - E.g. RE: (a){2} */ - for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx) - { - Idx node = cur_nodes->elems[node_idx]; - if (dfa->nodes[node].type == OP_OPEN_SUBEXP - && dfa->nodes[node].opr.idx < BITSET_WORD_BITS - && (dfa->used_bkref_map - & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx))) - { - err = match_ctx_add_subtop (mctx, node, str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - return REG_NOERROR; -} - -#if 0 -/* Return the next state to which the current state STATE will transit by - accepting the current input byte. */ - -static re_dfastate_t * -transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *state) -{ - const re_dfa_t *const dfa = mctx->dfa; - re_node_set next_nodes; - re_dfastate_t *next_state; - Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input); - unsigned int context; - - *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt) - { - Idx cur_node = state->nodes.elems[node_cnt]; - if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx)) - { - *err = re_node_set_merge (&next_nodes, - dfa->eclosures + dfa->nexts[cur_node]); - if (BE (*err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return NULL; - } - } - } - context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags); - next_state = re_acquire_state_context (err, dfa, &next_nodes, context); - /* We don't need to check errors here, since the return value of - this function is next_state and ERR is already set. */ - - re_node_set_free (&next_nodes); - re_string_skip_bytes (&mctx->input, 1); - return next_state; -} -#endif - -#ifdef RE_ENABLE_I18N -static reg_errcode_t -internal_function -transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx i; - - for (i = 0; i < pstate->nodes.nelem; ++i) - { - re_node_set dest_nodes, *new_nodes; - Idx cur_node_idx = pstate->nodes.elems[i]; - int naccepted; - Idx dest_idx; - unsigned int context; - re_dfastate_t *dest_state; - - if (!dfa->nodes[cur_node_idx].accept_mb) - continue; - - if (dfa->nodes[cur_node_idx].constraint) - { - context = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input), - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint, - context)) - continue; - } - - /* How many bytes the node can accept? */ - naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input, - re_string_cur_idx (&mctx->input)); - if (naccepted == 0) - continue; - - /* The node can accepts `naccepted' bytes. */ - dest_idx = re_string_cur_idx (&mctx->input) + naccepted; - mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted - : mctx->max_mb_elem_len); - err = clean_state_log_if_needed (mctx, dest_idx); - if (BE (err != REG_NOERROR, 0)) - return err; -#ifdef DEBUG - assert (dfa->nexts[cur_node_idx] != REG_MISSING); -#endif - new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx]; - - dest_state = mctx->state_log[dest_idx]; - if (dest_state == NULL) - dest_nodes = *new_nodes; - else - { - err = re_node_set_init_union (&dest_nodes, - dest_state->entrance_nodes, new_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - context = re_string_context_at (&mctx->input, dest_idx - 1, - mctx->eflags); - mctx->state_log[dest_idx] - = re_acquire_state_context (&err, dfa, &dest_nodes, context); - if (dest_state != NULL) - re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0)) - return err; - } - return REG_NOERROR; -} -#endif /* RE_ENABLE_I18N */ - -static reg_errcode_t -internal_function -transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx i; - Idx cur_str_idx = re_string_cur_idx (&mctx->input); - - for (i = 0; i < nodes->nelem; ++i) - { - Idx dest_str_idx, prev_nelem, bkc_idx; - Idx node_idx = nodes->elems[i]; - unsigned int context; - const re_token_t *node = dfa->nodes + node_idx; - re_node_set *new_dest_nodes; - - /* Check whether `node' is a backreference or not. */ - if (node->type != OP_BACK_REF) - continue; - - if (node->constraint) - { - context = re_string_context_at (&mctx->input, cur_str_idx, - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) - continue; - } - - /* `node' is a backreference. - Check the substring which the substring matched. */ - bkc_idx = mctx->nbkref_ents; - err = get_subexp (mctx, node_idx, cur_str_idx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* And add the epsilon closures (which is `new_dest_nodes') of - the backreference to appropriate state_log. */ -#ifdef DEBUG - assert (dfa->nexts[node_idx] != REG_MISSING); -#endif - for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx) - { - Idx subexp_len; - re_dfastate_t *dest_state; - struct re_backref_cache_entry *bkref_ent; - bkref_ent = mctx->bkref_ents + bkc_idx; - if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx) - continue; - subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from; - new_dest_nodes = (subexp_len == 0 - ? dfa->eclosures + dfa->edests[node_idx].elems[0] - : dfa->eclosures + dfa->nexts[node_idx]); - dest_str_idx = (cur_str_idx + bkref_ent->subexp_to - - bkref_ent->subexp_from); - context = re_string_context_at (&mctx->input, dest_str_idx - 1, - mctx->eflags); - dest_state = mctx->state_log[dest_str_idx]; - prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0 - : mctx->state_log[cur_str_idx]->nodes.nelem); - /* Add `new_dest_node' to state_log. */ - if (dest_state == NULL) - { - mctx->state_log[dest_str_idx] - = re_acquire_state_context (&err, dfa, new_dest_nodes, - context); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) - goto free_return; - } - else - { - re_node_set dest_nodes; - err = re_node_set_init_union (&dest_nodes, - dest_state->entrance_nodes, - new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&dest_nodes); - goto free_return; - } - mctx->state_log[dest_str_idx] - = re_acquire_state_context (&err, dfa, &dest_nodes, context); - re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) - goto free_return; - } - /* We need to check recursively if the backreference can epsilon - transit. */ - if (subexp_len == 0 - && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem) - { - err = check_subexp_matching_top (mctx, new_dest_nodes, - cur_str_idx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - err = transit_state_bkref (mctx, new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - } - } - err = REG_NOERROR; - free_return: - return err; -} - -/* Enumerate all the candidates which the backreference BKREF_NODE can match - at BKREF_STR_IDX, and register them by match_ctx_add_entry(). - Note that we might collect inappropriate candidates here. - However, the cost of checking them strictly here is too high, then we - delay these checking for prune_impossible_nodes(). */ - -static reg_errcode_t -internal_function -get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx subexp_num, sub_top_idx; - const char *buf = (const char *) re_string_get_buffer (&mctx->input); - /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX. */ - Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx); - if (cache_idx != REG_MISSING) - { - const struct re_backref_cache_entry *entry - = mctx->bkref_ents + cache_idx; - do - if (entry->node == bkref_node) - return REG_NOERROR; /* We already checked it. */ - while (entry++->more); - } - - subexp_num = dfa->nodes[bkref_node].opr.idx; - - /* For each sub expression */ - for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx) - { - reg_errcode_t err; - re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx]; - re_sub_match_last_t *sub_last; - Idx sub_last_idx, sl_str, bkref_str_off; - - if (dfa->nodes[sub_top->node].opr.idx != subexp_num) - continue; /* It isn't related. */ - - sl_str = sub_top->str_idx; - bkref_str_off = bkref_str_idx; - /* At first, check the last node of sub expressions we already - evaluated. */ - for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx) - { - regoff_t sl_str_diff; - sub_last = sub_top->lasts[sub_last_idx]; - sl_str_diff = sub_last->str_idx - sl_str; - /* The matched string by the sub expression match with the substring - at the back reference? */ - if (sl_str_diff > 0) - { - if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0)) - { - /* Not enough chars for a successful match. */ - if (bkref_str_off + sl_str_diff > mctx->input.len) - break; - - err = clean_state_log_if_needed (mctx, - bkref_str_off - + sl_str_diff); - if (BE (err != REG_NOERROR, 0)) - return err; - buf = (const char *) re_string_get_buffer (&mctx->input); - } - if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0) - /* We don't need to search this sub expression any more. */ - break; - } - bkref_str_off += sl_str_diff; - sl_str += sl_str_diff; - err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, - bkref_str_idx); - - /* Reload buf, since the preceding call might have reallocated - the buffer. */ - buf = (const char *) re_string_get_buffer (&mctx->input); - - if (err == REG_NOMATCH) - continue; - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (sub_last_idx < sub_top->nlasts) - continue; - if (sub_last_idx > 0) - ++sl_str; - /* Then, search for the other last nodes of the sub expression. */ - for (; sl_str <= bkref_str_idx; ++sl_str) - { - Idx cls_node; - regoff_t sl_str_off; - const re_node_set *nodes; - sl_str_off = sl_str - sub_top->str_idx; - /* The matched string by the sub expression match with the substring - at the back reference? */ - if (sl_str_off > 0) - { - if (BE (bkref_str_off >= mctx->input.valid_len, 0)) - { - /* If we are at the end of the input, we cannot match. */ - if (bkref_str_off >= mctx->input.len) - break; - - err = extend_buffers (mctx); - if (BE (err != REG_NOERROR, 0)) - return err; - - buf = (const char *) re_string_get_buffer (&mctx->input); - } - if (buf [bkref_str_off++] != buf[sl_str - 1]) - break; /* We don't need to search this sub expression - any more. */ - } - if (mctx->state_log[sl_str] == NULL) - continue; - /* Does this state have a ')' of the sub expression? */ - nodes = &mctx->state_log[sl_str]->nodes; - cls_node = find_subexp_node (dfa, nodes, subexp_num, - OP_CLOSE_SUBEXP); - if (cls_node == REG_MISSING) - continue; /* No. */ - if (sub_top->path == NULL) - { - sub_top->path = calloc (sizeof (state_array_t), - sl_str - sub_top->str_idx + 1); - if (sub_top->path == NULL) - return REG_ESPACE; - } - /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node - in the current context? */ - err = check_arrival (mctx, sub_top->path, sub_top->node, - sub_top->str_idx, cls_node, sl_str, - OP_CLOSE_SUBEXP); - if (err == REG_NOMATCH) - continue; - if (BE (err != REG_NOERROR, 0)) - return err; - sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str); - if (BE (sub_last == NULL, 0)) - return REG_ESPACE; - err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, - bkref_str_idx); - if (err == REG_NOMATCH) - continue; - } - } - return REG_NOERROR; -} - -/* Helper functions for get_subexp(). */ - -/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR. - If it can arrive, register the sub expression expressed with SUB_TOP - and SUB_LAST. */ - -static reg_errcode_t -internal_function -get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, - re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str) -{ - reg_errcode_t err; - Idx to_idx; - /* Can the subexpression arrive the back reference? */ - err = check_arrival (mctx, &sub_last->path, sub_last->node, - sub_last->str_idx, bkref_node, bkref_str, - OP_OPEN_SUBEXP); - if (err != REG_NOERROR) - return err; - err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx, - sub_last->str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx; - return clean_state_log_if_needed (mctx, to_idx); -} - -/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX. - Search '(' if FL_OPEN, or search ')' otherwise. - TODO: This function isn't efficient... - Because there might be more than one nodes whose types are - OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all - nodes. - E.g. RE: (a){2} */ - -static Idx -internal_function -find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, - Idx subexp_idx, int type) -{ - Idx cls_idx; - for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx) - { - Idx cls_node = nodes->elems[cls_idx]; - const re_token_t *node = dfa->nodes + cls_node; - if (node->type == type - && node->opr.idx == subexp_idx) - return cls_node; - } - return REG_MISSING; -} - -/* Check whether the node TOP_NODE at TOP_STR can arrive to the node - LAST_NODE at LAST_STR. We record the path onto PATH since it will be - heavily reused. - Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ - -static reg_errcode_t -internal_function -check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, - Idx top_str, Idx last_node, Idx last_str, int type) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err = REG_NOERROR; - Idx subexp_num, backup_cur_idx, str_idx, null_cnt; - re_dfastate_t *cur_state = NULL; - re_node_set *cur_nodes, next_nodes; - re_dfastate_t **backup_state_log; - unsigned int context; - - subexp_num = dfa->nodes[top_node].opr.idx; - /* Extend the buffer if we need. */ - if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0)) - { - re_dfastate_t **new_array; - Idx old_alloc = path->alloc; - Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1; - if (BE (new_alloc < old_alloc, 0) - || BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0)) - return REG_ESPACE; - new_array = re_realloc (path->array, re_dfastate_t *, new_alloc); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - path->array = new_array; - path->alloc = new_alloc; - memset (new_array + old_alloc, '\0', - sizeof (re_dfastate_t *) * (path->alloc - old_alloc)); - } - - str_idx = path->next_idx ? path->next_idx : top_str; - - /* Temporary modify MCTX. */ - backup_state_log = mctx->state_log; - backup_cur_idx = mctx->input.cur_idx; - mctx->state_log = path->array; - mctx->input.cur_idx = str_idx; - - /* Setup initial node set. */ - context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); - if (str_idx == top_str) - { - err = re_node_set_init_1 (&next_nodes, top_node); - if (BE (err != REG_NOERROR, 0)) - return err; - err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - else - { - cur_state = mctx->state_log[str_idx]; - if (cur_state && cur_state->has_backref) - { - err = re_node_set_init_copy (&next_nodes, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - re_node_set_init_empty (&next_nodes); - } - if (str_idx == top_str || (cur_state && cur_state->has_backref)) - { - if (next_nodes.nelem) - { - err = expand_bkref_cache (mctx, &next_nodes, str_idx, - subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - mctx->state_log[str_idx] = cur_state; - } - - for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) - { - re_node_set_empty (&next_nodes); - if (mctx->state_log[str_idx + 1]) - { - err = re_node_set_merge (&next_nodes, - &mctx->state_log[str_idx + 1]->nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - if (cur_state) - { - err = check_arrival_add_next_nodes (mctx, str_idx, - &cur_state->non_eps_nodes, - &next_nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - ++str_idx; - if (next_nodes.nelem) - { - err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - err = expand_bkref_cache (mctx, &next_nodes, str_idx, - subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); - cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - mctx->state_log[str_idx] = cur_state; - null_cnt = cur_state == NULL ? null_cnt + 1 : 0; - } - re_node_set_free (&next_nodes); - cur_nodes = (mctx->state_log[last_str] == NULL ? NULL - : &mctx->state_log[last_str]->nodes); - path->next_idx = str_idx; - - /* Fix MCTX. */ - mctx->state_log = backup_state_log; - mctx->input.cur_idx = backup_cur_idx; - - /* Then check the current node set has the node LAST_NODE. */ - if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node)) - return REG_NOERROR; - - return REG_NOMATCH; -} - -/* Helper functions for check_arrival. */ - -/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them - to NEXT_NODES. - TODO: This function is similar to the functions transit_state*(), - however this function has many additional works. - Can't we unify them? */ - -static reg_errcode_t -internal_function -check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, - re_node_set *cur_nodes, re_node_set *next_nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - bool ok; - Idx cur_idx; - reg_errcode_t err = REG_NOERROR; - re_node_set union_set; - re_node_set_init_empty (&union_set); - for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx) - { - int naccepted = 0; - Idx cur_node = cur_nodes->elems[cur_idx]; -#ifdef DEBUG - re_token_type_t type = dfa->nodes[cur_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N - /* If the node may accept `multi byte'. */ - if (dfa->nodes[cur_node].accept_mb) - { - naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input, - str_idx); - if (naccepted > 1) - { - re_dfastate_t *dest_state; - Idx next_node = dfa->nexts[cur_node]; - Idx next_idx = str_idx + naccepted; - dest_state = mctx->state_log[next_idx]; - re_node_set_empty (&union_set); - if (dest_state) - { - err = re_node_set_merge (&union_set, &dest_state->nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&union_set); - return err; - } - } - ok = re_node_set_insert (&union_set, next_node); - if (BE (! ok, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } - mctx->state_log[next_idx] = re_acquire_state (&err, dfa, - &union_set); - if (BE (mctx->state_log[next_idx] == NULL - && err != REG_NOERROR, 0)) - { - re_node_set_free (&union_set); - return err; - } - } - } -#endif /* RE_ENABLE_I18N */ - if (naccepted - || check_node_accept (mctx, dfa->nodes + cur_node, str_idx)) - { - ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]); - if (BE (! ok, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } - } - } - re_node_set_free (&union_set); - return REG_NOERROR; -} - -/* For all the nodes in CUR_NODES, add the epsilon closures of them to - CUR_NODES, however exclude the nodes which are: - - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN. - - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN. -*/ - -static reg_errcode_t -internal_function -check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, - Idx ex_subexp, int type) -{ - reg_errcode_t err; - Idx idx, outside_node; - re_node_set new_nodes; -#ifdef DEBUG - assert (cur_nodes->nelem); -#endif - err = re_node_set_alloc (&new_nodes, cur_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) - return err; - /* Create a new node set NEW_NODES with the nodes which are epsilon - closures of the node in CUR_NODES. */ - - for (idx = 0; idx < cur_nodes->nelem; ++idx) - { - Idx cur_node = cur_nodes->elems[idx]; - const re_node_set *eclosure = dfa->eclosures + cur_node; - outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type); - if (outside_node == REG_MISSING) - { - /* There are no problematic nodes, just merge them. */ - err = re_node_set_merge (&new_nodes, eclosure); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&new_nodes); - return err; - } - } - else - { - /* There are problematic nodes, re-calculate incrementally. */ - err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node, - ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&new_nodes); - return err; - } - } - } - re_node_set_free (cur_nodes); - *cur_nodes = new_nodes; - return REG_NOERROR; -} - -/* Helper function for check_arrival_expand_ecl. - Check incrementally the epsilon closure of TARGET, and if it isn't - problematic append it to DST_NODES. */ - -static reg_errcode_t -internal_function -check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, - Idx target, Idx ex_subexp, int type) -{ - Idx cur_node; - for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);) - { - bool ok; - - if (dfa->nodes[cur_node].type == type - && dfa->nodes[cur_node].opr.idx == ex_subexp) - { - if (type == OP_CLOSE_SUBEXP) - { - ok = re_node_set_insert (dst_nodes, cur_node); - if (BE (! ok, 0)) - return REG_ESPACE; - } - break; - } - ok = re_node_set_insert (dst_nodes, cur_node); - if (BE (! ok, 0)) - return REG_ESPACE; - if (dfa->edests[cur_node].nelem == 0) - break; - if (dfa->edests[cur_node].nelem == 2) - { - reg_errcode_t err; - err = check_arrival_expand_ecl_sub (dfa, dst_nodes, - dfa->edests[cur_node].elems[1], - ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) - return err; - } - cur_node = dfa->edests[cur_node].elems[0]; - } - return REG_NOERROR; -} - - -/* For all the back references in the current state, calculate the - destination of the back references by the appropriate entry - in MCTX->BKREF_ENTS. */ - -static reg_errcode_t -internal_function -expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, - Idx cur_str, Idx subexp_num, int type) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str); - struct re_backref_cache_entry *ent; - - if (cache_idx_start == REG_MISSING) - return REG_NOERROR; - - restart: - ent = mctx->bkref_ents + cache_idx_start; - do - { - Idx to_idx, next_node; - - /* Is this entry ENT is appropriate? */ - if (!re_node_set_contains (cur_nodes, ent->node)) - continue; /* No. */ - - to_idx = cur_str + ent->subexp_to - ent->subexp_from; - /* Calculate the destination of the back reference, and append it - to MCTX->STATE_LOG. */ - if (to_idx == cur_str) - { - /* The backreference did epsilon transit, we must re-check all the - node in the current state. */ - re_node_set new_dests; - reg_errcode_t err2, err3; - next_node = dfa->edests[ent->node].elems[0]; - if (re_node_set_contains (cur_nodes, next_node)) - continue; - err = re_node_set_init_1 (&new_dests, next_node); - err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type); - err3 = re_node_set_merge (cur_nodes, &new_dests); - re_node_set_free (&new_dests); - if (BE (err != REG_NOERROR || err2 != REG_NOERROR - || err3 != REG_NOERROR, 0)) - { - err = (err != REG_NOERROR ? err - : (err2 != REG_NOERROR ? err2 : err3)); - return err; - } - /* TODO: It is still inefficient... */ - goto restart; - } - else - { - re_node_set union_set; - next_node = dfa->nexts[ent->node]; - if (mctx->state_log[to_idx]) - { - bool ok; - if (re_node_set_contains (&mctx->state_log[to_idx]->nodes, - next_node)) - continue; - err = re_node_set_init_copy (&union_set, - &mctx->state_log[to_idx]->nodes); - ok = re_node_set_insert (&union_set, next_node); - if (BE (err != REG_NOERROR || ! ok, 0)) - { - re_node_set_free (&union_set); - err = err != REG_NOERROR ? err : REG_ESPACE; - return err; - } - } - else - { - err = re_node_set_init_1 (&union_set, next_node); - if (BE (err != REG_NOERROR, 0)) - return err; - } - mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set); - re_node_set_free (&union_set); - if (BE (mctx->state_log[to_idx] == NULL - && err != REG_NOERROR, 0)) - return err; - } - } - while (ent++->more); - return REG_NOERROR; -} - -/* Build transition table for the state. - Return true if successful. */ - -static bool -internal_function -build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) -{ - reg_errcode_t err; - Idx i, j; - int ch; - bool need_word_trtable = false; - bitset_word_t elem, mask; - bool dests_node_malloced = false; - bool dest_states_malloced = false; - Idx ndests; /* Number of the destination states from `state'. */ - re_dfastate_t **trtable; - re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; - re_node_set follows, *dests_node; - bitset_t *dests_ch; - bitset_t acceptable; - - struct dests_alloc - { - re_node_set dests_node[SBC_MAX]; - bitset_t dests_ch[SBC_MAX]; - } *dests_alloc; - - /* We build DFA states which corresponds to the destination nodes - from `state'. `dests_node[i]' represents the nodes which i-th - destination state contains, and `dests_ch[i]' represents the - characters which i-th destination state accepts. */ - if (__libc_use_alloca (sizeof (struct dests_alloc))) - dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc)); - else - { - dests_alloc = re_malloc (struct dests_alloc, 1); - if (BE (dests_alloc == NULL, 0)) - return false; - dests_node_malloced = true; - } - dests_node = dests_alloc->dests_node; - dests_ch = dests_alloc->dests_ch; - - /* Initialize transiton table. */ - state->word_trtable = state->trtable = NULL; - - /* At first, group all nodes belonging to `state' into several - destinations. */ - ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); - if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0)) - { - if (dests_node_malloced) - free (dests_alloc); - if (ndests == 0) - { - state->trtable = (re_dfastate_t **) - calloc (sizeof (re_dfastate_t *), SBC_MAX); - return true; - } - return false; - } - - err = re_node_set_alloc (&follows, ndests + 1); - if (BE (err != REG_NOERROR, 0)) - goto out_free; - - /* Avoid arithmetic overflow in size calculation. */ - if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX) - / (3 * sizeof (re_dfastate_t *))) - < ndests), - 0)) - goto out_free; - - if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX - + ndests * 3 * sizeof (re_dfastate_t *))) - dest_states = (re_dfastate_t **) - alloca (ndests * 3 * sizeof (re_dfastate_t *)); - else - { - dest_states = (re_dfastate_t **) - malloc (ndests * 3 * sizeof (re_dfastate_t *)); - if (BE (dest_states == NULL, 0)) - { -out_free: - if (dest_states_malloced) - free (dest_states); - re_node_set_free (&follows); - for (i = 0; i < ndests; ++i) - re_node_set_free (dests_node + i); - if (dests_node_malloced) - free (dests_alloc); - return false; - } - dest_states_malloced = true; - } - dest_states_word = dest_states + ndests; - dest_states_nl = dest_states_word + ndests; - bitset_empty (acceptable); - - /* Then build the states for all destinations. */ - for (i = 0; i < ndests; ++i) - { - Idx next_node; - re_node_set_empty (&follows); - /* Merge the follows of this destination states. */ - for (j = 0; j < dests_node[i].nelem; ++j) - { - next_node = dfa->nexts[dests_node[i].elems[j]]; - if (next_node != REG_MISSING) - { - err = re_node_set_merge (&follows, dfa->eclosures + next_node); - if (BE (err != REG_NOERROR, 0)) - goto out_free; - } - } - dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0); - if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - /* If the new state has context constraint, - build appropriate states for these contexts. */ - if (dest_states[i]->has_constraint) - { - dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows, - CONTEXT_WORD); - if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - - if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1) - need_word_trtable = true; - - dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, - CONTEXT_NEWLINE); - if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - } - else - { - dest_states_word[i] = dest_states[i]; - dest_states_nl[i] = dest_states[i]; - } - bitset_merge (acceptable, dests_ch[i]); - } - - if (!BE (need_word_trtable, 0)) - { - /* We don't care about whether the following character is a word - character, or we are in a single-byte character set so we can - discern by looking at the character code: allocate a - 256-entry transition table. */ - trtable = state->trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); - if (BE (trtable == NULL, 0)) - goto out_free; - - /* For all characters ch...: */ - for (i = 0; i < BITSET_WORDS; ++i) - for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; - elem; - mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) - { - /* There must be exactly one destination which accepts - character ch. See group_nodes_into_DFAstates. */ - for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) - ; - - /* j-th destination accepts the word character ch. */ - if (dfa->word_char[i] & mask) - trtable[ch] = dest_states_word[j]; - else - trtable[ch] = dest_states[j]; - } - } - else - { - /* We care about whether the following character is a word - character, and we are in a multi-byte character set: discern - by looking at the character code: build two 256-entry - transition tables, one starting at trtable[0] and one - starting at trtable[SBC_MAX]. */ - trtable = state->word_trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); - if (BE (trtable == NULL, 0)) - goto out_free; - - /* For all characters ch...: */ - for (i = 0; i < BITSET_WORDS; ++i) - for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; - elem; - mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) - { - /* There must be exactly one destination which accepts - character ch. See group_nodes_into_DFAstates. */ - for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) - ; - - /* j-th destination accepts the word character ch. */ - trtable[ch] = dest_states[j]; - trtable[ch + SBC_MAX] = dest_states_word[j]; - } - } - - /* new line */ - if (bitset_contain (acceptable, NEWLINE_CHAR)) - { - /* The current state accepts newline character. */ - for (j = 0; j < ndests; ++j) - if (bitset_contain (dests_ch[j], NEWLINE_CHAR)) - { - /* k-th destination accepts newline character. */ - trtable[NEWLINE_CHAR] = dest_states_nl[j]; - if (need_word_trtable) - trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j]; - /* There must be only one destination which accepts - newline. See group_nodes_into_DFAstates. */ - break; - } - } - - if (dest_states_malloced) - free (dest_states); - - re_node_set_free (&follows); - for (i = 0; i < ndests; ++i) - re_node_set_free (dests_node + i); - - if (dests_node_malloced) - free (dests_alloc); - - return true; -} - -/* Group all nodes belonging to STATE into several destinations. - Then for all destinations, set the nodes belonging to the destination - to DESTS_NODE[i] and set the characters accepted by the destination - to DEST_CH[i]. This function return the number of destinations. */ - -static Idx -internal_function -group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, - re_node_set *dests_node, bitset_t *dests_ch) -{ - reg_errcode_t err; - bool ok; - Idx i, j, k; - Idx ndests; /* Number of the destinations from `state'. */ - bitset_t accepts; /* Characters a node can accept. */ - const re_node_set *cur_nodes = &state->nodes; - bitset_empty (accepts); - ndests = 0; - - /* For all the nodes belonging to `state', */ - for (i = 0; i < cur_nodes->nelem; ++i) - { - re_token_t *node = &dfa->nodes[cur_nodes->elems[i]]; - re_token_type_t type = node->type; - unsigned int constraint = node->constraint; - - /* Enumerate all single byte character this node can accept. */ - if (type == CHARACTER) - bitset_set (accepts, node->opr.c); - else if (type == SIMPLE_BRACKET) - { - bitset_merge (accepts, node->opr.sbcset); - } - else if (type == OP_PERIOD) - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - bitset_merge (accepts, dfa->sb_char); - else -#endif - bitset_set_all (accepts); - if (!(dfa->syntax & RE_DOT_NEWLINE)) - bitset_clear (accepts, '\n'); - if (dfa->syntax & RE_DOT_NOT_NULL) - bitset_clear (accepts, '\0'); - } -#ifdef RE_ENABLE_I18N - else if (type == OP_UTF8_PERIOD) - { - if (ASCII_CHARS % BITSET_WORD_BITS == 0) - memset (accepts, -1, ASCII_CHARS / CHAR_BIT); - else - bitset_merge (accepts, utf8_sb_map); - if (!(dfa->syntax & RE_DOT_NEWLINE)) - bitset_clear (accepts, '\n'); - if (dfa->syntax & RE_DOT_NOT_NULL) - bitset_clear (accepts, '\0'); - } -#endif - else - continue; - - /* Check the `accepts' and sift the characters which are not - match it the context. */ - if (constraint) - { - if (constraint & NEXT_NEWLINE_CONSTRAINT) - { - bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR); - bitset_empty (accepts); - if (accepts_newline) - bitset_set (accepts, NEWLINE_CHAR); - else - continue; - } - if (constraint & NEXT_ENDBUF_CONSTRAINT) - { - bitset_empty (accepts); - continue; - } - - if (constraint & NEXT_WORD_CONSTRAINT) - { - bitset_word_t any_set = 0; - if (type == CHARACTER && !node->word_char) - { - bitset_empty (accepts); - continue; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j])); - else -#endif - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= dfa->word_char[j]); - if (!any_set) - continue; - } - if (constraint & NEXT_NOTWORD_CONSTRAINT) - { - bitset_word_t any_set = 0; - if (type == CHARACTER && node->word_char) - { - bitset_empty (accepts); - continue; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j])); - else -#endif - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= ~dfa->word_char[j]); - if (!any_set) - continue; - } - } - - /* Then divide `accepts' into DFA states, or create a new - state. Above, we make sure that accepts is not empty. */ - for (j = 0; j < ndests; ++j) - { - bitset_t intersec; /* Intersection sets, see below. */ - bitset_t remains; - /* Flags, see below. */ - bitset_word_t has_intersec, not_subset, not_consumed; - - /* Optimization, skip if this state doesn't accept the character. */ - if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c)) - continue; - - /* Enumerate the intersection set of this state and `accepts'. */ - has_intersec = 0; - for (k = 0; k < BITSET_WORDS; ++k) - has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k]; - /* And skip if the intersection set is empty. */ - if (!has_intersec) - continue; - - /* Then check if this state is a subset of `accepts'. */ - not_subset = not_consumed = 0; - for (k = 0; k < BITSET_WORDS; ++k) - { - not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k]; - not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k]; - } - - /* If this state isn't a subset of `accepts', create a - new group state, which has the `remains'. */ - if (not_subset) - { - bitset_copy (dests_ch[ndests], remains); - bitset_copy (dests_ch[j], intersec); - err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]); - if (BE (err != REG_NOERROR, 0)) - goto error_return; - ++ndests; - } - - /* Put the position in the current group. */ - ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]); - if (BE (! ok, 0)) - goto error_return; - - /* If all characters are consumed, go to next node. */ - if (!not_consumed) - break; - } - /* Some characters remain, create a new group. */ - if (j == ndests) - { - bitset_copy (dests_ch[ndests], accepts); - err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]); - if (BE (err != REG_NOERROR, 0)) - goto error_return; - ++ndests; - bitset_empty (accepts); - } - } - return ndests; - error_return: - for (j = 0; j < ndests; ++j) - re_node_set_free (dests_node + j); - return REG_MISSING; -} - -#ifdef RE_ENABLE_I18N -/* Check how many bytes the node `dfa->nodes[node_idx]' accepts. - Return the number of the bytes the node accepts. - STR_IDX is the current index of the input string. - - This function handles the nodes which can accept one character, or - one collating element like '.', '[a-z]', opposite to the other nodes - can only accept one byte. */ - -static int -internal_function -check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, - const re_string_t *input, Idx str_idx) -{ - const re_token_t *node = dfa->nodes + node_idx; - int char_len, elem_len; - Idx i; - - if (BE (node->type == OP_UTF8_PERIOD, 0)) - { - unsigned char c = re_string_byte_at (input, str_idx), d; - if (BE (c < 0xc2, 1)) - return 0; - - if (str_idx + 2 > input->len) - return 0; - - d = re_string_byte_at (input, str_idx + 1); - if (c < 0xe0) - return (d < 0x80 || d > 0xbf) ? 0 : 2; - else if (c < 0xf0) - { - char_len = 3; - if (c == 0xe0 && d < 0xa0) - return 0; - } - else if (c < 0xf8) - { - char_len = 4; - if (c == 0xf0 && d < 0x90) - return 0; - } - else if (c < 0xfc) - { - char_len = 5; - if (c == 0xf8 && d < 0x88) - return 0; - } - else if (c < 0xfe) - { - char_len = 6; - if (c == 0xfc && d < 0x84) - return 0; - } - else - return 0; - - if (str_idx + char_len > input->len) - return 0; - - for (i = 1; i < char_len; ++i) - { - d = re_string_byte_at (input, str_idx + i); - if (d < 0x80 || d > 0xbf) - return 0; - } - return char_len; - } - - char_len = re_string_char_size_at (input, str_idx); - if (node->type == OP_PERIOD) - { - if (char_len <= 1) - return 0; - /* FIXME: I don't think this if is needed, as both '\n' - and '\0' are char_len == 1. */ - /* '.' accepts any one character except the following two cases. */ - if ((!(dfa->syntax & RE_DOT_NEWLINE) && - re_string_byte_at (input, str_idx) == '\n') || - ((dfa->syntax & RE_DOT_NOT_NULL) && - re_string_byte_at (input, str_idx) == '\0')) - return 0; - return char_len; - } - - elem_len = re_string_elem_size_at (input, str_idx); - if ((elem_len <= 1 && char_len <= 1) || char_len == 0) - return 0; - - if (node->type == COMPLEX_BRACKET) - { - const re_charset_t *cset = node->opr.mbcset; -# ifdef _LIBC - const unsigned char *pin - = ((const unsigned char *) re_string_get_buffer (input) + str_idx); - Idx j; - uint32_t nrules; -# endif /* _LIBC */ - int match_len = 0; - wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars) - ? re_string_wchar_at (input, str_idx) : 0); - - /* match with multibyte character? */ - for (i = 0; i < cset->nmbchars; ++i) - if (wc == cset->mbchars[i]) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - /* match with character_class? */ - for (i = 0; i < cset->nchar_classes; ++i) - { - wctype_t wt = cset->char_classes[i]; - if (__iswctype (wc, wt)) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - } - -# ifdef _LIBC - nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules != 0) - { - unsigned int in_collseq = 0; - const int32_t *table, *indirect; - const unsigned char *weights, *extra; - const char *collseqwc; - int32_t idx; - /* This #include defines a local function! */ -# include - - /* match with collating_symbol? */ - if (cset->ncoll_syms) - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); - for (i = 0; i < cset->ncoll_syms; ++i) - { - const unsigned char *coll_sym = extra + cset->coll_syms[i]; - /* Compare the length of input collating element and - the length of current collating element. */ - if (*coll_sym != elem_len) - continue; - /* Compare each bytes. */ - for (j = 0; j < *coll_sym; j++) - if (pin[j] != coll_sym[1 + j]) - break; - if (j == *coll_sym) - { - /* Match if every bytes is equal. */ - match_len = j; - goto check_node_accept_bytes_match; - } - } - - if (cset->nranges) - { - if (elem_len <= char_len) - { - collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); - in_collseq = __collseq_table_lookup (collseqwc, wc); - } - else - in_collseq = find_collation_sequence_value (pin, elem_len); - } - /* match with range expression? */ - for (i = 0; i < cset->nranges; ++i) - if (cset->range_starts[i] <= in_collseq - && in_collseq <= cset->range_ends[i]) - { - match_len = elem_len; - goto check_node_accept_bytes_match; - } - - /* match with equivalence_class? */ - if (cset->nequiv_classes) - { - const unsigned char *cp = pin; - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - idx = findidx (&cp); - if (idx > 0) - for (i = 0; i < cset->nequiv_classes; ++i) - { - int32_t equiv_class_idx = cset->equiv_classes[i]; - size_t weight_len = weights[idx]; - if (weight_len == weights[equiv_class_idx]) - { - Idx cnt = 0; - while (cnt <= weight_len - && (weights[equiv_class_idx + 1 + cnt] - == weights[idx + 1 + cnt])) - ++cnt; - if (cnt > weight_len) - { - match_len = elem_len; - goto check_node_accept_bytes_match; - } - } - } - } - } - else -# endif /* _LIBC */ - { - /* match with range expression? */ -#if __GNUC__ >= 2 && ! (__STDC_VERSION__ < 199901L && __STRICT_ANSI__) - wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'}; -#else - wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; - cmp_buf[2] = wc; -#endif - for (i = 0; i < cset->nranges; ++i) - { - cmp_buf[0] = cset->range_starts[i]; - cmp_buf[4] = cset->range_ends[i]; - if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 - && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - } - } - check_node_accept_bytes_match: - if (!cset->non_match) - return match_len; - else - { - if (match_len > 0) - return 0; - else - return (elem_len > char_len) ? elem_len : char_len; - } - } - return 0; -} - -# ifdef _LIBC -static unsigned int -internal_function -find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) -{ - uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules == 0) - { - if (mbs_len == 1) - { - /* No valid character. Match it as a single byte character. */ - const unsigned char *collseq = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); - return collseq[mbs[0]]; - } - return UINT_MAX; - } - else - { - int32_t idx; - const unsigned char *extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); - int32_t extrasize = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra; - - for (idx = 0; idx < extrasize;) - { - int mbs_cnt; - bool found = false; - int32_t elem_mbs_len; - /* Skip the name of collating element name. */ - idx = idx + extra[idx] + 1; - elem_mbs_len = extra[idx++]; - if (mbs_len == elem_mbs_len) - { - for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt) - if (extra[idx + mbs_cnt] != mbs[mbs_cnt]) - break; - if (mbs_cnt == elem_mbs_len) - /* Found the entry. */ - found = true; - } - /* Skip the byte sequence of the collating element. */ - idx += elem_mbs_len; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - /* Skip the collation sequence value. */ - idx += sizeof (uint32_t); - /* Skip the wide char sequence of the collating element. */ - idx = idx + sizeof (uint32_t) * (extra[idx] + 1); - /* If we found the entry, return the sequence value. */ - if (found) - return *(uint32_t *) (extra + idx); - /* Skip the collation sequence value. */ - idx += sizeof (uint32_t); - } - return UINT_MAX; - } -} -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ - -/* Check whether the node accepts the byte which is IDX-th - byte of the INPUT. */ - -static bool -internal_function -check_node_accept (const re_match_context_t *mctx, const re_token_t *node, - Idx idx) -{ - unsigned char ch; - ch = re_string_byte_at (&mctx->input, idx); - switch (node->type) - { - case CHARACTER: - if (node->opr.c != ch) - return false; - break; - - case SIMPLE_BRACKET: - if (!bitset_contain (node->opr.sbcset, ch)) - return false; - break; - -#ifdef RE_ENABLE_I18N - case OP_UTF8_PERIOD: - if (ch >= ASCII_CHARS) - return false; - /* FALLTHROUGH */ -#endif - case OP_PERIOD: - if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE)) - || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL))) - return false; - break; - - default: - return false; - } - - if (node->constraint) - { - /* The node has constraints. Check whether the current context - satisfies the constraints. */ - unsigned int context = re_string_context_at (&mctx->input, idx, - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) - return false; - } - - return true; -} - -/* Extend the buffers, if the buffers have run out. */ - -static reg_errcode_t -internal_function -extend_buffers (re_match_context_t *mctx) -{ - reg_errcode_t ret; - re_string_t *pstr = &mctx->input; - - /* Avoid overflow. */ - if (BE (SIZE_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0)) - return REG_ESPACE; - - /* Double the lengthes of the buffers. */ - ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - if (mctx->state_log != NULL) - { - /* And double the length of state_log. */ - /* XXX We have no indication of the size of this buffer. If this - allocation fail we have no indication that the state_log array - does not have the right size. */ - re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *, - pstr->bufs_len + 1); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - mctx->state_log = new_array; - } - - /* Then reconstruct the buffers. */ - if (pstr->icase) - { -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - else -#endif /* RE_ENABLE_I18N */ - build_upper_buffer (pstr); - } - else - { -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - build_wcs_buffer (pstr); - else -#endif /* RE_ENABLE_I18N */ - { - if (pstr->trans != NULL) - re_string_translate_buffer (pstr); - } - } - return REG_NOERROR; -} - - -/* Functions for matching context. */ - -/* Initialize MCTX. */ - -static reg_errcode_t -internal_function -match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) -{ - mctx->eflags = eflags; - mctx->match_last = REG_MISSING; - if (n > 0) - { - /* Avoid overflow. */ - size_t max_object_size = - MAX (sizeof (struct re_backref_cache_entry), - sizeof (re_sub_match_top_t *)); - if (BE (SIZE_MAX / max_object_size < n, 0)) - return REG_ESPACE; - - mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n); - mctx->sub_tops = re_malloc (re_sub_match_top_t *, n); - if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0)) - return REG_ESPACE; - } - /* Already zero-ed by the caller. - else - mctx->bkref_ents = NULL; - mctx->nbkref_ents = 0; - mctx->nsub_tops = 0; */ - mctx->abkref_ents = n; - mctx->max_mb_elem_len = 1; - mctx->asub_tops = n; - return REG_NOERROR; -} - -/* Clean the entries which depend on the current input in MCTX. - This function must be invoked when the matcher changes the start index - of the input, or changes the input string. */ - -static void -internal_function -match_ctx_clean (re_match_context_t *mctx) -{ - Idx st_idx; - for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx) - { - Idx sl_idx; - re_sub_match_top_t *top = mctx->sub_tops[st_idx]; - for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx) - { - re_sub_match_last_t *last = top->lasts[sl_idx]; - re_free (last->path.array); - re_free (last); - } - re_free (top->lasts); - if (top->path) - { - re_free (top->path->array); - re_free (top->path); - } - free (top); - } - - mctx->nsub_tops = 0; - mctx->nbkref_ents = 0; -} - -/* Free all the memory associated with MCTX. */ - -static void -internal_function -match_ctx_free (re_match_context_t *mctx) -{ - /* First, free all the memory associated with MCTX->SUB_TOPS. */ - match_ctx_clean (mctx); - re_free (mctx->sub_tops); - re_free (mctx->bkref_ents); -} - -/* Add a new backreference entry to MCTX. - Note that we assume that caller never call this function with duplicate - entry, and call with STR_IDX which isn't smaller than any existing entry. -*/ - -static reg_errcode_t -internal_function -match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, - Idx to) -{ - if (mctx->nbkref_ents >= mctx->abkref_ents) - { - struct re_backref_cache_entry* new_entry; - new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry, - mctx->abkref_ents * 2); - if (BE (new_entry == NULL, 0)) - { - re_free (mctx->bkref_ents); - return REG_ESPACE; - } - mctx->bkref_ents = new_entry; - memset (mctx->bkref_ents + mctx->nbkref_ents, '\0', - sizeof (struct re_backref_cache_entry) * mctx->abkref_ents); - mctx->abkref_ents *= 2; - } - if (mctx->nbkref_ents > 0 - && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx) - mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1; - - mctx->bkref_ents[mctx->nbkref_ents].node = node; - mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx; - mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from; - mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to; - - /* This is a cache that saves negative results of check_dst_limits_calc_pos. - If bit N is clear, means that this entry won't epsilon-transition to - an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression. If - it is set, check_dst_limits_calc_pos_1 will recurse and try to find one - such node. - - A backreference does not epsilon-transition unless it is empty, so set - to all zeros if FROM != TO. */ - mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map - = (from == to ? -1 : 0); - - mctx->bkref_ents[mctx->nbkref_ents++].more = 0; - if (mctx->max_mb_elem_len < to - from) - mctx->max_mb_elem_len = to - from; - return REG_NOERROR; -} - -/* Return the first entry with the same str_idx, or REG_MISSING if none is - found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */ - -static Idx -internal_function -search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) -{ - Idx left, right, mid, last; - last = right = mctx->nbkref_ents; - for (left = 0; left < right;) - { - mid = (left + right) / 2; - if (mctx->bkref_ents[mid].str_idx < str_idx) - left = mid + 1; - else - right = mid; - } - if (left < last && mctx->bkref_ents[left].str_idx == str_idx) - return left; - else - return REG_MISSING; -} - -/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches - at STR_IDX. */ - -static reg_errcode_t -internal_function -match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) -{ -#ifdef DEBUG - assert (mctx->sub_tops != NULL); - assert (mctx->asub_tops > 0); -#endif - if (BE (mctx->nsub_tops == mctx->asub_tops, 0)) - { - Idx new_asub_tops = mctx->asub_tops * 2; - re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops, - re_sub_match_top_t *, - new_asub_tops); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - mctx->sub_tops = new_array; - mctx->asub_tops = new_asub_tops; - } - mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t)); - if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0)) - return REG_ESPACE; - mctx->sub_tops[mctx->nsub_tops]->node = node; - mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx; - return REG_NOERROR; -} - -/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches - at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */ - -static re_sub_match_last_t * -internal_function -match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) -{ - re_sub_match_last_t *new_entry; - if (BE (subtop->nlasts == subtop->alasts, 0)) - { - Idx new_alasts = 2 * subtop->alasts + 1; - re_sub_match_last_t **new_array = re_realloc (subtop->lasts, - re_sub_match_last_t *, - new_alasts); - if (BE (new_array == NULL, 0)) - return NULL; - subtop->lasts = new_array; - subtop->alasts = new_alasts; - } - new_entry = calloc (1, sizeof (re_sub_match_last_t)); - if (BE (new_entry != NULL, 1)) - { - subtop->lasts[subtop->nlasts] = new_entry; - new_entry->node = node; - new_entry->str_idx = str_idx; - ++subtop->nlasts; - } - return new_entry; -} - -static void -internal_function -sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, - re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx) -{ - sctx->sifted_states = sifted_sts; - sctx->limited_states = limited_sts; - sctx->last_node = last_node; - sctx->last_str_idx = last_str_idx; - re_node_set_init_empty (&sctx->limits); -} diff --git a/src/bin/tar/lib/rmdir.c b/src/bin/tar/lib/rmdir.c deleted file mode 100644 index 1221f4fef4..0000000000 --- a/src/bin/tar/lib/rmdir.c +++ /dev/null @@ -1,74 +0,0 @@ -/* BSD compatible remove directory function for System V - - Copyright (C) 1988, 1990, 1999, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include -#include -#include - -/* rmdir adapted from GNU tar. */ - -/* Remove directory DIR. - Return 0 if successful, -1 if not. */ - -int -rmdir (char const *dir) -{ - pid_t cpid; - int status; - struct stat statbuf; - - if (stat (dir, &statbuf) != 0) - return -1; /* errno already set */ - - if (!S_ISDIR (statbuf.st_mode)) - { - errno = ENOTDIR; - return -1; - } - - cpid = fork (); - switch (cpid) - { - case -1: /* cannot fork */ - return -1; /* errno already set */ - - case 0: /* child process */ - execl ("/bin/rmdir", "rmdir", dir, (char *) 0); - _exit (1); - - default: /* parent process */ - - /* Wait for kid to finish. */ - - while (wait (&status) != cpid) - /* Do nothing. */ ; - - if (status) - { - - /* /bin/rmdir failed. */ - - errno = EIO; - return -1; - } - return 0; - } -} diff --git a/src/bin/tar/lib/rmt-command.h b/src/bin/tar/lib/rmt-command.h deleted file mode 100644 index 9f24f066a1..0000000000 --- a/src/bin/tar/lib/rmt-command.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef DEFAULT_RMT_COMMAND -# define DEFAULT_RMT_COMMAND "/usr/local/libexec/rmt" -#endif diff --git a/src/bin/tar/lib/rmt.h b/src/bin/tar/lib/rmt.h deleted file mode 100644 index 50f037c5af..0000000000 --- a/src/bin/tar/lib/rmt.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Definitions for communicating with a remote tape drive. - - Copyright (C) 1988, 1992, 1996, 1997, 2001, 2003, 2004, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -extern char *rmt_command; -extern char *rmt_dev_name__; - -int rmt_open__ (const char *, int, int, const char *); -int rmt_close__ (int); -size_t rmt_read__ (int, char *, size_t); -size_t rmt_write__ (int, char *, size_t); -off_t rmt_lseek__ (int, off_t, int); -int rmt_ioctl__ (int, int, char *); - -extern bool force_local_option; - -/* A filename is remote if it contains a colon not preceded by a slash, - to take care of `/:/' which is a shorthand for `/...//fs' - on machines running OSF's Distributing Computing Environment (DCE) and - Distributed File System (DFS). However, when --force-local, a - filename is never remote. */ - -#define _remdev(dev_name) \ - (!force_local_option && (rmt_dev_name__ = strchr (dev_name, ':')) \ - && rmt_dev_name__ > (dev_name) \ - && ! memchr (dev_name, '/', rmt_dev_name__ - (dev_name))) - -#define _isrmt(fd) \ - ((fd) >= __REM_BIAS) - -#define __REM_BIAS (1 << 30) - -#ifndef O_CREAT -# define O_CREAT 01000 -#endif - -#define rmtopen(dev_name, oflag, mode, command) \ - (_remdev (dev_name) ? rmt_open__ (dev_name, oflag, __REM_BIAS, command) \ - : open (dev_name, oflag, mode)) - -#define rmtaccess(dev_name, amode) \ - (_remdev (dev_name) ? 0 : access (dev_name, amode)) - -#define rmtstat(dev_name, buffer) \ - (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : stat (dev_name, buffer)) - -#define rmtcreat(dev_name, mode, command) \ - (_remdev (dev_name) \ - ? rmt_open__ (dev_name, 1 | O_CREAT, __REM_BIAS, command) \ - : creat (dev_name, mode)) - -#define rmtlstat(dev_name, muffer) \ - (_remdev (dev_name) ? (errno = EOPNOTSUPP), -1 : lstat (dev_name, buffer)) - -#define rmtread(fd, buffer, length) \ - (_isrmt (fd) ? rmt_read__ (fd - __REM_BIAS, buffer, length) \ - : safe_read (fd, buffer, length)) - -#define rmtwrite(fd, buffer, length) \ - (_isrmt (fd) ? rmt_write__ (fd - __REM_BIAS, buffer, length) \ - : full_write (fd, buffer, length)) - -#define rmtlseek(fd, offset, where) \ - (_isrmt (fd) ? rmt_lseek__ (fd - __REM_BIAS, offset, where) \ - : lseek (fd, offset, where)) - -#define rmtclose(fd) \ - (_isrmt (fd) ? rmt_close__ (fd - __REM_BIAS) : close (fd)) - -#define rmtioctl(fd, request, argument) \ - (_isrmt (fd) ? rmt_ioctl__ (fd - __REM_BIAS, request, argument) \ - : ioctl (fd, request, argument)) - -#define rmtdup(fd) \ - (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : dup (fd)) - -#define rmtfstat(fd, buffer) \ - (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fstat (fd, buffer)) - -#define rmtfcntl(cd, command, argument) \ - (_isrmt (fd) ? (errno = EOPNOTSUPP), -1 : fcntl (fd, command, argument)) - -#define rmtisatty(fd) \ - (_isrmt (fd) ? 0 : isatty (fd)) diff --git a/src/bin/tar/lib/rpmatch.c b/src/bin/tar/lib/rpmatch.c deleted file mode 100644 index e5f79f8228..0000000000 --- a/src/bin/tar/lib/rpmatch.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Determine whether string value is affirmation or negative response - according to current locale's data. - - Copyright (C) 1996, 1998, 2000, 2002, 2003, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include -#include - -#if ENABLE_NLS -# include -# include -# include -# include "gettext.h" -# define _(msgid) gettext (msgid) - -static int -try (const char *response, const char *pattern, const int match, - const int nomatch, const char **lastp, regex_t *re) -{ - if (pattern != *lastp) - { - /* The pattern has changed. */ - if (*lastp) - { - /* Free the old compiled pattern. */ - regfree (re); - *lastp = NULL; - } - /* Compile the pattern and cache it for future runs. */ - if (regcomp (re, pattern, REG_EXTENDED) != 0) - return -1; - *lastp = pattern; - } - - /* See if the regular expression matches RESPONSE. */ - return regexec (re, response, 0, NULL, 0) == 0 ? match : nomatch; -} -#endif - - -int -rpmatch (const char *response) -{ -#if ENABLE_NLS - /* Match against one of the response patterns, compiling the pattern - first if necessary. */ - - /* We cache the response patterns and compiled regexps here. */ - static const char *yesexpr, *noexpr; - static regex_t yesre, nore; - int result; - - return ((result = try (response, _("^[yY]"), 1, 0, - &yesexpr, &yesre)) - ? result - : try (response, _("^[nN]"), 0, -1, &noexpr, &nore)); -#else - /* Test against "^[yY]" and "^[nN]", hardcoded to avoid requiring regex */ - return (*response == 'y' || *response == 'Y' ? 1 - : *response == 'n' || *response == 'N' ? 0 : -1); -#endif -} diff --git a/src/bin/tar/lib/rtapelib.c b/src/bin/tar/lib/rtapelib.c deleted file mode 100644 index 51faf3ce91..0000000000 --- a/src/bin/tar/lib/rtapelib.c +++ /dev/null @@ -1,740 +0,0 @@ -/* Functions for communicating with a remote tape drive. - - Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2004, - 2005, 2006, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* The man page rmt(8) for /etc/rmt documents the remote mag tape protocol - which rdump and rrestore use. Unfortunately, the man page is *WRONG*. - The author of the routines I'm including originally wrote his code just - based on the man page, and it didn't work, so he went to the rdump source - to figure out why. The only thing he had to change was to check for the - 'F' return code in addition to the 'E', and to separate the various - arguments with \n instead of a space. I personally don't think that this - is much of a problem, but I wanted to point it out. -- Arnold Robbins - - Originally written by Jeff Lee, modified some by Arnold Robbins. Redone - as a library that can replace open, read, write, etc., by Fred Fish, with - some additional work by Arnold Robbins. Modified to make all rmt* calls - into macros for speed by Jay Fenlason. Use -DWITH_REXEC for rexec - code, courtesy of Dan Kegel. */ - -#include "system.h" -#include "system-ioctl.h" - -#include -#include - -/* Try hard to get EOPNOTSUPP defined. 486/ISC has it in net/errno.h, - 3B2/SVR3 has it in sys/inet.h. Otherwise, like on MSDOS, use EINVAL. */ - -#ifndef EOPNOTSUPP -# if HAVE_NET_ERRNO_H -# include -# endif -# if HAVE_SYS_INET_H -# include -# endif -# ifndef EOPNOTSUPP -# define EOPNOTSUPP EINVAL -# endif -#endif - -#include - -#if HAVE_NETDB_H -# include -#endif - -#include -#include - -/* Exit status if exec errors. */ -#define EXIT_ON_EXEC_ERROR 128 - -/* FIXME: Size of buffers for reading and writing commands to rmt. */ -#define COMMAND_BUFFER_SIZE 64 - -#ifndef RETSIGTYPE -# define RETSIGTYPE void -#endif - -/* FIXME: Maximum number of simultaneous remote tape connections. */ -#define MAXUNIT 4 - -#define PREAD 0 /* read file descriptor from pipe() */ -#define PWRITE 1 /* write file descriptor from pipe() */ - -/* Return the parent's read side of remote tape connection Fd. */ -#define READ_SIDE(Fd) (from_remote[Fd][PREAD]) - -/* Return the parent's write side of remote tape connection Fd. */ -#define WRITE_SIDE(Fd) (to_remote[Fd][PWRITE]) - -/* The pipes for receiving data from remote tape drives. */ -static int from_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; - -/* The pipes for sending data to remote tape drives. */ -static int to_remote[MAXUNIT][2] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; - -char *rmt_command = DEFAULT_RMT_COMMAND; - -/* Temporary variable used by macros in rmt.h. */ -char *rmt_dev_name__; - -/* If true, always consider file names to be local, even if they contain - colons */ -bool force_local_option; - - - -/* Close remote tape connection HANDLE, and reset errno to ERRNO_VALUE. */ -static void -_rmt_shutdown (int handle, int errno_value) -{ - close (READ_SIDE (handle)); - close (WRITE_SIDE (handle)); - READ_SIDE (handle) = -1; - WRITE_SIDE (handle) = -1; - errno = errno_value; -} - -/* Attempt to perform the remote tape command specified in BUFFER on - remote tape connection HANDLE. Return 0 if successful, -1 on - error. */ -static int -do_command (int handle, const char *buffer) -{ - /* Save the current pipe handler and try to make the request. */ - - size_t length = strlen (buffer); - RETSIGTYPE (*pipe_handler) () = signal (SIGPIPE, SIG_IGN); - ssize_t written = full_write (WRITE_SIDE (handle), buffer, length); - signal (SIGPIPE, pipe_handler); - - if (written == length) - return 0; - - /* Something went wrong. Close down and go home. */ - - _rmt_shutdown (handle, EIO); - return -1; -} - -static char * -get_status_string (int handle, char *command_buffer) -{ - char *cursor; - int counter; - - /* Read the reply command line. */ - - for (counter = 0, cursor = command_buffer; - counter < COMMAND_BUFFER_SIZE; - counter++, cursor++) - { - if (safe_read (READ_SIDE (handle), cursor, 1) != 1) - { - _rmt_shutdown (handle, EIO); - return 0; - } - if (*cursor == '\n') - { - *cursor = '\0'; - break; - } - } - - if (counter == COMMAND_BUFFER_SIZE) - { - _rmt_shutdown (handle, EIO); - return 0; - } - - /* Check the return status. */ - - for (cursor = command_buffer; *cursor; cursor++) - if (*cursor != ' ') - break; - - if (*cursor == 'E' || *cursor == 'F') - { - /* Skip the error message line. */ - - /* FIXME: there is better to do than merely ignoring error messages - coming from the remote end. Translate them, too... */ - - { - char character; - - while (safe_read (READ_SIDE (handle), &character, 1) == 1) - if (character == '\n') - break; - } - - errno = atoi (cursor + 1); - - if (*cursor == 'F') - _rmt_shutdown (handle, errno); - - return 0; - } - - /* Check for mis-synced pipes. */ - - if (*cursor != 'A') - { - _rmt_shutdown (handle, EIO); - return 0; - } - - /* Got an `A' (success) response. */ - - return cursor + 1; -} - -/* Read and return the status from remote tape connection HANDLE. If - an error occurred, return -1 and set errno. */ -static long int -get_status (int handle) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - const char *status = get_status_string (handle, command_buffer); - if (status) - { - long int result = atol (status); - if (0 <= result) - return result; - errno = EIO; - } - return -1; -} - -static off_t -get_status_off (int handle) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - const char *status = get_status_string (handle, command_buffer); - - if (! status) - return -1; - else - { - /* Parse status, taking care to check for overflow. - We can't use standard functions, - since off_t might be longer than long. */ - - off_t count = 0; - int negative; - - for (; *status == ' ' || *status == '\t'; status++) - continue; - - negative = *status == '-'; - status += negative || *status == '+'; - - for (;;) - { - int digit = *status++ - '0'; - if (9 < (unsigned) digit) - break; - else - { - off_t c10 = 10 * count; - off_t nc = negative ? c10 - digit : c10 + digit; - if (c10 / 10 != count || (negative ? c10 < nc : nc < c10)) - return -1; - count = nc; - } - } - - return count; - } -} - -#if WITH_REXEC - -/* Execute /etc/rmt as user USER on remote system HOST using rexec. - Return a file descriptor of a bidirectional socket for stdin and - stdout. If USER is zero, use the current username. - - By default, this code is not used, since it requires that the user - have a .netrc file in his/her home directory, or that the - application designer be willing to have rexec prompt for login and - password info. This may be unacceptable, and .rhosts files for use - with rsh are much more common on BSD systems. */ -static int -_rmt_rexec (char *host, char *user) -{ - int saved_stdin = dup (STDIN_FILENO); - int saved_stdout = dup (STDOUT_FILENO); - struct servent *rexecserv; - int result; - - /* When using cpio -o < filename, stdin is no longer the tty. But the - rexec subroutine reads the login and the passwd on stdin, to allow - remote execution of the command. So, reopen stdin and stdout on - /dev/tty before the rexec and give them back their original value - after. */ - - if (! freopen ("/dev/tty", "r", stdin)) - freopen ("/dev/null", "r", stdin); - if (! freopen ("/dev/tty", "w", stdout)) - freopen ("/dev/null", "w", stdout); - - if (rexecserv = getservbyname ("exec", "tcp"), !rexecserv) - error (EXIT_ON_EXEC_ERROR, 0, _("exec/tcp: Service not available")); - - result = rexec (&host, rexecserv->s_port, user, 0, rmt_command, 0); - if (fclose (stdin) == EOF) - error (0, errno, _("stdin")); - fdopen (saved_stdin, "r"); - if (fclose (stdout) == EOF) - error (0, errno, _("stdout")); - fdopen (saved_stdout, "w"); - - return result; -} - -#endif /* WITH_REXEC */ - -/* Place into BUF a string representing OFLAG, which must be suitable - as argument 2 of `open'. BUF must be large enough to hold the - result. This function should generate a string that decode_oflag - can parse. */ -static void -encode_oflag (char *buf, int oflag) -{ - sprintf (buf, "%d ", oflag); - - switch (oflag & O_ACCMODE) - { - case O_RDONLY: strcat (buf, "O_RDONLY"); break; - case O_RDWR: strcat (buf, "O_RDWR"); break; - case O_WRONLY: strcat (buf, "O_WRONLY"); break; - default: abort (); - } - -#ifdef O_APPEND - if (oflag & O_APPEND) strcat (buf, "|O_APPEND"); -#endif - if (oflag & O_CREAT) strcat (buf, "|O_CREAT"); -#ifdef O_DSYNC - if (oflag & O_DSYNC) strcat (buf, "|O_DSYNC"); -#endif - if (oflag & O_EXCL) strcat (buf, "|O_EXCL"); -#ifdef O_LARGEFILE - if (oflag & O_LARGEFILE) strcat (buf, "|O_LARGEFILE"); -#endif -#ifdef O_NOCTTY - if (oflag & O_NOCTTY) strcat (buf, "|O_NOCTTY"); -#endif - if (oflag & O_NONBLOCK) strcat (buf, "|O_NONBLOCK"); -#ifdef O_RSYNC - if (oflag & O_RSYNC) strcat (buf, "|O_RSYNC"); -#endif -#ifdef O_SYNC - if (oflag & O_SYNC) strcat (buf, "|O_SYNC"); -#endif - if (oflag & O_TRUNC) strcat (buf, "|O_TRUNC"); -} - -/* Open a file (a magnetic tape device?) on the system specified in - FILE_NAME, as the given user. FILE_NAME has the form `[USER@]HOST:FILE'. - OPEN_MODE is O_RDONLY, O_WRONLY, etc. If successful, return the - remote pipe number plus BIAS. REMOTE_SHELL may be overridden. On - error, return -1. */ -int -rmt_open__ (const char *file_name, int open_mode, int bias, - const char *remote_shell) -{ - int remote_pipe_number; /* pseudo, biased file descriptor */ - char *file_name_copy; /* copy of file_name string */ - char *remote_host; /* remote host name */ - char *remote_file; /* remote file name (often a device) */ - char *remote_user; /* remote user name */ - - /* Find an unused pair of file descriptors. */ - - for (remote_pipe_number = 0; - remote_pipe_number < MAXUNIT; - remote_pipe_number++) - if (READ_SIDE (remote_pipe_number) == -1 - && WRITE_SIDE (remote_pipe_number) == -1) - break; - - if (remote_pipe_number == MAXUNIT) - { - errno = EMFILE; - return -1; - } - - /* Pull apart the system and device, and optional user. */ - - { - char *cursor; - - file_name_copy = xstrdup (file_name); - remote_host = file_name_copy; - remote_user = 0; - remote_file = 0; - - for (cursor = file_name_copy; *cursor; cursor++) - switch (*cursor) - { - default: - break; - - case '\n': - /* Do not allow newlines in the file_name, since the protocol - uses newline delimiters. */ - free (file_name_copy); - errno = ENOENT; - return -1; - - case '@': - if (!remote_user) - { - remote_user = remote_host; - *cursor = '\0'; - remote_host = cursor + 1; - } - break; - - case ':': - if (!remote_file) - { - *cursor = '\0'; - remote_file = cursor + 1; - } - break; - } - } - - /* FIXME: Should somewhat validate the decoding, here. */ - - if (remote_user && *remote_user == '\0') - remote_user = 0; - -#if WITH_REXEC - - /* Execute the remote command using rexec. */ - - READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user); - if (READ_SIDE (remote_pipe_number) < 0) - { - int e = errno; - free (file_name_copy); - errno = e; - return -1; - } - - WRITE_SIDE (remote_pipe_number) = READ_SIDE (remote_pipe_number); - -#else /* not WITH_REXEC */ - { - const char *remote_shell_basename; - pid_t status; - - /* Identify the remote command to be executed. */ - - if (!remote_shell) - { -#ifdef REMOTE_SHELL - remote_shell = REMOTE_SHELL; -#else - free (file_name_copy); - errno = EIO; - return -1; -#endif - } - remote_shell_basename = last_component (remote_shell); - - /* Set up the pipes for the `rsh' command, and fork. */ - - if (pipe (to_remote[remote_pipe_number]) == -1 - || pipe (from_remote[remote_pipe_number]) == -1) - { - int e = errno; - free (file_name_copy); - errno = e; - return -1; - } - - status = fork (); - if (status == -1) - { - int e = errno; - free (file_name_copy); - errno = e; - return -1; - } - - if (status == 0) - { - /* Child. */ - - close (STDIN_FILENO); - dup (to_remote[remote_pipe_number][PREAD]); - close (to_remote[remote_pipe_number][PREAD]); - close (to_remote[remote_pipe_number][PWRITE]); - - close (STDOUT_FILENO); - dup (from_remote[remote_pipe_number][PWRITE]); - close (from_remote[remote_pipe_number][PREAD]); - close (from_remote[remote_pipe_number][PWRITE]); - - sys_reset_uid_gid (); - - if (remote_user) - execl (remote_shell, remote_shell_basename, remote_host, - "-l", remote_user, rmt_command, (char *) 0); - else - execl (remote_shell, remote_shell_basename, remote_host, - rmt_command, (char *) 0); - - /* Bad problems if we get here. */ - - /* In a previous version, _exit was used here instead of exit. */ - error (EXIT_ON_EXEC_ERROR, errno, _("Cannot execute remote shell")); - } - - /* Parent. */ - - close (from_remote[remote_pipe_number][PWRITE]); - close (to_remote[remote_pipe_number][PREAD]); - } -#endif /* not WITH_REXEC */ - - /* Attempt to open the tape device. */ - - { - size_t remote_file_len = strlen (remote_file); - char *command_buffer = xmalloc (remote_file_len + 1000); - sprintf (command_buffer, "O%s\n", remote_file); - encode_oflag (command_buffer + remote_file_len + 2, open_mode); - strcat (command_buffer, "\n"); - if (do_command (remote_pipe_number, command_buffer) == -1 - || get_status (remote_pipe_number) == -1) - { - int e = errno; - free (command_buffer); - free (file_name_copy); - _rmt_shutdown (remote_pipe_number, e); - return -1; - } - free (command_buffer); - } - - free (file_name_copy); - return remote_pipe_number + bias; -} - -/* Close remote tape connection HANDLE and shut down. Return 0 if - successful, -1 on error. */ -int -rmt_close__ (int handle) -{ - long int status; - - if (do_command (handle, "C\n") == -1) - return -1; - - status = get_status (handle); - _rmt_shutdown (handle, errno); - return status; -} - -/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE. - Return the number of bytes read on success, SAFE_READ_ERROR on error. */ -size_t -rmt_read__ (int handle, char *buffer, size_t length) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - size_t status; - size_t rlen; - size_t counter; - - sprintf (command_buffer, "R%lu\n", (unsigned long) length); - if (do_command (handle, command_buffer) == -1 - || (status = get_status (handle)) == SAFE_READ_ERROR) - return SAFE_READ_ERROR; - - for (counter = 0; counter < status; counter += rlen, buffer += rlen) - { - rlen = safe_read (READ_SIDE (handle), buffer, status - counter); - if (rlen == SAFE_READ_ERROR || rlen == 0) - { - _rmt_shutdown (handle, EIO); - return SAFE_READ_ERROR; - } - } - - return status; -} - -/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE. - Return the number of bytes written. */ -size_t -rmt_write__ (int handle, char *buffer, size_t length) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - RETSIGTYPE (*pipe_handler) (); - size_t written; - - sprintf (command_buffer, "W%lu\n", (unsigned long) length); - if (do_command (handle, command_buffer) == -1) - return 0; - - pipe_handler = signal (SIGPIPE, SIG_IGN); - written = full_write (WRITE_SIDE (handle), buffer, length); - signal (SIGPIPE, pipe_handler); - if (written == length) - { - long int r = get_status (handle); - if (r < 0) - return 0; - if (r == length) - return length; - written = r; - } - - /* Write error. */ - - _rmt_shutdown (handle, EIO); - return written; -} - -/* Perform an imitation lseek operation on remote tape connection - HANDLE. Return the new file offset if successful, -1 if on error. */ -off_t -rmt_lseek__ (int handle, off_t offset, int whence) -{ - char command_buffer[COMMAND_BUFFER_SIZE]; - char operand_buffer[UINTMAX_STRSIZE_BOUND]; - uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset; - char *p = operand_buffer + sizeof operand_buffer; - - *--p = 0; - do - *--p = '0' + (int) (u % 10); - while ((u /= 10) != 0); - if (offset < 0) - *--p = '-'; - - switch (whence) - { - case SEEK_SET: whence = 0; break; - case SEEK_CUR: whence = 1; break; - case SEEK_END: whence = 2; break; - default: abort (); - } - - sprintf (command_buffer, "L%s\n%d\n", p, whence); - - if (do_command (handle, command_buffer) == -1) - return -1; - - return get_status_off (handle); -} - -/* Perform a raw tape operation on remote tape connection HANDLE. - Return the results of the ioctl, or -1 on error. */ -int -rmt_ioctl__ (int handle, int operation, char *argument) -{ - switch (operation) - { - default: - errno = EOPNOTSUPP; - return -1; - -#ifdef MTIOCTOP - case MTIOCTOP: - { - char command_buffer[COMMAND_BUFFER_SIZE]; - char operand_buffer[UINTMAX_STRSIZE_BOUND]; - uintmax_t u = (((struct mtop *) argument)->mt_count < 0 - ? - (uintmax_t) ((struct mtop *) argument)->mt_count - : (uintmax_t) ((struct mtop *) argument)->mt_count); - char *p = operand_buffer + sizeof operand_buffer; - - *--p = 0; - do - *--p = '0' + (int) (u % 10); - while ((u /= 10) != 0); - if (((struct mtop *) argument)->mt_count < 0) - *--p = '-'; - - /* MTIOCTOP is the easy one. Nothing is transferred in binary. */ - - sprintf (command_buffer, "I%d\n%s\n", - ((struct mtop *) argument)->mt_op, p); - if (do_command (handle, command_buffer) == -1) - return -1; - - return get_status (handle); - } -#endif /* MTIOCTOP */ - -#ifdef MTIOCGET - case MTIOCGET: - { - ssize_t status; - size_t counter; - - /* Grab the status and read it directly into the structure. This - assumes that the status buffer is not padded and that 2 shorts - fit in a long without any word alignment problems; i.e., the - whole struct is contiguous. NOTE - this is probably NOT a good - assumption. */ - - if (do_command (handle, "S") == -1 - || (status = get_status (handle), status == -1)) - return -1; - - for (; status > 0; status -= counter, argument += counter) - { - counter = safe_read (READ_SIDE (handle), argument, status); - if (counter == SAFE_READ_ERROR || counter == 0) - { - _rmt_shutdown (handle, EIO); - return -1; - } - } - - /* Check for byte position. mt_type (or mt_model) is a small integer - field (normally) so we will check its magnitude. If it is larger - than 256, we will assume that the bytes are swapped and go through - and reverse all the bytes. */ - - if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256) - return 0; - - for (counter = 0; counter < status; counter += 2) - { - char copy = argument[counter]; - - argument[counter] = argument[counter + 1]; - argument[counter + 1] = copy; - } - - return 0; - } -#endif /* MTIOCGET */ - - } -} diff --git a/src/bin/tar/lib/safe-read.c b/src/bin/tar/lib/safe-read.c deleted file mode 100644 index b7bf1d5cd6..0000000000 --- a/src/bin/tar/lib/safe-read.c +++ /dev/null @@ -1,78 +0,0 @@ -/* An interface to read and write that retries after interrupts. - - Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#ifdef SAFE_WRITE -# include "safe-write.h" -#else -# include "safe-read.h" -#endif - -/* Get ssize_t. */ -#include -#include - -#include - -#ifdef EINTR -# define IS_EINTR(x) ((x) == EINTR) -#else -# define IS_EINTR(x) 0 -#endif - -#include - -#ifdef SAFE_WRITE -# define safe_rw safe_write -# define rw write -#else -# define safe_rw safe_read -# define rw read -# undef const -# define const /* empty */ -#endif - -/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if - interrupted. Return the actual number of bytes read(written), zero for EOF, - or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */ -size_t -safe_rw (int fd, void const *buf, size_t count) -{ - /* Work around a bug in Tru64 5.1. Attempting to read more than - INT_MAX bytes fails with errno == EINVAL. See - . - When decreasing COUNT, keep it block-aligned. */ - enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 }; - - for (;;) - { - ssize_t result = rw (fd, buf, count); - - if (0 <= result) - return result; - else if (IS_EINTR (errno)) - continue; - else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count) - count = BUGGY_READ_MAXIMUM; - else - return result; - } -} diff --git a/src/bin/tar/lib/safe-read.h b/src/bin/tar/lib/safe-read.h deleted file mode 100644 index 3451955ad4..0000000000 --- a/src/bin/tar/lib/safe-read.h +++ /dev/null @@ -1,35 +0,0 @@ -/* An interface to read() that retries after interrupts. - Copyright (C) 2002, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -#define SAFE_READ_ERROR ((size_t) -1) - -/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted. - Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR - upon error. */ -extern size_t safe_read (int fd, void *buf, size_t count); - - -#ifdef __cplusplus -} -#endif diff --git a/src/bin/tar/lib/safe-write.c b/src/bin/tar/lib/safe-write.c deleted file mode 100644 index 4c375a6ca1..0000000000 --- a/src/bin/tar/lib/safe-write.c +++ /dev/null @@ -1,19 +0,0 @@ -/* An interface to write that retries after interrupts. - Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#define SAFE_WRITE -#include "safe-read.c" diff --git a/src/bin/tar/lib/safe-write.h b/src/bin/tar/lib/safe-write.h deleted file mode 100644 index c194636209..0000000000 --- a/src/bin/tar/lib/safe-write.h +++ /dev/null @@ -1,25 +0,0 @@ -/* An interface to write() that retries after interrupts. - Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#define SAFE_WRITE_ERROR ((size_t) -1) - -/* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted. - Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR - upon error. */ -extern size_t safe_write (int fd, const void *buf, size_t count); diff --git a/src/bin/tar/lib/same-inode.h b/src/bin/tar/lib/same-inode.h deleted file mode 100644 index deca87b03b..0000000000 --- a/src/bin/tar/lib/same-inode.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Determine whether two stat buffers refer to the same file. - - Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef SAME_INODE_H -# define SAME_INODE_H 1 - -# define SAME_INODE(Stat_buf_1, Stat_buf_2) \ - ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \ - && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev) - -#endif diff --git a/src/bin/tar/lib/save-cwd.c b/src/bin/tar/lib/save-cwd.c deleted file mode 100644 index f07973a3ab..0000000000 --- a/src/bin/tar/lib/save-cwd.c +++ /dev/null @@ -1,103 +0,0 @@ -/* save-cwd.c -- Save and restore current working directory. - - Copyright (C) 1995, 1997, 1998, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -#include "save-cwd.h" - -#include -#include -#include -#include -#include - -#include "chdir-long.h" -#include "fcntl--.h" -#include "xgetcwd.h" - -/* On systems without the fchdir function (WOE), pretend that open - always returns -1 so that save_cwd resorts to using xgetcwd. - Since chdir_long requires fchdir, use chdir instead. */ -#if !HAVE_FCHDIR -# undef open -# define open(File, Flags) (-1) -# undef fchdir -# define fchdir(Fd) (abort (), -1) -# undef chdir_long -# define chdir_long(Dir) chdir (Dir) -#endif - -/* Record the location of the current working directory in CWD so that - the program may change to other directories and later use restore_cwd - to return to the recorded location. This function may allocate - space using malloc (via xgetcwd) or leave a file descriptor open; - use free_cwd to perform the necessary free or close. Upon failure, - no memory is allocated, any locally opened file descriptors are - closed; return non-zero -- in that case, free_cwd need not be - called, but doing so is ok. Otherwise, return zero. - - The `raison d'etre' for this interface is that the working directory - is sometimes inaccessible, and getcwd is not robust or as efficient. - So, we prefer to use the open/fchdir approach, but fall back on - getcwd if necessary. - - Some systems lack fchdir altogether: e.g., OS/2, pre-2001 Cygwin, - SCO Xenix. Also, SunOS 4 and Irix 5.3 provide the function, yet it - doesn't work for partitions on which auditing is enabled. If - you're still using an obsolete system with these problems, please - send email to the maintainer of this code. */ - -int -save_cwd (struct saved_cwd *cwd) -{ - cwd->name = NULL; - - cwd->desc = open (".", O_RDONLY); - if (cwd->desc < 0) - { - cwd->name = xgetcwd (); - return cwd->name ? 0 : -1; - } - - return 0; -} - -/* Change to recorded location, CWD, in directory hierarchy. - Upon failure, return -1 (errno is set by chdir or fchdir). - Upon success, return zero. */ - -int -restore_cwd (const struct saved_cwd *cwd) -{ - if (0 <= cwd->desc) - return fchdir (cwd->desc); - else - return chdir_long (cwd->name); -} - -void -free_cwd (struct saved_cwd *cwd) -{ - if (cwd->desc >= 0) - close (cwd->desc); - if (cwd->name) - free (cwd->name); -} diff --git a/src/bin/tar/lib/save-cwd.h b/src/bin/tar/lib/save-cwd.h deleted file mode 100644 index d646b5540b..0000000000 --- a/src/bin/tar/lib/save-cwd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Save and restore current working directory. - - Copyright (C) 1995, 1997, 1998, 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#ifndef SAVE_CWD_H -# define SAVE_CWD_H 1 - -struct saved_cwd - { - int desc; - char *name; - }; - -int save_cwd (struct saved_cwd *cwd); -int restore_cwd (const struct saved_cwd *cwd); -void free_cwd (struct saved_cwd *cwd); - -#endif /* SAVE_CWD_H */ diff --git a/src/bin/tar/lib/savedir.c b/src/bin/tar/lib/savedir.c deleted file mode 100644 index d930fb4af2..0000000000 --- a/src/bin/tar/lib/savedir.c +++ /dev/null @@ -1,137 +0,0 @@ -/* savedir.c -- save the list of files in a directory in a string - - Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie . */ - -#include - -#include "savedir.h" - -#include - -#include - -#include -#ifndef _D_EXACT_NAMLEN -# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name) -#endif - -#include -#include -#include - -#include "openat.h" -#include "xalloc.h" - -#ifndef NAME_SIZE_DEFAULT -# define NAME_SIZE_DEFAULT 512 -#endif - -/* The results of opendir() in this file are not used with dirfd and fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef opendir -#undef closedir - -/* Return a freshly allocated string containing the file names - in directory DIRP, separated by '\0' characters; - the end is marked by two '\0' characters in a row. - Return NULL (setting errno) if DIRP cannot be read or closed. - If DIRP is NULL, return NULL without affecting errno. */ - -static char * -savedirstream (DIR *dirp) -{ - char *name_space; - size_t allocated = NAME_SIZE_DEFAULT; - size_t used = 0; - int save_errno; - - if (dirp == NULL) - return NULL; - - name_space = xmalloc (allocated); - - for (;;) - { - struct dirent const *dp; - char const *entry; - - errno = 0; - dp = readdir (dirp); - if (! dp) - break; - - /* Skip "", ".", and "..". "" is returned by at least one buggy - implementation: Solaris 2.4 readdir on NFS file systems. */ - entry = dp->d_name; - if (entry[entry[0] != '.' ? 0 : entry[1] != '.' ? 1 : 2] != '\0') - { - size_t entry_size = _D_EXACT_NAMLEN (dp) + 1; - if (used + entry_size < used) - xalloc_die (); - if (allocated <= used + entry_size) - { - do - { - if (2 * allocated < allocated) - xalloc_die (); - allocated *= 2; - } - while (allocated <= used + entry_size); - - name_space = xrealloc (name_space, allocated); - } - memcpy (name_space + used, entry, entry_size); - used += entry_size; - } - } - name_space[used] = '\0'; - save_errno = errno; - if (closedir (dirp) != 0) - save_errno = errno; - if (save_errno != 0) - { - free (name_space); - errno = save_errno; - return NULL; - } - return name_space; -} - -/* Return a freshly allocated string containing the file names - in directory DIR, separated by '\0' characters; - the end is marked by two '\0' characters in a row. - Return NULL (setting errno) if DIR cannot be opened, read, or closed. */ - -char * -savedir (char const *dir) -{ - return savedirstream (opendir (dir)); -} - -/* Return a freshly allocated string containing the file names - in directory FD, separated by '\0' characters; - the end is marked by two '\0' characters in a row. - Return NULL (setting errno) if FD cannot be read or closed. */ - -char * -fdsavedir (int fd) -{ - return savedirstream (fdopendir (fd)); -} diff --git a/src/bin/tar/lib/savedir.h b/src/bin/tar/lib/savedir.h deleted file mode 100644 index 5b7bef9713..0000000000 --- a/src/bin/tar/lib/savedir.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Save the list of files in a directory in a string. - - Copyright (C) 1997, 1999, 2001, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by David MacKenzie . */ - -#if !defined SAVEDIR_H_ -# define SAVEDIR_H_ - -char *savedir (char const *dir); -char *fdsavedir (int fd); - -#endif diff --git a/src/bin/tar/lib/setenv.c b/src/bin/tar/lib/setenv.c deleted file mode 100644 index 458029482b..0000000000 --- a/src/bin/tar/lib/setenv.c +++ /dev/null @@ -1,332 +0,0 @@ -/* Copyright (C) 1992,1995-1999,2000-2003,2005-2007 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if !_LIBC -# include -#endif -#include - -#include -#ifndef __set_errno -# define __set_errno(ev) ((errno) = (ev)) -#endif - -#include -#include -#if _LIBC || HAVE_UNISTD_H -# include -#endif - -#if _LIBC || !HAVE_SETENV - -#if !_LIBC -# include "malloca.h" -#endif - -#if !_LIBC -# define __environ environ -# ifndef HAVE_ENVIRON_DECL -extern char **environ; -# endif -#endif - -#if _LIBC -/* This lock protects against simultaneous modifications of `environ'. */ -# include -__libc_lock_define_initialized (static, envlock) -# define LOCK __libc_lock_lock (envlock) -# define UNLOCK __libc_lock_unlock (envlock) -#else -# define LOCK -# define UNLOCK -#endif - -/* In the GNU C library we must keep the namespace clean. */ -#ifdef _LIBC -# define setenv __setenv -# define clearenv __clearenv -# define tfind __tfind -# define tsearch __tsearch -#endif - -/* In the GNU C library implementation we try to be more clever and - allow arbitrarily many changes of the environment given that the used - values are from a small set. Outside glibc this will eat up all - memory after a while. */ -#if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \ - && defined __GNUC__) -# define USE_TSEARCH 1 -# include -typedef int (*compar_fn_t) (const void *, const void *); - -/* This is a pointer to the root of the search tree with the known - values. */ -static void *known_values; - -# define KNOWN_VALUE(Str) \ - ({ \ - void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \ - value != NULL ? *(char **) value : NULL; \ - }) -# define STORE_VALUE(Str) \ - tsearch (Str, &known_values, (compar_fn_t) strcmp) - -#else -# undef USE_TSEARCH - -# define KNOWN_VALUE(Str) NULL -# define STORE_VALUE(Str) do { } while (0) - -#endif - - -/* If this variable is not a null pointer we allocated the current - environment. */ -static char **last_environ; - - -/* This function is used by `setenv' and `putenv'. The difference between - the two functions is that for the former must create a new string which - is then placed in the environment, while the argument of `putenv' - must be used directly. This is all complicated by the fact that we try - to reuse values once generated for a `setenv' call since we can never - free the strings. */ -int -__add_to_environ (const char *name, const char *value, const char *combined, - int replace) -{ - register char **ep; - register size_t size; - const size_t namelen = strlen (name); - const size_t vallen = value != NULL ? strlen (value) + 1 : 0; - - LOCK; - - /* We have to get the pointer now that we have the lock and not earlier - since another thread might have created a new environment. */ - ep = __environ; - - size = 0; - if (ep != NULL) - { - for (; *ep != NULL; ++ep) - if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') - break; - else - ++size; - } - - if (ep == NULL || *ep == NULL) - { - char **new_environ; -#ifdef USE_TSEARCH - char *new_value; -#endif - - /* We allocated this space; we can extend it. */ - new_environ = - (char **) (last_environ == NULL - ? malloc ((size + 2) * sizeof (char *)) - : realloc (last_environ, (size + 2) * sizeof (char *))); - if (new_environ == NULL) - { - UNLOCK; - return -1; - } - - /* If the whole entry is given add it. */ - if (combined != NULL) - /* We must not add the string to the search tree since it belongs - to the user. */ - new_environ[size] = (char *) combined; - else - { - /* See whether the value is already known. */ -#ifdef USE_TSEARCH -# ifdef _LIBC - new_value = (char *) alloca (namelen + 1 + vallen); - __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), - value, vallen); -# else - new_value = (char *) malloca (namelen + 1 + vallen); - if (new_value == NULL) - { - __set_errno (ENOMEM); - UNLOCK; - return -1; - } - memcpy (new_value, name, namelen); - new_value[namelen] = '='; - memcpy (&new_value[namelen + 1], value, vallen); -# endif - - new_environ[size] = KNOWN_VALUE (new_value); - if (new_environ[size] == NULL) -#endif - { - new_environ[size] = (char *) malloc (namelen + 1 + vallen); - if (new_environ[size] == NULL) - { -#if defined USE_TSEARCH && !defined _LIBC - freea (new_value); -#endif - __set_errno (ENOMEM); - UNLOCK; - return -1; - } - -#ifdef USE_TSEARCH - memcpy (new_environ[size], new_value, namelen + 1 + vallen); -#else - memcpy (new_environ[size], name, namelen); - new_environ[size][namelen] = '='; - memcpy (&new_environ[size][namelen + 1], value, vallen); -#endif - /* And save the value now. We cannot do this when we remove - the string since then we cannot decide whether it is a - user string or not. */ - STORE_VALUE (new_environ[size]); - } -#if defined USE_TSEARCH && !defined _LIBC - freea (new_value); -#endif - } - - if (__environ != last_environ) - memcpy ((char *) new_environ, (char *) __environ, - size * sizeof (char *)); - - new_environ[size + 1] = NULL; - - last_environ = __environ = new_environ; - } - else if (replace) - { - char *np; - - /* Use the user string if given. */ - if (combined != NULL) - np = (char *) combined; - else - { -#ifdef USE_TSEARCH - char *new_value; -# ifdef _LIBC - new_value = alloca (namelen + 1 + vallen); - __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), - value, vallen); -# else - new_value = malloca (namelen + 1 + vallen); - if (new_value == NULL) - { - __set_errno (ENOMEM); - UNLOCK; - return -1; - } - memcpy (new_value, name, namelen); - new_value[namelen] = '='; - memcpy (&new_value[namelen + 1], value, vallen); -# endif - - np = KNOWN_VALUE (new_value); - if (np == NULL) -#endif - { - np = malloc (namelen + 1 + vallen); - if (np == NULL) - { -#if defined USE_TSEARCH && !defined _LIBC - freea (new_value); -#endif - __set_errno (ENOMEM); - UNLOCK; - return -1; - } - -#ifdef USE_TSEARCH - memcpy (np, new_value, namelen + 1 + vallen); -#else - memcpy (np, name, namelen); - np[namelen] = '='; - memcpy (&np[namelen + 1], value, vallen); -#endif - /* And remember the value. */ - STORE_VALUE (np); - } -#if defined USE_TSEARCH && !defined _LIBC - freea (new_value); -#endif - } - - *ep = np; - } - - UNLOCK; - - return 0; -} - -int -setenv (const char *name, const char *value, int replace) -{ - return __add_to_environ (name, value, NULL, replace); -} - -/* The `clearenv' was planned to be added to POSIX.1 but probably - never made it. Nevertheless the POSIX.9 standard (POSIX bindings - for Fortran 77) requires this function. */ -int -clearenv (void) -{ - LOCK; - - if (__environ == last_environ && __environ != NULL) - { - /* We allocated this environment so we can free it. */ - free (__environ); - last_environ = NULL; - } - - /* Clear the environment pointer removes the whole environment. */ - __environ = NULL; - - UNLOCK; - - return 0; -} - -#ifdef _LIBC -static void -free_mem (void) -{ - /* Remove all traces. */ - clearenv (); - - /* Now remove the search tree. */ - __tdestroy (known_values, free); - known_values = NULL; -} -text_set_element (__libc_subfreeres, free_mem); - - -# undef setenv -# undef clearenv -weak_alias (__setenv, setenv) -weak_alias (__clearenv, clearenv) -#endif - -#endif /* _LIBC || !HAVE_SETENV */ diff --git a/src/bin/tar/lib/setenv.h b/src/bin/tar/lib/setenv.h deleted file mode 100644 index 92e7bbaf7f..0000000000 --- a/src/bin/tar/lib/setenv.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Setting environment variables. - Copyright (C) 2001-2004, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if HAVE_SETENV || HAVE_UNSETENV - -/* Get setenv(), unsetenv() declarations. */ -# include - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if !HAVE_SETENV - -/* Set NAME to VALUE in the environment. - If REPLACE is nonzero, overwrite an existing value. */ -extern int setenv (const char *name, const char *value, int replace); - -#endif - -#if HAVE_UNSETENV - -# if VOID_UNSETENV -/* On some systems, unsetenv() returns void. - This is the case for FreeBSD 4.8, NetBSD 1.6, OpenBSD 3.4. */ -# define unsetenv(name) ((unsetenv)(name), 0) -# endif - -#else - -/* Remove the variable NAME from the environment. */ -extern int unsetenv (const char *name); - -#endif - -#ifdef __cplusplus -} -#endif diff --git a/src/bin/tar/lib/sleep.c b/src/bin/tar/lib/sleep.c deleted file mode 100644 index 037559b016..0000000000 --- a/src/bin/tar/lib/sleep.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Pausing execution of the current thread. - Copyright (C) 2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2007. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - -# define WIN32_LEAN_AND_MEAN /* avoid including junk */ -# include - -unsigned int -sleep (unsigned int seconds) -{ - unsigned int remaining; - - /* Sleep for 1 second many times, because - 1. Sleep is not interruptiple by Ctrl-C, - 2. we want to avoid arithmetic overflow while multiplying with 1000. */ - for (remaining = seconds; remaining > 0; remaining--) - Sleep (1000); - - return remaining; -} - -#else - - #error "Please port gnulib sleep.c to your platform, possibly using usleep() or select(), then report this to bug-gnulib." - -#endif diff --git a/src/bin/tar/lib/stat-macros.h b/src/bin/tar/lib/stat-macros.h deleted file mode 100644 index 690216c74e..0000000000 --- a/src/bin/tar/lib/stat-macros.h +++ /dev/null @@ -1,3 +0,0 @@ -/* All the mode bits that can be affected by chmod. */ -#define CHMOD_MODE_BITS \ - (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) diff --git a/src/bin/tar/lib/stat-time.h b/src/bin/tar/lib/stat-time.h deleted file mode 100644 index 649c848732..0000000000 --- a/src/bin/tar/lib/stat-time.h +++ /dev/null @@ -1,184 +0,0 @@ -/* stat-related time functions. - - Copyright (C) 2005, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#ifndef STAT_TIME_H -#define STAT_TIME_H 1 - -#include -#include - -/* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type - struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST, - ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST, - if available. ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim - for access, status change, data modification, or birth (creation) - time respectively. - - These macros are private to stat-time.h. */ -#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC -# ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC -# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim) -# else -# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec) -# endif -#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC -# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec) -#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC -# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec) -#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC -# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec) -#endif - -/* Return the nanosecond component of *ST's access time. */ -static inline long int -get_stat_atime_ns (struct stat const *st) -{ -# if defined STAT_TIMESPEC - return STAT_TIMESPEC (st, st_atim).tv_nsec; -# elif defined STAT_TIMESPEC_NS - return STAT_TIMESPEC_NS (st, st_atim); -# else - return 0; -# endif -} - -/* Return the nanosecond component of *ST's status change time. */ -static inline long int -get_stat_ctime_ns (struct stat const *st) -{ -# if defined STAT_TIMESPEC - return STAT_TIMESPEC (st, st_ctim).tv_nsec; -# elif defined STAT_TIMESPEC_NS - return STAT_TIMESPEC_NS (st, st_ctim); -# else - return 0; -# endif -} - -/* Return the nanosecond component of *ST's data modification time. */ -static inline long int -get_stat_mtime_ns (struct stat const *st) -{ -# if defined STAT_TIMESPEC - return STAT_TIMESPEC (st, st_mtim).tv_nsec; -# elif defined STAT_TIMESPEC_NS - return STAT_TIMESPEC_NS (st, st_mtim); -# else - return 0; -# endif -} - -/* Return the nanosecond component of *ST's birth time. */ -static inline long int -get_stat_birthtime_ns (struct stat const *st) -{ -# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC - return STAT_TIMESPEC (st, st_birthtim).tv_nsec; -# elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC - return STAT_TIMESPEC_NS (st, st_birthtim); -# else - return 0; -# endif -} - -/* Return *ST's access time. */ -static inline struct timespec -get_stat_atime (struct stat const *st) -{ -#ifdef STAT_TIMESPEC - return STAT_TIMESPEC (st, st_atim); -#else - struct timespec t; - t.tv_sec = st->st_atime; - t.tv_nsec = get_stat_atime_ns (st); - return t; -#endif -} - -/* Return *ST's status change time. */ -static inline struct timespec -get_stat_ctime (struct stat const *st) -{ -#ifdef STAT_TIMESPEC - return STAT_TIMESPEC (st, st_ctim); -#else - struct timespec t; - t.tv_sec = st->st_ctime; - t.tv_nsec = get_stat_ctime_ns (st); - return t; -#endif -} - -/* Return *ST's data modification time. */ -static inline struct timespec -get_stat_mtime (struct stat const *st) -{ -#ifdef STAT_TIMESPEC - return STAT_TIMESPEC (st, st_mtim); -#else - struct timespec t; - t.tv_sec = st->st_mtime; - t.tv_nsec = get_stat_mtime_ns (st); - return t; -#endif -} - -/* Return *ST's birth time, if available; otherwise return a value - with negative tv_nsec. */ -static inline struct timespec -get_stat_birthtime (struct stat const *st) -{ - struct timespec t; - -#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ - || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) - t = STAT_TIMESPEC (st, st_birthtim); -#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC - t.tv_sec = st->st_birthtime; - t.tv_nsec = st->st_birthtimensec; -#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - /* Woe32 native platforms (but not Cygwin) put the "file creation - time" in st_ctime (!). See - . */ - t.tv_sec = st->st_ctime; - t.tv_nsec = 0; -#else - /* Birth time is not supported. Set tv_sec to avoid undefined behavior. */ - t.tv_sec = -1; - t.tv_nsec = -1; -#endif - -#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ - || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \ - || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) - /* FreeBSD and NetBSD sometimes signal the absence of knowledge by - using zero. Attempt to work around this problem. Alas, this can - report failure even for valid time stamps. Also, NetBSD - sometimes returns junk in the birth time fields; work around this - bug if it it is detected. There's no need to detect negative - tv_nsec junk as negative tv_nsec already indicates an error. */ - if (t.tv_sec == 0 || 1000000000 <= t.tv_nsec) - t.tv_nsec = -1; -#endif - - return t; -} - -#endif diff --git a/src/bin/tar/lib/stdbool.in.h b/src/bin/tar/lib/stdbool.in.h deleted file mode 100644 index 61018e89e4..0000000000 --- a/src/bin/tar/lib/stdbool.in.h +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2001. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GL_STDBOOL_H -#define _GL_STDBOOL_H - -/* ISO C 99 for platforms that lack it. */ - -/* Usage suggestions: - - Programs that use should be aware of some limitations - and standards compliance issues. - - Standards compliance: - - - must be #included before 'bool', 'false', 'true' - can be used. - - - You cannot assume that sizeof (bool) == 1. - - - Programs should not undefine the macros bool, true, and false, - as C99 lists that as an "obsolescent feature". - - Limitations of this substitute, when used in a C89 environment: - - - must be #included before the '_Bool' type can be used. - - - You cannot assume that _Bool is a typedef; it might be a macro. - - - Bit-fields of type 'bool' are not supported. Portable code - should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'. - - - In C99, casts and automatic conversions to '_Bool' or 'bool' are - performed in such a way that every nonzero value gets converted - to 'true', and zero gets converted to 'false'. This doesn't work - with this substitute. With this substitute, only the values 0 and 1 - give the expected result when converted to _Bool' or 'bool'. - - Also, it is suggested that programs use 'bool' rather than '_Bool'; - this isn't required, but 'bool' is more common. */ - - -/* 7.16. Boolean type and values */ - -/* BeOS already #defines false 0, true 1. We use the same - definitions below, but temporarily we have to #undef them. */ -#if (defined(__BEOS__) || defined(__HAIKU__)) -# include /* defines bool but not _Bool */ -# undef false -# undef true -#endif - -/* For the sake of symbolic names in gdb, we define true and false as - enum constants, not only as macros. - It is tempting to write - typedef enum { false = 0, true = 1 } _Bool; - so that gdb prints values of type 'bool' symbolically. But if we do - this, values of type '_Bool' may promote to 'int' or 'unsigned int' - (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int' - (see ISO C 99 6.3.1.1.(2)). So we add a negative value to the - enum; this ensures that '_Bool' promotes to 'int'. */ -#if defined __cplusplus || (defined(__BEOS__) || defined(__HAIKU__)) - /* A compiler known to have 'bool'. */ - /* If the compiler already has both 'bool' and '_Bool', we can assume they - are the same types. */ -# if !@HAVE__BOOL@ -typedef bool _Bool; -# endif -#else -# if !defined __GNUC__ - /* If @HAVE__BOOL@: - Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when - the built-in _Bool type is used. See - http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html - Similar bugs are likely with other compilers as well; this file - wouldn't be used if was working. - So we override the _Bool type. - If !@HAVE__BOOL@: - Need to define _Bool ourselves. As 'signed char' or as an enum type? - Use of a typedef, with SunPRO C, leads to a stupid - "warning: _Bool is a keyword in ISO C99". - Use of an enum type, with IRIX cc, leads to a stupid - "warning(1185): enumerated type mixed with another type". - The only benefit of the enum type, debuggability, is not important - with these compilers. So use 'signed char' and no typedef. */ -# define _Bool signed char -enum { false = 0, true = 1 }; -# else - /* With this compiler, trust the _Bool type if the compiler has it. */ -# if !@HAVE__BOOL@ -typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; -# endif -# endif -#endif -#define bool _Bool - -/* The other macros must be usable in preprocessor directives. */ -#define false 0 -#define true 1 -#define __bool_true_false_are_defined 1 - -#endif /* _GL_STDBOOL_H */ diff --git a/src/bin/tar/lib/stdint.in.h b/src/bin/tar/lib/stdint.in.h deleted file mode 100644 index 121118cff7..0000000000 --- a/src/bin/tar/lib/stdint.in.h +++ /dev/null @@ -1,508 +0,0 @@ -/* Copyright (C) 2001-2002, 2004-2007 Free Software Foundation, Inc. - Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. - This file is part of gnulib. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* - * ISO C 99 for platforms that lack it. - * - */ - -#ifndef _GL_STDINT_H - -/* Get those types that are already defined in other system include - files, so that we can "#define int8_t signed char" below without - worrying about a later system include file containing a "typedef - signed char int8_t;" that will get messed up by our macro. Our - macros should all be consistent with the system versions, except - for the "fast" types and macros, which we recommend against using - in public interfaces due to compiler differences. */ - -#if @HAVE_STDINT_H@ -# if defined __sgi && ! defined __c99 - /* Bypass IRIX's if in C89 mode, since it merely annoys users - with "This header file is to be used only for c99 mode compilations" - diagnostics. */ -# define __STDINT_H__ -# endif - /* Other systems may have an incomplete or buggy . - Include it before , since any "#include " - in would reinclude us, skipping our contents because - _GL_STDINT_H is defined. - The include_next requires a split double-inclusion guard. */ -# @INCLUDE_NEXT@ @NEXT_STDINT_H@ -#endif - -#if ! defined _GL_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H -#define _GL_STDINT_H - -/* defines some of the stdint.h types as well, on glibc, - IRIX 6.5, and OpenBSD 3.8 (via ). - AIX 5.2 isn't needed and causes troubles. - MacOS X 10.4.6 includes (which is us), but - relies on the system definitions, so include - after @NEXT_STDINT_H@. */ -#if @HAVE_SYS_TYPES_H@ && ! defined _AIX -# include -#endif - -/* Get LONG_MIN, LONG_MAX, ULONG_MAX. */ -#include - -#if @HAVE_INTTYPES_H@ - /* In OpenBSD 3.8, includes , which defines - int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. - also defines intptr_t and uintptr_t. */ -# define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H -# include -# undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H -#elif @HAVE_SYS_INTTYPES_H@ - /* Solaris 7 has the types except the *_fast*_t types, and - the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ -# include -#endif - -#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ - /* Linux libc4 >= 4.6.7 and libc5 have a that defines - int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is - included by . */ -# include -#endif - -#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS - -/* Get WCHAR_MIN, WCHAR_MAX. */ -# if ! (defined WCHAR_MIN && defined WCHAR_MAX) -# include -# endif - -#endif - -/* Minimum and maximum values for a integer type under the usual assumption. - Return an unspecified value if BITS == 0, adding a check to pacify - picky compilers. */ - -#define _STDINT_MIN(signed, bits, zero) \ - ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) - -#define _STDINT_MAX(signed, bits, zero) \ - ((signed) \ - ? ~ _STDINT_MIN (signed, bits, zero) \ - : ((((zero) + 1) << ((bits) ? (bits) - 1 : 0)) - 1) * 2 + 1) - -/* 7.18.1.1. Exact-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. */ - -#undef int8_t -#undef uint8_t -#define int8_t signed char -#define uint8_t unsigned char - -#undef int16_t -#undef uint16_t -#define int16_t short int -#define uint16_t unsigned short int - -#undef int32_t -#undef uint32_t -#define int32_t int -#define uint32_t unsigned int - -/* Do not undefine int64_t if gnulib is not being used with 64-bit - types, since otherwise it breaks platforms like Tandem/NSK. */ -#if LONG_MAX >> 31 >> 31 == 1 -# undef int64_t -# define int64_t long int -# define GL_INT64_T -#elif defined _MSC_VER -# undef int64_t -# define int64_t __int64 -# define GL_INT64_T -#elif @HAVE_LONG_LONG_INT@ -# undef int64_t -# define int64_t long long int -# define GL_INT64_T -#endif - -#if ULONG_MAX >> 31 >> 31 >> 1 == 1 -# undef uint64_t -# define uint64_t unsigned long int -# define GL_UINT64_T -#elif defined _MSC_VER -# undef uint64_t -# define uint64_t unsigned __int64 -# define GL_UINT64_T -#elif @HAVE_UNSIGNED_LONG_LONG_INT@ -# undef uint64_t -# define uint64_t unsigned long long int -# define GL_UINT64_T -#endif - -/* Avoid collision with Solaris 2.5.1 etc. */ -#define _UINT8_T -#define _UINT32_T -#define _UINT64_T - - -/* 7.18.1.2. Minimum-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types - are the same as the corresponding N_t types. */ - -#undef int_least8_t -#undef uint_least8_t -#undef int_least16_t -#undef uint_least16_t -#undef int_least32_t -#undef uint_least32_t -#undef int_least64_t -#undef uint_least64_t -#define int_least8_t int8_t -#define uint_least8_t uint8_t -#define int_least16_t int16_t -#define uint_least16_t uint16_t -#define int_least32_t int32_t -#define uint_least32_t uint32_t -#ifdef GL_INT64_T -# define int_least64_t int64_t -#endif -#ifdef GL_UINT64_T -# define uint_least64_t uint64_t -#endif - -/* 7.18.1.3. Fastest minimum-width integer types */ - -/* Note: Other substitutes may define these types differently. - It is not recommended to use these types in public header files. */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types - are taken from the same list of types. Assume that 'long int' - is fast enough for all narrower integers. */ - -#undef int_fast8_t -#undef uint_fast8_t -#undef int_fast16_t -#undef uint_fast16_t -#undef int_fast32_t -#undef uint_fast32_t -#undef int_fast64_t -#undef uint_fast64_t -#define int_fast8_t long int -#define uint_fast8_t unsigned int_fast8_t -#define int_fast16_t long int -#define uint_fast16_t unsigned int_fast16_t -#define int_fast32_t long int -#define uint_fast32_t unsigned int_fast32_t -#ifdef GL_INT64_T -# define int_fast64_t int64_t -#endif -#ifdef GL_UINT64_T -# define uint_fast64_t uint64_t -#endif - -/* 7.18.1.4. Integer types capable of holding object pointers */ - -#undef intptr_t -#undef uintptr_t -#define intptr_t long int -#define uintptr_t unsigned long int - -/* 7.18.1.5. Greatest-width integer types */ - -/* Note: These types are compiler dependent. It may be unwise to use them in - public header files. */ - -#undef intmax_t -#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 -# define intmax_t long long int -#elif defined GL_INT64_T -# define intmax_t int64_t -#else -# define intmax_t long int -#endif - -#undef uintmax_t -#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 -# define uintmax_t unsigned long long int -#elif defined GL_UINT64_T -# define uintmax_t uint64_t -#else -# define uintmax_t unsigned long int -#endif - -/* 7.18.2. Limits of specified-width integer types */ - -#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS - -/* 7.18.2.1. Limits of exact-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. */ - -#undef INT8_MIN -#undef INT8_MAX -#undef UINT8_MAX -#define INT8_MIN (~ INT8_MAX) -#define INT8_MAX 127 -#define UINT8_MAX 255 - -#undef INT16_MIN -#undef INT16_MAX -#undef UINT16_MAX -#define INT16_MIN (~ INT16_MAX) -#define INT16_MAX 32767 -#define UINT16_MAX 65535 - -#undef INT32_MIN -#undef INT32_MAX -#undef UINT32_MAX -#define INT32_MIN (~ INT32_MAX) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U - -#undef INT64_MIN -#undef INT64_MAX -#ifdef GL_INT64_T -/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 - evaluates the latter incorrectly in preprocessor expressions. */ -# define INT64_MIN (- INTMAX_C (1) << 63) -# define INT64_MAX INTMAX_C (9223372036854775807) -#endif - -#undef UINT64_MAX -#ifdef GL_UINT64_T -# define UINT64_MAX UINTMAX_C (18446744073709551615) -#endif - -/* 7.18.2.2. Limits of minimum-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types - are the same as the corresponding N_t types. */ - -#undef INT_LEAST8_MIN -#undef INT_LEAST8_MAX -#undef UINT_LEAST8_MAX -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define UINT_LEAST8_MAX UINT8_MAX - -#undef INT_LEAST16_MIN -#undef INT_LEAST16_MAX -#undef UINT_LEAST16_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define UINT_LEAST16_MAX UINT16_MAX - -#undef INT_LEAST32_MIN -#undef INT_LEAST32_MAX -#undef UINT_LEAST32_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define UINT_LEAST32_MAX UINT32_MAX - -#undef INT_LEAST64_MIN -#undef INT_LEAST64_MAX -#ifdef GL_INT64_T -# define INT_LEAST64_MIN INT64_MIN -# define INT_LEAST64_MAX INT64_MAX -#endif - -#undef UINT_LEAST64_MAX -#ifdef GL_UINT64_T -# define UINT_LEAST64_MAX UINT64_MAX -#endif - -/* 7.18.2.3. Limits of fastest minimum-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types - are taken from the same list of types. */ - -#undef INT_FAST8_MIN -#undef INT_FAST8_MAX -#undef UINT_FAST8_MAX -#define INT_FAST8_MIN LONG_MIN -#define INT_FAST8_MAX LONG_MAX -#define UINT_FAST8_MAX ULONG_MAX - -#undef INT_FAST16_MIN -#undef INT_FAST16_MAX -#undef UINT_FAST16_MAX -#define INT_FAST16_MIN LONG_MIN -#define INT_FAST16_MAX LONG_MAX -#define UINT_FAST16_MAX ULONG_MAX - -#undef INT_FAST32_MIN -#undef INT_FAST32_MAX -#undef UINT_FAST32_MAX -#define INT_FAST32_MIN LONG_MIN -#define INT_FAST32_MAX LONG_MAX -#define UINT_FAST32_MAX ULONG_MAX - -#undef INT_FAST64_MIN -#undef INT_FAST64_MAX -#ifdef GL_INT64_T -# define INT_FAST64_MIN INT64_MIN -# define INT_FAST64_MAX INT64_MAX -#endif - -#undef UINT_FAST64_MAX -#ifdef GL_UINT64_T -# define UINT_FAST64_MAX UINT64_MAX -#endif - -/* 7.18.2.4. Limits of integer types capable of holding object pointers */ - -#undef INTPTR_MIN -#undef INTPTR_MAX -#undef UINTPTR_MAX -#define INTPTR_MIN LONG_MIN -#define INTPTR_MAX LONG_MAX -#define UINTPTR_MAX ULONG_MAX - -/* 7.18.2.5. Limits of greatest-width integer types */ - -#undef INTMAX_MIN -#undef INTMAX_MAX -#ifdef INT64_MAX -# define INTMAX_MIN INT64_MIN -# define INTMAX_MAX INT64_MAX -#else -# define INTMAX_MIN INT32_MIN -# define INTMAX_MAX INT32_MAX -#endif - -#undef UINTMAX_MAX -#ifdef UINT64_MAX -# define UINTMAX_MAX UINT64_MAX -#else -# define UINTMAX_MAX UINT32_MAX -#endif - -/* 7.18.3. Limits of other integer types */ - -/* ptrdiff_t limits */ -#undef PTRDIFF_MIN -#undef PTRDIFF_MAX -#define PTRDIFF_MIN \ - _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) -#define PTRDIFF_MAX \ - _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) - -/* sig_atomic_t limits */ -#undef SIG_ATOMIC_MIN -#undef SIG_ATOMIC_MAX -#define SIG_ATOMIC_MIN \ - _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ - 0@SIG_ATOMIC_T_SUFFIX@) -#define SIG_ATOMIC_MAX \ - _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ - 0@SIG_ATOMIC_T_SUFFIX@) - - -/* size_t limit */ -#undef SIZE_MAX -#define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) - -/* wchar_t limits */ -#undef WCHAR_MIN -#undef WCHAR_MAX -#define WCHAR_MIN \ - _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) -#define WCHAR_MAX \ - _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) - -/* wint_t limits */ -#undef WINT_MIN -#undef WINT_MAX -#define WINT_MIN \ - _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) -#define WINT_MAX \ - _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) - -#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */ - -/* 7.18.4. Macros for integer constants */ - -#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS - -/* 7.18.4.1. Macros for minimum-width integer constants */ -/* According to ISO C 99 Technical Corrigendum 1 */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ - -#undef INT8_C -#undef UINT8_C -#define INT8_C(x) x -#define UINT8_C(x) x - -#undef INT16_C -#undef UINT16_C -#define INT16_C(x) x -#define UINT16_C(x) x - -#undef INT32_C -#undef UINT32_C -#define INT32_C(x) x -#define UINT32_C(x) x ## U - -#undef INT64_C -#undef UINT64_C -#if LONG_MAX >> 31 >> 31 == 1 -# define INT64_C(x) x##L -#elif defined _MSC_VER -# define INT64_C(x) x##i64 -#elif @HAVE_LONG_LONG_INT@ -# define INT64_C(x) x##LL -#endif -#if ULONG_MAX >> 31 >> 31 >> 1 == 1 -# define UINT64_C(x) x##UL -#elif defined _MSC_VER -# define UINT64_C(x) x##ui64 -#elif @HAVE_UNSIGNED_LONG_LONG_INT@ -# define UINT64_C(x) x##ULL -#endif - -/* 7.18.4.2. Macros for greatest-width integer constants */ - -#undef INTMAX_C -#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 -# define INTMAX_C(x) x##LL -#elif defined GL_INT64_T -# define INTMAX_C(x) INT64_C(x) -#else -# define INTMAX_C(x) x##L -#endif - -#undef UINTMAX_C -#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 -# define UINTMAX_C(x) x##ULL -#elif defined GL_UINT64_T -# define UINTMAX_C(x) UINT64_C(x) -#else -# define UINTMAX_C(x) x##UL -#endif - -#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */ - -#endif /* _GL_STDINT_H */ -#endif /* !defined _GL_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ diff --git a/src/bin/tar/lib/stdio.in.h b/src/bin/tar/lib/stdio.in.h deleted file mode 100644 index 5264194bdf..0000000000 --- a/src/bin/tar/lib/stdio.in.h +++ /dev/null @@ -1,356 +0,0 @@ -/* A GNU-like . - - Copyright (C) 2004, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if defined __need_FILE || defined __need___FILE -/* Special invocation convention inside glibc header files. */ - -#@INCLUDE_NEXT@ @NEXT_STDIO_H@ - -#else -/* Normal invocation convention. */ - -#ifndef _GL_STDIO_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_STDIO_H@ - -#ifndef _GL_STDIO_H -#define _GL_STDIO_H - -#include -#include - -#if (@GNULIB_FSEEKO@ && @REPLACE_FSEEKO@) \ - || (@GNULIB_FTELLO@ && @REPLACE_FTELLO@) \ - || (@GNULIB_GETDELIM@ && !@HAVE_DECL_GETDELIM@) \ - || (@GNULIB_GETLINE@ && (!@HAVE_DECL_GETLINE@ || @REPLACE_GETLINE@)) -/* Get off_t and ssize_t. */ -# include -#endif - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif -#endif - - -/* The definition of GL_LINK_WARNING is copied here. */ - - -#ifdef __cplusplus -extern "C" { -#endif - - -#if @GNULIB_FPRINTF_POSIX@ -# if @REPLACE_FPRINTF@ -# define fprintf rpl_fprintf -extern int fprintf (FILE *fp, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef fprintf -# define fprintf \ - (GL_LINK_WARNING ("fprintf is not always POSIX compliant - " \ - "use gnulib module fprintf-posix for portable " \ - "POSIX compliance"), \ - fprintf) -#endif - -#if @GNULIB_VFPRINTF_POSIX@ -# if @REPLACE_VFPRINTF@ -# define vfprintf rpl_vfprintf -extern int vfprintf (FILE *fp, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef vfprintf -# define vfprintf(s,f,a) \ - (GL_LINK_WARNING ("vfprintf is not always POSIX compliant - " \ - "use gnulib module vfprintf-posix for portable " \ - "POSIX compliance"), \ - vfprintf (s, f, a)) -#endif - -#if @GNULIB_PRINTF_POSIX@ -# if @REPLACE_PRINTF@ -/* Don't break __attribute__((format(printf,M,N))). */ -# define printf __printf__ -extern int printf (const char *format, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef printf -# define printf \ - (GL_LINK_WARNING ("printf is not always POSIX compliant - " \ - "use gnulib module printf-posix for portable " \ - "POSIX compliance"), \ - printf) -/* Don't break __attribute__((format(printf,M,N))). */ -# define format(kind,m,n) format (__##kind##__, m, n) -# define __format__(kind,m,n) __format__ (__##kind##__, m, n) -# define ____printf____ __printf__ -# define ____scanf____ __scanf__ -# define ____strftime____ __strftime__ -# define ____strfmon____ __strfmon__ -#endif - -#if @GNULIB_VPRINTF_POSIX@ -# if @REPLACE_VPRINTF@ -# define vprintf rpl_vprintf -extern int vprintf (const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 1, 0))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef vprintf -# define vprintf(f,a) \ - (GL_LINK_WARNING ("vprintf is not always POSIX compliant - " \ - "use gnulib module vprintf-posix for portable " \ - "POSIX compliance"), \ - vprintf (f, a)) -#endif - -#if @GNULIB_SNPRINTF@ -# if @REPLACE_SNPRINTF@ -# define snprintf rpl_snprintf -# endif -# if @REPLACE_SNPRINTF@ || !@HAVE_DECL_SNPRINTF@ -extern int snprintf (char *str, size_t size, const char *format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef snprintf -# define snprintf \ - (GL_LINK_WARNING ("snprintf is unportable - " \ - "use gnulib module snprintf for portability"), \ - snprintf) -#endif - -#if @GNULIB_VSNPRINTF@ -# if @REPLACE_VSNPRINTF@ -# define vsnprintf rpl_vsnprintf -# endif -# if @REPLACE_VSNPRINTF@ || !@HAVE_DECL_VSNPRINTF@ -extern int vsnprintf (char *str, size_t size, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 3, 0))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef vsnprintf -# define vsnprintf(b,s,f,a) \ - (GL_LINK_WARNING ("vsnprintf is unportable - " \ - "use gnulib module vsnprintf for portability"), \ - vsnprintf (b, s, f, a)) -#endif - -#if @GNULIB_SPRINTF_POSIX@ -# if @REPLACE_SPRINTF@ -# define sprintf rpl_sprintf -extern int sprintf (char *str, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef sprintf -# define sprintf \ - (GL_LINK_WARNING ("sprintf is not always POSIX compliant - " \ - "use gnulib module sprintf-posix for portable " \ - "POSIX compliance"), \ - sprintf) -#endif - -#if @GNULIB_VSPRINTF_POSIX@ -# if @REPLACE_VSPRINTF@ -# define vsprintf rpl_vsprintf -extern int vsprintf (char *str, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); -# endif -#elif defined GNULIB_POSIXCHECK -# undef vsprintf -# define vsprintf(b,f,a) \ - (GL_LINK_WARNING ("vsprintf is not always POSIX compliant - " \ - "use gnulib module vsprintf-posix for portable " \ - "POSIX compliance"), \ - vsprintf (b, f, a)) -#endif - -#if @GNULIB_VASPRINTF@ -# if @REPLACE_VASPRINTF@ -# define asprintf rpl_asprintf -# define vasprintf rpl_vasprintf -# endif -# if @REPLACE_VASPRINTF@ || !@HAVE_VASPRINTF@ - /* Write formatted output to a string dynamically allocated with malloc(). - If the memory allocation succeeds, store the address of the string in - *RESULT and return the number of resulting bytes, excluding the trailing - NUL. Upon memory allocation error, or some other error, return -1. */ - extern int asprintf (char **result, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - extern int vasprintf (char **result, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); -# endif -#endif - -#if @GNULIB_FSEEKO@ -# if @REPLACE_FSEEKO@ -/* Provide fseek, fseeko functions that are aware of a preceding - fflush(), and which detect pipes. */ -# define fseeko rpl_fseeko -extern int fseeko (FILE *fp, off_t offset, int whence); -# define fseek(fp, offset, whence) fseeko (fp, (off_t)(offset), whence) -# endif -#elif defined GNULIB_POSIXCHECK -# undef fseeko -# define fseeko(f,o,w) \ - (GL_LINK_WARNING ("fseeko is unportable - " \ - "use gnulib module fseeko for portability"), \ - fseeko (f, o, w)) -#endif - -#if @GNULIB_FSEEK@ && @REPLACE_FSEEK@ -extern int rpl_fseek (FILE *fp, long offset, int whence); -# undef fseek -# if defined GNULIB_POSIXCHECK -# define fseek(f,o,w) \ - (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use fseeko function for handling of large files"), \ - rpl_fseek (f, o, w)) -# else -# define fseek rpl_fseek -# endif -#elif defined GNULIB_POSIXCHECK -# ifndef fseek -# define fseek(f,o,w) \ - (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use fseeko function for handling of large files"), \ - fseek (f, o, w)) -# endif -#endif - -#if @GNULIB_FTELLO@ -# if @REPLACE_FTELLO@ -# define ftello rpl_ftello -extern off_t ftello (FILE *fp); -# define ftell(fp) ftello (fp) -# endif -#elif defined GNULIB_POSIXCHECK -# undef ftello -# define ftello(f) \ - (GL_LINK_WARNING ("ftello is unportable - " \ - "use gnulib module ftello for portability"), \ - ftello (f)) -#endif - -#if @GNULIB_FTELL@ && @REPLACE_FTELL@ -extern long rpl_ftell (FILE *fp); -# undef ftell -# if GNULIB_POSIXCHECK -# define ftell(f) \ - (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use ftello function for handling of large files"), \ - rpl_ftell (f)) -# else -# define ftell rpl_ftell -# endif -#elif defined GNULIB_POSIXCHECK -# ifndef ftell -# define ftell(f) \ - (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use ftello function for handling of large files"), \ - ftell (f)) -# endif -#endif - -#if @GNULIB_FFLUSH@ -# if @REPLACE_FFLUSH@ -# define fflush rpl_fflush - /* Flush all pending data on STREAM according to POSIX rules. Both - output and seekable input streams are supported. - Note! LOSS OF DATA can occur if fflush is applied on an input stream - that is _not_seekable_ or on an update stream that is _not_seekable_ - and in which the most recent operation was input. Seekability can - be tested with lseek(fileno(fp),0,SEEK_CUR). */ - extern int fflush (FILE *gl_stream); -# endif -#elif defined GNULIB_POSIXCHECK -# undef fflush -# define fflush(f) \ - (GL_LINK_WARNING ("fflush is not always POSIX compliant - " \ - "use gnulib module fflush for portable " \ - "POSIX compliance"), \ - fflush (f)) -#endif - -#if @GNULIB_GETDELIM@ -# if !@HAVE_DECL_GETDELIM@ -/* Read input, up to (and including) the next occurrence of DELIMITER, from - STREAM, store it in *LINEPTR (and NUL-terminate it). - *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE - bytes of space. It is realloc'd as necessary. - Return the number of bytes read and stored at *LINEPTR (not including the - NUL terminator), or -1 on error or EOF. */ -extern ssize_t getdelim (char **lineptr, size_t *linesize, int delimiter, - FILE *stream); -# endif -#elif defined GNULIB_POSIXCHECK -# undef getdelim -# define getdelim(l, s, d, f) \ - (GL_LINK_WARNING ("getdelim is unportable - " \ - "use gnulib module getdelim for portability"), \ - getdelim (l, s, d, f)) -#endif - -#if @GNULIB_GETLINE@ -# if @REPLACE_GETLINE@ -# undef getline -# define getline rpl_getline -# endif -# if !@HAVE_DECL_GETLINE@ || @REPLACE_GETLINE@ -/* Read a line, up to (and including) the next newline, from STREAM, store it - in *LINEPTR (and NUL-terminate it). - *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE - bytes of space. It is realloc'd as necessary. - Return the number of bytes read and stored at *LINEPTR (not including the - NUL terminator), or -1 on error or EOF. */ -extern ssize_t getline (char **lineptr, size_t *linesize, FILE *stream); -# endif -#elif defined GNULIB_POSIXCHECK -# undef getline -# define getline(l, s, f) \ - (GL_LINK_WARNING ("getline is unportable - " \ - "use gnulib module getline for portability"), \ - getline (l, s, f)) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _GL_STDIO_H */ -#endif /* _GL_STDIO_H */ -#endif diff --git a/src/bin/tar/lib/stdlib.in.h b/src/bin/tar/lib/stdlib.in.h deleted file mode 100644 index a4946e6840..0000000000 --- a/src/bin/tar/lib/stdlib.in.h +++ /dev/null @@ -1,177 +0,0 @@ -/* A GNU-like . - - Copyright (C) 1995, 2001-2002, 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if defined __need_malloc_and_calloc -/* Special invocation convention inside glibc header files. */ - -#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ - -#else -/* Normal invocation convention. */ - -#ifndef _GL_STDLIB_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ - -#ifndef _GL_STDLIB_H -#define _GL_STDLIB_H - - -/* The definition of GL_LINK_WARNING is copied here. */ - - -/* Some systems do not define EXIT_*, despite otherwise supporting C89. */ -#ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -#endif -/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere - with proper operation of xargs. */ -#ifndef EXIT_FAILURE -# define EXIT_FAILURE 1 -#elif EXIT_FAILURE != 1 -# undef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - -#if @GNULIB_MALLOC_POSIX@ -# if !@HAVE_MALLOC_POSIX@ -# undef malloc -# define malloc rpl_malloc -extern void * malloc (size_t size); -# endif -#elif defined GNULIB_POSIXCHECK -# undef malloc -# define malloc(s) \ - (GL_LINK_WARNING ("malloc is not POSIX compliant everywhere - " \ - "use gnulib module malloc-posix for portability"), \ - malloc (s)) -#endif - - -#if @GNULIB_REALLOC_POSIX@ -# if !@HAVE_REALLOC_POSIX@ -# undef realloc -# define realloc rpl_realloc -extern void * realloc (void *ptr, size_t size); -# endif -#elif defined GNULIB_POSIXCHECK -# undef realloc -# define realloc(p,s) \ - (GL_LINK_WARNING ("realloc is not POSIX compliant everywhere - " \ - "use gnulib module realloc-posix for portability"), \ - realloc (p, s)) -#endif - - -#if @GNULIB_CALLOC_POSIX@ -# if !@HAVE_CALLOC_POSIX@ -# undef calloc -# define calloc rpl_calloc -extern void * calloc (size_t nmemb, size_t size); -# endif -#elif defined GNULIB_POSIXCHECK -# undef calloc -# define calloc(n,s) \ - (GL_LINK_WARNING ("calloc is not POSIX compliant everywhere - " \ - "use gnulib module calloc-posix for portability"), \ - calloc (n, s)) -#endif - - -#if @GNULIB_GETSUBOPT@ -/* Assuming *OPTIONP is a comma separated list of elements of the form - "token" or "token=value", getsubopt parses the first of these elements. - If the first element refers to a "token" that is member of the given - NULL-terminated array of tokens: - - It replaces the comma with a NUL byte, updates *OPTIONP to point past - the first option and the comma, sets *VALUEP to the value of the - element (or NULL if it doesn't contain an "=" sign), - - It returns the index of the "token" in the given array of tokens. - Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined. - For more details see the POSIX:2001 specification. - http://www.opengroup.org/susv3xsh/getsubopt.html */ -# if !@HAVE_GETSUBOPT@ -extern int getsubopt (char **optionp, char *const *tokens, char **valuep); -# endif -#elif defined GNULIB_POSIXCHECK -# undef getsubopt -# define getsubopt(o,t,v) \ - (GL_LINK_WARNING ("getsubopt is unportable - " \ - "use gnulib module getsubopt for portability"), \ - getsubopt (o, t, v)) -#endif - - -#if @GNULIB_MKDTEMP@ -# if !@HAVE_MKDTEMP@ -/* Create a unique temporary directory from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the directory name unique. - Returns TEMPLATE, or a null pointer if it cannot get a unique name. - The directory is created mode 700. */ -extern char * mkdtemp (char * /*template*/); -# endif -#elif defined GNULIB_POSIXCHECK -# undef mkdtemp -# define mkdtemp(t) \ - (GL_LINK_WARNING ("mkdtemp is unportable - " \ - "use gnulib module mkdtemp for portability"), \ - mkdtemp (t)) -#endif - - -#if @GNULIB_MKSTEMP@ -# if @REPLACE_MKSTEMP@ -/* Create a unique temporary file from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the file name unique. - The file is then created, ensuring it didn't exist before. - The file is created read-write (mask at least 0600 & ~umask), but it may be - world-readable and world-writable (mask 0666 & ~umask), depending on the - implementation. - Returns the open file descriptor if successful, otherwise -1 and errno - set. */ -# define mkstemp rpl_mkstemp -extern int mkstemp (char * /*template*/); -# else -/* On MacOS X 10.3, only declares mkstemp. */ -# include -# endif -#elif defined GNULIB_POSIXCHECK -# undef mkstemp -# define mkstemp(t) \ - (GL_LINK_WARNING ("mkstemp is unportable - " \ - "use gnulib module mkstemp for portability"), \ - mkstemp (t)) -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* _GL_STDLIB_H */ -#endif /* _GL_STDLIB_H */ -#endif diff --git a/src/bin/tar/lib/stdopen.c b/src/bin/tar/lib/stdopen.c deleted file mode 100644 index 0b637ad17f..0000000000 --- a/src/bin/tar/lib/stdopen.c +++ /dev/null @@ -1,77 +0,0 @@ -/* stdopen.c - ensure that the three standard file descriptors are in use - - Copyright (C) 2005, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert and Jim Meyering. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "stdopen.h" - -#include -#include -#include -#include -#include - -/* Try to ensure that all of the standard file numbers (0, 1, 2) - are in use. Without this, each application would have to guard - every call to open, dup, fopen, etc. with tests to ensure they - don't use one of the special file numbers when opening a file. - Return false if at least one of the file descriptors is initially - closed and an attempt to reopen it fails. Otherwise, return true. */ -bool -stdopen (void) -{ - int fd; - bool ok = true; - - for (fd = 0; fd <= 2; fd++) - { - if (fcntl (fd, F_GETFD) < 0) - { - if (errno != EBADF) - ok = false; - else - { - static const int contrary_mode[] - = { O_WRONLY, O_RDONLY, O_RDONLY }; - int mode = contrary_mode[fd]; - int new_fd; - /* Open /dev/null with the contrary mode so that the typical - read (stdin) or write (stdout, stderr) operation will fail. - With descriptor 0, we can do even better on systems that - have /dev/full, by opening that write-only instead of - /dev/null. The only drawback is that a write-provoked - failure comes with a misleading errno value, ENOSPC. */ - if (mode == O_RDONLY - || (new_fd = open ("/dev/full", mode) != fd)) - new_fd = open ("/dev/null", mode); - if (new_fd != fd) - { - if (0 <= new_fd) - close (new_fd); - ok = false; - } - } - } - } - - return ok; -} diff --git a/src/bin/tar/lib/stdopen.h b/src/bin/tar/lib/stdopen.h deleted file mode 100644 index d54e5f1350..0000000000 --- a/src/bin/tar/lib/stdopen.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef STDOPEN_H -# define STDOPEN_H 1 - -# include - -# ifdef __cplusplus -extern "C" { -# endif - -bool stdopen (void); - -# ifdef __cplusplus -} -# endif - -#endif diff --git a/src/bin/tar/lib/stpcpy.c b/src/bin/tar/lib/stpcpy.c deleted file mode 100644 index 4089d3946a..0000000000 --- a/src/bin/tar/lib/stpcpy.c +++ /dev/null @@ -1,49 +0,0 @@ -/* stpcpy.c -- copy a string and return pointer to end of new string - Copyright (C) 1992, 1995, 1997-1998, 2006 Free Software Foundation, Inc. - - NOTE: The canonical source of this file is maintained with the GNU C Library. - Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include - -#undef __stpcpy -#ifdef _LIBC -# undef stpcpy -#endif - -#ifndef weak_alias -# define __stpcpy stpcpy -#endif - -/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ -char * -__stpcpy (char *dest, const char *src) -{ - register char *d = dest; - register const char *s = src; - - do - *d++ = *s; - while (*s++ != '\0'); - - return d - 1; -} -#ifdef weak_alias -weak_alias (__stpcpy, stpcpy) -#endif diff --git a/src/bin/tar/lib/strcasecmp.c b/src/bin/tar/lib/strcasecmp.c deleted file mode 100644 index c605fb0f59..0000000000 --- a/src/bin/tar/lib/strcasecmp.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Case-insensitive string comparison function. - Copyright (C) 1998-1999, 2005-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -#include -#include - -#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) - -/* Compare strings S1 and S2, ignoring case, returning less than, equal to or - greater than zero if S1 is lexicographically less than, equal to or greater - than S2. - Note: This function does not work with multibyte strings! */ - -int -strcasecmp (const char *s1, const char *s2) -{ - const unsigned char *p1 = (const unsigned char *) s1; - const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - - if (p1 == p2) - return 0; - - do - { - c1 = TOLOWER (*p1); - c2 = TOLOWER (*p2); - - if (c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - if (UCHAR_MAX <= INT_MAX) - return c1 - c2; - else - /* On machines where 'char' and 'int' are types of the same size, the - difference of two 'unsigned char' values - including the sign bit - - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); -} diff --git a/src/bin/tar/lib/strchrnul.c b/src/bin/tar/lib/strchrnul.c deleted file mode 100644 index 07014be17a..0000000000 --- a/src/bin/tar/lib/strchrnul.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Searching in a string. - Copyright (C) 2003, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -/* Find the first occurrence of C in S or the final NUL byte. */ -char * -strchrnul (const char *s, int c_in) -{ - char c = c_in; - while (*s && (*s != c)) - s++; - - return (char *) s; -} diff --git a/src/bin/tar/lib/strdup.c b/src/bin/tar/lib/strdup.c deleted file mode 100644 index c614108786..0000000000 --- a/src/bin/tar/lib/strdup.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 1991, 1996, 1997, 1998, 2002, 2003, 2004, 2006, 2007 Free - Software Foundation, Inc. - - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _LIBC -# include -#endif - -/* Get specification. */ -#include - -#include - -#undef __strdup -#ifdef _LIBC -# undef strdup -#endif - -#ifndef weak_alias -# define __strdup strdup -#endif - -/* Duplicate S, returning an identical malloc'd string. */ -char * -__strdup (const char *s) -{ - size_t len = strlen (s) + 1; - void *new = malloc (len); - - if (new == NULL) - return NULL; - - return (char *) memcpy (new, s, len); -} -#ifdef libc_hidden_def -libc_hidden_def (__strdup) -#endif -#ifdef weak_alias -weak_alias (__strdup, strdup) -#endif diff --git a/src/bin/tar/lib/streq.h b/src/bin/tar/lib/streq.h deleted file mode 100644 index 03ea1d1dba..0000000000 --- a/src/bin/tar/lib/streq.h +++ /dev/null @@ -1,178 +0,0 @@ -/* Optimized string comparison. - Copyright (C) 2001-2002, 2007 Free Software Foundation, Inc. - - This program 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, 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -/* Written by Bruno Haible . */ - -#ifndef _GL_STREQ_H -#define _GL_STREQ_H - -#include - -/* STREQ allows to optimize string comparison with a small literal string. - STREQ (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) - is semantically equivalent to - strcmp (s, "EUC-KR") == 0 - just faster. */ - -/* Help GCC to generate good code for string comparisons with - immediate strings. */ -#if defined (__GNUC__) && defined (__OPTIMIZE__) - -static inline int -streq9 (const char *s1, const char *s2) -{ - return strcmp (s1 + 9, s2 + 9) == 0; -} - -static inline int -streq8 (const char *s1, const char *s2, char s28) -{ - if (s1[8] == s28) - { - if (s28 == 0) - return 1; - else - return streq9 (s1, s2); - } - else - return 0; -} - -static inline int -streq7 (const char *s1, const char *s2, char s27, char s28) -{ - if (s1[7] == s27) - { - if (s27 == 0) - return 1; - else - return streq8 (s1, s2, s28); - } - else - return 0; -} - -static inline int -streq6 (const char *s1, const char *s2, char s26, char s27, char s28) -{ - if (s1[6] == s26) - { - if (s26 == 0) - return 1; - else - return streq7 (s1, s2, s27, s28); - } - else - return 0; -} - -static inline int -streq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) -{ - if (s1[5] == s25) - { - if (s25 == 0) - return 1; - else - return streq6 (s1, s2, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[4] == s24) - { - if (s24 == 0) - return 1; - else - return streq5 (s1, s2, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[3] == s23) - { - if (s23 == 0) - return 1; - else - return streq4 (s1, s2, s24, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[2] == s22) - { - if (s22 == 0) - return 1; - else - return streq3 (s1, s2, s23, s24, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[1] == s21) - { - if (s21 == 0) - return 1; - else - return streq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[0] == s20) - { - if (s20 == 0) - return 1; - else - return streq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); - } - else - return 0; -} - -#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ - streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) - -#else - -#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ - (strcmp (s1, s2) == 0) - -#endif - -#endif /* _GL_STREQ_H */ diff --git a/src/bin/tar/lib/strerror.c b/src/bin/tar/lib/strerror.c deleted file mode 100644 index ef6234e4fa..0000000000 --- a/src/bin/tar/lib/strerror.c +++ /dev/null @@ -1,79 +0,0 @@ -/* strerror.c --- ANSI C compatible system error routine - - Copyright (C) 1986, 1988, 1989, 1991, 2002, 2003, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#if REPLACE_STRERROR - -# include -# include - -# undef strerror - -char *rpl_strerror (int n) -{ - static char const fmt[] = "Unknown error (%d)"; - static char mesg[sizeof fmt + sizeof n * CHAR_BIT / 3]; - - char *result = strerror (n); - - if (! result) - { - sprintf (mesg, fmt, n); - return mesg; - } - return result; -} - -#elif !HAVE_STRERROR - -#include - -/* Don't include , since it may or may not declare - sys_errlist and its declarations may collide with ours. Just - declare the stuff that we need directly. Standard hosted C89 - implementations define strerror and they don't need this strerror - function, so take some liberties with the standard to cater to - ancient or limited freestanding implementations. */ -int sprintf (char *, char const *, ...); -extern int sys_nerr; -extern char *sys_errlist[]; - -char * -strerror (int n) -{ - static char const fmt[] = "Unknown error (%d)"; - static char mesg[sizeof fmt + sizeof n * CHAR_BIT / 3]; - - if (n < 0 || n >= sys_nerr) - { - sprintf (mesg, fmt, n); - return mesg; - } - else - return sys_errlist[n]; -} - -#else - -/* This declaration is solely to ensure that after preprocessing - this file is never empty. */ -typedef int dummy; - -#endif diff --git a/src/bin/tar/lib/string.in.h b/src/bin/tar/lib/string.in.h deleted file mode 100644 index 41e539f235..0000000000 --- a/src/bin/tar/lib/string.in.h +++ /dev/null @@ -1,565 +0,0 @@ -/* A GNU-like . - - Copyright (C) 1995-1996, 2001-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GL_STRING_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_STRING_H@ - -#ifndef _GL_STRING_H -#define _GL_STRING_H - - -/* The definition of GL_LINK_WARNING is copied here. */ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Return the first occurrence of NEEDLE in HAYSTACK. */ -#if @GNULIB_MEMMEM@ -# if ! @HAVE_DECL_MEMMEM@ -extern void *memmem (void const *__haystack, size_t __haystack_len, - void const *__needle, size_t __needle_len); -# endif -#elif defined GNULIB_POSIXCHECK -# undef memmem -# define memmem(a,al,b,bl) \ - (GL_LINK_WARNING ("memmem is unportable - " \ - "use gnulib module memmem for portability"), \ - memmem (a, al, b, bl)) -#endif - -/* Copy N bytes of SRC to DEST, return pointer to bytes after the - last written byte. */ -#if @GNULIB_MEMPCPY@ -# if ! @HAVE_MEMPCPY@ -extern void *mempcpy (void *restrict __dest, void const *restrict __src, - size_t __n); -# endif -#elif defined GNULIB_POSIXCHECK -# undef mempcpy -# define mempcpy(a,b,n) \ - (GL_LINK_WARNING ("mempcpy is unportable - " \ - "use gnulib module mempcpy for portability"), \ - mempcpy (a, b, n)) -#endif - -/* Search backwards through a block for a byte (specified as an int). */ -#if @GNULIB_MEMRCHR@ -# if ! @HAVE_DECL_MEMRCHR@ -extern void *memrchr (void const *, int, size_t); -# endif -#elif defined GNULIB_POSIXCHECK -# undef memrchr -# define memrchr(a,b,c) \ - (GL_LINK_WARNING ("memrchr is unportable - " \ - "use gnulib module memrchr for portability"), \ - memrchr (a, b, c)) -#endif - -/* Copy SRC to DST, returning the address of the terminating '\0' in DST. */ -#if @GNULIB_STPCPY@ -# if ! @HAVE_STPCPY@ -extern char *stpcpy (char *restrict __dst, char const *restrict __src); -# endif -#elif defined GNULIB_POSIXCHECK -# undef stpcpy -# define stpcpy(a,b) \ - (GL_LINK_WARNING ("stpcpy is unportable - " \ - "use gnulib module stpcpy for portability"), \ - stpcpy (a, b)) -#endif - -/* Copy no more than N bytes of SRC to DST, returning a pointer past the - last non-NUL byte written into DST. */ -#if @GNULIB_STPNCPY@ -# if ! @HAVE_STPNCPY@ -# define stpncpy gnu_stpncpy -extern char *stpncpy (char *restrict __dst, char const *restrict __src, - size_t __n); -# endif -#elif defined GNULIB_POSIXCHECK -# undef stpncpy -# define stpncpy(a,b,n) \ - (GL_LINK_WARNING ("stpncpy is unportable - " \ - "use gnulib module stpncpy for portability"), \ - stpncpy (a, b, n)) -#endif - -/* Compare strings S1 and S2, ignoring case, returning less than, equal to or - greater than zero if S1 is lexicographically less than, equal to or greater - than S2. - Note: This function does not work in multibyte locales. */ -#if ! @HAVE_STRCASECMP@ -extern int strcasecmp (char const *s1, char const *s2); -#endif -#if defined GNULIB_POSIXCHECK -/* strcasecmp() does not work with multibyte strings: - POSIX says that it operates on "strings", and "string" in POSIX is defined - as a sequence of bytes, not of characters. */ -# undef strcasecmp -# define strcasecmp(a,b) \ - (GL_LINK_WARNING ("strcasecmp cannot work correctly on character strings " \ - "in multibyte locales - " \ - "use mbscasecmp if you care about " \ - "internationalization, or use c_strcasecmp (from " \ - "gnulib module c-strcase) if you want a locale " \ - "independent function"), \ - strcasecmp (a, b)) -#endif - -/* Compare no more than N bytes of strings S1 and S2, ignoring case, - returning less than, equal to or greater than zero if S1 is - lexicographically less than, equal to or greater than S2. - Note: This function cannot work correctly in multibyte locales. */ -#if ! @HAVE_DECL_STRNCASECMP@ -extern int strncasecmp (char const *s1, char const *s2, size_t n); -#endif -#if defined GNULIB_POSIXCHECK -/* strncasecmp() does not work with multibyte strings: - POSIX says that it operates on "strings", and "string" in POSIX is defined - as a sequence of bytes, not of characters. */ -# undef strncasecmp -# define strncasecmp(a,b,n) \ - (GL_LINK_WARNING ("strncasecmp cannot work correctly on character " \ - "strings in multibyte locales - " \ - "use mbsncasecmp or mbspcasecmp if you care about " \ - "internationalization, or use c_strncasecmp (from " \ - "gnulib module c-strcase) if you want a locale " \ - "independent function"), \ - strncasecmp (a, b, n)) -#endif - -#if defined GNULIB_POSIXCHECK -/* strchr() does not work with multibyte strings if the locale encoding is - GB18030 and the character to be searched is a digit. */ -# undef strchr -# define strchr(s,c) \ - (GL_LINK_WARNING ("strchr cannot work correctly on character strings " \ - "in some multibyte locales - " \ - "use mbschr if you care about internationalization"), \ - strchr (s, c)) -#endif - -/* Find the first occurrence of C in S or the final NUL byte. */ -#if @GNULIB_STRCHRNUL@ -# if ! @HAVE_STRCHRNUL@ -extern char *strchrnul (char const *__s, int __c_in); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strchrnul -# define strchrnul(a,b) \ - (GL_LINK_WARNING ("strchrnul is unportable - " \ - "use gnulib module strchrnul for portability"), \ - strchrnul (a, b)) -#endif - -/* Duplicate S, returning an identical malloc'd string. */ -#if @GNULIB_STRDUP@ -# if ! @HAVE_DECL_STRDUP@ && ! defined strdup -extern char *strdup (char const *__s); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strdup -# define strdup(a) \ - (GL_LINK_WARNING ("strdup is unportable - " \ - "use gnulib module strdup for portability"), \ - strdup (a)) -#endif - -/* Return a newly allocated copy of at most N bytes of STRING. */ -#if @GNULIB_STRNDUP@ -# if ! @HAVE_STRNDUP@ -# undef strndup -# define strndup rpl_strndup -# endif -# if ! @HAVE_STRNDUP@ || ! @HAVE_DECL_STRNDUP@ -extern char *strndup (char const *__string, size_t __n); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strndup -# define strndup(a,n) \ - (GL_LINK_WARNING ("strndup is unportable - " \ - "use gnulib module strndup for portability"), \ - strndup (a, n)) -#endif - -/* Find the length (number of bytes) of STRING, but scan at most - MAXLEN bytes. If no '\0' terminator is found in that many bytes, - return MAXLEN. */ -#if @GNULIB_STRNLEN@ -# if ! @HAVE_DECL_STRNLEN@ -extern size_t strnlen (char const *__string, size_t __maxlen); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strnlen -# define strnlen(a,n) \ - (GL_LINK_WARNING ("strnlen is unportable - " \ - "use gnulib module strnlen for portability"), \ - strnlen (a, n)) -#endif - -#if defined GNULIB_POSIXCHECK -/* strcspn() assumes the second argument is a list of single-byte characters. - Even in this simple case, it does not work with multibyte strings if the - locale encoding is GB18030 and one of the characters to be searched is a - digit. */ -# undef strcspn -# define strcspn(s,a) \ - (GL_LINK_WARNING ("strcspn cannot work correctly on character strings " \ - "in multibyte locales - " \ - "use mbscspn if you care about internationalization"), \ - strcspn (s, a)) -#endif - -/* Find the first occurrence in S of any character in ACCEPT. */ -#if @GNULIB_STRPBRK@ -# if ! @HAVE_STRPBRK@ -extern char *strpbrk (char const *__s, char const *__accept); -# endif -# if defined GNULIB_POSIXCHECK -/* strpbrk() assumes the second argument is a list of single-byte characters. - Even in this simple case, it does not work with multibyte strings if the - locale encoding is GB18030 and one of the characters to be searched is a - digit. */ -# undef strpbrk -# define strpbrk(s,a) \ - (GL_LINK_WARNING ("strpbrk cannot work correctly on character strings " \ - "in multibyte locales - " \ - "use mbspbrk if you care about internationalization"), \ - strpbrk (s, a)) -# endif -#elif defined GNULIB_POSIXCHECK -# undef strpbrk -# define strpbrk(s,a) \ - (GL_LINK_WARNING ("strpbrk is unportable - " \ - "use gnulib module strpbrk for portability"), \ - strpbrk (s, a)) -#endif - -#if defined GNULIB_POSIXCHECK -/* strspn() assumes the second argument is a list of single-byte characters. - Even in this simple case, it cannot work with multibyte strings. */ -# undef strspn -# define strspn(s,a) \ - (GL_LINK_WARNING ("strspn cannot work correctly on character strings " \ - "in multibyte locales - " \ - "use mbsspn if you care about internationalization"), \ - strspn (s, a)) -#endif - -#if defined GNULIB_POSIXCHECK -/* strrchr() does not work with multibyte strings if the locale encoding is - GB18030 and the character to be searched is a digit. */ -# undef strrchr -# define strrchr(s,c) \ - (GL_LINK_WARNING ("strrchr cannot work correctly on character strings " \ - "in some multibyte locales - " \ - "use mbsrchr if you care about internationalization"), \ - strrchr (s, c)) -#endif - -/* Search the next delimiter (char listed in DELIM) starting at *STRINGP. - If one is found, overwrite it with a NUL, and advance *STRINGP - to point to the next char after it. Otherwise, set *STRINGP to NULL. - If *STRINGP was already NULL, nothing happens. - Return the old value of *STRINGP. - - This is a variant of strtok() that is multithread-safe and supports - empty fields. - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - Caveat: It doesn't work with multibyte strings unless all of the delimiter - characters are ASCII characters < 0x30. - - See also strtok_r(). */ -#if @GNULIB_STRSEP@ -# if ! @HAVE_STRSEP@ -extern char *strsep (char **restrict __stringp, char const *restrict __delim); -# endif -# if defined GNULIB_POSIXCHECK -# undef strsep -# define strsep(s,d) \ - (GL_LINK_WARNING ("strsep cannot work correctly on character strings " \ - "in multibyte locales - " \ - "use mbssep if you care about internationalization"), \ - strsep (s, d)) -# endif -#elif defined GNULIB_POSIXCHECK -# undef strsep -# define strsep(s,d) \ - (GL_LINK_WARNING ("strsep is unportable - " \ - "use gnulib module strsep for portability"), \ - strsep (s, d)) -#endif - -#if defined GNULIB_POSIXCHECK -/* strstr() does not work with multibyte strings if the locale encoding is - different from UTF-8: - POSIX says that it operates on "strings", and "string" in POSIX is defined - as a sequence of bytes, not of characters. */ -# undef strstr -# define strstr(a,b) \ - (GL_LINK_WARNING ("strstr cannot work correctly on character strings " \ - "in most multibyte locales - " \ - "use mbsstr if you care about internationalization"), \ - strstr (a, b)) -#endif - -/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive - comparison. */ -#if ! @HAVE_STRCASESTR@ -extern char *strcasestr (const char *haystack, const char *needle); -#endif -#if defined GNULIB_POSIXCHECK -/* strcasestr() does not work with multibyte strings: - It is a glibc extension, and glibc implements it only for unibyte - locales. */ -# undef strcasestr -# define strcasestr(a,b) \ - (GL_LINK_WARNING ("strcasestr does work correctly on character strings " \ - "in multibyte locales - " \ - "use mbscasestr if you care about " \ - "internationalization, or use c-strcasestr if you want " \ - "a locale independent function"), \ - strcasestr (a, b)) -#endif - -/* Parse S into tokens separated by characters in DELIM. - If S is NULL, the saved pointer in SAVE_PTR is used as - the next starting point. For example: - char s[] = "-abc-=-def"; - char *sp; - x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = strtok_r(NULL, "=", &sp); // x = NULL - // s = "abc\0-def\0" - - This is a variant of strtok() that is multithread-safe. - - For the POSIX documentation for this function, see: - http://www.opengroup.org/susv3xsh/strtok.html - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - Caveat: It doesn't work with multibyte strings unless all of the delimiter - characters are ASCII characters < 0x30. - - See also strsep(). */ -#if @GNULIB_STRTOK_R@ -# if ! @HAVE_DECL_STRTOK_R@ -extern char *strtok_r (char *restrict s, char const *restrict delim, - char **restrict save_ptr); -# endif -# if defined GNULIB_POSIXCHECK -# undef strtok_r -# define strtok_r(s,d,p) \ - (GL_LINK_WARNING ("strtok_r cannot work correctly on character strings " \ - "in multibyte locales - " \ - "use mbstok_r if you care about internationalization"), \ - strtok_r (s, d, p)) -# endif -#elif defined GNULIB_POSIXCHECK -# undef strtok_r -# define strtok_r(s,d,p) \ - (GL_LINK_WARNING ("strtok_r is unportable - " \ - "use gnulib module strtok_r for portability"), \ - strtok_r (s, d, p)) -#endif - - -/* The following functions are not specified by POSIX. They are gnulib - extensions. */ - -#if @GNULIB_MBSLEN@ -/* Return the number of multibyte characters in the character string STRING. - This considers multibyte characters, unlike strlen, which counts bytes. */ -extern size_t mbslen (const char *string); -#endif - -#if @GNULIB_MBSNLEN@ -/* Return the number of multibyte characters in the character string starting - at STRING and ending at STRING + LEN. */ -extern size_t mbsnlen (const char *string, size_t len); -#endif - -#if @GNULIB_MBSCHR@ -/* Locate the first single-byte character C in the character string STRING, - and return a pointer to it. Return NULL if C is not found in STRING. - Unlike strchr(), this function works correctly in multibyte locales with - encodings such as GB18030. */ -# define mbschr rpl_mbschr /* avoid collision with HP-UX function */ -extern char * mbschr (const char *string, int c); -#endif - -#if @GNULIB_MBSRCHR@ -/* Locate the last single-byte character C in the character string STRING, - and return a pointer to it. Return NULL if C is not found in STRING. - Unlike strrchr(), this function works correctly in multibyte locales with - encodings such as GB18030. */ -# define mbsrchr rpl_mbsrchr /* avoid collision with HP-UX function */ -extern char * mbsrchr (const char *string, int c); -#endif - -#if @GNULIB_MBSSTR@ -/* Find the first occurrence of the character string NEEDLE in the character - string HAYSTACK. Return NULL if NEEDLE is not found in HAYSTACK. - Unlike strstr(), this function works correctly in multibyte locales with - encodings different from UTF-8. */ -extern char * mbsstr (const char *haystack, const char *needle); -#endif - -#if @GNULIB_MBSCASECMP@ -/* Compare the character strings S1 and S2, ignoring case, returning less than, - equal to or greater than zero if S1 is lexicographically less than, equal to - or greater than S2. - Note: This function may, in multibyte locales, return 0 for strings of - different lengths! - Unlike strcasecmp(), this function works correctly in multibyte locales. */ -extern int mbscasecmp (const char *s1, const char *s2); -#endif - -#if @GNULIB_MBSNCASECMP@ -/* Compare the initial segment of the character string S1 consisting of at most - N characters with the initial segment of the character string S2 consisting - of at most N characters, ignoring case, returning less than, equal to or - greater than zero if the initial segment of S1 is lexicographically less - than, equal to or greater than the initial segment of S2. - Note: This function may, in multibyte locales, return 0 for initial segments - of different lengths! - Unlike strncasecmp(), this function works correctly in multibyte locales. - But beware that N is not a byte count but a character count! */ -extern int mbsncasecmp (const char *s1, const char *s2, size_t n); -#endif - -#if @GNULIB_MBSPCASECMP@ -/* Compare the initial segment of the character string STRING consisting of - at most mbslen (PREFIX) characters with the character string PREFIX, - ignoring case, returning less than, equal to or greater than zero if this - initial segment is lexicographically less than, equal to or greater than - PREFIX. - Note: This function may, in multibyte locales, return 0 if STRING is of - smaller length than PREFIX! - Unlike strncasecmp(), this function works correctly in multibyte - locales. */ -extern char * mbspcasecmp (const char *string, const char *prefix); -#endif - -#if @GNULIB_MBSCASESTR@ -/* Find the first occurrence of the character string NEEDLE in the character - string HAYSTACK, using case-insensitive comparison. - Note: This function may, in multibyte locales, return success even if - strlen (haystack) < strlen (needle) ! - Unlike strcasestr(), this function works correctly in multibyte locales. */ -extern char * mbscasestr (const char *haystack, const char *needle); -#endif - -#if @GNULIB_MBSCSPN@ -/* Find the first occurrence in the character string STRING of any character - in the character string ACCEPT. Return the number of bytes from the - beginning of the string to this occurrence, or to the end of the string - if none exists. - Unlike strcspn(), this function works correctly in multibyte locales. */ -extern size_t mbscspn (const char *string, const char *accept); -#endif - -#if @GNULIB_MBSPBRK@ -/* Find the first occurrence in the character string STRING of any character - in the character string ACCEPT. Return the pointer to it, or NULL if none - exists. - Unlike strpbrk(), this function works correctly in multibyte locales. */ -# define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ -extern char * mbspbrk (const char *string, const char *accept); -#endif - -#if @GNULIB_MBSSPN@ -/* Find the first occurrence in the character string STRING of any character - not in the character string REJECT. Return the number of bytes from the - beginning of the string to this occurrence, or to the end of the string - if none exists. - Unlike strspn(), this function works correctly in multibyte locales. */ -extern size_t mbsspn (const char *string, const char *reject); -#endif - -#if @GNULIB_MBSSEP@ -/* Search the next delimiter (multibyte character listed in the character - string DELIM) starting at the character string *STRINGP. - If one is found, overwrite it with a NUL, and advance *STRINGP to point - to the next multibyte character after it. Otherwise, set *STRINGP to NULL. - If *STRINGP was already NULL, nothing happens. - Return the old value of *STRINGP. - - This is a variant of mbstok_r() that supports empty fields. - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - - See also mbstok_r(). */ -extern char * mbssep (char **stringp, const char *delim); -#endif - -#if @GNULIB_MBSTOK_R@ -/* Parse the character string STRING into tokens separated by characters in - the character string DELIM. - If STRING is NULL, the saved pointer in SAVE_PTR is used as - the next starting point. For example: - char s[] = "-abc-=-def"; - char *sp; - x = mbstok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = mbstok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = mbstok_r(NULL, "=", &sp); // x = NULL - // s = "abc\0-def\0" - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - - See also mbssep(). */ -extern char * mbstok_r (char *string, const char *delim, char **save_ptr); -#endif - -/* Map any int, typically from errno, into an error message. */ -#if @GNULIB_STRERROR@ -# if @REPLACE_STRERROR@ -# undef strerror -# define strerror rpl_strerror -# endif -# if !@HAVE_DECL_STRERROR@ || @REPLACE_STRERROR@ -extern char *strerror (int); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strerror -# define strerror(e) \ - (GL_LINK_WARNING ("strerror is unportable - " \ - "use gnulib module strerror to guarantee non-NULL result"), \ - strerror (e)) -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* _GL_STRING_H */ -#endif /* _GL_STRING_H */ diff --git a/src/bin/tar/lib/stripslash.c b/src/bin/tar/lib/stripslash.c deleted file mode 100644 index 342d497c89..0000000000 --- a/src/bin/tar/lib/stripslash.c +++ /dev/null @@ -1,45 +0,0 @@ -/* stripslash.c -- remove redundant trailing slashes from a file name - - Copyright (C) 1990, 2001, 2003-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "dirname.h" - -/* Remove trailing slashes from FILE. Return true if a trailing slash - was removed. This is useful when using file name completion from a - shell that adds a "/" after directory names (such as tcsh and - bash), because on symlinks to directories, several system calls - have different semantics according to whether a trailing slash is - present. */ - -bool -strip_trailing_slashes (char *file) -{ - char *base = last_component (file); - char *base_lim; - bool had_slash; - - /* last_component returns "" for file system roots, but we need to turn - `///' into `/'. */ - if (! *base) - base = file; - base_lim = base + base_len (base); - had_slash = (*base_lim != '\0'); - *base_lim = '\0'; - return had_slash; -} diff --git a/src/bin/tar/lib/strncasecmp.c b/src/bin/tar/lib/strncasecmp.c deleted file mode 100644 index 473a610fe0..0000000000 --- a/src/bin/tar/lib/strncasecmp.c +++ /dev/null @@ -1,63 +0,0 @@ -/* strncasecmp.c -- case insensitive string comparator - Copyright (C) 1998-1999, 2005-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -#include -#include - -#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) - -/* Compare no more than N bytes of strings S1 and S2, ignoring case, - returning less than, equal to or greater than zero if S1 is - lexicographically less than, equal to or greater than S2. - Note: This function cannot work correctly in multibyte locales. */ - -int -strncasecmp (const char *s1, const char *s2, size_t n) -{ - register const unsigned char *p1 = (const unsigned char *) s1; - register const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - - if (p1 == p2 || n == 0) - return 0; - - do - { - c1 = TOLOWER (*p1); - c2 = TOLOWER (*p2); - - if (--n == 0 || c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - if (UCHAR_MAX <= INT_MAX) - return c1 - c2; - else - /* On machines where 'char' and 'int' are types of the same size, the - difference of two 'unsigned char' values - including the sign bit - - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); -} diff --git a/src/bin/tar/lib/strndup.c b/src/bin/tar/lib/strndup.c deleted file mode 100644 index 3a1b0eae2e..0000000000 --- a/src/bin/tar/lib/strndup.c +++ /dev/null @@ -1,37 +0,0 @@ -/* A replacement function, for systems that lack strndup. - - Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include - -#include - -char * -strndup (char const *s, size_t n) -{ - size_t len = strnlen (s, n); - char *new = malloc (len + 1); - - if (new == NULL) - return NULL; - - new[len] = '\0'; - return memcpy (new, s, len); -} diff --git a/src/bin/tar/lib/strnlen.c b/src/bin/tar/lib/strnlen.c deleted file mode 100644 index d346d3272c..0000000000 --- a/src/bin/tar/lib/strnlen.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Find the length of STRING, but scan at most MAXLEN characters. - Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. - Written by Simon Josefsson. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include - -/* Find the length of STRING, but scan at most MAXLEN characters. - If no '\0' terminator is found in that many characters, return MAXLEN. */ - -size_t -strnlen (const char *string, size_t maxlen) -{ - const char *end = memchr (string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} diff --git a/src/bin/tar/lib/strnlen1.c b/src/bin/tar/lib/strnlen1.c deleted file mode 100644 index 422ed9e80c..0000000000 --- a/src/bin/tar/lib/strnlen1.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - Copyright (C) 2005-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include "strnlen1.h" - -#include - -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - If no '\0' terminator is found in that many characters, return MAXLEN. */ -/* This is the same as strnlen (string, maxlen - 1) + 1. */ -size_t -strnlen1 (const char *string, size_t maxlen) -{ - const char *end = (const char *) memchr (string, '\0', maxlen); - if (end != NULL) - return end - string + 1; - else - return maxlen; -} diff --git a/src/bin/tar/lib/strnlen1.h b/src/bin/tar/lib/strnlen1.h deleted file mode 100644 index 7ce7d0c803..0000000000 --- a/src/bin/tar/lib/strnlen1.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _STRNLEN1_H -#define _STRNLEN1_H - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - If no '\0' terminator is found in that many characters, return MAXLEN. */ -/* This is the same as strnlen (string, maxlen - 1) + 1. */ -extern size_t strnlen1 (const char *string, size_t maxlen); - - -#ifdef __cplusplus -} -#endif - - -#endif /* _STRNLEN1_H */ diff --git a/src/bin/tar/lib/strtoimax.c b/src/bin/tar/lib/strtoimax.c deleted file mode 100644 index 82dc4f0d75..0000000000 --- a/src/bin/tar/lib/strtoimax.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Convert string representation of a number into an intmax_t value. - - Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -/* Verify interface. */ -#include - -#include - -#include "verify.h" - -#ifdef UNSIGNED -# ifndef HAVE_DECL_STRTOULL -"this configure-time declaration test was not run" -# endif -# if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG_INT -unsigned long long int strtoull (char const *, char **, int); -# endif - -#else - -# ifndef HAVE_DECL_STRTOLL -"this configure-time declaration test was not run" -# endif -# if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG_INT -long long int strtoll (char const *, char **, int); -# endif -#endif - -#ifdef UNSIGNED -# define Have_long_long HAVE_UNSIGNED_LONG_LONG_INT -# define Int uintmax_t -# define Unsigned unsigned -# define strtoimax strtoumax -# define strtol strtoul -# define strtoll strtoull -#else -# define Have_long_long HAVE_LONG_LONG_INT -# define Int intmax_t -# define Unsigned -#endif - -Int -strtoimax (char const *ptr, char **endptr, int base) -{ -#if Have_long_long - verify (sizeof (Int) == sizeof (Unsigned long int) - || sizeof (Int) == sizeof (Unsigned long long int)); - - if (sizeof (Int) != sizeof (Unsigned long int)) - return strtoll (ptr, endptr, base); -#else - verify (sizeof (Int) == sizeof (Unsigned long int)); -#endif - - return strtol (ptr, endptr, base); -} diff --git a/src/bin/tar/lib/strtol.c b/src/bin/tar/lib/strtol.c deleted file mode 100644 index e14d3cf9cd..0000000000 --- a/src/bin/tar/lib/strtol.c +++ /dev/null @@ -1,436 +0,0 @@ -/* Convert string representation of a number into an integer value. - - Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2005, - 2006, 2007 - Free Software Foundation, Inc. - - NOTE: The canonical source of this file is maintained with the GNU C - Library. Bugs can be reported to bug-glibc@gnu.org. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef _LIBC -# define USE_NUMBER_GROUPING -#else -# include -#endif - -#include -#include -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif - -#include -#include -#include -#include - -#ifdef USE_NUMBER_GROUPING -# include "../locale/localeinfo.h" -#endif - -/* Nonzero if we are defining `strtoul' or `strtoull', operating on - unsigned integers. */ -#ifndef UNSIGNED -# define UNSIGNED 0 -# define INT LONG int -#else -# define INT unsigned LONG int -#endif - -/* Determine the name. */ -#ifdef USE_IN_EXTENDED_LOCALE_MODEL -# if UNSIGNED -# ifdef USE_WIDE_CHAR -# ifdef QUAD -# define strtol __wcstoull_l -# else -# define strtol __wcstoul_l -# endif -# else -# ifdef QUAD -# define strtol __strtoull_l -# else -# define strtol __strtoul_l -# endif -# endif -# else -# ifdef USE_WIDE_CHAR -# ifdef QUAD -# define strtol __wcstoll_l -# else -# define strtol __wcstol_l -# endif -# else -# ifdef QUAD -# define strtol __strtoll_l -# else -# define strtol __strtol_l -# endif -# endif -# endif -#else -# if UNSIGNED -# ifdef USE_WIDE_CHAR -# ifdef QUAD -# define strtol wcstoull -# else -# define strtol wcstoul -# endif -# else -# ifdef QUAD -# define strtol strtoull -# else -# define strtol strtoul -# endif -# endif -# else -# ifdef USE_WIDE_CHAR -# ifdef QUAD -# define strtol wcstoll -# else -# define strtol wcstol -# endif -# else -# ifdef QUAD -# define strtol strtoll -# endif -# endif -# endif -#endif - -/* If QUAD is defined, we are defining `strtoll' or `strtoull', - operating on `long long int's. */ -#ifdef QUAD -# define LONG long long -# define STRTOL_LONG_MIN LONG_LONG_MIN -# define STRTOL_LONG_MAX LONG_LONG_MAX -# define STRTOL_ULONG_MAX ULONG_LONG_MAX - -/* The extra casts in the following macros work around compiler bugs, - e.g., in Cray C 5.0.3.0. */ - -/* True if negative values of the signed integer type T use two's - complement, ones' complement, or signed magnitude representation, - respectively. Much GNU code assumes two's complement, but some - people like to be portable to all possible C hosts. */ -# define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) -# define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) -# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) - -/* True if the arithmetic type T is signed. */ -# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* The maximum and minimum values for the integer type T. These - macros have undefined behavior if T is signed and has padding bits. - If this is a problem for you, please let us know how to fix it for - your host. */ -# define TYPE_MINIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) 0 \ - : TYPE_SIGNED_MAGNITUDE (t) \ - ? ~ (t) 0 \ - : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) -# define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) - -# ifndef ULONG_LONG_MAX -# define ULONG_LONG_MAX TYPE_MAXIMUM (unsigned long long) -# endif -# ifndef LONG_LONG_MAX -# define LONG_LONG_MAX TYPE_MAXIMUM (long long int) -# endif -# ifndef LONG_LONG_MIN -# define LONG_LONG_MIN TYPE_MINIMUM (long long int) -# endif - -# if __GNUC__ == 2 && __GNUC_MINOR__ < 7 - /* Work around gcc bug with using this constant. */ - static const unsigned long long int maxquad = ULONG_LONG_MAX; -# undef STRTOL_ULONG_MAX -# define STRTOL_ULONG_MAX maxquad -# endif -#else -# define LONG long -# define STRTOL_LONG_MIN LONG_MIN -# define STRTOL_LONG_MAX LONG_MAX -# define STRTOL_ULONG_MAX ULONG_MAX -#endif - - -/* We use this code also for the extended locale handling where the - function gets as an additional argument the locale which has to be - used. To access the values we have to redefine the _NL_CURRENT - macro. */ -#ifdef USE_IN_EXTENDED_LOCALE_MODEL -# undef _NL_CURRENT -# define _NL_CURRENT(category, item) \ - (current->values[_NL_ITEM_INDEX (item)].string) -# define LOCALE_PARAM , loc -# define LOCALE_PARAM_PROTO , __locale_t loc -#else -# define LOCALE_PARAM -# define LOCALE_PARAM_PROTO -#endif - -#include - -#ifdef USE_WIDE_CHAR -# include -# define L_(Ch) L##Ch -# define UCHAR_TYPE wint_t -# define STRING_TYPE wchar_t -# ifdef USE_IN_EXTENDED_LOCALE_MODEL -# define ISSPACE(Ch) __iswspace_l ((Ch), loc) -# define ISALPHA(Ch) __iswalpha_l ((Ch), loc) -# define TOUPPER(Ch) __towupper_l ((Ch), loc) -# else -# define ISSPACE(Ch) iswspace (Ch) -# define ISALPHA(Ch) iswalpha (Ch) -# define TOUPPER(Ch) towupper (Ch) -# endif -#else -# define L_(Ch) Ch -# define UCHAR_TYPE unsigned char -# define STRING_TYPE char -# ifdef USE_IN_EXTENDED_LOCALE_MODEL -# define ISSPACE(Ch) __isspace_l ((Ch), loc) -# define ISALPHA(Ch) __isalpha_l ((Ch), loc) -# define TOUPPER(Ch) __toupper_l ((Ch), loc) -# else -# define ISSPACE(Ch) isspace (Ch) -# define ISALPHA(Ch) isalpha (Ch) -# define TOUPPER(Ch) toupper (Ch) -# endif -#endif - -#define INTERNAL(X) INTERNAL1(X) -#define INTERNAL1(X) __##X##_internal -#define WEAKNAME(X) WEAKNAME1(X) - -#ifdef USE_NUMBER_GROUPING -/* This file defines a function to check for correct grouping. */ -# include "grouping.h" -#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. */ - -INT -INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr, - int base, int group LOCALE_PARAM_PROTO) -{ - int negative; - register unsigned LONG int cutoff; - register unsigned int cutlim; - register unsigned LONG int i; - register const STRING_TYPE *s; - register UCHAR_TYPE c; - const STRING_TYPE *save, *end; - int overflow; - -#ifdef USE_NUMBER_GROUPING -# ifdef USE_IN_EXTENDED_LOCALE_MODEL - struct locale_data *current = loc->__locales[LC_NUMERIC]; -# endif - /* The thousands character of the current locale. */ - wchar_t thousands = L'\0'; - /* The numeric grouping specification of the current locale, - in the format described in . */ - const char *grouping; - - if (group) - { - grouping = _NL_CURRENT (LC_NUMERIC, GROUPING); - if (*grouping <= 0 || *grouping == CHAR_MAX) - grouping = NULL; - else - { - /* Figure out the thousands separator character. */ -# if defined _LIBC || defined _HAVE_BTOWC - thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP)); - if (thousands == WEOF) - thousands = L'\0'; -# endif - if (thousands == L'\0') - grouping = NULL; - } - } - else - grouping = NULL; -#endif - - if (base < 0 || base == 1 || base > 36) - { - __set_errno (EINVAL); - return 0; - } - - save = s = nptr; - - /* Skip white space. */ - while (ISSPACE (*s)) - ++s; - if (*s == L_('\0')) - goto noconv; - - /* Check for a sign. */ - if (*s == L_('-')) - { - negative = 1; - ++s; - } - else if (*s == L_('+')) - { - negative = 0; - ++s; - } - else - negative = 0; - - /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ - if (*s == L_('0')) - { - if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X')) - { - s += 2; - base = 16; - } - else if (base == 0) - base = 8; - } - else if (base == 0) - base = 10; - - /* Save the pointer so we can check later if anything happened. */ - save = s; - -#ifdef USE_NUMBER_GROUPING - if (group) - { - /* Find the end of the digit string and check its grouping. */ - end = s; - for (c = *end; c != L_('\0'); c = *++end) - if ((wchar_t) c != thousands - && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9')) - && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base)) - break; - if (*s == thousands) - end = s; - else - end = correctly_grouped_prefix (s, end, thousands, grouping); - } - else -#endif - end = NULL; - - cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base; - cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base; - - overflow = 0; - i = 0; - for (c = *s; c != L_('\0'); c = *++s) - { - if (s == end) - break; - if (c >= L_('0') && c <= L_('9')) - c -= L_('0'); - else if (ISALPHA (c)) - c = TOUPPER (c) - L_('A') + 10; - else - break; - if ((int) 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 = (STRING_TYPE *) s; - -#if !UNSIGNED - /* Check for a value that is within the range of - `unsigned LONG int', but outside the range of `LONG int'. */ - if (overflow == 0 - && i > (negative - ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1 - : (unsigned LONG int) STRTOL_LONG_MAX)) - overflow = 1; -#endif - - if (overflow) - { - __set_errno (ERANGE); -#if UNSIGNED - return STRTOL_ULONG_MAX; -#else - return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX; -#endif - } - - /* Return the result of the appropriate sign. */ - return negative ? -i : i; - -noconv: - /* We must handle a special case here: the base is 0 or 16 and the - first two characters are '0' and 'x', but the rest are no - hexadecimal digits. This is no error case. We return 0 and - ENDPTR points to the `x`. */ - if (endptr != NULL) - { - if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X') - && save[-2] == L_('0')) - *endptr = (STRING_TYPE *) &save[-1]; - else - /* There was no number to convert. */ - *endptr = (STRING_TYPE *) nptr; - } - - return 0L; -} - -/* External user entry point. */ - - -INT -#ifdef weak_function -weak_function -#endif -strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr, - int base LOCALE_PARAM_PROTO) -{ - return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM); -} diff --git a/src/bin/tar/lib/strtoll.c b/src/bin/tar/lib/strtoll.c deleted file mode 100644 index f61f5ada64..0000000000 --- a/src/bin/tar/lib/strtoll.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Function to parse a `long long int' from text. - Copyright (C) 1995, 1996, 1997, 1999, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#define QUAD 1 - -#include - -#ifdef _LIBC -# ifdef SHARED -# include - -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) -compat_symbol (libc, __strtoll_internal, __strtoq_internal, GLIBC_2_0); -# endif - -# endif -weak_alias (strtoll, strtoq) -#endif diff --git a/src/bin/tar/lib/strtoul.c b/src/bin/tar/lib/strtoul.c deleted file mode 100644 index 79ceed2f31..0000000000 --- a/src/bin/tar/lib/strtoul.c +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 1991, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#define UNSIGNED 1 - -#include "strtol.c" diff --git a/src/bin/tar/lib/strtoull.c b/src/bin/tar/lib/strtoull.c deleted file mode 100644 index 6186bfb65a..0000000000 --- a/src/bin/tar/lib/strtoull.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Function to parse an `unsigned long long int' from text. - Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C - Library. Bugs can be reported to bug-glibc@gnu.org. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#define QUAD 1 - -#include "strtoul.c" - -#ifdef _LIBC -strong_alias (__strtoull_internal, __strtouq_internal) -weak_alias (strtoull, strtouq) -#endif diff --git a/src/bin/tar/lib/strtoumax.c b/src/bin/tar/lib/strtoumax.c deleted file mode 100644 index dc395d626a..0000000000 --- a/src/bin/tar/lib/strtoumax.c +++ /dev/null @@ -1,2 +0,0 @@ -#define UNSIGNED 1 -#include "strtoimax.c" diff --git a/src/bin/tar/lib/sys_stat.in.h b/src/bin/tar/lib/sys_stat.in.h deleted file mode 100644 index 2e411cd3c6..0000000000 --- a/src/bin/tar/lib/sys_stat.in.h +++ /dev/null @@ -1,280 +0,0 @@ -/* Provide a more complete sys/stat header file. - Copyright (C) 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Eric Blake, Paul Eggert, and Jim Meyering. */ - -/* This file is supposed to be used on platforms where is - incomplete. It is intended to provide definitions and prototypes - needed by an application. Start with what the system provides. */ - -#ifndef _GL_SYS_STAT_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_SYS_STAT_H@ - -#ifndef _GL_SYS_STAT_H -#define _GL_SYS_STAT_H - -#ifndef S_IFMT -# define S_IFMT 0170000 -#endif - -#if STAT_MACROS_BROKEN -# undef S_ISBLK -# undef S_ISCHR -# undef S_ISDIR -# undef S_ISFIFO -# undef S_ISLNK -# undef S_ISNAM -# undef S_ISMPB -# undef S_ISMPC -# undef S_ISNWK -# undef S_ISREG -# undef S_ISSOCK -#endif - -#ifndef S_ISBLK -# ifdef S_IFBLK -# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -# else -# define S_ISBLK(m) 0 -# endif -#endif - -#ifndef S_ISCHR -# ifdef S_IFCHR -# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -# else -# define S_ISCHR(m) 0 -# endif -#endif - -#ifndef S_ISDIR -# ifdef S_IFDIR -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -# else -# define S_ISDIR(m) 0 -# endif -#endif - -#ifndef S_ISDOOR /* Solaris 2.5 and up */ -# define S_ISDOOR(m) 0 -#endif - -#ifndef S_ISFIFO -# ifdef S_IFIFO -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(m) 0 -# endif -#endif - -#ifndef S_ISLNK -# ifdef S_IFLNK -# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -# else -# define S_ISLNK(m) 0 -# endif -#endif - -#ifndef S_ISMPB /* V7 */ -# ifdef S_IFMPB -# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -# else -# define S_ISMPB(m) 0 -# define S_ISMPC(m) 0 -# endif -#endif - -#ifndef S_ISNAM /* Xenix */ -# ifdef S_IFNAM -# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) -# else -# define S_ISNAM(m) 0 -# endif -#endif - -#ifndef S_ISNWK /* HP/UX */ -# ifdef S_IFNWK -# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) -# else -# define S_ISNWK(m) 0 -# endif -#endif - -#ifndef S_ISPORT /* Solaris 10 and up */ -# define S_ISPORT(m) 0 -#endif - -#ifndef S_ISREG -# ifdef S_IFREG -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -# else -# define S_ISREG(m) 0 -# endif -#endif - -#ifndef S_ISSOCK -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) 0 -# endif -#endif - - -#ifndef S_TYPEISMQ -# define S_TYPEISMQ(p) 0 -#endif - -#ifndef S_TYPEISTMO -# define S_TYPEISTMO(p) 0 -#endif - - -#ifndef S_TYPEISSEM -# ifdef S_INSEM -# define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM) -# else -# define S_TYPEISSEM(p) 0 -# endif -#endif - -#ifndef S_TYPEISSHM -# ifdef S_INSHD -# define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD) -# else -# define S_TYPEISSHM(p) 0 -# endif -#endif - -/* high performance ("contiguous data") */ -#ifndef S_ISCTG -# define S_ISCTG(p) 0 -#endif - -/* Cray DMF (data migration facility): off line, with data */ -#ifndef S_ISOFD -# define S_ISOFD(p) 0 -#endif - -/* Cray DMF (data migration facility): off line, with no data */ -#ifndef S_ISOFL -# define S_ISOFL(p) 0 -#endif - -/* 4.4BSD whiteout */ -#ifndef S_ISWHT -# define S_ISWHT(m) 0 -#endif - -/* If any of the following are undefined, - define them to their de facto standard values. */ -#if !S_ISUID -# define S_ISUID 04000 -#endif -#if !S_ISGID -# define S_ISGID 02000 -#endif - -/* S_ISVTX is a common extension to POSIX. */ -#ifndef S_ISVTX -# define S_ISVTX 01000 -#endif - -#if !S_IRUSR && S_IREAD -# define S_IRUSR S_IREAD -#endif -#if !S_IRUSR -# define S_IRUSR 00400 -#endif -#if !S_IRGRP -# define S_IRGRP (S_IRUSR >> 3) -#endif -#if !S_IROTH -# define S_IROTH (S_IRUSR >> 6) -#endif - -#if !S_IWUSR && S_IWRITE -# define S_IWUSR S_IWRITE -#endif -#if !S_IWUSR -# define S_IWUSR 00200 -#endif -#if !S_IWGRP -# define S_IWGRP (S_IWUSR >> 3) -#endif -#if !S_IWOTH -# define S_IWOTH (S_IWUSR >> 6) -#endif - -#if !S_IXUSR && S_IEXEC -# define S_IXUSR S_IEXEC -#endif -#if !S_IXUSR -# define S_IXUSR 00100 -#endif -#if !S_IXGRP -# define S_IXGRP (S_IXUSR >> 3) -#endif -#if !S_IXOTH -# define S_IXOTH (S_IXUSR >> 6) -#endif - -#if !S_IRWXU -# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) -#endif -#if !S_IRWXG -# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) -#endif -#if !S_IRWXO -# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) -#endif - -/* S_IXUGO is a common extension to POSIX. */ -#if !S_IXUGO -# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) -#endif - -#ifndef S_IRWXUGO -# define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO) -#endif - -/* mingw does not support symlinks, therefore it does not have lstat. But - without links, stat does just fine. */ -#if ! @HAVE_LSTAT@ -# define lstat stat -#endif - -/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. - Additionally, it declares _mkdir (and depending on compile flags, an - alias mkdir), only in the nonstandard io.h. */ -#if ! @HAVE_DECL_MKDIR@ && @HAVE_IO_H@ -# include - -static inline int -rpl_mkdir (char const *name, mode_t mode) -{ - return _mkdir (name); -} - -# define mkdir rpl_mkdir -#endif - -#endif /* _GL_SYS_STAT_H */ -#endif /* _GL_SYS_STAT_H */ diff --git a/src/bin/tar/lib/sys_time.in.h b/src/bin/tar/lib/sys_time.in.h deleted file mode 100644 index 296d20df47..0000000000 --- a/src/bin/tar/lib/sys_time.in.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Provide a more complete sys/time.h. - - Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#if defined _GL_SYS_TIME_H - -/* Simply delegate to the system's header, without adding anything. */ -# if @HAVE_SYS_TIME_H@ -# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ -# endif - -#else - -# define _GL_SYS_TIME_H - -# if @HAVE_SYS_TIME_H@ -# @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@ -# else -# include -# endif - -# if ! @HAVE_STRUCT_TIMEVAL@ -struct timeval -{ - time_t tv_sec; - long int tv_usec; -}; -# endif - -# if @REPLACE_GETTIMEOFDAY@ -# undef gettimeofday -# define gettimeofday rpl_gettimeofday -int gettimeofday (struct timeval *restrict, void *restrict); -# endif - -#endif /* _GL_SYS_TIME_H */ diff --git a/src/bin/tar/lib/sysexits.h b/src/bin/tar/lib/sysexits.h deleted file mode 100644 index 37246b6e75..0000000000 --- a/src/bin/tar/lib/sysexits.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)sysexits.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _SYSEXITS_H -#define _SYSEXITS_H 1 - -/* - * SYSEXITS.H -- Exit status codes for system programs. - * - * This include file attempts to categorize possible error - * exit statuses for system programs, notably delivermail - * and the Berkeley network. - * - * Error numbers begin at EX__BASE to reduce the possibility of - * clashing with other exit statuses that random programs may - * already return. The meaning of the codes is approximately - * as follows: - * - * EX_USAGE -- The command was used incorrectly, e.g., with - * the wrong number of arguments, a bad flag, a bad - * syntax in a parameter, or whatever. - * EX_DATAERR -- The input data was incorrect in some way. - * This should only be used for user's data & not - * system files. - * EX_NOINPUT -- An input file (not a system file) did not - * exist or was not readable. This could also include - * errors like "No message" to a mailer (if it cared - * to catch it). - * EX_NOUSER -- The user specified did not exist. This might - * be used for mail addresses or remote logins. - * EX_NOHOST -- The host specified did not exist. This is used - * in mail addresses or network requests. - * EX_UNAVAILABLE -- A service is unavailable. This can occur - * if a support program or file does not exist. This - * can also be used as a catchall message when something - * you wanted to do doesn't work, but you don't know - * why. - * EX_SOFTWARE -- An internal software error has been detected. - * This should be limited to non-operating system related - * errors as possible. - * EX_OSERR -- An operating system error has been detected. - * This is intended to be used for such things as "cannot - * fork", "cannot create pipe", or the like. It includes - * things like getuid returning a user that does not - * exist in the passwd file. - * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, - * etc.) does not exist, cannot be opened, or has some - * sort of error (e.g., syntax error). - * EX_CANTCREAT -- A (user specified) output file cannot be - * created. - * EX_IOERR -- An error occurred while doing I/O on some file. - * EX_TEMPFAIL -- temporary failure, indicating something that - * is not really an error. In sendmail, this means - * that a mailer (e.g.) could not create a connection, - * and the request should be reattempted later. - * EX_PROTOCOL -- the remote system returned something that - * was "not possible" during a protocol exchange. - * EX_NOPERM -- You did not have sufficient permission to - * perform the operation. This is not intended for - * file system problems, which should use NOINPUT or - * CANTCREAT, but rather for higher level permissions. - */ - -#define EX_OK 0 /* successful termination */ - -#define EX__BASE 64 /* base value for error messages */ - -#define EX_USAGE 64 /* command line usage error */ -#define EX_DATAERR 65 /* data format error */ -#define EX_NOINPUT 66 /* cannot open input */ -#define EX_NOUSER 67 /* addressee unknown */ -#define EX_NOHOST 68 /* host name unknown */ -#define EX_UNAVAILABLE 69 /* service unavailable */ -#define EX_SOFTWARE 70 /* internal software error */ -#define EX_OSERR 71 /* system error (e.g., can't fork) */ -#define EX_OSFILE 72 /* critical OS file missing */ -#define EX_CANTCREAT 73 /* can't create (user) output file */ -#define EX_IOERR 74 /* input/output error */ -#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ -#define EX_PROTOCOL 76 /* remote error in protocol */ -#define EX_NOPERM 77 /* permission denied */ -#define EX_CONFIG 78 /* configuration error */ - -#define EX__MAX 78 /* maximum listed value */ - -#endif /* sysexits.h */ diff --git a/src/bin/tar/lib/sysexits.in.h b/src/bin/tar/lib/sysexits.in.h deleted file mode 100644 index b65e0ccc32..0000000000 --- a/src/bin/tar/lib/sysexits.in.h +++ /dev/null @@ -1,68 +0,0 @@ -/* exit() exit codes for some BSD system programs. - Copyright (C) 2003, 2006-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Simon Josefsson based on sysexits(3) man page */ - -#ifndef _GL_SYSEXITS_H - -#if @HAVE_SYSEXITS_H@ - -/* IRIX 6.5 has an that defines a macro EX_OK with a nonzero - value. Override it. See - */ -# ifdef __sgi -# include -# undef EX_OK -# endif - -/* The include_next requires a split double-inclusion guard. */ -# @INCLUDE_NEXT@ @NEXT_SYSEXITS_H@ - -/* HP-UX 11 ends at EX_NOPERM. */ -# ifndef EX_CONFIG -# define EX_CONFIG 78 -# endif - -#endif - -#ifndef _GL_SYSEXITS_H -#define _GL_SYSEXITS_H - -#if !@HAVE_SYSEXITS_H@ - -# define EX_OK 0 /* same value as EXIT_SUCCESS */ - -# define EX_USAGE 64 -# define EX_DATAERR 65 -# define EX_NOINPUT 66 -# define EX_NOUSER 67 -# define EX_NOHOST 68 -# define EX_UNAVAILABLE 69 -# define EX_SOFTWARE 70 -# define EX_OSERR 71 -# define EX_OSFILE 72 -# define EX_CANTCREAT 73 -# define EX_IOERR 74 -# define EX_TEMPFAIL 75 -# define EX_PROTOCOL 76 -# define EX_NOPERM 77 -# define EX_CONFIG 78 - -#endif - -#endif /* _GL_SYSEXITS_H */ -#endif /* _GL_SYSEXITS_H */ diff --git a/src/bin/tar/lib/system-ioctl.h b/src/bin/tar/lib/system-ioctl.h deleted file mode 100644 index f3276cfe0c..0000000000 --- a/src/bin/tar/lib/system-ioctl.h +++ /dev/null @@ -1,55 +0,0 @@ -/* System dependent definitions for GNU tar's use of ioctl macros. - - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, - 2004, 2005, 2006, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This is a real challenge to properly get MTIO* symbols :-(. ISC uses - . SCO and BSDi uses ; BSDi also requires - and for defining tp_dev and tpr_t. It - seems that the rest use , which itself requires other files, - depending on systems. Pyramid defines _IOW in , for example. */ - -#if HAVE_SYS_GENTAPE_H -# include -#else -# if HAVE_SYS_TAPE_H -# if HAVE_SYS_DEVICE_H -# include -# endif -# if HAVE_SYS_PARAM_H -# include -# endif -# if HAVE_SYS_BUF_H -# include -# endif -# if HAVE_SYS_TPRINTF_H -# include -# endif -# include -# else -# if HAVE_SYS_MTIO_H -# include -# if HAVE_SGTTY_H -# include -# endif -# if HAVE_SYS_IO_TRIOCTL_H -# include -# endif -# include -# endif -# endif -#endif diff --git a/src/bin/tar/lib/system.h b/src/bin/tar/lib/system.h deleted file mode 100644 index bfddf76e8b..0000000000 --- a/src/bin/tar/lib/system.h +++ /dev/null @@ -1,475 +0,0 @@ -/* System dependent definitions for GNU tar. - - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, - 2004, 2005, 2006, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(spec) /* empty */ -# endif -#endif - -#include -#include - -/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given - as an argument to macros like `isspace'. */ -#if STDC_HEADERS -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177) -#endif - -#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) -#define ISODIGIT(c) ((unsigned) (c) - '0' <= 7) -#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) -#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) - -/* Declare string and memory handling routines. Take care that an ANSI - string.h and pre-ANSI memory.h might conflict, and that memory.h and - strings.h conflict on some systems. */ - -#if STDC_HEADERS || HAVE_STRING_H -# include -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -#else -# include -# ifndef strchr -# define strchr index -# endif -# ifndef strrchr -# define strrchr rindex -# endif -# ifndef memcpy -# define memcpy(d, s, n) bcopy ((char const *) (s), (char *) (d), n) -# endif -# ifndef memcmp -# define memcmp(a, b, n) bcmp ((char const *) (a), (char const *) (b), n) -# endif -#endif - -/* Declare errno. */ - -#include -#ifndef errno -extern int errno; -#endif - -/* Declare open parameters. */ - -#if HAVE_FCNTL_H -# include -#else -# include -#endif - /* Pick only one of the next three: */ -#ifndef O_RDONLY -# define O_RDONLY 0 /* only allow read */ -#endif -#ifndef O_WRONLY -# define O_WRONLY 1 /* only allow write */ -#endif -#ifndef O_RDWR -# define O_RDWR 2 /* both are allowed */ -#endif -#ifndef O_ACCMODE -# define O_ACCMODE (O_RDONLY | O_RDWR | O_WRONLY) -#endif - /* The rest can be OR-ed in to the above: */ -#ifndef O_CREAT -# define O_CREAT 8 /* create file if needed */ -#endif -#ifndef O_EXCL -# define O_EXCL 16 /* file cannot already exist */ -#endif -#ifndef O_TRUNC -# define O_TRUNC 32 /* truncate file on open */ -#endif - -#ifndef O_BINARY -# define O_BINARY 0 -#endif -#ifndef O_DIRECTORY -# define O_DIRECTORY 0 -#endif -#ifndef O_NOATIME -# define O_NOATIME 0 -#endif -#ifndef O_NONBLOCK -# define O_NONBLOCK 0 -#endif - -/* Declare file status routines and bits. */ - -#include - -#if !HAVE_LSTAT && !defined lstat -# define lstat stat -#endif - -#if STX_HIDDEN && !_LARGE_FILES /* AIX */ -# ifdef stat -# undef stat -# endif -# define stat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN) -# ifdef lstat -# undef lstat -# endif -# define lstat(file_name, buf) statx (file_name, buf, STATSIZE, STX_HIDDEN | STX_LINK) -#endif - -#if STAT_MACROS_BROKEN -# undef S_ISBLK -# undef S_ISCHR -# undef S_ISCTG -# undef S_ISDIR -# undef S_ISFIFO -# undef S_ISLNK -# undef S_ISREG -# undef S_ISSOCK -#endif - -/* On MSDOS, there are missing things from . */ -#if MSDOS -# define S_ISUID 0 -# define S_ISGID 0 -# define S_ISVTX 0 -#endif - -#ifndef S_ISDIR -# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif -#ifndef S_ISREG -# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif - -#ifndef S_ISBLK -# ifdef S_IFBLK -# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) -# else -# define S_ISBLK(mode) 0 -# endif -#endif -#ifndef S_ISCHR -# ifdef S_IFCHR -# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) -# else -# define S_ISCHR(mode) 0 -# endif -#endif -#ifndef S_ISCTG -# ifdef S_IFCTG -# define S_ISCTG(mode) (((mode) & S_IFMT) == S_IFCTG) -# else -# define S_ISCTG(mode) 0 -# endif -#endif -#ifndef S_ISDOOR -# define S_ISDOOR(mode) 0 -#endif -#ifndef S_ISFIFO -# ifdef S_IFIFO -# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(mode) 0 -# endif -#endif -#ifndef S_ISLNK -# ifdef S_IFLNK -# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -# else -# define S_ISLNK(mode) 0 -# endif -#endif -#ifndef S_ISSOCK -# ifdef S_IFSOCK -# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(mode) 0 -# endif -#endif - -#if !HAVE_MKFIFO && !defined mkfifo && defined S_IFIFO -# define mkfifo(file_name, mode) (mknod (file_name, (mode) | S_IFIFO, 0)) -#endif - -#ifndef S_ISUID -# define S_ISUID 0004000 -#endif -#ifndef S_ISGID -# define S_ISGID 0002000 -#endif -#ifndef S_ISVTX -# define S_ISVTX 0001000 -#endif -#ifndef S_IRUSR -# define S_IRUSR 0000400 -#endif -#ifndef S_IWUSR -# define S_IWUSR 0000200 -#endif -#ifndef S_IXUSR -# define S_IXUSR 0000100 -#endif -#ifndef S_IRGRP -# define S_IRGRP 0000040 -#endif -#ifndef S_IWGRP -# define S_IWGRP 0000020 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0000010 -#endif -#ifndef S_IROTH -# define S_IROTH 0000004 -#endif -#ifndef S_IWOTH -# define S_IWOTH 0000002 -#endif -#ifndef S_IXOTH -# define S_IXOTH 0000001 -#endif - -#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) - -/* Include before any preprocessor test of _POSIX_VERSION. */ -#include - -#ifndef SEEK_SET -# define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -# define SEEK_CUR 1 -#endif -#ifndef SEEK_END -# define SEEK_END 2 -#endif - -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif - -/* Declare make device, major and minor. Since major is a function on - SVR4, we have to resort to GOT_MAJOR instead of just testing if - major is #define'd. */ - -#if MAJOR_IN_MKDEV -# include -# if !defined(makedev) && defined(mkdev) -# define makedev(a,b) mkdev((a),(b)) -# endif -# define GOT_MAJOR -#endif - -#if MAJOR_IN_SYSMACROS -# include -# define GOT_MAJOR -#endif - -/* Some defines the macros. */ -#ifdef major -# define GOT_MAJOR -#endif - -#ifndef GOT_MAJOR -# if MSDOS -# define major(device) (device) -# define minor(device) (device) -# define makedev(major, minor) (((major) << 8) | (minor)) -# define GOT_MAJOR -# endif -#endif - -/* For HP-UX before HP-UX 8, major/minor are not in . */ -#ifndef GOT_MAJOR -# if defined(hpux) || defined(__hpux__) || defined(__hpux) -# include -# define GOT_MAJOR -# endif -#endif - -#ifndef GOT_MAJOR -# define major(device) (((device) >> 8) & 0xff) -# define minor(device) ((device) & 0xff) -# define makedev(major, minor) (((major) << 8) | (minor)) -#endif - -#undef GOT_MAJOR - -/* Declare wait status. */ - -#if HAVE_SYS_WAIT_H -# include -#endif -#ifndef WEXITSTATUS -# define WEXITSTATUS(s) (((s) >> 8) & 0xff) -#endif -#ifndef WIFSIGNALED -# define WIFSIGNALED(s) (((s) & 0xffff) - 1 < (unsigned) 0xff) -#endif -#ifndef WTERMSIG -# define WTERMSIG(s) ((s) & 0x7f) -#endif - -/* FIXME: It is wrong to use BLOCKSIZE for buffers when the logical block - size is greater than 512 bytes; so ST_BLKSIZE code below, in preparation - for some cleanup in this area, later. */ - -/* Extract or fake data from a `struct stat'. ST_BLKSIZE gives the - optimal I/O blocksize for the file, in bytes. Some systems, like - Sequents, return st_blksize of 0 on pipes. */ - -#define DEFAULT_ST_BLKSIZE 512 - -#if !HAVE_ST_BLKSIZE -# define ST_BLKSIZE(statbuf) DEFAULT_ST_BLKSIZE -#else -# define ST_BLKSIZE(statbuf) \ - ((statbuf).st_blksize > 0 ? (statbuf).st_blksize : DEFAULT_ST_BLKSIZE) -#endif - -/* Extract or fake data from a `struct stat'. ST_NBLOCKS gives the - number of ST_NBLOCKSIZE-byte blocks in the file (including indirect blocks). - HP-UX counts st_blocks in 1024-byte units, - this loses when mixing HP-UX and BSD filesystems with NFS. AIX PS/2 - counts st_blocks in 4K units. */ - -#if !HAVE_ST_BLOCKS -# if defined(_POSIX_SOURCE) || !defined(BSIZE) -# define ST_NBLOCKS(statbuf) ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0)) -# else - off_t st_blocks (); -# define ST_NBLOCKS(statbuf) (st_blocks ((statbuf).st_size)) -# endif -#else -# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks) -# if defined(hpux) || defined(__hpux__) || defined(__hpux) -# define ST_NBLOCKSIZE 1024 -# else -# if defined(_AIX) && defined(_I386) -# define ST_NBLOCKSIZE (4 * 1024) -# endif -# endif -#endif - -#ifndef ST_NBLOCKSIZE -# define ST_NBLOCKSIZE 512 -#endif - -#define ST_IS_SPARSE(st) \ - (ST_NBLOCKS (st) \ - < ((st).st_size / ST_NBLOCKSIZE + ((st).st_size % ST_NBLOCKSIZE != 0))) - -/* Declare standard functions. */ - -#if STDC_HEADERS -# include -#else -void *malloc (); -char *getenv (); -#endif - -#include -#include - -#include -#if !defined _POSIX_VERSION && MSDOS -# include -#endif - -#if WITH_DMALLOC -# define DMALLOC_FUNC_CHECK -# include -#endif - -#include - -#ifndef MB_LEN_MAX -# define MB_LEN_MAX 1 -#endif - -#include - -#include - -#define UINTMAX_STRSIZE_BOUND INT_BUFSIZE_BOUND (uintmax_t) - -/* Prototypes for external functions. */ - -#if HAVE_LOCALE_H -# include -#endif -#if !HAVE_SETLOCALE -# define setlocale(category, locale) /* empty */ -#endif - -#include -#ifdef TIME_WITH_SYS_TIME -# include -#endif - -/* Library modules. */ - -#include -#include -#include -#include -#include - -#include -#define _(msgid) gettext (msgid) -#define N_(msgid) msgid - -#if MSDOS -# include -# define SET_BINARY_MODE(arc) setmode(arc, O_BINARY) -# define ERRNO_IS_EACCES errno == EACCES -# define mkdir(file, mode) (mkdir) (file) -# define TTY_NAME "con" -# define sys_reset_uid_gid() -#else -# include -# include -# define SET_BINARY_MODE(arc) -# define ERRNO_IS_EACCES 0 -# define TTY_NAME "/dev/tty" -# define sys_reset_uid_gid() \ - do { setuid (getuid ()); setgid (getgid ()); } while (0) -#endif - -#if XENIX -# include -#endif diff --git a/src/bin/tar/lib/tempname.c b/src/bin/tar/lib/tempname.c deleted file mode 100644 index e213600e3f..0000000000 --- a/src/bin/tar/lib/tempname.c +++ /dev/null @@ -1,315 +0,0 @@ -/* tempname.c - generate the name of a temporary file. - - Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */ - -#if !_LIBC -# include -# include "tempname.h" -#endif - -#include -#include - -#include -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif - -#include -#ifndef P_tmpdir -# define P_tmpdir "/tmp" -#endif -#ifndef TMP_MAX -# define TMP_MAX 238328 -#endif -#ifndef __GT_FILE -# define __GT_FILE 0 -# define __GT_BIGFILE 1 -# define __GT_DIR 2 -# define __GT_NOCREATE 3 -#endif - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#if _LIBC -# define struct_stat64 struct stat64 -# define small_open __open -# define large_open __open64 -#else -# define struct_stat64 struct stat -# define small_open open -# define large_open open -# define __gen_tempname gen_tempname -# define __getpid getpid -# define __gettimeofday gettimeofday -# define __mkdir mkdir -# define __lxstat64(version, file, buf) lstat (file, buf) -# define __xstat64(version, file, buf) stat (file, buf) -#endif - -#if ! (HAVE___SECURE_GETENV || _LIBC) -# define __secure_getenv getenv -#endif - -#ifdef _LIBC -# include -# if HP_TIMING_AVAIL -# define RANDOM_BITS(Var) \ - if (__builtin_expect (value == UINT64_C (0), 0)) \ - { \ - /* If this is the first time this function is used initialize \ - the variable we accumulate the value in to some somewhat \ - random value. If we'd not do this programs at startup time \ - might have a reduced set of possible names, at least on slow \ - machines. */ \ - struct timeval tv; \ - __gettimeofday (&tv, NULL); \ - value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ - } \ - HP_TIMING_NOW (Var) -# endif -#endif - -/* Use the widest available unsigned type if uint64_t is not - available. The algorithm below extracts a number less than 62**6 - (approximately 2**35.725) from uint64_t, so ancient hosts where - uintmax_t is only 32 bits lose about 3.725 bits of randomness, - which is better than not having mkstemp at all. */ -#if !defined UINT64_MAX && !defined uint64_t -# define uint64_t uintmax_t -#endif - -#if _LIBC -/* Return nonzero if DIR is an existent directory. */ -static int -direxists (const char *dir) -{ - struct_stat64 buf; - return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); -} - -/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is - non-null and exists, uses it; otherwise uses the first of $TMPDIR, - P_tmpdir, /tmp that exists. Copies into TMPL a template suitable - for use with mk[s]temp. Will fail (-1) if DIR is non-null and - doesn't exist, none of the searched dirs exists, or there's not - enough space in TMPL. */ -int -__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, - int try_tmpdir) -{ - const char *d; - size_t dlen, plen; - - if (!pfx || !pfx[0]) - { - pfx = "file"; - plen = 4; - } - else - { - plen = strlen (pfx); - if (plen > 5) - plen = 5; - } - - if (try_tmpdir) - { - d = __secure_getenv ("TMPDIR"); - if (d != NULL && direxists (d)) - dir = d; - else if (dir != NULL && direxists (dir)) - /* nothing */ ; - else - dir = NULL; - } - if (dir == NULL) - { - if (direxists (P_tmpdir)) - dir = P_tmpdir; - else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) - dir = "/tmp"; - else - { - __set_errno (ENOENT); - return -1; - } - } - - dlen = strlen (dir); - while (dlen > 1 && dir[dlen - 1] == '/') - dlen--; /* remove trailing slashes */ - - /* check we have room for "${dir}/${pfx}XXXXXX\0" */ - if (tmpl_len < dlen + 1 + plen + 6 + 1) - { - __set_errno (EINVAL); - return -1; - } - - sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); - return 0; -} -#endif /* _LIBC */ - -/* These are the characters used in temporary file names. */ -static const char letters[] = -"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - -/* Generate a temporary file name based on TMPL. TMPL must match the - rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed - does not exist at the time of the call to __gen_tempname. TMPL is - overwritten with the result. - - KIND may be one of: - __GT_NOCREATE: simply verify that the name does not exist - at the time of the call. - __GT_FILE: create the file using open(O_CREAT|O_EXCL) - and return a read-write fd. The file is mode 0600. - __GT_BIGFILE: same as __GT_FILE but use open64(). - __GT_DIR: create a directory, which will be mode 0700. - - We use a clever algorithm to get hard-to-predict names. */ -int -__gen_tempname (char *tmpl, int kind) -{ - int len; - char *XXXXXX; - static uint64_t value; - uint64_t random_time_bits; - unsigned int count; - int fd = -1; - int save_errno = errno; - struct_stat64 st; - - /* A lower bound on the number of temporary files to attempt to - generate. The maximum total number of temporary file names that - can exist for a given template is 62**6. It should never be - necessary to try all these combinations. Instead if a reasonable - number of names is tried (we define reasonable as 62**3) fail to - give the system administrator the chance to remove the problems. */ -#define ATTEMPTS_MIN (62 * 62 * 62) - - /* The number of times to attempt to generate a temporary file. To - conform to POSIX, this must be no smaller than TMP_MAX. */ -#if ATTEMPTS_MIN < TMP_MAX - unsigned int attempts = TMP_MAX; -#else - unsigned int attempts = ATTEMPTS_MIN; -#endif - - len = strlen (tmpl); - if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX")) - { - __set_errno (EINVAL); - return -1; - } - - /* This is where the Xs start. */ - XXXXXX = &tmpl[len - 6]; - - /* Get some more or less random data. */ -#ifdef RANDOM_BITS - RANDOM_BITS (random_time_bits); -#else - { - struct timeval tv; - __gettimeofday (&tv, NULL); - random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; - } -#endif - value += random_time_bits ^ __getpid (); - - for (count = 0; count < attempts; value += 7777, ++count) - { - uint64_t v = value; - - /* Fill in the random bits. */ - XXXXXX[0] = letters[v % 62]; - v /= 62; - XXXXXX[1] = letters[v % 62]; - v /= 62; - XXXXXX[2] = letters[v % 62]; - v /= 62; - XXXXXX[3] = letters[v % 62]; - v /= 62; - XXXXXX[4] = letters[v % 62]; - v /= 62; - XXXXXX[5] = letters[v % 62]; - - switch (kind) - { - case __GT_FILE: - fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - break; - - case __GT_BIGFILE: - fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - break; - - case __GT_DIR: - fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); - break; - - case __GT_NOCREATE: - /* This case is backward from the other three. __gen_tempname - succeeds if __xstat fails because the name does not exist. - Note the continue to bypass the common logic at the bottom - of the loop. */ - if (__lxstat64 (_STAT_VER, tmpl, &st) < 0) - { - if (errno == ENOENT) - { - __set_errno (save_errno); - return 0; - } - else - /* Give up now. */ - return -1; - } - continue; - - default: - assert (! "invalid KIND in __gen_tempname"); - } - - if (fd >= 0) - { - __set_errno (save_errno); - return fd; - } - else if (errno != EEXIST) - return -1; - } - - /* We got out of the loop because we ran out of combinations to try. */ - __set_errno (EEXIST); - return -1; -} diff --git a/src/bin/tar/lib/tempname.h b/src/bin/tar/lib/tempname.h deleted file mode 100644 index c51fa69424..0000000000 --- a/src/bin/tar/lib/tempname.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Create a temporary file or directory. - - Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* header written by Eric Blake */ - -/* In gnulib, always prefer large files. GT_FILE maps to - __GT_BIGFILE, not __GT_FILE, for a reason. */ -#define GT_FILE 1 -#define GT_DIR 2 -#define GT_NOCREATE 3 - -/* Generate a temporary file name based on TMPL. TMPL must match the - rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed - does not exist at the time of the call to gen_tempname. TMPL is - overwritten with the result. - - KIND may be one of: - GT_NOCREATE: simply verify that the name does not exist - at the time of the call. - GT_FILE: create a large file using open(O_CREAT|O_EXCL) - and return a read-write fd. The file is mode 0600. - GT_DIR: create a directory, which will be mode 0700. - - We use a clever algorithm to get hard-to-predict names. */ -extern int gen_tempname (char *tmpl, int kind); diff --git a/src/bin/tar/lib/time.in.h b/src/bin/tar/lib/time.in.h deleted file mode 100644 index 4d5cab8daf..0000000000 --- a/src/bin/tar/lib/time.in.h +++ /dev/null @@ -1,114 +0,0 @@ -/* A more-standard . - - Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Don't get in the way of glibc when it includes time.h merely to - declare a few standard symbols, rather than to declare all the - symbols. Also, Solaris 8 eventually includes itself - recursively; if that is happening, just include the system - without adding our own declarations. */ -#if (defined __need_time_t || defined __need_clock_t \ - || defined __need_timespec \ - || defined _GL_TIME_H) - -# @INCLUDE_NEXT@ @NEXT_TIME_H@ - -#else - -# define _GL_TIME_H - -# @INCLUDE_NEXT@ @NEXT_TIME_H@ - -# ifdef __cplusplus -extern "C" { -# endif - -/* Some systems don't define struct timespec (e.g., AIX 4.1, Ultrix 4.3). - Or they define it with the wrong member names or define it in - (e.g., FreeBSD circa 1997). */ -# if ! @TIME_H_DEFINES_STRUCT_TIMESPEC@ -# if @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ -# include -# else -# undef timespec -# define timespec rpl_timespec -struct timespec -{ - time_t tv_sec; - long int tv_nsec; -}; -# endif -# endif - -/* Sleep for at least RQTP seconds unless interrupted, If interrupted, - return -1 and store the remaining time into RMTP. See - . */ -# if @REPLACE_NANOSLEEP@ -# define nanosleep rpl_nanosleep -int nanosleep (struct timespec const *__rqtp, struct timespec *__rmtp); -# endif - -/* Convert TIMER to RESULT, assuming local time and UTC respectively. See - and - . */ -# if @REPLACE_LOCALTIME_R@ -# undef localtime_r -# define localtime_r rpl_localtime_r -# undef gmtime_r -# define gmtime_r rpl_gmtime_r -struct tm *localtime_r (time_t const *restrict __timer, - struct tm *restrict __result); -struct tm *gmtime_r (time_t const *restrict __timer, - struct tm *restrict __result); -# endif - -/* Parse BUF as a time stamp, assuming FORMAT specifies its layout, and store - the resulting broken-down time into TM. See - . */ -# if @REPLACE_STRPTIME@ -# undef strptime -# define strptime rpl_strptime -char *strptime (char const *restrict __buf, char const *restrict __format, - struct tm *restrict __tm); -# endif - -/* Convert TM to a time_t value, assuming UTC. */ -# if @REPLACE_TIMEGM@ -# undef timegm -# define timegm rpl_timegm -time_t timegm (struct tm *__tm); -# endif - -/* Encourage applications to avoid unsafe functions that can overrun - buffers when given outlandish struct tm values. Portable - applications should use strftime (or even sprintf) instead. */ -# if GNULIB_PORTCHECK -# undef asctime -# define asctime eschew_asctime -# undef asctime_r -# define asctime_r eschew_asctime_r -# undef ctime -# define ctime eschew_ctime -# undef ctime_r -# define ctime_r eschew_ctime_r -# endif - -# ifdef __cplusplus -} -# endif - -#endif diff --git a/src/bin/tar/lib/time_r.c b/src/bin/tar/lib/time_r.c deleted file mode 100644 index 2b72692844..0000000000 --- a/src/bin/tar/lib/time_r.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Reentrant time functions like localtime_r. - - Copyright (C) 2003, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include - -#include - -#include - -static struct tm * -copy_tm_result (struct tm *dest, struct tm const *src) -{ - if (! src) - return 0; - *dest = *src; - return dest; -} - - -struct tm * -gmtime_r (time_t const * restrict t, struct tm * restrict tp) -{ - return copy_tm_result (tp, gmtime (t)); -} - -struct tm * -localtime_r (time_t const * restrict t, struct tm * restrict tp) -{ - return copy_tm_result (tp, localtime (t)); -} diff --git a/src/bin/tar/lib/timespec.h b/src/bin/tar/lib/timespec.h deleted file mode 100644 index cce2d663ad..0000000000 --- a/src/bin/tar/lib/timespec.h +++ /dev/null @@ -1,37 +0,0 @@ -/* timespec -- System time interface - - Copyright (C) 2000, 2002, 2004, 2005, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if ! defined TIMESPEC_H -# define TIMESPEC_H - -# include - -/* Return negative, zero, positive if A < B, A == B, A > B, respectively. - Assume the nanosecond components are in range, or close to it. */ -static inline int -timespec_cmp (struct timespec a, struct timespec b) -{ - return (a.tv_sec < b.tv_sec ? -1 - : a.tv_sec > b.tv_sec ? 1 - : a.tv_nsec - b.tv_nsec); -} - -void gettime (struct timespec *); -int settime (struct timespec const *); - -#endif diff --git a/src/bin/tar/lib/uinttostr.c b/src/bin/tar/lib/uinttostr.c deleted file mode 100644 index 52d288e44e..0000000000 --- a/src/bin/tar/lib/uinttostr.c +++ /dev/null @@ -1,3 +0,0 @@ -#define inttostr uinttostr -#define inttype unsigned int -#include "inttostr.c" diff --git a/src/bin/tar/lib/umaxtostr.c b/src/bin/tar/lib/umaxtostr.c deleted file mode 100644 index 4f49a7f8dd..0000000000 --- a/src/bin/tar/lib/umaxtostr.c +++ /dev/null @@ -1,3 +0,0 @@ -#define inttostr umaxtostr -#define inttype uintmax_t -#include "inttostr.c" diff --git a/src/bin/tar/lib/unistd--.h b/src/bin/tar/lib/unistd--.h deleted file mode 100644 index 1fe6ce8b27..0000000000 --- a/src/bin/tar/lib/unistd--.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Like unistd.h, but redefine some names to avoid glitches. - - Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -#include -#include "unistd-safer.h" - -#undef dup -#define dup dup_safer - -#undef pipe -#define pipe pipe_safer diff --git a/src/bin/tar/lib/unistd-safer.h b/src/bin/tar/lib/unistd-safer.h deleted file mode 100644 index f95999d391..0000000000 --- a/src/bin/tar/lib/unistd-safer.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Invoke unistd-like functions, but avoid some glitches. - - Copyright (C) 2001, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -int dup_safer (int); -int fd_safer (int); -int pipe_safer (int[2]); diff --git a/src/bin/tar/lib/unistd.in.h b/src/bin/tar/lib/unistd.in.h deleted file mode 100644 index 07c4877836..0000000000 --- a/src/bin/tar/lib/unistd.in.h +++ /dev/null @@ -1,262 +0,0 @@ -/* Substitute for and wrapper around . - Copyright (C) 2004-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _GL_UNISTD_H - -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_UNISTD_H@ -# @INCLUDE_NEXT@ @NEXT_UNISTD_H@ -#endif - -#ifndef _GL_UNISTD_H -#define _GL_UNISTD_H - -/* mingw doesn't define the SEEK_* macros in . */ -#if !(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) -# include -#endif - -/* mingw fails to declare _exit in . */ -#include - -/* The definition of GL_LINK_WARNING is copied here. */ - - -/* Declare overridden functions. */ - -#ifdef __cplusplus -extern "C" { -#endif - - -#if @GNULIB_CHOWN@ -# if @REPLACE_CHOWN@ -# ifndef REPLACE_CHOWN -# define REPLACE_CHOWN 1 -# endif -# if REPLACE_CHOWN -/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE - to GID (if GID is not -1). Follow symbolic links. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2001 specification - . */ -# define chown rpl_chown -extern int chown (const char *file, uid_t uid, gid_t gid); -# endif -# endif -#elif defined GNULIB_POSIXCHECK -# undef chown -# define chown(f,u,g) \ - (GL_LINK_WARNING ("chown fails to follow symlinks on some systems and " \ - "doesn't treat a uid or gid of -1 on some systems - " \ - "use gnulib module chown for portability"), \ - chown (f, u, g)) -#endif - - -#if @GNULIB_DUP2@ -# if !@HAVE_DUP2@ -/* Copy the file descriptor OLDFD into file descriptor NEWFD. Do nothing if - NEWFD = OLDFD, otherwise close NEWFD first if it is open. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2001 specification - . */ -extern int dup2 (int oldfd, int newfd); -# endif -#elif defined GNULIB_POSIXCHECK -# undef dup2 -# define dup2(o,n) \ - (GL_LINK_WARNING ("dup2 is unportable - " \ - "use gnulib module dup2 for portability"), \ - dup2 (o, n)) -#endif - - -#if @GNULIB_FCHDIR@ -# if @REPLACE_FCHDIR@ - -/* Change the process' current working directory to the directory on which - the given file descriptor is open. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2001 specification - . */ -extern int fchdir (int /*fd*/); - -# define close rpl_close -extern int close (int); -# define dup rpl_dup -extern int dup (int); -# define dup2 rpl_dup2 -extern int dup2 (int, int); - -# endif -#elif defined GNULIB_POSIXCHECK -# undef fchdir -# define fchdir(f) \ - (GL_LINK_WARNING ("fchdir is unportable - " \ - "use gnulib module fchdir for portability"), \ - fchdir (f)) -#endif - - -#if @GNULIB_FTRUNCATE@ -# if !@HAVE_FTRUNCATE@ -/* Change the size of the file to which FD is opened to become equal to LENGTH. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2001 specification - . */ -extern int ftruncate (int fd, off_t length); -# endif -#elif defined GNULIB_POSIXCHECK -# undef ftruncate -# define ftruncate(f,l) \ - (GL_LINK_WARNING ("ftruncate is unportable - " \ - "use gnulib module ftruncate for portability"), \ - ftruncate (f, l)) -#endif - - -#if @GNULIB_GETCWD@ -/* Include the headers that might declare getcwd so that they will not - cause confusion if included after this file. */ -# include -# if @REPLACE_GETCWD@ -/* Get the name of the current working directory, and put it in SIZE bytes - of BUF. - Return BUF if successful, or NULL if the directory couldn't be determined - or SIZE was too small. - See the POSIX:2001 specification - . - Additionally, the gnulib module 'getcwd' guarantees the following GNU - extension: If BUF is NULL, an array is allocated with 'malloc'; the array - is SIZE bytes long, unless SIZE == 0, in which case it is as big as - necessary. */ -# define getcwd rpl_getcwd -extern char * getcwd (char *buf, size_t size); -# endif -#elif defined GNULIB_POSIXCHECK -# undef getcwd -# define getcwd(b,s) \ - (GL_LINK_WARNING ("getcwd is unportable - " \ - "use gnulib module getcwd for portability"), \ - getcwd (b, s)) -#endif - - -#if @GNULIB_GETLOGIN_R@ -/* Copies the user's login name to NAME. - The array pointed to by NAME has room for SIZE bytes. - - Returns 0 if successful. Upon error, an error number is returned, or -1 in - the case that the login name cannot be found but no specific error is - provided (this case is hopefully rare but is left open by the POSIX spec). - - See . - */ -# if !@HAVE_DECL_GETLOGIN_R@ -# include -extern int getlogin_r (char *name, size_t size); -# endif -#elif defined GNULIB_POSIXCHECK -# undef getlogin_r -# define getlogin_r(n,s) \ - (GL_LINK_WARNING ("getlogin_r is unportable - " \ - "use gnulib module getlogin_r for portability"), \ - getlogin_r (n, s)) -#endif - - -#if @GNULIB_LCHOWN@ -# if @REPLACE_LCHOWN@ -/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE - to GID (if GID is not -1). Do not follow symbolic links. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2001 specification - . */ -# define lchown rpl_lchown -extern int lchown (char const *file, uid_t owner, gid_t group); -# endif -#elif defined GNULIB_POSIXCHECK -# undef lchown -# define lchown(f,u,g) \ - (GL_LINK_WARNING ("lchown is unportable to pre-POSIX.1-2001 " \ - "systems - use gnulib module lchown for portability"), \ - lchown (f, u, g)) -#endif - - -#if @GNULIB_LSEEK@ -# if @REPLACE_LSEEK@ -/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END. - Return the new offset if successful, otherwise -1 and errno set. - See the POSIX:2001 specification - . */ -# define lseek rpl_lseek - extern off_t lseek (int fd, off_t offset, int whence); -# endif -#elif defined GNULIB_POSIXCHECK -# undef lseek -# define lseek(f,o,w) \ - (GL_LINK_WARNING ("lseek does not fail with ESPIPE on pipes on some " \ - "systems - use gnulib module lseek for portability"), \ - lseek (f, o, w)) -#endif - - -#if @GNULIB_READLINK@ -/* Read the contents of the symbolic link FILE and place the first BUFSIZE - bytes of it into BUF. Return the number of bytes placed into BUF if - successful, otherwise -1 and errno set. - See the POSIX:2001 specification - . */ -# if !@HAVE_READLINK@ -# include -extern int readlink (const char *file, char *buf, size_t bufsize); -# endif -#elif defined GNULIB_POSIXCHECK -# undef readlink -# define readlink(f,b,s) \ - (GL_LINK_WARNING ("readlink is unportable - " \ - "use gnulib module readlink for portability"), \ - readlink (f, b, s)) -#endif - - -#if @GNULIB_SLEEP@ -/* Pause the execution of the current thread for N seconds. - Returns the number of seconds left to sleep. - See the POSIX:2001 specification - . */ -# if !@HAVE_SLEEP@ -extern unsigned int sleep (unsigned int n); -# endif -#elif defined GNULIB_POSIXCHECK -# undef sleep -# define sleep(n) \ - (GL_LINK_WARNING ("sleep is unportable - " \ - "use gnulib module sleep for portability"), \ - sleep (n)) -#endif - - -#ifdef __cplusplus -} -#endif - - -#endif /* _GL_UNISTD_H */ -#endif /* _GL_UNISTD_H */ diff --git a/src/bin/tar/lib/unitypes.h b/src/bin/tar/lib/unitypes.h deleted file mode 100644 index 75502adf25..0000000000 --- a/src/bin/tar/lib/unitypes.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Elementary types for the GNU UniString library. - Copyright (C) 2002, 2005-2006 Free Software Foundation, Inc. - - This program 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, 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#ifndef _UNITYPES_H -#define _UNITYPES_H - -/* Get uint8_t, uint16_t, uint32_t. */ -#include - -/* Type representing a Unicode character. */ -typedef uint32_t ucs4_t; - -#endif /* _UNITYPES_H */ diff --git a/src/bin/tar/lib/uniwidth.h b/src/bin/tar/lib/uniwidth.h deleted file mode 100644 index 6dfad2c73a..0000000000 --- a/src/bin/tar/lib/uniwidth.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Display width functions. - Copyright (C) 2001-2002, 2005, 2007 Free Software Foundation, Inc. - - This program 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, 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#ifndef _UNIWIDTH_H -#define _UNIWIDTH_H - -#include "unitypes.h" - -/* Get size_t. */ -#include - -/* Get locale_charset() declaration. */ -#include "localcharset.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Display width. */ - -/* These functions are locale dependent. The encoding argument identifies - the encoding (e.g. "ISO-8859-2" for Polish). */ - -/* Determine number of column positions required for UC. */ -extern int - uc_width (ucs4_t uc, const char *encoding); - -/* Determine number of column positions required for first N units - (or fewer if S ends before this) in S. */ -extern int - u8_width (const uint8_t *s, size_t n, const char *encoding); -extern int - u16_width (const uint16_t *s, size_t n, const char *encoding); -extern int - u32_width (const uint32_t *s, size_t n, const char *encoding); - -/* Determine number of column positions required for S. */ -extern int - u8_strwidth (const uint8_t *s, const char *encoding); -extern int - u16_strwidth (const uint16_t *s, const char *encoding); -extern int - u32_strwidth (const uint32_t *s, const char *encoding); - - -#ifdef __cplusplus -} -#endif - -#endif /* _UNIWIDTH_H */ diff --git a/src/bin/tar/lib/uniwidth/cjk.h b/src/bin/tar/lib/uniwidth/cjk.h deleted file mode 100644 index 6d2e0f1f29..0000000000 --- a/src/bin/tar/lib/uniwidth/cjk.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Test for CJK encoding. - Copyright (C) 2001-2002, 2005-2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2002. - - This program 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, 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#include "streq.h" - -static int -is_cjk_encoding (const char *encoding) -{ - if (0 - /* Legacy Japanese encodings */ - || STREQ (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0) - /* Legacy Chinese encodings */ - || STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) - || STREQ (encoding, "GBK", 'G', 'B', 'K', 0, 0, 0, 0, 0, 0) - || STREQ (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0) - || STREQ (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0) - /* Legacy Korean encodings */ - || STREQ (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) - || STREQ (encoding, "CP949", 'C', 'P', '9', '4', '9', 0, 0, 0, 0) - || STREQ (encoding, "JOHAB", 'J', 'O', 'H', 'A', 'B', 0, 0, 0, 0)) - return 1; - return 0; -} diff --git a/src/bin/tar/lib/uniwidth/width.c b/src/bin/tar/lib/uniwidth/width.c deleted file mode 100644 index d215eeffb4..0000000000 --- a/src/bin/tar/lib/uniwidth/width.c +++ /dev/null @@ -1,325 +0,0 @@ -/* Determine display width of Unicode character. - Copyright (C) 2001-2002, 2006-2007 Free Software Foundation, Inc. - Written by Bruno Haible , 2002. - - This program 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, 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#include - -/* Specification. */ -#include "uniwidth.h" - -#include "cjk.h" - -/* - * Non-spacing attribute table. - * Consists of: - * - Non-spacing characters; generated from PropList.txt or - * "grep '^[^;]*;[^;]*;[^;]*;[^;]*;NSM;' UnicodeData.txt" - * - Format control characters; generated from - * "grep '^[^;]*;[^;]*;Cf;' UnicodeData.txt" - * - Zero width characters; generated from - * "grep '^[^;]*;ZERO WIDTH ' UnicodeData.txt" - */ -static const unsigned char nonspacing_table_data[22*64] = { - /* 0x0000-0x01ff */ - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0000-0x003f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x0040-0x007f */ - 0xff, 0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, /* 0x0080-0x00bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00c0-0x00ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0100-0x013f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0140-0x017f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180-0x01bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0-0x01ff */ - /* 0x0200-0x03ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200-0x023f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240-0x027f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280-0x02bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c0-0x02ff */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x0300-0x033f */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, /* 0x0340-0x037f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0380-0x03bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x03c0-0x03ff */ - /* 0x0400-0x05ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0400-0x043f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0440-0x047f */ - 0x78, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0480-0x04bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04c0-0x04ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0500-0x053f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0540-0x057f */ - 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, /* 0x0580-0x05bf */ - 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x05c0-0x05ff */ - /* 0x0600-0x07ff */ - 0x0f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0600-0x063f */ - 0x00, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x01, 0x00, /* 0x0640-0x067f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0680-0x06bf */ - 0x00, 0x00, 0xc0, 0xff, 0x9f, 0x3d, 0x00, 0x00, /* 0x06c0-0x06ff */ - 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x0700-0x073f */ - 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0740-0x077f */ - 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, /* 0x0780-0x07bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x07c0-0x07ff */ - /* 0x0800-0x09ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0800-0x083f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0840-0x087f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0880-0x08bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08c0-0x08ff */ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0900-0x093f */ - 0xfe, 0x21, 0x1e, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0940-0x097f */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0980-0x09bf */ - 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x09c0-0x09ff */ - /* 0x0a00-0x0bff */ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a00-0x0a3f */ - 0x86, 0x39, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0x0a40-0x0a7f */ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a80-0x0abf */ - 0xbe, 0x21, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0ac0-0x0aff */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0x0b00-0x0b3f */ - 0x0e, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b40-0x0b7f */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b80-0x0bbf */ - 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0bc0-0x0bff */ - /* 0x0c00-0x0dff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, /* 0x0c00-0x0c3f */ - 0xc1, 0x3d, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c40-0x0c7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0c80-0x0cbf */ - 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0cc0-0x0cff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d00-0x0d3f */ - 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d40-0x0d7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d80-0x0dbf */ - 0x00, 0x04, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0dc0-0x0dff */ - /* 0x0e00-0x0fff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x07, /* 0x0e00-0x0e3f */ - 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e40-0x0e7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x1b, /* 0x0e80-0x0ebf */ - 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0ec0-0x0eff */ - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xa0, 0x02, /* 0x0f00-0x0f3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, /* 0x0f40-0x0f7f */ - 0xdf, 0x00, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, /* 0x0f80-0x0fbf */ - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0fc0-0x0fff */ - /* 0x1000-0x11ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc5, 0x02, /* 0x1000-0x103f */ - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* 0x1040-0x107f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1080-0x10bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c0-0x10ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1100-0x113f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1140-0x117f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1180-0x11bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11c0-0x11ff */ - /* 0x1200-0x13ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1200-0x123f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1240-0x127f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1280-0x12bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x12c0-0x12ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1300-0x133f */ - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, /* 0x1340-0x137f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1380-0x13bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13c0-0x13ff */ - /* 0x1600-0x17ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1600-0x163f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1640-0x167f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1680-0x16bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16c0-0x16ff */ - 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, /* 0x1700-0x173f */ - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1740-0x177f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x3f, /* 0x1780-0x17bf */ - 0x40, 0xfe, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x17c0-0x17ff */ - /* 0x1800-0x19ff */ - 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1800-0x183f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1840-0x187f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x1880-0x18bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18c0-0x18ff */ - 0x00, 0x00, 0x00, 0x00, 0x87, 0x0f, 0x04, 0x0e, /* 0x1900-0x193f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1940-0x197f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1980-0x19bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x19c0-0x19ff */ - /* 0x1a00-0x1bff */ - 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, /* 0x1a00-0x1a3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a40-0x1a7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a80-0x1abf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ac0-0x1aff */ - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x17, /* 0x1b00-0x1b3f */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x1b40-0x1b7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b80-0x1bbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1bc0-0x1bff */ - /* 0x1c00-0x1dff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c00-0x1c3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c40-0x1c7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c80-0x1cbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1cc0-0x1cff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d00-0x1d3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d40-0x1d7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d80-0x1dbf */ - 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, /* 0x1dc0-0x1dff */ - /* 0x2000-0x21ff */ - 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, /* 0x2000-0x203f */ - 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, /* 0x2040-0x207f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2080-0x20bf */ - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, /* 0x20c0-0x20ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2100-0x213f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2140-0x217f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2180-0x21bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x21c0-0x21ff */ - /* 0x3000-0x31ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, /* 0x3000-0x303f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3040-0x307f */ - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, /* 0x3080-0x30bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30c0-0x30ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3100-0x313f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3140-0x317f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3180-0x31bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x31c0-0x31ff */ - /* 0xa800-0xa9ff */ - 0x44, 0x08, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0xa800-0xa83f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa840-0xa87f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa880-0xa8bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8c0-0xa8ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa900-0xa93f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa940-0xa97f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa980-0xa9bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa9c0-0xa9ff */ - /* 0xfa00-0xfbff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa00-0xfa3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa40-0xfa7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa80-0xfabf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfac0-0xfaff */ - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0xfb00-0xfb3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb40-0xfb7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb80-0xfbbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfbc0-0xfbff */ - /* 0xfe00-0xffff */ - 0xff, 0xff, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, /* 0xfe00-0xfe3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe40-0xfe7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe80-0xfebf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xfec0-0xfeff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff00-0xff3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff40-0xff7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff80-0xffbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, /* 0xffc0-0xffff */ - /* 0x10a00-0x10bff */ - 0x6e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0x10a00-0x10a3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a40-0x10a7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a80-0x10abf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10ac0-0x10aff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b00-0x10b3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b40-0x10b7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b80-0x10bbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10bc0-0x10bff */ - /* 0x1d000-0x1d1ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d000-0x1d03f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d040-0x1d07f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d080-0x1d0bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0c0-0x1d0ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d100-0x1d13f */ - 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xf8, /* 0x1d140-0x1d17f */ - 0xe7, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x1d180-0x1d1bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d1c0-0x1d1ff */ - /* 0x1d200-0x1d3ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d200-0x1d23f */ - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d240-0x1d27f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d280-0x1d2bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d2c0-0x1d2ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d300-0x1d33f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d340-0x1d37f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d380-0x1d3bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x1d3c0-0x1d3ff */ -}; -static const signed char nonspacing_table_ind[240] = { - 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000-0x0fff */ - 8, 9, -1, 10, 11, 12, 13, -1, /* 0x1000-0x1fff */ - 14, -1, -1, -1, -1, -1, -1, -1, /* 0x2000-0x2fff */ - 15, -1, -1, -1, -1, -1, -1, -1, /* 0x3000-0x3fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x4000-0x4fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x5000-0x5fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x6000-0x6fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x7000-0x7fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x8000-0x8fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9000-0x9fff */ - -1, -1, -1, -1, 16, -1, -1, -1, /* 0xa000-0xafff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb000-0xbfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc000-0xcfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd000-0xdfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe000-0xefff */ - -1, -1, -1, -1, -1, 17, -1, 18, /* 0xf000-0xffff */ - -1, -1, -1, -1, -1, 19, -1, -1, /* 0x10000-0x10fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x11000-0x11fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x12000-0x12fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x13000-0x13fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x14000-0x14fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x15000-0x15fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x16000-0x16fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x17000-0x17fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18000-0x18fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x19000-0x19fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1a000-0x1afff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1b000-0x1bfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1c000-0x1cfff */ - 20, 21, -1, -1, -1, -1, -1, -1 /* 0x1d000-0x1dfff */ -}; - -/* Determine number of column positions required for UC. */ -int -uc_width (ucs4_t uc, const char *encoding) -{ - /* Test for non-spacing or control character. */ - if ((uc >> 9) < 240) - { - int ind = nonspacing_table_ind[uc >> 9]; - if (ind >= 0) - if ((nonspacing_table_data[64*ind + ((uc >> 3) & 63)] >> (uc & 7)) & 1) - { - if (uc > 0 && uc < 0xa0) - return -1; - else - return 0; - } - } - else if ((uc >> 9) == (0xe0000 >> 9)) - { - if (uc >= 0xe0100) - { - if (uc <= 0xe01ef) - return 0; - } - else - { - if (uc >= 0xe0020 ? uc <= 0xe007f : uc == 0xe0001) - return 0; - } - } - /* Test for double-width character. - * Generated from "grep '^....;[WF]' EastAsianWidth.txt" - * and "grep '^....;[^WF]' EastAsianWidth.txt" - */ - if (uc >= 0x1100 - && ((uc < 0x1160) /* Hangul Jamo */ - || (uc >= 0x2329 && uc < 0x232b) /* Angle Brackets */ - || (uc >= 0x2e80 && uc < 0xa4d0 /* CJK ... Yi */ - && !(uc == 0x303f) && !(uc >= 0x4dc0 && uc < 0x4e00)) - || (uc >= 0xac00 && uc < 0xd7a4) /* Hangul Syllables */ - || (uc >= 0xf900 && uc < 0xfb00) /* CJK Compatibility Ideographs */ - || (uc >= 0xfe10 && uc < 0xfe20) /* Presentation Forms for Vertical */ - || (uc >= 0xfe30 && uc < 0xfe70) /* CJK Compatibility Forms */ - || (uc >= 0xff00 && uc < 0xff61) /* Fullwidth Forms */ - || (uc >= 0xffe0 && uc < 0xffe7) /* Fullwidth Signs */ - || (uc >= 0x20000 && uc <= 0x2a6d6) /* CJK */ - || (uc >= 0x2f800 && uc <= 0x2fa1d) /* CJK Compatibility Ideographs */ - ) ) - return 2; - /* In ancient CJK encodings, Cyrillic and most other characters are - double-width as well. */ - if (uc >= 0x00A1 && uc < 0xFF61 && uc != 0x20A9 - && is_cjk_encoding (encoding)) - return 2; - return 1; -} diff --git a/src/bin/tar/lib/unlinkdir.c b/src/bin/tar/lib/unlinkdir.c deleted file mode 100644 index 07620dbf05..0000000000 --- a/src/bin/tar/lib/unlinkdir.c +++ /dev/null @@ -1,68 +0,0 @@ -/* unlinkdir.c - determine (and maybe change) whether we can unlink directories - - Copyright (C) 2005, 2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert and Jim Meyering. */ - -#include - -#include "unlinkdir.h" - -#if HAVE_PRIV_H -# include -#endif -#include - -#if ! UNLINK_CANNOT_UNLINK_DIR - -/* Return true if we cannot unlink directories, false if we might be - able to unlink directories. If possible, tell the kernel we don't - want to be able to unlink directories, so that we can return true. */ - -bool -cannot_unlink_dir (void) -{ - static bool initialized; - static bool cannot; - - if (! initialized) - { -# if defined PRIV_EFFECTIVE && defined PRIV_SYS_LINKDIR - /* We might be able to unlink directories if we cannot - determine our privileges, or if we have the - PRIV_SYS_LINKDIR privilege and cannot delete it. */ - priv_set_t *pset = priv_allocset (); - if (pset) - { - cannot = - (getppriv (PRIV_EFFECTIVE, pset) == 0 - && (! priv_ismember (pset, PRIV_SYS_LINKDIR) - || (priv_delset (pset, PRIV_SYS_LINKDIR) == 0 - && setppriv (PRIV_SET, PRIV_EFFECTIVE, pset) == 0))); - priv_freeset (pset); - } -# else - /* In traditional Unix, only root can unlink directories. */ - cannot = (geteuid () != 0); -# endif - initialized = true; - } - - return cannot; -} - -#endif diff --git a/src/bin/tar/lib/unlinkdir.h b/src/bin/tar/lib/unlinkdir.h deleted file mode 100644 index 6582418bc9..0000000000 --- a/src/bin/tar/lib/unlinkdir.h +++ /dev/null @@ -1,27 +0,0 @@ -/* unlinkdir.h - determine (and maybe change) whether we can unlink directories - - Copyright (C) 2005 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert and Jim Meyering. */ - -#include - -#if UNLINK_CANNOT_UNLINK_DIR -# define cannot_unlink_dir() true -#else -bool cannot_unlink_dir (void); -#endif diff --git a/src/bin/tar/lib/unlocked-io.h b/src/bin/tar/lib/unlocked-io.h deleted file mode 100644 index d00930361c..0000000000 --- a/src/bin/tar/lib/unlocked-io.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Prefer faster, non-thread-safe stdio functions if available. - - Copyright (C) 2001, 2002, 2003, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#ifndef UNLOCKED_IO_H -# define UNLOCKED_IO_H 1 - -/* These are wrappers for functions/macros from the GNU C library, and - from other C libraries supporting POSIX's optional thread-safe functions. - - The standard I/O functions are thread-safe. These *_unlocked ones are - more efficient but not thread-safe. That they're not thread-safe is - fine since all of the applications in this package are single threaded. - - Also, some code that is shared with the GNU C library may invoke - the *_unlocked functions directly. On hosts that lack those - functions, invoke the non-thread-safe versions instead. */ - -# include - -# if HAVE_DECL_CLEARERR_UNLOCKED -# undef clearerr -# define clearerr(x) clearerr_unlocked (x) -# else -# define clearerr_unlocked(x) clearerr (x) -# endif - -# if HAVE_DECL_FEOF_UNLOCKED -# undef feof -# define feof(x) feof_unlocked (x) -# else -# define feof_unlocked(x) feof (x) -# endif - -# if HAVE_DECL_FERROR_UNLOCKED -# undef ferror -# define ferror(x) ferror_unlocked (x) -# else -# define ferror_unlocked(x) ferror (x) -# endif - -# if HAVE_DECL_FFLUSH_UNLOCKED -# undef fflush -# define fflush(x) fflush_unlocked (x) -# else -# define fflush_unlocked(x) fflush (x) -# endif - -# if HAVE_DECL_FGETS_UNLOCKED -# undef fgets -# define fgets(x,y,z) fgets_unlocked (x,y,z) -# else -# define fgets_unlocked(x,y,z) fgets (x,y,z) -# endif - -# if HAVE_DECL_FPUTC_UNLOCKED -# undef fputc -# define fputc(x,y) fputc_unlocked (x,y) -# else -# define fputc_unlocked(x,y) fputc (x,y) -# endif - -# if HAVE_DECL_FPUTS_UNLOCKED -# undef fputs -# define fputs(x,y) fputs_unlocked (x,y) -# else -# define fputs_unlocked(x,y) fputs (x,y) -# endif - -# if HAVE_DECL_FREAD_UNLOCKED -# undef fread -# define fread(w,x,y,z) fread_unlocked (w,x,y,z) -# else -# define fread_unlocked(w,x,y,z) fread (w,x,y,z) -# endif - -# if HAVE_DECL_FWRITE_UNLOCKED -# undef fwrite -# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z) -# else -# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) -# endif - -# if HAVE_DECL_GETC_UNLOCKED -# undef getc -# define getc(x) getc_unlocked (x) -# else -# define getc_unlocked(x) getc (x) -# endif - -# if HAVE_DECL_GETCHAR_UNLOCKED -# undef getchar -# define getchar() getchar_unlocked () -# else -# define getchar_unlocked() getchar () -# endif - -# if HAVE_DECL_PUTC_UNLOCKED -# undef putc -# define putc(x,y) putc_unlocked (x,y) -# else -# define putc_unlocked(x,y) putc (x,y) -# endif - -# if HAVE_DECL_PUTCHAR_UNLOCKED -# undef putchar -# define putchar(x) putchar_unlocked (x) -# else -# define putchar_unlocked(x) putchar (x) -# endif - -# undef flockfile -# define flockfile(x) ((void) 0) - -# undef ftrylockfile -# define ftrylockfile(x) 0 - -# undef funlockfile -# define funlockfile(x) ((void) 0) - -#endif /* UNLOCKED_IO_H */ diff --git a/src/bin/tar/lib/unsetenv.c b/src/bin/tar/lib/unsetenv.c deleted file mode 100644 index 0f837440db..0000000000 --- a/src/bin/tar/lib/unsetenv.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (C) 1992,1995-1999,2000-2002,2005-2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include -#if !_LIBC -# define __set_errno(ev) ((errno) = (ev)) -#endif - -#include -#include -#include - -#if !_LIBC -# define __environ environ -# ifndef HAVE_ENVIRON_DECL -extern char **environ; -# endif -#endif - -#if _LIBC -/* This lock protects against simultaneous modifications of `environ'. */ -# include -__libc_lock_define_initialized (static, envlock) -# define LOCK __libc_lock_lock (envlock) -# define UNLOCK __libc_lock_unlock (envlock) -#else -# define LOCK -# define UNLOCK -#endif - -/* In the GNU C library we must keep the namespace clean. */ -#ifdef _LIBC -# define unsetenv __unsetenv -#endif - - -int -unsetenv (const char *name) -{ - size_t len; - char **ep; - - if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) - { - __set_errno (EINVAL); - return -1; - } - - len = strlen (name); - - LOCK; - - ep = __environ; - while (*ep != NULL) - if (!strncmp (*ep, name, len) && (*ep)[len] == '=') - { - /* Found it. Remove this pointer by moving later ones back. */ - char **dp = ep; - - do - dp[0] = dp[1]; - while (*dp++); - /* Continue the loop in case NAME appears again. */ - } - else - ++ep; - - UNLOCK; - - return 0; -} - -#ifdef _LIBC -# undef unsetenv -weak_alias (__unsetenv, unsetenv) -#endif diff --git a/src/bin/tar/lib/utime.c b/src/bin/tar/lib/utime.c deleted file mode 100644 index 273a5fb31f..0000000000 --- a/src/bin/tar/lib/utime.c +++ /dev/null @@ -1,109 +0,0 @@ -/* Copyright (C) 1998, 2001, 2002, 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* derived from a function in touch.c */ - -#include -#undef utime - -#include - -#ifdef HAVE_UTIME_H -# include -#endif - -#if !HAVE_UTIMES_NULL -# include -# include -#endif - -#include -#include - -#include "full-write.h" -#include "safe-read.h" - -/* Some systems (even some that do have ) don't declare this - structure anywhere. */ -#ifndef HAVE_STRUCT_UTIMBUF -struct utimbuf -{ - long actime; - long modtime; -}; -#endif - -/* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef open -#undef close - -/* Emulate utime (file, NULL) for systems (like 4.3BSD) that do not - interpret it to set the access and modification times of FILE to - the current time. Return 0 if successful, -1 if not. */ - -static int -utime_null (const char *file) -{ -#if HAVE_UTIMES_NULL - return utimes (file, 0); -#else - int fd; - char c; - int status = 0; - struct stat st; - int saved_errno = 0; - - fd = open (file, O_RDWR); - if (fd < 0 - || fstat (fd, &st) < 0 - || safe_read (fd, &c, sizeof c) == SAFE_READ_ERROR - || lseek (fd, (off_t) 0, SEEK_SET) < 0 - || full_write (fd, &c, sizeof c) != sizeof c - /* Maybe do this -- it's necessary on SunOS 4.1.3 with some combination - of patches, but that system doesn't use this code: it has utimes. - || fsync (fd) < 0 - */ - || (st.st_size == 0 && ftruncate (fd, st.st_size) < 0)) - { - saved_errno = errno; - status = -1; - } - - if (0 <= fd) - { - if (close (fd) < 0) - status = -1; - - /* If there was a prior failure, use the saved errno value. - But if the only failure was in the close, don't change errno. */ - if (saved_errno) - errno = saved_errno; - } - - return status; -#endif -} - -int -rpl_utime (const char *file, const struct utimbuf *times) -{ - if (times) - return utime (file, times); - - return utime_null (file); -} diff --git a/src/bin/tar/lib/utimens.c b/src/bin/tar/lib/utimens.c deleted file mode 100644 index 7e3175a495..0000000000 --- a/src/bin/tar/lib/utimens.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Set file access and modification times. - - Copyright (C) 2003, 2004, 2005, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert. */ - -/* derived from a function in touch.c */ - -#include - -#include "utimens.h" - -#include -#include -#include -#include - -#if HAVE_UTIME_H -# include -#endif - -/* Some systems (even some that do have ) don't declare this - structure anywhere. */ -#ifndef HAVE_STRUCT_UTIMBUF -struct utimbuf -{ - long actime; - long modtime; -}; -#endif - -/* Some systems don't have ENOSYS. */ -#ifndef ENOSYS -# ifdef ENOTSUP -# define ENOSYS ENOTSUP -# else -/* Some systems don't have ENOTSUP either. */ -# define ENOSYS EINVAL -# endif -#endif - -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -#endif - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#endif - -/* Set the access and modification time stamps of FD (a.k.a. FILE) to be - TIMESPEC[0] and TIMESPEC[1], respectively. - FD must be either negative -- in which case it is ignored -- - or a file descriptor that is open on FILE. - If FD is nonnegative, then FILE can be NULL, which means - use just futimes (or equivalent) instead of utimes (or equivalent), - and fail if on an old system without futimes (or equivalent). - If TIMESPEC is null, set the time stamps to the current time. - Return 0 on success, -1 (setting errno) on failure. */ - -int -gl_futimens (int fd ATTRIBUTE_UNUSED, - char const *file, struct timespec const timespec[2]) -{ - /* Some Linux-based NFS clients are buggy, and mishandle time stamps - of files in NFS file systems in some cases. We have no - configure-time test for this, but please see - for references to - some of the problems with Linux 2.6.16. If this affects you, - compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to - help in some cases, albeit at a cost in performance. But you - really should upgrade your kernel to a fixed version, since the - problem affects many applications. */ - -#if HAVE_BUGGY_NFS_TIME_STAMPS - if (fd < 0) - sync (); - else - fsync (fd); -#endif - - /* There's currently no interface to set file timestamps with - nanosecond resolution, so do the best we can, discarding any - fractional part of the timestamp. */ -#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES - struct timeval timeval[2]; - struct timeval const *t; - if (timespec) - { - timeval[0].tv_sec = timespec[0].tv_sec; - timeval[0].tv_usec = timespec[0].tv_nsec / 1000; - timeval[1].tv_sec = timespec[1].tv_sec; - timeval[1].tv_usec = timespec[1].tv_nsec / 1000; - t = timeval; - } - else - t = NULL; - - - if (fd < 0) - { -# if HAVE_FUTIMESAT - return futimesat (AT_FDCWD, file, t); -# endif - } - else - { - /* If futimesat or futimes fails here, don't try to speed things - up by returning right away. glibc can incorrectly fail with - errno == ENOENT if /proc isn't mounted. Also, Mandrake 10.0 - in high security mode doesn't allow ordinary users to read - /proc/self, so glibc incorrectly fails with errno == EACCES. - If errno == EIO, EPERM, or EROFS, it's probably safe to fail - right away, but these cases are rare enough that they're not - worth optimizing, and who knows what other messed-up systems - are out there? So play it safe and fall back on the code - below. */ -# if HAVE_FUTIMESAT - if (futimesat (fd, NULL, t) == 0) - return 0; -# elif HAVE_FUTIMES - if (futimes (fd, t) == 0) - return 0; -# endif - } -#endif - - if (!file) - { -#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) - errno = ENOSYS; -#endif - - /* Prefer EBADF to ENOSYS if both error numbers apply. */ - if (errno == ENOSYS) - { - int fd2 = dup (fd); - int dup_errno = errno; - if (0 <= fd2) - close (fd2); - errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS); - } - - return -1; - } - -#if HAVE_WORKING_UTIMES - return utimes (file, t); -#else - { - struct utimbuf utimbuf; - struct utimbuf const *ut; - if (timespec) - { - utimbuf.actime = timespec[0].tv_sec; - utimbuf.modtime = timespec[1].tv_sec; - ut = &utimbuf; - } - else - ut = NULL; - - return utime (file, ut); - } -#endif -} - -/* Set the access and modification time stamps of FILE to be - TIMESPEC[0] and TIMESPEC[1], respectively. */ -int -utimens (char const *file, struct timespec const timespec[2]) -{ - return gl_futimens (-1, file, timespec); -} diff --git a/src/bin/tar/lib/utimens.h b/src/bin/tar/lib/utimens.h deleted file mode 100644 index 169521da73..0000000000 --- a/src/bin/tar/lib/utimens.h +++ /dev/null @@ -1,3 +0,0 @@ -#include -int gl_futimens (int, char const *, struct timespec const [2]); -int utimens (char const *, struct timespec const [2]); diff --git a/src/bin/tar/lib/vasnprintf.c b/src/bin/tar/lib/vasnprintf.c deleted file mode 100644 index 88154d1da7..0000000000 --- a/src/bin/tar/lib/vasnprintf.c +++ /dev/null @@ -1,3966 +0,0 @@ -/* vsprintf with automatic memory allocation. - Copyright (C) 1999, 2002-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* This file can be parametrized with the following macros: - VASNPRINTF The name of the function being defined. - FCHAR_T The element type of the format string. - DCHAR_T The element type of the destination (result) string. - FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters - in the format string are ASCII. MUST be set if - FCHAR_T and DCHAR_T are not the same type. - DIRECTIVE Structure denoting a format directive. - Depends on FCHAR_T. - DIRECTIVES Structure denoting the set of format directives of a - format string. Depends on FCHAR_T. - PRINTF_PARSE Function that parses a format string. - Depends on FCHAR_T. - DCHAR_CPY memcpy like function for DCHAR_T[] arrays. - DCHAR_SET memset like function for DCHAR_T[] arrays. - DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. - SNPRINTF The system's snprintf (or similar) function. - This may be either snprintf or swprintf. - TCHAR_T The element type of the argument and result string - of the said SNPRINTF function. This may be either - char or wchar_t. The code exploits that - sizeof (TCHAR_T) | sizeof (DCHAR_T) and - alignof (TCHAR_T) <= alignof (DCHAR_T). - DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type. - DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[]. - DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t. - DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t. - DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */ - -/* Tell glibc's to provide a prototype for snprintf(). - This must come before because may include - , and once has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifndef VASNPRINTF -# include -#endif -#ifndef IN_LIBINTL -# include -#endif - -/* Specification. */ -#ifndef VASNPRINTF -# if WIDE_CHAR_VERSION -# include "vasnwprintf.h" -# else -# include "vasnprintf.h" -# endif -#endif - -#include /* localeconv() */ -#include /* snprintf(), sprintf() */ -#include /* abort(), malloc(), realloc(), free() */ -#include /* memcpy(), strlen() */ -#include /* errno */ -#include /* CHAR_BIT */ -#include /* DBL_MAX_EXP, LDBL_MAX_EXP */ -#if HAVE_NL_LANGINFO -# include -#endif -#ifndef VASNPRINTF -# if WIDE_CHAR_VERSION -# include "wprintf-parse.h" -# else -# include "printf-parse.h" -# endif -#endif - -/* Checked size_t computations. */ -#include "xsize.h" - -#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL -# include -# include "float+.h" -# include "fpucw.h" -#endif - -#if NEED_PRINTF_INFINITE_DOUBLE && !defined IN_LIBINTL -# include -# include "isnan.h" -#endif - -#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !defined IN_LIBINTL -# include -# include "isnanl-nolibm.h" -# include "fpucw.h" -#endif - -#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL -# include -# include "isnan.h" -# include "printf-frexp.h" -# include "isnanl-nolibm.h" -# include "printf-frexpl.h" -# include "fpucw.h" -#endif - -/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ -#ifndef EOVERFLOW -# define EOVERFLOW E2BIG -#endif - -#if HAVE_WCHAR_T -# if HAVE_WCSLEN -# define local_wcslen wcslen -# else - /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid - a dependency towards this library, here is a local substitute. - Define this substitute only once, even if this file is included - twice in the same compilation unit. */ -# ifndef local_wcslen_defined -# define local_wcslen_defined 1 -static size_t -local_wcslen (const wchar_t *s) -{ - const wchar_t *ptr; - - for (ptr = s; *ptr != (wchar_t) 0; ptr++) - ; - return ptr - s; -} -# endif -# endif -#endif - -/* Default parameters. */ -#ifndef VASNPRINTF -# if WIDE_CHAR_VERSION -# define VASNPRINTF vasnwprintf -# define FCHAR_T wchar_t -# define DCHAR_T wchar_t -# define TCHAR_T wchar_t -# define DCHAR_IS_TCHAR 1 -# define DIRECTIVE wchar_t_directive -# define DIRECTIVES wchar_t_directives -# define PRINTF_PARSE wprintf_parse -# define DCHAR_CPY wmemcpy -# else -# define VASNPRINTF vasnprintf -# define FCHAR_T char -# define DCHAR_T char -# define TCHAR_T char -# define DCHAR_IS_TCHAR 1 -# define DIRECTIVE char_directive -# define DIRECTIVES char_directives -# define PRINTF_PARSE printf_parse -# define DCHAR_CPY memcpy -# endif -#endif -#if WIDE_CHAR_VERSION - /* TCHAR_T is wchar_t. */ -# define USE_SNPRINTF 1 -# if HAVE_DECL__SNWPRINTF - /* On Windows, the function swprintf() has a different signature than - on Unix; we use the _snwprintf() function instead. */ -# define SNPRINTF _snwprintf -# else - /* Unix. */ -# define SNPRINTF swprintf -# endif -#else - /* TCHAR_T is char. */ -# /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. - But don't use it on BeOS, since BeOS snprintf produces no output if the - size argument is >= 0x3000000. */ -# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !(defined(__BEOS__) || defined(__HAIKU__)) -# define USE_SNPRINTF 1 -# else -# define USE_SNPRINTF 0 -# endif -# if HAVE_DECL__SNPRINTF - /* Windows. */ -# define SNPRINTF _snprintf -# else - /* Unix. */ -# define SNPRINTF snprintf - /* Here we need to call the native snprintf, not rpl_snprintf. */ -# undef snprintf -# endif -#endif -/* Here we need to call the native sprintf, not rpl_sprintf. */ -#undef sprintf - -#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL -/* Determine the decimal-point character according to the current locale. */ -# ifndef decimal_point_char_defined -# define decimal_point_char_defined 1 -static char -decimal_point_char () -{ - const char *point; - /* Determine it in a multithread-safe way. We know nl_langinfo is - multithread-safe on glibc systems, but is not required to be multithread- - safe by POSIX. sprintf(), however, is multithread-safe. localeconv() - is rarely multithread-safe. */ -# if HAVE_NL_LANGINFO && __GLIBC__ - point = nl_langinfo (RADIXCHAR); -# elif 1 - char pointbuf[5]; - sprintf (pointbuf, "%#.0f", 1.0); - point = &pointbuf[1]; -# else - point = localeconv () -> decimal_point; -# endif - /* The decimal point is always a single byte: either '.' or ','. */ - return (point[0] != '\0' ? point[0] : '.'); -} -# endif -#endif - -#if NEED_PRINTF_INFINITE_DOUBLE && !defined IN_LIBINTL - -/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ -static int -is_infinite_or_zero (double x) -{ - return isnan (x) || x + x == x; -} - -#endif - -#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !defined IN_LIBINTL - -/* Equivalent to !isfinite(x), but does not require libm. */ -static int -is_infinitel (long double x) -{ - return isnanl (x) || (x + x == x && x != 0.0L); -} - -#endif - -#if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL - -/* Converting 'long double' to decimal without rare rounding bugs requires - real bignums. We use the naming conventions of GNU gmp, but vastly simpler - (and slower) algorithms. */ - -typedef unsigned int mp_limb_t; -# define GMP_LIMB_BITS 32 -typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1]; - -typedef unsigned long long mp_twolimb_t; -# define GMP_TWOLIMB_BITS 64 -typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1]; - -/* Representation of a bignum >= 0. */ -typedef struct -{ - size_t nlimbs; - mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */ -} mpn_t; - -/* Compute the product of two bignums >= 0. - Return the allocated memory in case of success, NULL in case of memory - allocation failure. */ -static void * -multiply (mpn_t src1, mpn_t src2, mpn_t *dest) -{ - const mp_limb_t *p1; - const mp_limb_t *p2; - size_t len1; - size_t len2; - - if (src1.nlimbs <= src2.nlimbs) - { - len1 = src1.nlimbs; - p1 = src1.limbs; - len2 = src2.nlimbs; - p2 = src2.limbs; - } - else - { - len1 = src2.nlimbs; - p1 = src2.limbs; - len2 = src1.nlimbs; - p2 = src1.limbs; - } - /* Now 0 <= len1 <= len2. */ - if (len1 == 0) - { - /* src1 or src2 is zero. */ - dest->nlimbs = 0; - dest->limbs = (mp_limb_t *) malloc (1); - } - else - { - /* Here 1 <= len1 <= len2. */ - size_t dlen; - mp_limb_t *dp; - size_t k, i, j; - - dlen = len1 + len2; - dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t)); - if (dp == NULL) - return NULL; - for (k = len2; k > 0; ) - dp[--k] = 0; - for (i = 0; i < len1; i++) - { - mp_limb_t digit1 = p1[i]; - mp_twolimb_t carry = 0; - for (j = 0; j < len2; j++) - { - mp_limb_t digit2 = p2[j]; - carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; - carry += dp[i + j]; - dp[i + j] = (mp_limb_t) carry; - carry = carry >> GMP_LIMB_BITS; - } - dp[i + len2] = (mp_limb_t) carry; - } - /* Normalise. */ - while (dlen > 0 && dp[dlen - 1] == 0) - dlen--; - dest->nlimbs = dlen; - dest->limbs = dp; - } - return dest->limbs; -} - -/* Compute the quotient of a bignum a >= 0 and a bignum b > 0. - a is written as a = q * b + r with 0 <= r < b. q is the quotient, r - the remainder. - Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd, - q is incremented. - Return the allocated memory in case of success, NULL in case of memory - allocation failure. */ -static void * -divide (mpn_t a, mpn_t b, mpn_t *q) -{ - /* Algorithm: - First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]] - with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS). - If m=n=1, perform a single-precision division: - r:=0, j:=m, - while j>0 do - {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j = - = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r=n>1, perform a multiple-precision division: - We have a/b < beta^(m-n+1). - s:=intDsize-1-(hightest bit in b[n-1]), 0<=s=beta/2. - For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).} - Compute q* : - q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]). - In case of overflow (q* >= beta) set q* := beta-1. - Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2] - and c3 := b[n-2] * q*. - {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow - occurred. Furthermore 0 <= c3 < beta^2. - If there was overflow and - r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2, - the next test can be skipped.} - While c3 > c2, {Here 0 <= c2 < c3 < beta^2} - Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2]. - If q* > 0: - Put r := r - b * q* * beta^j. In detail: - [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]]. - hence: u:=0, for i:=0 to n-1 do - u := u + q* * b[i], - r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry), - u:=u div beta (+ 1, if carry in subtraction) - r[n+j]:=r[n+j]-u. - {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1 - < q* + 1 <= beta, - the carry u does not overflow.} - If a negative carry occurs, put q* := q* - 1 - and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]]. - Set q[j] := q*. - Normalise [q[m-n],..,q[0]]; this yields the quotient q. - Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the - rest r. - The room for q[j] can be allocated at the memory location of r[n+j]. - Finally, round-to-even: - Shift r left by 1 bit. - If r > b or if r = b and q[0] is odd, q := q+1. - */ - const mp_limb_t *a_ptr = a.limbs; - size_t a_len = a.nlimbs; - const mp_limb_t *b_ptr = b.limbs; - size_t b_len = b.nlimbs; - mp_limb_t *roomptr; - mp_limb_t *tmp_roomptr = NULL; - mp_limb_t *q_ptr; - size_t q_len; - mp_limb_t *r_ptr; - size_t r_len; - - /* Allocate room for a_len+2 digits. - (Need a_len+1 digits for the real division and 1 more digit for the - final rounding of q.) */ - roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t)); - if (roomptr == NULL) - return NULL; - - /* Normalise a. */ - while (a_len > 0 && a_ptr[a_len - 1] == 0) - a_len--; - - /* Normalise b. */ - for (;;) - { - if (b_len == 0) - /* Division by zero. */ - abort (); - if (b_ptr[b_len - 1] == 0) - b_len--; - else - break; - } - - /* Here m = a_len >= 0 and n = b_len > 0. */ - - if (a_len < b_len) - { - /* m beta^(m-2) <= a/b < beta^m */ - r_ptr = roomptr; - q_ptr = roomptr + 1; - { - mp_limb_t den = b_ptr[0]; - mp_limb_t remainder = 0; - const mp_limb_t *sourceptr = a_ptr + a_len; - mp_limb_t *destptr = q_ptr + a_len; - size_t count; - for (count = a_len; count > 0; count--) - { - mp_twolimb_t num = - ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr; - *--destptr = num / den; - remainder = num % den; - } - /* Normalise and store r. */ - if (remainder > 0) - { - r_ptr[0] = remainder; - r_len = 1; - } - else - r_len = 0; - /* Normalise q. */ - q_len = a_len; - if (q_ptr[q_len - 1] == 0) - q_len--; - } - } - else - { - /* n>1: multiple precision division. - beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==> - beta^(m-n-1) <= a/b < beta^(m-n+1). */ - /* Determine s. */ - size_t s; - { - mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */ - s = 31; - if (msd >= 0x10000) - { - msd = msd >> 16; - s -= 16; - } - if (msd >= 0x100) - { - msd = msd >> 8; - s -= 8; - } - if (msd >= 0x10) - { - msd = msd >> 4; - s -= 4; - } - if (msd >= 0x4) - { - msd = msd >> 2; - s -= 2; - } - if (msd >= 0x2) - { - msd = msd >> 1; - s -= 1; - } - } - /* 0 <= s < GMP_LIMB_BITS. - Copy b, shifting it left by s bits. */ - if (s > 0) - { - tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t)); - if (tmp_roomptr == NULL) - { - free (roomptr); - return NULL; - } - { - const mp_limb_t *sourceptr = b_ptr; - mp_limb_t *destptr = tmp_roomptr; - mp_twolimb_t accu = 0; - size_t count; - for (count = b_len; count > 0; count--) - { - accu += (mp_twolimb_t) *sourceptr++ << s; - *destptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - /* accu must be zero, since that was how s was determined. */ - if (accu != 0) - abort (); - } - b_ptr = tmp_roomptr; - } - /* Copy a, shifting it left by s bits, yields r. - Memory layout: - At the beginning: r = roomptr[0..a_len], - at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */ - r_ptr = roomptr; - if (s == 0) - { - memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t)); - r_ptr[a_len] = 0; - } - else - { - const mp_limb_t *sourceptr = a_ptr; - mp_limb_t *destptr = r_ptr; - mp_twolimb_t accu = 0; - size_t count; - for (count = a_len; count > 0; count--) - { - accu += (mp_twolimb_t) *sourceptr++ << s; - *destptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - *destptr++ = (mp_limb_t) accu; - } - q_ptr = roomptr + b_len; - q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */ - { - size_t j = a_len - b_len; /* m-n */ - mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */ - mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */ - mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */ - ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd; - /* Division loop, traversed m-n+1 times. - j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */ - for (;;) - { - mp_limb_t q_star; - mp_limb_t c1; - if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */ - { - /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */ - mp_twolimb_t num = - ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS) - | r_ptr[j + b_len - 1]; - q_star = num / b_msd; - c1 = num % b_msd; - } - else - { - /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */ - q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */ - /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta - <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta - <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) - {<= beta !}. - If yes, jump directly to the subtraction loop. - (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta - <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */ - if (r_ptr[j + b_len] > b_msd - || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd) - /* r[j+n] >= b[n-1]+1 or - r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a - carry. */ - goto subtract; - } - /* q_star = q*, - c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, 0, decrease it by - b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2 - this can happen only twice. */ - if (c3 > c2) - { - q_star = q_star - 1; /* q* := q* - 1 */ - if (c3 - c2 > b_msdd) - q_star = q_star - 1; /* q* := q* - 1 */ - } - } - if (q_star > 0) - subtract: - { - /* Subtract r := r - b * q* * beta^j. */ - mp_limb_t cr; - { - const mp_limb_t *sourceptr = b_ptr; - mp_limb_t *destptr = r_ptr + j; - mp_twolimb_t carry = 0; - size_t count; - for (count = b_len; count > 0; count--) - { - /* Here 0 <= carry <= q*. */ - carry = - carry - + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++ - + (mp_limb_t) ~(*destptr); - /* Here 0 <= carry <= beta*q* + beta-1. */ - *destptr++ = ~(mp_limb_t) carry; - carry = carry >> GMP_LIMB_BITS; /* <= q* */ - } - cr = (mp_limb_t) carry; - } - /* Subtract cr from r_ptr[j + b_len], then forget about - r_ptr[j + b_len]. */ - if (cr > r_ptr[j + b_len]) - { - /* Subtraction gave a carry. */ - q_star = q_star - 1; /* q* := q* - 1 */ - /* Add b back. */ - { - const mp_limb_t *sourceptr = b_ptr; - mp_limb_t *destptr = r_ptr + j; - mp_limb_t carry = 0; - size_t count; - for (count = b_len; count > 0; count--) - { - mp_limb_t source1 = *sourceptr++; - mp_limb_t source2 = *destptr; - *destptr++ = source1 + source2 + carry; - carry = - (carry - ? source1 >= (mp_limb_t) ~source2 - : source1 > (mp_limb_t) ~source2); - } - } - /* Forget about the carry and about r[j+n]. */ - } - } - /* q* is determined. Store it as q[j]. */ - q_ptr[j] = q_star; - if (j == 0) - break; - j--; - } - } - r_len = b_len; - /* Normalise q. */ - if (q_ptr[q_len - 1] == 0) - q_len--; -# if 0 /* Not needed here, since we need r only to compare it with b/2, and - b is shifted left by s bits. */ - /* Shift r right by s bits. */ - if (s > 0) - { - mp_limb_t ptr = r_ptr + r_len; - mp_twolimb_t accu = 0; - size_t count; - for (count = r_len; count > 0; count--) - { - accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS; - accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s); - *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS); - } - } -# endif - /* Normalise r. */ - while (r_len > 0 && r_ptr[r_len - 1] == 0) - r_len--; - } - /* Compare r << 1 with b. */ - if (r_len > b_len) - goto increment_q; - { - size_t i; - for (i = b_len;;) - { - mp_limb_t r_i = - (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0) - | (i < r_len ? r_ptr[i] << 1 : 0); - mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0); - if (r_i > b_i) - goto increment_q; - if (r_i < b_i) - goto keep_q; - if (i == 0) - break; - i--; - } - } - if (q_len > 0 && ((q_ptr[0] & 1) != 0)) - /* q is odd. */ - increment_q: - { - size_t i; - for (i = 0; i < q_len; i++) - if (++(q_ptr[i]) != 0) - goto keep_q; - q_ptr[q_len++] = 1; - } - keep_q: - if (tmp_roomptr != NULL) - free (tmp_roomptr); - q->limbs = q_ptr; - q->nlimbs = q_len; - return roomptr; -} - -/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal - representation. - Destroys the contents of a. - Return the allocated memory - containing the decimal digits in low-to-high - order, terminated with a NUL character - in case of success, NULL in case - of memory allocation failure. */ -static char * -convert_to_decimal (mpn_t a, size_t extra_zeroes) -{ - mp_limb_t *a_ptr = a.limbs; - size_t a_len = a.nlimbs; - /* 0.03345 is slightly larger than log(2)/(9*log(10)). */ - size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1); - char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); - if (c_ptr != NULL) - { - char *d_ptr = c_ptr; - for (; extra_zeroes > 0; extra_zeroes--) - *d_ptr++ = '0'; - while (a_len > 0) - { - /* Divide a by 10^9, in-place. */ - mp_limb_t remainder = 0; - mp_limb_t *ptr = a_ptr + a_len; - size_t count; - for (count = a_len; count > 0; count--) - { - mp_twolimb_t num = - ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr; - *ptr = num / 1000000000; - remainder = num % 1000000000; - } - /* Store the remainder as 9 decimal digits. */ - for (count = 9; count > 0; count--) - { - *d_ptr++ = '0' + (remainder % 10); - remainder = remainder / 10; - } - /* Normalize a. */ - if (a_ptr[a_len - 1] == 0) - a_len--; - } - /* Remove leading zeroes. */ - while (d_ptr > c_ptr && d_ptr[-1] == '0') - d_ptr--; - /* But keep at least one zero. */ - if (d_ptr == c_ptr) - *d_ptr++ = '0'; - /* Terminate the string. */ - *d_ptr = '\0'; - } - return c_ptr; -} - -/* Assuming x is finite and >= 0: - write x as x = 2^e * m, where m is a bignum. - Return the allocated memory in case of success, NULL in case of memory - allocation failure. */ -static void * -decode_long_double (long double x, int *ep, mpn_t *mp) -{ - mpn_t m; - int exp; - long double y; - size_t i; - - /* Allocate memory for result. */ - m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; - m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); - if (m.limbs == NULL) - return NULL; - /* Split into exponential part and mantissa. */ - y = frexpl (x, &exp); - if (!(y >= 0.0L && y < 1.0L)) - abort (); - /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the - latter is an integer. */ - /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs. - I'm not sure whether it's safe to cast a 'long double' value between - 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only - 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int', - doesn't matter). */ -# if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0 -# if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 - { - mp_limb_t hi, lo; - y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2)); - hi = (int) y; - y -= hi; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - lo = (int) y; - y -= lo; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; - } -# else - { - mp_limb_t d; - y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS); - d = (int) y; - y -= d; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d; - } -# endif -# endif - for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) - { - mp_limb_t hi, lo; - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - hi = (int) y; - y -= hi; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - lo = (int) y; - y -= lo; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; - } - if (!(y == 0.0L)) - abort (); - /* Normalise. */ - while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) - m.nlimbs--; - *mp = m; - *ep = exp - LDBL_MANT_BIT; - return m.limbs; -} - -/* Assuming x is finite and >= 0, and n is an integer: - Returns the decimal representation of round (x * 10^n). - Return the allocated memory - containing the decimal digits in low-to-high - order, terminated with a NUL character - in case of success, NULL in case - of memory allocation failure. */ -static char * -scale10_round_decimal_long_double (long double x, int n) -{ - int e; - mpn_t m; - void *memory = decode_long_double (x, &e, &m); - int s; - size_t extra_zeroes; - unsigned int abs_n; - unsigned int abs_s; - mp_limb_t *pow5_ptr; - size_t pow5_len; - unsigned int s_limbs; - unsigned int s_bits; - mpn_t pow5; - mpn_t z; - void *z_memory; - char *digits; - - if (memory == NULL) - return NULL; - /* x = 2^e * m, hence - y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m) - = round (2^s * 5^n * m). */ - s = e + n; - extra_zeroes = 0; - /* Factor out a common power of 10 if possible. */ - if (s > 0 && n > 0) - { - extra_zeroes = (s < n ? s : n); - s -= extra_zeroes; - n -= extra_zeroes; - } - /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes. - Before converting to decimal, we need to compute - z = round (2^s * 5^n * m). */ - /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same - sign. 2.322 is slightly larger than log(5)/log(2). */ - abs_n = (n >= 0 ? n : -n); - abs_s = (s >= 0 ? s : -s); - pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1 - + abs_s / GMP_LIMB_BITS + 1) - * sizeof (mp_limb_t)); - if (pow5_ptr == NULL) - { - free (memory); - return NULL; - } - /* Initialize with 1. */ - pow5_ptr[0] = 1; - pow5_len = 1; - /* Multiply with 5^|n|. */ - if (abs_n > 0) - { - static mp_limb_t const small_pow5[13 + 1] = - { - 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, - 48828125, 244140625, 1220703125 - }; - unsigned int n13; - for (n13 = 0; n13 <= abs_n; n13 += 13) - { - mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13]; - size_t j; - mp_twolimb_t carry = 0; - for (j = 0; j < pow5_len; j++) - { - mp_limb_t digit2 = pow5_ptr[j]; - carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; - pow5_ptr[j] = (mp_limb_t) carry; - carry = carry >> GMP_LIMB_BITS; - } - if (carry > 0) - pow5_ptr[pow5_len++] = (mp_limb_t) carry; - } - } - s_limbs = abs_s / GMP_LIMB_BITS; - s_bits = abs_s % GMP_LIMB_BITS; - if (n >= 0 ? s >= 0 : s <= 0) - { - /* Multiply with 2^|s|. */ - if (s_bits > 0) - { - mp_limb_t *ptr = pow5_ptr; - mp_twolimb_t accu = 0; - size_t count; - for (count = pow5_len; count > 0; count--) - { - accu += (mp_twolimb_t) *ptr << s_bits; - *ptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - if (accu > 0) - { - *ptr = (mp_limb_t) accu; - pow5_len++; - } - } - if (s_limbs > 0) - { - size_t count; - for (count = pow5_len; count > 0;) - { - count--; - pow5_ptr[s_limbs + count] = pow5_ptr[count]; - } - for (count = s_limbs; count > 0;) - { - count--; - pow5_ptr[count] = 0; - } - pow5_len += s_limbs; - } - pow5.limbs = pow5_ptr; - pow5.nlimbs = pow5_len; - if (n >= 0) - { - /* Multiply m with pow5. No division needed. */ - z_memory = multiply (m, pow5, &z); - } - else - { - /* Divide m by pow5 and round. */ - z_memory = divide (m, pow5, &z); - } - } - else - { - pow5.limbs = pow5_ptr; - pow5.nlimbs = pow5_len; - if (n >= 0) - { - /* n >= 0, s < 0. - Multiply m with pow5, then divide by 2^|s|. */ - mpn_t numerator; - mpn_t denominator; - void *tmp_memory; - tmp_memory = multiply (m, pow5, &numerator); - if (tmp_memory == NULL) - { - free (pow5_ptr); - free (memory); - return NULL; - } - /* Construct 2^|s|. */ - { - mp_limb_t *ptr = pow5_ptr + pow5_len; - size_t i; - for (i = 0; i < s_limbs; i++) - ptr[i] = 0; - ptr[s_limbs] = (mp_limb_t) 1 << s_bits; - denominator.limbs = ptr; - denominator.nlimbs = s_limbs + 1; - } - z_memory = divide (numerator, denominator, &z); - free (tmp_memory); - } - else - { - /* n < 0, s > 0. - Multiply m with 2^s, then divide by pow5. */ - mpn_t numerator; - mp_limb_t *num_ptr; - num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1) - * sizeof (mp_limb_t)); - if (num_ptr == NULL) - { - free (pow5_ptr); - free (memory); - return NULL; - } - { - mp_limb_t *destptr = num_ptr; - { - size_t i; - for (i = 0; i < s_limbs; i++) - *destptr++ = 0; - } - if (s_bits > 0) - { - const mp_limb_t *sourceptr = m.limbs; - mp_twolimb_t accu = 0; - size_t count; - for (count = m.nlimbs; count > 0; count--) - { - accu += (mp_twolimb_t) *sourceptr++ << s; - *destptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - if (accu > 0) - *destptr++ = (mp_limb_t) accu; - } - else - { - const mp_limb_t *sourceptr = m.limbs; - size_t count; - for (count = m.nlimbs; count > 0; count--) - *destptr++ = *sourceptr++; - } - numerator.limbs = num_ptr; - numerator.nlimbs = destptr - num_ptr; - } - z_memory = divide (numerator, pow5, &z); - free (num_ptr); - } - } - free (pow5_ptr); - free (memory); - - /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */ - - if (z_memory == NULL) - return NULL; - digits = convert_to_decimal (z, extra_zeroes); - free (z_memory); - return digits; -} - -/* Assuming x is finite and > 0: - Return an approximation for n with 10^n <= x < 10^(n+1). - The approximation is usually the right n, but may be off by 1 sometimes. */ -static int -floorlog10l (long double x) -{ - int exp; - long double y; - double z; - double l; - - /* Split into exponential part and mantissa. */ - y = frexpl (x, &exp); - if (!(y >= 0.0L && y < 1.0L)) - abort (); - if (y == 0.0L) - return INT_MIN; - if (y < 0.5L) - { - while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) - { - y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); - exp -= GMP_LIMB_BITS; - } - if (y < (1.0L / (1 << 16))) - { - y *= 1.0L * (1 << 16); - exp -= 16; - } - if (y < (1.0L / (1 << 8))) - { - y *= 1.0L * (1 << 8); - exp -= 8; - } - if (y < (1.0L / (1 << 4))) - { - y *= 1.0L * (1 << 4); - exp -= 4; - } - if (y < (1.0L / (1 << 2))) - { - y *= 1.0L * (1 << 2); - exp -= 2; - } - if (y < (1.0L / (1 << 1))) - { - y *= 1.0L * (1 << 1); - exp -= 1; - } - } - if (!(y >= 0.5L && y < 1.0L)) - abort (); - /* Compute an approximation for l = log2(x) = exp + log2(y). */ - l = exp; - z = y; - if (z < 0.70710678118654752444) - { - z *= 1.4142135623730950488; - l -= 0.5; - } - if (z < 0.8408964152537145431) - { - z *= 1.1892071150027210667; - l -= 0.25; - } - if (z < 0.91700404320467123175) - { - z *= 1.0905077326652576592; - l -= 0.125; - } - if (z < 0.9576032806985736469) - { - z *= 1.0442737824274138403; - l -= 0.0625; - } - /* Now 0.95 <= z <= 1.01. */ - z = 1 - z; - /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ... - Four terms are enough to get an approximation with error < 10^-7. */ - l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); - /* Finally multiply with log(2)/log(10), yields an approximation for - log10(x). */ - l *= 0.30102999566398119523; - /* Round down to the next integer. */ - return (int) l + (l < 0 ? -1 : 0); -} - -#endif - -DCHAR_T * -VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, - const FCHAR_T *format, va_list args) -{ - DIRECTIVES d; - arguments a; - - if (PRINTF_PARSE (format, &d, &a) < 0) - { - errno = EINVAL; - return NULL; - } - -#define CLEANUP() \ - free (d.dir); \ - if (a.arg) \ - free (a.arg); - - if (PRINTF_FETCHARGS (args, &a) < 0) - { - CLEANUP (); - errno = EINVAL; - return NULL; - } - - { - size_t buf_neededlength; - TCHAR_T *buf; - TCHAR_T *buf_malloced; - const FCHAR_T *cp; - size_t i; - DIRECTIVE *dp; - /* Output string accumulator. */ - DCHAR_T *result; - size_t allocated; - size_t length; - - /* Allocate a small buffer that will hold a directive passed to - sprintf or snprintf. */ - buf_neededlength = - xsum4 (7, d.max_width_length, d.max_precision_length, 6); -#if HAVE_ALLOCA - if (buf_neededlength < 4000 / sizeof (TCHAR_T)) - { - buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T)); - buf_malloced = NULL; - } - else -#endif - { - size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T)); - if (size_overflow_p (buf_memsize)) - goto out_of_memory_1; - buf = (TCHAR_T *) malloc (buf_memsize); - if (buf == NULL) - goto out_of_memory_1; - buf_malloced = buf; - } - - if (resultbuf != NULL) - { - result = resultbuf; - allocated = *lengthp; - } - else - { - result = NULL; - allocated = 0; - } - length = 0; - /* Invariants: - result is either == resultbuf or == NULL or malloc-allocated. - If length > 0, then result != NULL. */ - - /* Ensures that allocated >= needed. Aborts through a jump to - out_of_memory if needed is SIZE_MAX or otherwise too big. */ -#define ENSURE_ALLOCATION(needed) \ - if ((needed) > allocated) \ - { \ - size_t memory_size; \ - DCHAR_T *memory; \ - \ - allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \ - if ((needed) > allocated) \ - allocated = (needed); \ - memory_size = xtimes (allocated, sizeof (DCHAR_T)); \ - if (size_overflow_p (memory_size)) \ - goto out_of_memory; \ - if (result == resultbuf || result == NULL) \ - memory = (DCHAR_T *) malloc (memory_size); \ - else \ - memory = (DCHAR_T *) realloc (result, memory_size); \ - if (memory == NULL) \ - goto out_of_memory; \ - if (result == resultbuf && length > 0) \ - DCHAR_CPY (memory, result, length); \ - result = memory; \ - } - - for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++) - { - if (cp != dp->dir_start) - { - size_t n = dp->dir_start - cp; - size_t augmented_length = xsum (length, n); - - ENSURE_ALLOCATION (augmented_length); - /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we - need that the format string contains only ASCII characters - if FCHAR_T and DCHAR_T are not the same type. */ - if (sizeof (FCHAR_T) == sizeof (DCHAR_T)) - { - DCHAR_CPY (result + length, (const DCHAR_T *) cp, n); - length = augmented_length; - } - else - { - do - result[length++] = (unsigned char) *cp++; - while (--n > 0); - } - } - if (i == d.count) - break; - - /* Execute a single directive. */ - if (dp->conversion == '%') - { - size_t augmented_length; - - if (!(dp->arg_index == ARG_NONE)) - abort (); - augmented_length = xsum (length, 1); - ENSURE_ALLOCATION (augmented_length); - result[length] = '%'; - length = augmented_length; - } - else - { - if (!(dp->arg_index != ARG_NONE)) - abort (); - - if (dp->conversion == 'n') - { - switch (a.arg[dp->arg_index].type) - { - case TYPE_COUNT_SCHAR_POINTER: - *a.arg[dp->arg_index].a.a_count_schar_pointer = length; - break; - case TYPE_COUNT_SHORT_POINTER: - *a.arg[dp->arg_index].a.a_count_short_pointer = length; - break; - case TYPE_COUNT_INT_POINTER: - *a.arg[dp->arg_index].a.a_count_int_pointer = length; - break; - case TYPE_COUNT_LONGINT_POINTER: - *a.arg[dp->arg_index].a.a_count_longint_pointer = length; - break; -#if HAVE_LONG_LONG_INT - case TYPE_COUNT_LONGLONGINT_POINTER: - *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; - break; -#endif - default: - abort (); - } - } -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - else if (dp->conversion == 'U') - { - arg_type type = a.arg[dp->arg_index].type; - int flags = dp->flags; - int has_width; - size_t width; - int has_precision; - size_t precision; - - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } - - has_precision = 0; - precision = 0; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } - - switch (type) - { - case TYPE_U8_STRING: - { - const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string; - const uint8_t *arg_end; - size_t characters; - - if (has_precision) - { - /* Use only PRECISION characters, from the left. */ - arg_end = arg; - characters = 0; - for (; precision > 0; precision--) - { - int count = u8_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else if (has_width) - { - /* Use the entire string, and count the number of - characters. */ - arg_end = arg; - characters = 0; - for (;;) - { - int count = u8_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else - { - /* Use the entire string. */ - arg_end = arg + u8_strlen (arg); - /* The number of characters doesn't matter. */ - characters = 0; - } - - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - -# if DCHAR_IS_UINT8_T - { - size_t n = arg_end - arg; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_CPY (result + length, arg, n); - length += n; - } -# else - { /* Convert. */ - DCHAR_T *converted = result + length; - size_t converted_len = allocated - length; -# if DCHAR_IS_TCHAR - /* Convert from UTF-8 to locale encoding. */ - if (u8_conv_to_encoding (locale_charset (), - iconveh_question_mark, - arg, arg_end - arg, NULL, - &converted, &converted_len) - < 0) -# else - /* Convert from UTF-8 to UTF-16/UTF-32. */ - converted = - U8_TO_DCHAR (arg, arg_end - arg, - converted, &converted_len); - if (converted == NULL) -# endif - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - if (converted != result + length) - { - ENSURE_ALLOCATION (xsum (length, converted_len)); - DCHAR_CPY (result + length, converted, converted_len); - free (converted); - } - length += converted_len; - } -# endif - - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } - break; - - case TYPE_U16_STRING: - { - const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string; - const uint16_t *arg_end; - size_t characters; - - if (has_precision) - { - /* Use only PRECISION characters, from the left. */ - arg_end = arg; - characters = 0; - for (; precision > 0; precision--) - { - int count = u16_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else if (has_width) - { - /* Use the entire string, and count the number of - characters. */ - arg_end = arg; - characters = 0; - for (;;) - { - int count = u16_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else - { - /* Use the entire string. */ - arg_end = arg + u16_strlen (arg); - /* The number of characters doesn't matter. */ - characters = 0; - } - - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - -# if DCHAR_IS_UINT16_T - { - size_t n = arg_end - arg; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_CPY (result + length, arg, n); - length += n; - } -# else - { /* Convert. */ - DCHAR_T *converted = result + length; - size_t converted_len = allocated - length; -# if DCHAR_IS_TCHAR - /* Convert from UTF-16 to locale encoding. */ - if (u16_conv_to_encoding (locale_charset (), - iconveh_question_mark, - arg, arg_end - arg, NULL, - &converted, &converted_len) - < 0) -# else - /* Convert from UTF-16 to UTF-8/UTF-32. */ - converted = - U16_TO_DCHAR (arg, arg_end - arg, - converted, &converted_len); - if (converted == NULL) -# endif - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - if (converted != result + length) - { - ENSURE_ALLOCATION (xsum (length, converted_len)); - DCHAR_CPY (result + length, converted, converted_len); - free (converted); - } - length += converted_len; - } -# endif - - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } - break; - - case TYPE_U32_STRING: - { - const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string; - const uint32_t *arg_end; - size_t characters; - - if (has_precision) - { - /* Use only PRECISION characters, from the left. */ - arg_end = arg; - characters = 0; - for (; precision > 0; precision--) - { - int count = u32_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else if (has_width) - { - /* Use the entire string, and count the number of - characters. */ - arg_end = arg; - characters = 0; - for (;;) - { - int count = u32_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else - { - /* Use the entire string. */ - arg_end = arg + u32_strlen (arg); - /* The number of characters doesn't matter. */ - characters = 0; - } - - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - -# if DCHAR_IS_UINT32_T - { - size_t n = arg_end - arg; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_CPY (result + length, arg, n); - length += n; - } -# else - { /* Convert. */ - DCHAR_T *converted = result + length; - size_t converted_len = allocated - length; -# if DCHAR_IS_TCHAR - /* Convert from UTF-32 to locale encoding. */ - if (u32_conv_to_encoding (locale_charset (), - iconveh_question_mark, - arg, arg_end - arg, NULL, - &converted, &converted_len) - < 0) -# else - /* Convert from UTF-32 to UTF-8/UTF-16. */ - converted = - U32_TO_DCHAR (arg, arg_end - arg, - converted, &converted_len); - if (converted == NULL) -# endif - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - if (converted != result + length) - { - ENSURE_ALLOCATION (xsum (length, converted_len)); - DCHAR_CPY (result + length, converted, converted_len); - free (converted); - } - length += converted_len; - } -# endif - - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } - break; - - default: - abort (); - } - } -#endif -#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL - else if (dp->conversion == 'a' || dp->conversion == 'A') - { - arg_type type = a.arg[dp->arg_index].type; - int flags = dp->flags; - int has_width; - size_t width; - int has_precision; - size_t precision; - size_t tmp_length; - DCHAR_T tmpbuf[700]; - DCHAR_T *tmp; - DCHAR_T *pad_ptr; - DCHAR_T *p; - - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } - - has_precision = 0; - precision = 0; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } - - /* Allocate a temporary buffer of sufficient size. */ - if (type == TYPE_LONGDOUBLE) - tmp_length = - (unsigned int) ((LDBL_DIG + 1) - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) ((DBL_DIG + 1) - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Account for sign, decimal point etc. */ - tmp_length = xsum (tmp_length, 12); - - if (tmp_length < width) - tmp_length = width; - - tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ - - if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) - tmp = tmpbuf; - else - { - size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); - - if (size_overflow_p (tmp_memsize)) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - tmp = (DCHAR_T *) malloc (tmp_memsize); - if (tmp == NULL) - /* Out of memory. */ - goto out_of_memory; - } - - pad_ptr = NULL; - p = tmp; - if (type == TYPE_LONGDOUBLE) - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - - if (isnanl (arg)) - { - if (dp->conversion == 'A') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - DECL_LONG_DOUBLE_ROUNDING - - BEGIN_LONG_DOUBLE_ROUNDING (); - - if (signbit (arg)) /* arg < 0.0L or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0L && arg + arg == arg) - { - if (dp->conversion == 'A') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { - int exponent; - long double mantissa; - - if (arg > 0.0L) - mantissa = printf_frexpl (arg, &exponent); - else - { - exponent = 0; - mantissa = 0.0L; - } - - if (has_precision - && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1) - { - /* Round the mantissa. */ - long double tail = mantissa; - size_t q; - - for (q = precision; ; q--) - { - int digit = (int) tail; - tail -= digit; - if (q == 0) - { - if (digit & 1 ? tail >= 0.5L : tail > 0.5L) - tail = 1 - tail; - else - tail = - tail; - break; - } - tail *= 16.0L; - } - if (tail != 0.0L) - for (q = precision; q > 0; q--) - tail *= 0.0625L; - mantissa += tail; - } - - *p++ = '0'; - *p++ = dp->conversion - 'A' + 'X'; - pad_ptr = p; - { - int digit; - - digit = (int) mantissa; - mantissa -= digit; - *p++ = '0' + digit; - if ((flags & FLAG_ALT) - || mantissa > 0.0L || precision > 0) - { - *p++ = decimal_point_char (); - /* This loop terminates because we assume - that FLT_RADIX is a power of 2. */ - while (mantissa > 0.0L) - { - mantissa *= 16.0L; - digit = (int) mantissa; - mantissa -= digit; - *p++ = digit - + (digit < 10 - ? '0' - : dp->conversion - 10); - if (precision > 0) - precision--; - } - while (precision > 0) - { - *p++ = '0'; - precision--; - } - } - } - *p++ = dp->conversion - 'A' + 'P'; -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - - END_LONG_DOUBLE_ROUNDING (); - } - } - else - { - double arg = a.arg[dp->arg_index].a.a_double; - - if (isnan (arg)) - { - if (dp->conversion == 'A') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - - if (signbit (arg)) /* arg < 0.0 or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0 && arg + arg == arg) - { - if (dp->conversion == 'A') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { - int exponent; - double mantissa; - - if (arg > 0.0) - mantissa = printf_frexp (arg, &exponent); - else - { - exponent = 0; - mantissa = 0.0; - } - - if (has_precision - && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1) - { - /* Round the mantissa. */ - double tail = mantissa; - size_t q; - - for (q = precision; ; q--) - { - int digit = (int) tail; - tail -= digit; - if (q == 0) - { - if (digit & 1 ? tail >= 0.5 : tail > 0.5) - tail = 1 - tail; - else - tail = - tail; - break; - } - tail *= 16.0; - } - if (tail != 0.0) - for (q = precision; q > 0; q--) - tail *= 0.0625; - mantissa += tail; - } - - *p++ = '0'; - *p++ = dp->conversion - 'A' + 'X'; - pad_ptr = p; - { - int digit; - - digit = (int) mantissa; - mantissa -= digit; - *p++ = '0' + digit; - if ((flags & FLAG_ALT) - || mantissa > 0.0 || precision > 0) - { - *p++ = decimal_point_char (); - /* This loop terminates because we assume - that FLT_RADIX is a power of 2. */ - while (mantissa > 0.0) - { - mantissa *= 16.0; - digit = (int) mantissa; - mantissa -= digit; - *p++ = digit - + (digit < 10 - ? '0' - : dp->conversion - 10); - if (precision > 0) - precision--; - } - while (precision > 0) - { - *p++ = '0'; - precision--; - } - } - } - *p++ = dp->conversion - 'A' + 'P'; -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - } - } - /* The generated string now extends from tmp to p, with the - zero padding insertion point being at pad_ptr. */ - if (has_width && p - tmp < width) - { - size_t pad = width - (p - tmp); - DCHAR_T *end = p + pad; - - if (flags & FLAG_LEFT) - { - /* Pad with spaces on the right. */ - for (; pad > 0; pad--) - *p++ = ' '; - } - else if ((flags & FLAG_ZERO) && pad_ptr != NULL) - { - /* Pad with zeroes. */ - DCHAR_T *q = end; - - while (p > pad_ptr) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = '0'; - } - else - { - /* Pad with spaces on the left. */ - DCHAR_T *q = end; - - while (p > tmp) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = ' '; - } - - p = end; - } - - { - size_t count = p - tmp; - - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); - - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); - - ENSURE_ALLOCATION (n); - } - - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; - } - } -#endif -#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL - else if ((dp->conversion == 'f' || dp->conversion == 'F' - || dp->conversion == 'e' || dp->conversion == 'E' - || dp->conversion == 'g' || dp->conversion == 'G' - || dp->conversion == 'a' || dp->conversion == 'A') - && (0 -# if NEED_PRINTF_INFINITE_DOUBLE - || (a.arg[dp->arg_index].type == TYPE_DOUBLE - /* The systems (mingw) which produce wrong output - for Inf, -Inf, and NaN also do so for -0.0. - Therefore we treat this case here as well. */ - && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double)) -# endif -# if NEED_PRINTF_LONG_DOUBLE - || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE -# elif NEED_PRINTF_INFINITE_LONG_DOUBLE - || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE - /* Some systems produce wrong output for Inf, - -Inf, and NaN. */ - && is_infinitel (a.arg[dp->arg_index].a.a_longdouble)) -# endif - )) - { -# if NEED_PRINTF_INFINITE_DOUBLE && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) - arg_type type = a.arg[dp->arg_index].type; -# endif - int flags = dp->flags; - int has_width; - size_t width; - int has_precision; - size_t precision; - size_t tmp_length; - DCHAR_T tmpbuf[700]; - DCHAR_T *tmp; - DCHAR_T *pad_ptr; - DCHAR_T *p; - - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } - - has_precision = 0; - precision = 0; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } - - /* POSIX specifies the default precision to be 6 for %f, %F, - %e, %E, but not for %g, %G. Implementations appear to use - the same default precision also for %g, %G. */ - if (!has_precision) - precision = 6; - - /* Allocate a temporary buffer of sufficient size. */ -# if NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE - tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0); -# elif NEED_PRINTF_LONG_DOUBLE - tmp_length = LDBL_DIG + 1; -# else - tmp_length = 0; -# endif - if (tmp_length < precision) - tmp_length = precision; -# if NEED_PRINTF_LONG_DOUBLE -# if NEED_PRINTF_INFINITE_DOUBLE - if (type == TYPE_LONGDOUBLE) -# endif - if (dp->conversion == 'f' || dp->conversion == 'F') - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - if (!(isnanl (arg) || arg + arg == arg)) - { - /* arg is finite and nonzero. */ - int exponent = floorlog10l (arg < 0 ? -arg : arg); - if (exponent >= 0 && tmp_length < exponent + precision) - tmp_length = exponent + precision; - } - } -# endif - /* Account for sign, decimal point etc. */ - tmp_length = xsum (tmp_length, 12); - - if (tmp_length < width) - tmp_length = width; - - tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ - - if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) - tmp = tmpbuf; - else - { - size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); - - if (size_overflow_p (tmp_memsize)) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - tmp = (DCHAR_T *) malloc (tmp_memsize); - if (tmp == NULL) - /* Out of memory. */ - goto out_of_memory; - } - - pad_ptr = NULL; - p = tmp; - -# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE -# if NEED_PRINTF_INFINITE_DOUBLE - if (type == TYPE_LONGDOUBLE) -# endif - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - - if (isnanl (arg)) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - DECL_LONG_DOUBLE_ROUNDING - - BEGIN_LONG_DOUBLE_ROUNDING (); - - if (signbit (arg)) /* arg < 0.0L or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0L && arg + arg == arg) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { -# if NEED_PRINTF_LONG_DOUBLE - pad_ptr = p; - - if (dp->conversion == 'f' || dp->conversion == 'F') - { - char *digits; - size_t ndigits; - - digits = - scale10_round_decimal_long_double (arg, precision); - if (digits == NULL) - { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - ndigits = strlen (digits); - - if (ndigits > precision) - do - { - --ndigits; - *p++ = digits[ndigits]; - } - while (ndigits > precision); - else - *p++ = '0'; - /* Here ndigits <= precision. */ - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > ndigits; precision--) - *p++ = '0'; - while (ndigits > 0) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - - free (digits); - } - else if (dp->conversion == 'e' || dp->conversion == 'E') - { - int exponent; - - if (arg == 0.0L) - { - exponent = 0; - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - } - else - { - /* arg > 0.0L. */ - int adjusted; - char *digits; - size_t ndigits; - - exponent = floorlog10l (arg); - adjusted = 0; - for (;;) - { - digits = - scale10_round_decimal_long_double (arg, - (int)precision - exponent); - if (digits == NULL) - { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - ndigits = strlen (digits); - - if (ndigits == precision + 1) - break; - if (ndigits < precision - || ndigits > precision + 2) - /* The exponent was not guessed - precisely enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is - the right one. Prevent an endless - loop. */ - abort (); - free (digits); - if (ndigits == precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; - } - - /* Here ndigits = precision+1. */ - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - while (ndigits > 0) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - - free (digits); - } - - *p++ = dp->conversion; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', '.', '2', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+.2d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+.2d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - else if (dp->conversion == 'g' || dp->conversion == 'G') - { - if (precision == 0) - precision = 1; - /* precision >= 1. */ - - if (arg == 0.0L) - /* The exponent is 0, >= -4, < precision. - Use fixed-point notation. */ - { - size_t ndigits = precision; - /* Number of trailing zeroes that have to be - dropped. */ - size_t nzeroes = - (flags & FLAG_ALT ? 0 : precision - 1); - - --ndigits; - *p++ = '0'; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = '0'; - } - } - } - else - { - /* arg > 0.0L. */ - int exponent; - int adjusted; - char *digits; - size_t ndigits; - size_t nzeroes; - - exponent = floorlog10l (arg); - adjusted = 0; - for (;;) - { - digits = - scale10_round_decimal_long_double (arg, - (int)(precision - 1) - exponent); - if (digits == NULL) - { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - ndigits = strlen (digits); - - if (ndigits == precision) - break; - if (ndigits < precision - 1 - || ndigits > precision + 1) - /* The exponent was not guessed - precisely enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is - the right one. Prevent an endless - loop. */ - abort (); - free (digits); - if (ndigits < precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; - } - /* Here ndigits = precision. */ - - /* Determine the number of trailing zeroes - that have to be dropped. */ - nzeroes = 0; - if ((flags & FLAG_ALT) == 0) - while (nzeroes < ndigits - && digits[nzeroes] == '0') - nzeroes++; - - /* The exponent is now determined. */ - if (exponent >= -4 - && exponent < (long)precision) - { - /* Fixed-point notation: - max(exponent,0)+1 digits, then the - decimal point, then the remaining - digits without trailing zeroes. */ - if (exponent >= 0) - { - size_t count = exponent + 1; - /* Note: count <= precision = ndigits. */ - for (; count > 0; count--) - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - } - else - { - size_t count = -exponent - 1; - *p++ = '0'; - *p++ = decimal_point_char (); - for (; count > 0; count--) - *p++ = '0'; - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - } - else - { - /* Exponential notation. */ - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', '.', '2', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+.2d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+.2d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - - free (digits); - } - } - else - abort (); -# else - /* arg is finite. */ - abort (); -# endif - } - - END_LONG_DOUBLE_ROUNDING (); - } - } -# if NEED_PRINTF_INFINITE_DOUBLE - else -# endif -# endif -# if NEED_PRINTF_INFINITE_DOUBLE - { - /* Simpler than above: handle only NaN, Infinity, zero. */ - double arg = a.arg[dp->arg_index].a.a_double; - - if (isnan (arg)) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - - if (signbit (arg)) /* arg < 0.0L or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0 && arg + arg == arg) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { - if (!(arg == 0.0)) - abort (); - - pad_ptr = p; - - if (dp->conversion == 'f' || dp->conversion == 'F') - { - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - } - else if (dp->conversion == 'e' || dp->conversion == 'E') - { - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - *p++ = dp->conversion; /* 'e' or 'E' */ - *p++ = '+'; - /* Produce the same number of exponent digits as - the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - *p++ = '0'; -# endif - *p++ = '0'; - *p++ = '0'; - } - else if (dp->conversion == 'g' || dp->conversion == 'G') - { - *p++ = '0'; - if (flags & FLAG_ALT) - { - size_t ndigits = - (precision > 0 ? precision - 1 : 0); - *p++ = decimal_point_char (); - for (; ndigits > 0; --ndigits) - *p++ = '0'; - } - } - else - abort (); - } - } - } -# endif - - /* The generated string now extends from tmp to p, with the - zero padding insertion point being at pad_ptr. */ - if (has_width && p - tmp < width) - { - size_t pad = width - (p - tmp); - DCHAR_T *end = p + pad; - - if (flags & FLAG_LEFT) - { - /* Pad with spaces on the right. */ - for (; pad > 0; pad--) - *p++ = ' '; - } - else if ((flags & FLAG_ZERO) && pad_ptr != NULL) - { - /* Pad with zeroes. */ - DCHAR_T *q = end; - - while (p > pad_ptr) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = '0'; - } - else - { - /* Pad with spaces on the left. */ - DCHAR_T *q = end; - - while (p > tmp) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = ' '; - } - - p = end; - } - - { - size_t count = p - tmp; - - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); - - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); - - ENSURE_ALLOCATION (n); - } - - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; - } - } -#endif - else - { - arg_type type = a.arg[dp->arg_index].type; - int flags = dp->flags; -#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO - int has_width; - size_t width; -#endif -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO - int pad_ourselves; -#else -# define pad_ourselves 0 -#endif - TCHAR_T *fbp; - unsigned int prefix_count; - int prefixes[2]; -#if !USE_SNPRINTF - size_t tmp_length; - TCHAR_T tmpbuf[700]; - TCHAR_T *tmp; -#endif - -#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } -#endif - -#if !USE_SNPRINTF - /* Allocate a temporary buffer of sufficient size for calling - sprintf. */ - { - size_t precision; - - precision = 6; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - precision = (arg < 0 ? 0 : arg); - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - } - } - - switch (dp->conversion) - { - - case 'd': case 'i': case 'u': -# if HAVE_LONG_LONG_INT - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Multiply by 2, as an estimate for FLAG_GROUP. */ - tmp_length = xsum (tmp_length, tmp_length); - /* Add 1, to account for a leading sign. */ - tmp_length = xsum (tmp_length, 1); - break; - - case 'o': -# if HAVE_LONG_LONG_INT - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Add 1, to account for a leading sign. */ - tmp_length = xsum (tmp_length, 1); - break; - - case 'x': case 'X': -# if HAVE_LONG_LONG_INT - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Add 2, to account for a leading sign or alternate form. */ - tmp_length = xsum (tmp_length, 2); - break; - - case 'f': case 'F': - if (type == TYPE_LONGDOUBLE) - tmp_length = - (unsigned int) (LDBL_MAX_EXP - * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ - ) - + 1 /* turn floor into ceil */ - + 10; /* sign, decimal point etc. */ - else - tmp_length = - (unsigned int) (DBL_MAX_EXP - * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ - ) - + 1 /* turn floor into ceil */ - + 10; /* sign, decimal point etc. */ - tmp_length = xsum (tmp_length, precision); - break; - - case 'e': case 'E': case 'g': case 'G': - tmp_length = - 12; /* sign, decimal point, exponent etc. */ - tmp_length = xsum (tmp_length, precision); - break; - - case 'a': case 'A': - if (type == TYPE_LONGDOUBLE) - tmp_length = - (unsigned int) (LDBL_DIG - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (DBL_DIG - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Account for sign, decimal point etc. */ - tmp_length = xsum (tmp_length, 12); - break; - - case 'c': -# if HAVE_WINT_T && !WIDE_CHAR_VERSION - if (type == TYPE_WIDE_CHAR) - tmp_length = MB_CUR_MAX; - else -# endif - tmp_length = 1; - break; - - case 's': -# if HAVE_WCHAR_T - if (type == TYPE_WIDE_STRING) - { - tmp_length = - local_wcslen (a.arg[dp->arg_index].a.a_wide_string); - -# if !WIDE_CHAR_VERSION - tmp_length = xtimes (tmp_length, MB_CUR_MAX); -# endif - } - else -# endif - tmp_length = strlen (a.arg[dp->arg_index].a.a_string); - break; - - case 'p': - tmp_length = - (unsigned int) (sizeof (void *) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1 /* turn floor into ceil */ - + 2; /* account for leading 0x */ - break; - - default: - abort (); - } - -# if ENABLE_UNISTDIO - /* Padding considers the number of characters, therefore the - number of elements after padding may be - > max (tmp_length, width) - but is certainly - <= tmp_length + width. */ - tmp_length = xsum (tmp_length, width); -# else - /* Padding considers the number of elements, says POSIX. */ - if (tmp_length < width) - tmp_length = width; -# endif - - tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ - } - - if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T)) - tmp = tmpbuf; - else - { - size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T)); - - if (size_overflow_p (tmp_memsize)) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - tmp = (TCHAR_T *) malloc (tmp_memsize); - if (tmp == NULL) - /* Out of memory. */ - goto out_of_memory; - } -#endif - - /* Decide whether to perform the padding ourselves. */ -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO - switch (dp->conversion) - { -# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO - /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need - to perform the padding after this conversion. Functions - with unistdio extensions perform the padding based on - character count rather than element count. */ - case 'c': case 's': -# endif -# if NEED_PRINTF_FLAG_ZERO - case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': - case 'a': case 'A': -# endif - pad_ourselves = 1; - break; - default: - pad_ourselves = 0; - break; - } -#endif - - /* Construct the format string for calling snprintf or - sprintf. */ - fbp = buf; - *fbp++ = '%'; -#if NEED_PRINTF_FLAG_GROUPING - /* The underlying implementation doesn't support the ' flag. - Produce no grouping characters in this case; this is - acceptable because the grouping is locale dependent. */ -#else - if (flags & FLAG_GROUP) - *fbp++ = '\''; -#endif - if (flags & FLAG_LEFT) - *fbp++ = '-'; - if (flags & FLAG_SHOWSIGN) - *fbp++ = '+'; - if (flags & FLAG_SPACE) - *fbp++ = ' '; - if (flags & FLAG_ALT) - *fbp++ = '#'; - if (!pad_ourselves) - { - if (flags & FLAG_ZERO) - *fbp++ = '0'; - if (dp->width_start != dp->width_end) - { - size_t n = dp->width_end - dp->width_start; - /* The width specification is known to consist only - of standard ASCII characters. */ - if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) - { - memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T)); - fbp += n; - } - else - { - const FCHAR_T *mp = dp->width_start; - do - *fbp++ = (unsigned char) *mp++; - while (--n > 0); - } - } - } - if (dp->precision_start != dp->precision_end) - { - size_t n = dp->precision_end - dp->precision_start; - /* The precision specification is known to consist only - of standard ASCII characters. */ - if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) - { - memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T)); - fbp += n; - } - else - { - const FCHAR_T *mp = dp->precision_start; - do - *fbp++ = (unsigned char) *mp++; - while (--n > 0); - } - } - - switch (type) - { -#if HAVE_LONG_LONG_INT - case TYPE_LONGLONGINT: - case TYPE_ULONGLONGINT: -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - *fbp++ = 'I'; - *fbp++ = '6'; - *fbp++ = '4'; - break; -# else - *fbp++ = 'l'; - /*FALLTHROUGH*/ -# endif -#endif - case TYPE_LONGINT: - case TYPE_ULONGINT: -#if HAVE_WINT_T - case TYPE_WIDE_CHAR: -#endif -#if HAVE_WCHAR_T - case TYPE_WIDE_STRING: -#endif - *fbp++ = 'l'; - break; - case TYPE_LONGDOUBLE: - *fbp++ = 'L'; - break; - default: - break; - } -#if NEED_PRINTF_DIRECTIVE_F - if (dp->conversion == 'F') - *fbp = 'f'; - else -#endif - *fbp = dp->conversion; -#if USE_SNPRINTF - fbp[1] = '%'; - fbp[2] = 'n'; - fbp[3] = '\0'; -#else - fbp[1] = '\0'; -#endif - - /* Construct the arguments for calling snprintf or sprintf. */ - prefix_count = 0; - if (!pad_ourselves && dp->width_arg_index != ARG_NONE) - { - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; - } - if (dp->precision_arg_index != ARG_NONE) - { - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int; - } - -#if USE_SNPRINTF - /* The SNPRINTF result is appended after result[0..length]. - The latter is an array of DCHAR_T; SNPRINTF appends an - array of TCHAR_T to it. This is possible because - sizeof (TCHAR_T) divides sizeof (DCHAR_T) and - alignof (TCHAR_T) <= alignof (DCHAR_T). */ -# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T)) - /* Prepare checking whether snprintf returns the count - via %n. */ - ENSURE_ALLOCATION (xsum (length, 1)); - *(TCHAR_T *) (result + length) = '\0'; -#endif - - for (;;) - { - int count = -1; - -#if USE_SNPRINTF - int retcount = 0; - size_t maxlen = allocated - length; - /* SNPRINTF can fail if its second argument is - > INT_MAX. */ - if (maxlen > INT_MAX / TCHARS_PER_DCHAR) - goto overflow; - maxlen = maxlen * TCHARS_PER_DCHAR; -# define SNPRINTF_BUF(arg) \ - switch (prefix_count) \ - { \ - case 0: \ - retcount = SNPRINTF ((TCHAR_T *) (result + length), \ - maxlen, buf, \ - arg, &count); \ - break; \ - case 1: \ - retcount = SNPRINTF ((TCHAR_T *) (result + length), \ - maxlen, buf, \ - prefixes[0], arg, &count); \ - break; \ - case 2: \ - retcount = SNPRINTF ((TCHAR_T *) (result + length), \ - maxlen, buf, \ - prefixes[0], prefixes[1], arg, \ - &count); \ - break; \ - default: \ - abort (); \ - } -#else -# define SNPRINTF_BUF(arg) \ - switch (prefix_count) \ - { \ - case 0: \ - count = sprintf (tmp, buf, arg); \ - break; \ - case 1: \ - count = sprintf (tmp, buf, prefixes[0], arg); \ - break; \ - case 2: \ - count = sprintf (tmp, buf, prefixes[0], prefixes[1],\ - arg); \ - break; \ - default: \ - abort (); \ - } -#endif - - switch (type) - { - case TYPE_SCHAR: - { - int arg = a.arg[dp->arg_index].a.a_schar; - SNPRINTF_BUF (arg); - } - break; - case TYPE_UCHAR: - { - unsigned int arg = a.arg[dp->arg_index].a.a_uchar; - SNPRINTF_BUF (arg); - } - break; - case TYPE_SHORT: - { - int arg = a.arg[dp->arg_index].a.a_short; - SNPRINTF_BUF (arg); - } - break; - case TYPE_USHORT: - { - unsigned int arg = a.arg[dp->arg_index].a.a_ushort; - SNPRINTF_BUF (arg); - } - break; - case TYPE_INT: - { - int arg = a.arg[dp->arg_index].a.a_int; - SNPRINTF_BUF (arg); - } - break; - case TYPE_UINT: - { - unsigned int arg = a.arg[dp->arg_index].a.a_uint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_LONGINT: - { - long int arg = a.arg[dp->arg_index].a.a_longint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_ULONGINT: - { - unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint; - SNPRINTF_BUF (arg); - } - break; -#if HAVE_LONG_LONG_INT - case TYPE_LONGLONGINT: - { - long long int arg = a.arg[dp->arg_index].a.a_longlongint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_ULONGLONGINT: - { - unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_DOUBLE: - { - double arg = a.arg[dp->arg_index].a.a_double; - SNPRINTF_BUF (arg); - } - break; - case TYPE_LONGDOUBLE: - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - SNPRINTF_BUF (arg); - } - break; - case TYPE_CHAR: - { - int arg = a.arg[dp->arg_index].a.a_char; - SNPRINTF_BUF (arg); - } - break; -#if HAVE_WINT_T - case TYPE_WIDE_CHAR: - { - wint_t arg = a.arg[dp->arg_index].a.a_wide_char; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_STRING: - { - const char *arg = a.arg[dp->arg_index].a.a_string; - SNPRINTF_BUF (arg); - } - break; -#if HAVE_WCHAR_T - case TYPE_WIDE_STRING: - { - const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_POINTER: - { - void *arg = a.arg[dp->arg_index].a.a_pointer; - SNPRINTF_BUF (arg); - } - break; - default: - abort (); - } - -#if USE_SNPRINTF - /* Portability: Not all implementations of snprintf() - are ISO C 99 compliant. Determine the number of - bytes that snprintf() has produced or would have - produced. */ - if (count >= 0) - { - /* Verify that snprintf() has NUL-terminated its - result. */ - if (count < maxlen - && ((TCHAR_T *) (result + length)) [count] != '\0') - abort (); - /* Portability hack. */ - if (retcount > count) - count = retcount; - } - else - { - /* snprintf() doesn't understand the '%n' - directive. */ - if (fbp[1] != '\0') - { - /* Don't use the '%n' directive; instead, look - at the snprintf() return value. */ - fbp[1] = '\0'; - continue; - } - else - { - /* Look at the snprintf() return value. */ - if (retcount < 0) - { - /* HP-UX 10.20 snprintf() is doubly deficient: - It doesn't understand the '%n' directive, - *and* it returns -1 (rather than the length - that would have been required) when the - buffer is too small. */ - size_t bigger_need = - xsum (xtimes (allocated, 2), 12); - ENSURE_ALLOCATION (bigger_need); - continue; - } - else - count = retcount; - } - } -#endif - - /* Attempt to handle failure. */ - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EINVAL; - return NULL; - } - -#if USE_SNPRINTF - /* Handle overflow of the allocated buffer. */ - if (count >= maxlen) - { - /* Need at least count * sizeof (TCHAR_T) bytes. But - allocate proportionally, to avoid looping eternally - if snprintf() reports a too small count. */ - size_t n = - xmax (xsum (length, - (count + TCHARS_PER_DCHAR - 1) - / TCHARS_PER_DCHAR), - xtimes (allocated, 2)); - - ENSURE_ALLOCATION (n); - continue; - } -#endif - -#if !DCHAR_IS_TCHAR -# if !USE_SNPRINTF - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); -# endif - - /* Convert from TCHAR_T[] to DCHAR_T[]. */ - if (dp->conversion == 'c' || dp->conversion == 's') - { - /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING - TYPE_WIDE_STRING. - The result string is not certainly ASCII. */ - const TCHAR_T *tmpsrc; - DCHAR_T *tmpdst; - size_t tmpdst_len; - /* This code assumes that TCHAR_T is 'char'. */ - typedef int TCHAR_T_verify - [2 * (sizeof (TCHAR_T) == 1) - 1]; -# if USE_SNPRINTF - tmpsrc = (TCHAR_T *) (result + length); -# else - tmpsrc = tmp; -# endif - tmpdst = NULL; - tmpdst_len = 0; - if (DCHAR_CONV_FROM_ENCODING (locale_charset (), - iconveh_question_mark, - tmpsrc, count, - NULL, - &tmpdst, &tmpdst_len) - < 0) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - ENSURE_ALLOCATION (xsum (length, tmpdst_len)); - DCHAR_CPY (result + length, tmpdst, tmpdst_len); - free (tmpdst); - count = tmpdst_len; - } - else - { - /* The result string is ASCII. - Simple 1:1 conversion. */ -# if USE_SNPRINTF - /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a - no-op conversion, in-place on the array starting - at (result + length). */ - if (sizeof (DCHAR_T) != sizeof (TCHAR_T)) -# endif - { - const TCHAR_T *tmpsrc; - DCHAR_T *tmpdst; - size_t n; - -# if USE_SNPRINTF - if (result == resultbuf) - { - tmpsrc = (TCHAR_T *) (result + length); - /* ENSURE_ALLOCATION will not move tmpsrc - (because it's part of resultbuf). */ - ENSURE_ALLOCATION (xsum (length, count)); - } - else - { - /* ENSURE_ALLOCATION will move the array - (because it uses realloc(). */ - ENSURE_ALLOCATION (xsum (length, count)); - tmpsrc = (TCHAR_T *) (result + length); - } -# else - tmpsrc = tmp; - ENSURE_ALLOCATION (xsum (length, count)); -# endif - tmpdst = result + length; - /* Copy backwards, because of overlapping. */ - tmpsrc += count; - tmpdst += count; - for (n = count; n > 0; n--) - *--tmpdst = (unsigned char) *--tmpsrc; - } - } -#endif - -#if DCHAR_IS_TCHAR && !USE_SNPRINTF - /* Make room for the result. */ - if (count > allocated - length) - { - /* Need at least count elements. But allocate - proportionally. */ - size_t n = - xmax (xsum (length, count), xtimes (allocated, 2)); - - ENSURE_ALLOCATION (n); - } -#endif - - /* Here count <= allocated - length. */ - - /* Perform padding. */ -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO - if (pad_ourselves && has_width) - { - size_t w; -# if ENABLE_UNISTDIO - /* Outside POSIX, it's preferrable to compare the width - against the number of _characters_ of the converted - value. */ - w = DCHAR_MBSNLEN (result + length, count); -# else - /* The width is compared against the number of _bytes_ - of the converted value, says POSIX. */ - w = count; -# endif - if (w < width) - { - size_t pad = width - w; -# if USE_SNPRINTF - /* Make room for the result. */ - if (xsum (count, pad) > allocated - length) - { - /* Need at least count + pad elements. But - allocate proportionally. */ - size_t n = - xmax (xsum3 (length, count, pad), - xtimes (allocated, 2)); - - length += count; - ENSURE_ALLOCATION (n); - length -= count; - } - /* Here count + pad <= allocated - length. */ -# endif - { -# if !DCHAR_IS_TCHAR || USE_SNPRINTF - DCHAR_T * const rp = result + length; -# else - DCHAR_T * const rp = tmp; -# endif - DCHAR_T *p = rp + count; - DCHAR_T *end = p + pad; -# if NEED_PRINTF_FLAG_ZERO - DCHAR_T *pad_ptr; -# if !DCHAR_IS_TCHAR - if (dp->conversion == 'c' - || dp->conversion == 's') - /* No zero-padding for string directives. */ - pad_ptr = NULL; - else -# endif - { - pad_ptr = (*rp == '-' ? rp + 1 : rp); - /* No zero-padding of "inf" and "nan". */ - if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z') - || (*pad_ptr >= 'a' && *pad_ptr <= 'z')) - pad_ptr = NULL; - } -# endif - /* The generated string now extends from rp to p, - with the zero padding insertion point being at - pad_ptr. */ - - count = count + pad; /* = end - rp */ - - if (flags & FLAG_LEFT) - { - /* Pad with spaces on the right. */ - for (; pad > 0; pad--) - *p++ = ' '; - } -# if NEED_PRINTF_FLAG_ZERO - else if ((flags & FLAG_ZERO) && pad_ptr != NULL) - { - /* Pad with zeroes. */ - DCHAR_T *q = end; - - while (p > pad_ptr) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = '0'; - } -# endif - else - { - /* Pad with spaces on the left. */ - DCHAR_T *q = end; - - while (p > rp) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = ' '; - } - } - } - } -#endif - -#if DCHAR_IS_TCHAR && !USE_SNPRINTF - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); -#endif - - /* Here still count <= allocated - length. */ - -#if !DCHAR_IS_TCHAR || USE_SNPRINTF - /* The snprintf() result did fit. */ -#else - /* Append the sprintf() result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); -#endif -#if !USE_SNPRINTF - if (tmp != tmpbuf) - free (tmp); -#endif - -#if NEED_PRINTF_DIRECTIVE_F - if (dp->conversion == 'F') - { - /* Convert the %f result to upper case for %F. */ - DCHAR_T *rp = result + length; - size_t rc; - for (rc = count; rc > 0; rc--, rp++) - if (*rp >= 'a' && *rp <= 'z') - *rp = *rp - 'a' + 'A'; - } -#endif - - length += count; - break; - } - } - } - } - - /* Add the final NUL. */ - ENSURE_ALLOCATION (xsum (length, 1)); - result[length] = '\0'; - - if (result != resultbuf && length + 1 < allocated) - { - /* Shrink the allocated memory if possible. */ - DCHAR_T *memory; - - memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T)); - if (memory != NULL) - result = memory; - } - - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - *lengthp = length; - /* Note that we can produce a big string of a length > INT_MAX. POSIX - says that snprintf() fails with errno = EOVERFLOW in this case, but - that's only because snprintf() returns an 'int'. This function does - not have this limitation. */ - return result; - - overflow: - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EOVERFLOW; - return NULL; - - out_of_memory: - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - out_of_memory_1: - CLEANUP (); - errno = ENOMEM; - return NULL; - } -} - -#undef TCHARS_PER_DCHAR -#undef SNPRINTF -#undef USE_SNPRINTF -#undef PRINTF_PARSE -#undef DIRECTIVES -#undef DIRECTIVE -#undef TCHAR_T -#undef DCHAR_T -#undef FCHAR_T -#undef VASNPRINTF diff --git a/src/bin/tar/lib/vasnprintf.h b/src/bin/tar/lib/vasnprintf.h deleted file mode 100644 index 7a0c01f4bf..0000000000 --- a/src/bin/tar/lib/vasnprintf.h +++ /dev/null @@ -1,81 +0,0 @@ -/* vsprintf with automatic memory allocation. - Copyright (C) 2002-2004, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _VASNPRINTF_H -#define _VASNPRINTF_H - -/* Get va_list. */ -#include - -/* Get size_t. */ -#include - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Write formatted output to a string dynamically allocated with malloc(). - You can pass a preallocated buffer for the result in RESULTBUF and its - size in *LENGTHP; otherwise you pass RESULTBUF = NULL. - If successful, return the address of the string (this may be = RESULTBUF - if no dynamic memory allocation was necessary) and set *LENGTHP to the - number of resulting bytes, excluding the trailing NUL. Upon error, set - errno and return NULL. - - When dynamic memory allocation occurs, the preallocated buffer is left - alone (with possibly modified contents). This makes it possible to use - a statically allocated or stack-allocated buffer, like this: - - char buf[100]; - size_t len = sizeof (buf); - char *output = vasnprintf (buf, &len, format, args); - if (output == NULL) - ... error handling ...; - else - { - ... use the output string ...; - if (output != buf) - free (output); - } - */ -#if REPLACE_VASNPRINTF -# define asnprintf rpl_asnprintf -# define vasnprintf rpl_vasnprintf -#endif -extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 3, 0))); - -#ifdef __cplusplus -} -#endif - -#endif /* _VASNPRINTF_H */ diff --git a/src/bin/tar/lib/verify.h b/src/bin/tar/lib/verify.h deleted file mode 100644 index d603b17379..0000000000 --- a/src/bin/tar/lib/verify.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Compile-time assert-like macros. - - Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ - -#ifndef VERIFY_H -# define VERIFY_H 1 - -/* Each of these macros verifies that its argument R is nonzero. To - be portable, R should be an integer constant expression. Unlike - assert (R), there is no run-time overhead. - - There are two macros, since no single macro can be used in all - contexts in C. verify_true (R) is for scalar contexts, including - integer constant expression contexts. verify (R) is for declaration - contexts, e.g., the top level. - - Symbols ending in "__" are private to this header. - - The code below uses several ideas. - - * The first step is ((R) ? 1 : -1). Given an expression R, of - integral or boolean or floating-point type, this yields an - expression of integral type, whose value is later verified to be - constant and nonnegative. - - * Next this expression W is wrapped in a type - struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }. - If W is negative, this yields a compile-time error. No compiler can - deal with a bit-field of negative size. - - One might think that an array size check would have the same - effect, that is, that the type struct { unsigned int dummy[W]; } - would work as well. However, inside a function, some compilers - (such as C++ compilers and GNU C) allow local parameters and - variables inside array size expressions. With these compilers, - an array size check would not properly diagnose this misuse of - the verify macro: - - void function (int n) { verify (n < 0); } - - * For the verify macro, the struct verify_type__ will need to - somehow be embedded into a declaration. To be portable, this - declaration must declare an object, a constant, a function, or a - typedef name. If the declared entity uses the type directly, - such as in - - struct dummy {...}; - typedef struct {...} dummy; - extern struct {...} *dummy; - extern void dummy (struct {...} *); - extern struct {...} *dummy (void); - - two uses of the verify macro would yield colliding declarations - if the entity names are not disambiguated. A workaround is to - attach the current line number to the entity name: - - #define GL_CONCAT0(x, y) x##y - #define GL_CONCAT(x, y) GL_CONCAT0 (x, y) - extern struct {...} * GL_CONCAT(dummy,__LINE__); - - But this has the problem that two invocations of verify from - within the same macro would collide, since the __LINE__ value - would be the same for both invocations. - - A solution is to use the sizeof operator. It yields a number, - getting rid of the identity of the type. Declarations like - - extern int dummy [sizeof (struct {...})]; - extern void dummy (int [sizeof (struct {...})]); - extern int (*dummy (void)) [sizeof (struct {...})]; - - can be repeated. - - * Should the implementation use a named struct or an unnamed struct? - Which of the following alternatives can be used? - - extern int dummy [sizeof (struct {...})]; - extern int dummy [sizeof (struct verify_type__ {...})]; - extern void dummy (int [sizeof (struct {...})]); - extern void dummy (int [sizeof (struct verify_type__ {...})]); - extern int (*dummy (void)) [sizeof (struct {...})]; - extern int (*dummy (void)) [sizeof (struct verify_type__ {...})]; - - In the second and sixth case, the struct type is exported to the - outer scope; two such declarations therefore collide. GCC warns - about the first, third, and fourth cases. So the only remaining - possibility is the fifth case: - - extern int (*dummy (void)) [sizeof (struct {...})]; - - * This implementation exploits the fact that GCC does not warn about - the last declaration mentioned above. If a future version of GCC - introduces a warning for this, the problem could be worked around - by using code specialized to GCC, e.g.,: - - #if 4 <= __GNUC__ - # define verify(R) \ - extern int (* verify_function__ (void)) \ - [__builtin_constant_p (R) && (R) ? 1 : -1] - #endif - - * In C++, any struct definition inside sizeof is invalid. - Use a template type to work around the problem. */ - - -/* Verify requirement R at compile-time, as an integer constant expression. - Return 1. */ - -# ifdef __cplusplus -template - struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; -# define verify_true(R) \ - (!!sizeof (verify_type__<(R) ? 1 : -1>)) -# else -# define verify_true(R) \ - (!!sizeof \ - (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) -# endif - -/* Verify requirement R at compile-time, as a declaration without a - trailing ';'. */ - -# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)] - -#endif diff --git a/src/bin/tar/lib/version-etc-fsf.c b/src/bin/tar/lib/version-etc-fsf.c deleted file mode 100644 index f25eb653ea..0000000000 --- a/src/bin/tar/lib/version-etc-fsf.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Variable with FSF copyright information, for version-etc. - Copyright (C) 1999-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -/* Specification. */ -#include "version-etc.h" - -/* Default copyright goes to the FSF. */ - -const char version_etc_copyright[] = - /* Do *not* mark this string for translation. %s is a copyright - symbol suitable for this locale, and %d is the copyright - year. */ - "Copyright %s %d Free Software Foundation, Inc."; diff --git a/src/bin/tar/lib/version-etc.c b/src/bin/tar/lib/version-etc.c deleted file mode 100644 index 14f101e553..0000000000 --- a/src/bin/tar/lib/version-etc.c +++ /dev/null @@ -1,173 +0,0 @@ -/* Utility to help print --version output in a consistent format. - Copyright (C) 1999-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -/* Specification. */ -#include "version-etc.h" - -#include -#include -#include - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -enum { COPYRIGHT_YEAR = 2007 }; - -/* Like version_etc, below, but with the NULL-terminated author list - provided via a variable of type va_list. */ -void -version_etc_va (FILE *stream, - const char *command_name, const char *package, - const char *version, va_list authors) -{ - size_t n_authors; - - /* Count the number of authors. */ - { - va_list tmp_authors; - - va_copy (tmp_authors, authors); - - n_authors = 0; - while (va_arg (tmp_authors, const char *) != NULL) - ++n_authors; - } - - if (command_name) - fprintf (stream, "%s (%s) %s\n", command_name, package, version); - else - fprintf (stream, "%s %s\n", package, version); - - /* TRANSLATORS: Translate "(C)" to the copyright symbol - (C-in-a-circle), if this symbol is available in the user's - locale. Otherwise, do not translate "(C)"; leave it as-is. */ - fprintf (stream, version_etc_copyright, _("(C)"), COPYRIGHT_YEAR); - - fputs (_("\ -\n\ -License GPLv3+: GNU GPL version 3 or later \n\ -This is free software: you are free to change and redistribute it.\n\ -There is NO WARRANTY, to the extent permitted by law.\n\ -\n\ -"), - stream); - - switch (n_authors) - { - case 0: - /* The caller must provide at least one author name. */ - abort (); - case 1: - /* TRANSLATORS: %s denotes an author name. */ - vfprintf (stream, _("Written by %s.\n"), authors); - break; - case 2: - /* TRANSLATORS: Each %s denotes an author name. */ - vfprintf (stream, _("Written by %s and %s.\n"), authors); - break; - case 3: - /* TRANSLATORS: Each %s denotes an author name. */ - vfprintf (stream, _("Written by %s, %s, and %s.\n"), authors); - break; - case 4: - /* TRANSLATORS: Each %s denotes an author name. - You can use line breaks, estimating that each author name occupies - ca. 16 screen columns and that a screen line has ca. 80 columns. */ - vfprintf (stream, _("Written by %s, %s, %s,\nand %s.\n"), authors); - break; - case 5: - /* TRANSLATORS: Each %s denotes an author name. - You can use line breaks, estimating that each author name occupies - ca. 16 screen columns and that a screen line has ca. 80 columns. */ - vfprintf (stream, _("Written by %s, %s, %s,\n%s, and %s.\n"), authors); - break; - case 6: - /* TRANSLATORS: Each %s denotes an author name. - You can use line breaks, estimating that each author name occupies - ca. 16 screen columns and that a screen line has ca. 80 columns. */ - vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, and %s.\n"), - authors); - break; - case 7: - /* TRANSLATORS: Each %s denotes an author name. - You can use line breaks, estimating that each author name occupies - ca. 16 screen columns and that a screen line has ca. 80 columns. */ - vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, %s, and %s.\n"), - authors); - break; - case 8: - /* TRANSLATORS: Each %s denotes an author name. - You can use line breaks, estimating that each author name occupies - ca. 16 screen columns and that a screen line has ca. 80 columns. */ - vfprintf (stream, _("\ -Written by %s, %s, %s,\n%s, %s, %s, %s,\nand %s.\n"), - authors); - break; - case 9: - /* TRANSLATORS: Each %s denotes an author name. - You can use line breaks, estimating that each author name occupies - ca. 16 screen columns and that a screen line has ca. 80 columns. */ - vfprintf (stream, _("\ -Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, and %s.\n"), - authors); - break; - default: - /* 10 or more authors. Use an abbreviation, since the human reader - will probably not want to read the entire list anyway. */ - /* TRANSLATORS: Each %s denotes an author name. - You can use line breaks, estimating that each author name occupies - ca. 16 screen columns and that a screen line has ca. 80 columns. */ - vfprintf (stream, _("\ -Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, %s, and others.\n"), - authors); - break; - } - va_end (authors); -} - - -/* Display the --version information the standard way. - - If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of - the program. The formats are therefore: - - PACKAGE VERSION - - or - - COMMAND_NAME (PACKAGE) VERSION. - - The author names are passed as separate arguments, with an additional - NULL argument at the end. */ -void -version_etc (FILE *stream, - const char *command_name, const char *package, - const char *version, /* const char *author1, ...*/ ...) -{ - va_list authors; - - va_start (authors, version); - version_etc_va (stream, command_name, package, version, authors); -} diff --git a/src/bin/tar/lib/version-etc.h b/src/bin/tar/lib/version-etc.h deleted file mode 100644 index 84da535001..0000000000 --- a/src/bin/tar/lib/version-etc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Utility to help print --version output in a consistent format. - Copyright (C) 1999, 2003, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#ifndef VERSION_ETC_H -# define VERSION_ETC_H 1 - -# include -# include - -extern const char version_etc_copyright[]; - -extern void version_etc_va (FILE *stream, - const char *command_name, const char *package, - const char *version, va_list authors); - -extern void version_etc (FILE *stream, - const char *command_name, const char *package, - const char *version, - /* const char *author1, ...*/ ...); - -#endif /* VERSION_ETC_H */ diff --git a/src/bin/tar/lib/vsnprintf.c b/src/bin/tar/lib/vsnprintf.c deleted file mode 100644 index 4f841fc477..0000000000 --- a/src/bin/tar/lib/vsnprintf.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Formatted output to strings. - Copyright (C) 2004, 2006-2007 Free Software Foundation, Inc. - Written by Simon Josefsson and Yoann Vandoorselaere . - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* Specification. */ -#include - -#include -#include -#include -#include -#include - -#include "vasnprintf.h" - -/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ -#ifndef EOVERFLOW -# define EOVERFLOW E2BIG -#endif - -/* Print formatted output to string STR. Similar to vsprintf, but - additional length SIZE limit how much is written into STR. Returns - string length of formatted string (which may be larger than SIZE). - STR may be NULL, in which case nothing will be written. On error, - return a negative value. */ -int -vsnprintf (char *str, size_t size, const char *format, va_list args) -{ - char *output; - size_t len; - size_t lenbuf = size; - - output = vasnprintf (str, &lenbuf, format, args); - len = lenbuf; - - if (!output) - return -1; - - if (output != str) - { - if (size) - { - size_t pruned_len = (len < size ? len : size - 1); - memcpy (str, output, pruned_len); - str[pruned_len] = '\0'; - } - - free (output); - } - - if (len > INT_MAX) - { - errno = EOVERFLOW; - return -1; - } - - return len; -} diff --git a/src/bin/tar/lib/waitpid.c b/src/bin/tar/lib/waitpid.c deleted file mode 100644 index eab9430bd0..0000000000 --- a/src/bin/tar/lib/waitpid.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Emulate waitpid on systems that just have wait. - Copyright 1994, 1995, 1998, 1999, 2007 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, 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; see the file COPYING. - If not, write to the Free Software Foundation, - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include -#ifndef errno -extern int errno; -#endif - -#define WAITPID_CHILDREN 8 -static pid_t waited_pid[WAITPID_CHILDREN]; -static int waited_status[WAITPID_CHILDREN]; - -pid_t -waitpid (pid_t pid, int *stat_loc, int options) -{ - int i; - pid_t p; - - if (!options && (pid == -1 || 0 < pid)) - { - /* If we have already waited for this child, return it immediately. */ - for (i = 0; i < WAITPID_CHILDREN; i++) - { - p = waited_pid[i]; - if (p && (p == pid || pid == -1)) - { - waited_pid[i] = 0; - goto success; - } - } - - /* The child has not returned yet; wait for it, accumulating status. */ - for (i = 0; i < WAITPID_CHILDREN; i++) - if (! waited_pid[i]) - { - p = wait (&waited_status[i]); - if (p < 0) - return p; - if (p == pid || pid == -1) - goto success; - waited_pid[i] = p; - } - } - - /* We cannot emulate this wait call, e.g. because of too many children. */ - errno = EINVAL; - return -1; - -success: - if (stat_loc) - *stat_loc = waited_status[i]; - return p; -} diff --git a/src/bin/tar/lib/wchar.in.h b/src/bin/tar/lib/wchar.in.h deleted file mode 100644 index 924a3382d3..0000000000 --- a/src/bin/tar/lib/wchar.in.h +++ /dev/null @@ -1,82 +0,0 @@ -/* A substitute for ISO C99 , for platforms that have issues. - - Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Eric Blake. */ - -/* - * ISO C 99 for platforms that have issues. - * - * - * For now, this just ensures proper prerequisite inclusion order and - * the declaration of wcwidth(). - */ - -#ifndef _GL_WCHAR_H - -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include - -/* Include the original if it exists. - Some builds of uClibc lack it. */ -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_WCHAR_H@ -# @INCLUDE_NEXT@ @NEXT_WCHAR_H@ -#endif - -#ifndef _GL_WCHAR_H -#define _GL_WCHAR_H - -/* The definition of GL_LINK_WARNING is copied here. */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Return the number of screen columns needed for WC. */ -#if @GNULIB_WCWIDTH@ -# if @REPLACE_WCWIDTH@ -# undef wcwidth -# define wcwidth rpl_wcwidth -extern int wcwidth (wchar_t); -# else -# if !defined wcwidth && !@HAVE_DECL_WCWIDTH@ -/* wcwidth exists but is not declared. */ -extern int wcwidth (int /* actually wchar_t */); -# endif -# endif -#elif defined GNULIB_POSIXCHECK -# undef wcwidth -# define wcwidth(w) \ - (GL_LINK_WARNING ("wcwidth is unportable - " \ - "use gnulib module wcwidth for portability"), \ - wcwidth (w)) -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* _GL_WCHAR_H */ -#endif /* _GL_WCHAR_H */ diff --git a/src/bin/tar/lib/wctype.in.h b/src/bin/tar/lib/wctype.in.h deleted file mode 100644 index 73ce09f450..0000000000 --- a/src/bin/tar/lib/wctype.in.h +++ /dev/null @@ -1,161 +0,0 @@ -/* A substitute for ISO C99 , for platforms that lack it. - - Copyright (C) 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Bruno Haible and Paul Eggert. */ - -/* - * ISO C 99 for platforms that lack it. - * - * - * iswctype, towctrans, towlower, towupper, wctrans, wctype, - * wctrans_t, and wctype_t are not yet implemented. - */ - -#ifndef _GL_WCTYPE_H - -#if @HAVE_WINT_T@ -/* Solaris 2.5 has a bug: must be included before . - Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -# include -# include -# include -# include -#endif - -/* Include the original if it exists. - BeOS 5 has the functions but no . */ -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_WCTYPE_H@ -# @INCLUDE_NEXT@ @NEXT_WCTYPE_H@ -#endif - -#ifndef _GL_WCTYPE_H -#define _GL_WCTYPE_H - -#if @HAVE_WINT_T@ -typedef wint_t __wctype_wint_t; -#else -typedef int __wctype_wint_t; -#endif - -/* FreeBSD 4.4 to 4.11 has but lacks the functions. - Assume all 12 functions are implemented the same way, or not at all. */ -#if ! @HAVE_ISWCNTRL@ - -/* IRIX 5.3 has macros but no functions, its isw* macros refer to an - undefined variable _ctmp_ and to macros like _P, and they - refer to system functions like _iswctype that are not in the - standard C library. Rather than try to get ancient buggy - implementations like this to work, just disable them. */ -# undef iswalnum -# undef iswalpha -# undef iswblank -# undef iswcntrl -# undef iswdigit -# undef iswgraph -# undef iswlower -# undef iswprint -# undef iswpunct -# undef iswspace -# undef iswupper -# undef iswxdigit - -static inline int -iswalnum (__wctype_wint_t wc) -{ - return ((wc >= '0' && wc <= '9') - || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); -} - -static inline int -iswalpha (__wctype_wint_t wc) -{ - return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; -} - -static inline int -iswblank (__wctype_wint_t wc) -{ - return wc == ' ' || wc == '\t'; -} - -static inline int -iswcntrl (__wctype_wint_t wc) -{ - return (wc & ~0x1f) == 0 || wc == 0x7f; -} - -static inline int -iswdigit (__wctype_wint_t wc) -{ - return wc >= '0' && wc <= '9'; -} - -static inline int -iswgraph (__wctype_wint_t wc) -{ - return wc >= '!' && wc <= '~'; -} - -static inline int -iswlower (__wctype_wint_t wc) -{ - return wc >= 'a' && wc <= 'z'; -} - -static inline int -iswprint (__wctype_wint_t wc) -{ - return wc >= ' ' && wc <= '~'; -} - -static inline int -iswpunct (__wctype_wint_t wc) -{ - return (wc >= '!' && wc <= '~' - && !((wc >= '0' && wc <= '9') - || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'))); -} - -static inline int -iswspace (__wctype_wint_t wc) -{ - return (wc == ' ' || wc == '\t' - || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r'); -} - -static inline int -iswupper (__wctype_wint_t wc) -{ - return wc >= 'A' && wc <= 'Z'; -} - -static inline int -iswxdigit (__wctype_wint_t wc) -{ - return ((wc >= '0' && wc <= '9') - || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); -} - -# endif /* ! HAVE_ISWCNTRL */ - -#endif /* _GL_WCTYPE_H */ -#endif /* _GL_WCTYPE_H */ diff --git a/src/bin/tar/lib/wcwidth.c b/src/bin/tar/lib/wcwidth.c deleted file mode 100644 index 77042c2ae3..0000000000 --- a/src/bin/tar/lib/wcwidth.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Determine the number of screen columns needed for a character. - Copyright (C) 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include - -/* Get iswprint. */ -#include - -#include "localcharset.h" -#include "streq.h" -#include "uniwidth.h" - -#undef wcwidth - -int -rpl_wcwidth (wchar_t wc) -{ - /* In UTF-8 locales, use a Unicode aware width function. */ - const char *encoding = locale_charset (); - if (STREQ (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0 ,0)) - { - /* We assume that in a UTF-8 locale, a wide character is the same as a - Unicode character. */ - return uc_width (wc, encoding); - } - else - { - /* Otherwise, fall back to the system's wcwidth function. */ -#if HAVE_WCWIDTH - return wcwidth (wc); -#else - return wc == 0 ? 0 : iswprint (wc) ? 1 : -1; -#endif - } -} diff --git a/src/bin/tar/lib/xalloc-die.c b/src/bin/tar/lib/xalloc-die.c deleted file mode 100644 index 090f060df7..0000000000 --- a/src/bin/tar/lib/xalloc-die.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Report a memory allocation failure and exit. - - Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include "xalloc.h" - -#include - -#include "error.h" -#include "exitfail.h" - -#include "gettext.h" -#define _(msgid) gettext (msgid) - -void -xalloc_die (void) -{ - error (exit_failure, 0, "%s", _("memory exhausted")); - - /* The `noreturn' cannot be given to error, since it may return if - its first argument is 0. To help compilers understand the - xalloc_die does not return, call abort. Also, the abort is a - safety feature if exit_failure is 0 (which shouldn't happen). */ - abort (); -} diff --git a/src/bin/tar/lib/xalloc.h b/src/bin/tar/lib/xalloc.h deleted file mode 100644 index 0c6d8dcf50..0000000000 --- a/src/bin/tar/lib/xalloc.h +++ /dev/null @@ -1,271 +0,0 @@ -/* xalloc.h -- malloc with out-of-memory checking - - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2003, 2004, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef XALLOC_H_ -# define XALLOC_H_ - -# include - - -# ifdef __cplusplus -extern "C" { -# endif - - -# ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -# endif - -# ifndef ATTRIBUTE_NORETURN -# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -# endif - -/* This function is always triggered when memory is exhausted. - It must be defined by the application, either explicitly - or by using gnulib's xalloc-die module. This is the - function to call when one wants the program to die because of a - memory allocation failure. */ -extern void xalloc_die (void) ATTRIBUTE_NORETURN; - -void *xmalloc (size_t s); -void *xzalloc (size_t s); -void *xcalloc (size_t n, size_t s); -void *xrealloc (void *p, size_t s); -void *x2realloc (void *p, size_t *pn); -void *xmemdup (void const *p, size_t s); -char *xstrdup (char const *str); - -/* Return 1 if an array of N objects, each of size S, cannot exist due - to size arithmetic overflow. S must be positive and N must be - nonnegative. This is a macro, not an inline function, so that it - works correctly even when SIZE_MAX < N. - - By gnulib convention, SIZE_MAX represents overflow in size - calculations, so the conservative dividend to use here is - SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. - However, malloc (SIZE_MAX) fails on all known hosts where - sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for - exactly-SIZE_MAX allocations on such hosts; this avoids a test and - branch when S is known to be 1. */ -# define xalloc_oversized(n, s) \ - ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) - - -/* In the following macros, T must be an elementary or structure/union or - typedef'ed type, or a pointer to such a type. To apply one of the - following macros to a function pointer or array type, you need to typedef - it first and use the typedef name. */ - -/* Allocate an object of type T dynamically, with error checking. */ -/* extern t *XMALLOC (typename t); */ -# define XMALLOC(t) ((t *) xmalloc (sizeof (t))) - -/* Allocate memory for N elements of type T, with error checking. */ -/* extern t *XNMALLOC (size_t n, typename t); */ -# define XNMALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t)))) - -/* Allocate an object of type T dynamically, with error checking, - and zero it. */ -/* extern t *XZALLOC (typename t); */ -# define XZALLOC(t) ((t *) xzalloc (sizeof (t))) - -/* Allocate memory for N elements of type T, with error checking, - and zero it. */ -/* extern t *XCALLOC (size_t n, typename t); */ -# define XCALLOC(n, t) \ - ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t)))) - - -# if HAVE_INLINE -# define static_inline static inline -# else - void *xnmalloc (size_t n, size_t s); - void *xnrealloc (void *p, size_t n, size_t s); - void *x2nrealloc (void *p, size_t *pn, size_t s); - char *xcharalloc (size_t n); -# endif - -# ifdef static_inline - -/* Allocate an array of N objects, each with S bytes of memory, - dynamically, with error checking. S must be nonzero. */ - -static_inline void * -xnmalloc (size_t n, size_t s) -{ - if (xalloc_oversized (n, s)) - xalloc_die (); - return xmalloc (n * s); -} - -/* Change the size of an allocated block of memory P to an array of N - objects each of S bytes, with error checking. S must be nonzero. */ - -static_inline void * -xnrealloc (void *p, size_t n, size_t s) -{ - if (xalloc_oversized (n, s)) - xalloc_die (); - return xrealloc (p, n * s); -} - -/* If P is null, allocate a block of at least *PN such objects; - otherwise, reallocate P so that it contains more than *PN objects - each of S bytes. *PN must be nonzero unless P is null, and S must - be nonzero. Set *PN to the new number of objects, and return the - pointer to the new block. *PN is never set to zero, and the - returned pointer is never null. - - Repeated reallocations are guaranteed to make progress, either by - allocating an initial block with a nonzero size, or by allocating a - larger block. - - In the following implementation, nonzero sizes are increased by a - factor of approximately 1.5 so that repeated reallocations have - O(N) overall cost rather than O(N**2) cost, but the - specification for this function does not guarantee that rate. - - Here is an example of use: - - int *p = NULL; - size_t used = 0; - size_t allocated = 0; - - void - append_int (int value) - { - if (used == allocated) - p = x2nrealloc (p, &allocated, sizeof *p); - p[used++] = value; - } - - This causes x2nrealloc to allocate a block of some nonzero size the - first time it is called. - - To have finer-grained control over the initial size, set *PN to a - nonzero value before calling this function with P == NULL. For - example: - - int *p = NULL; - size_t used = 0; - size_t allocated = 0; - size_t allocated1 = 1000; - - void - append_int (int value) - { - if (used == allocated) - { - p = x2nrealloc (p, &allocated1, sizeof *p); - allocated = allocated1; - } - p[used++] = value; - } - - */ - -static_inline void * -x2nrealloc (void *p, size_t *pn, size_t s) -{ - size_t n = *pn; - - if (! p) - { - if (! n) - { - /* The approximate size to use for initial small allocation - requests, when the invoking code specifies an old size of - zero. 64 bytes is the largest "small" request for the - GNU C library malloc. */ - enum { DEFAULT_MXFAST = 64 }; - - n = DEFAULT_MXFAST / s; - n += !n; - } - } - else - { - /* Set N = ceil (1.5 * N) so that progress is made if N == 1. - Check for overflow, so that N * S stays in size_t range. - The check is slightly conservative, but an exact check isn't - worth the trouble. */ - if ((size_t) -1 / 3 * 2 / s <= n) - xalloc_die (); - n += (n + 1) / 2; - } - - *pn = n; - return xrealloc (p, n * s); -} - -/* Return a pointer to a new buffer of N bytes. This is like xmalloc, - except it returns char *. */ - -static_inline char * -xcharalloc (size_t n) -{ - return XNMALLOC (n, char); -} - -# endif - -# ifdef __cplusplus -} - -/* C++ does not allow conversions from void * to other pointer types - without a cast. Use templates to work around the problem when - possible. */ - -template inline T * -xrealloc (T *p, size_t s) -{ - return (T *) xrealloc ((void *) p, s); -} - -template inline T * -xnrealloc (T *p, size_t n, size_t s) -{ - return (T *) xnrealloc ((void *) p, n, s); -} - -template inline T * -x2realloc (T *p, size_t *pn) -{ - return (T *) x2realloc ((void *) p, pn); -} - -template inline T * -x2nrealloc (T *p, size_t *pn, size_t s) -{ - return (T *) x2nrealloc ((void *) p, pn, s); -} - -template inline T * -xmemdup (T const *p, size_t s) -{ - return (T *) xmemdup ((void const *) p, s); -} - -# endif - - -#endif /* !XALLOC_H_ */ diff --git a/src/bin/tar/lib/xgetcwd.c b/src/bin/tar/lib/xgetcwd.c deleted file mode 100644 index 26ea5da53d..0000000000 --- a/src/bin/tar/lib/xgetcwd.c +++ /dev/null @@ -1,41 +0,0 @@ -/* xgetcwd.c -- return current directory with unlimited length - - Copyright (C) 2001, 2003, 2004, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#include - -#include "xgetcwd.h" - -#include -#include - -#include "xalloc.h" - -/* Return the current directory, newly allocated. - Upon an out-of-memory error, call xalloc_die. - Upon any other type of error, return NULL. */ - -char * -xgetcwd (void) -{ - char *cwd = getcwd (NULL, 0); - if (! cwd && errno == ENOMEM) - xalloc_die (); - return cwd; -} diff --git a/src/bin/tar/lib/xgetcwd.h b/src/bin/tar/lib/xgetcwd.h deleted file mode 100644 index 70afe35e7c..0000000000 --- a/src/bin/tar/lib/xgetcwd.h +++ /dev/null @@ -1,18 +0,0 @@ -/* prototype for xgetcwd - Copyright (C) 1995, 2001, 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -extern char *xgetcwd (void); diff --git a/src/bin/tar/lib/xmalloc.c b/src/bin/tar/lib/xmalloc.c deleted file mode 100644 index 318e0ddb5a..0000000000 --- a/src/bin/tar/lib/xmalloc.c +++ /dev/null @@ -1,123 +0,0 @@ -/* xmalloc.c -- malloc with out of memory checking - - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002, 2003, 2004, 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#if ! HAVE_INLINE -# define static_inline -#endif -#include "xalloc.h" -#undef static_inline - -#include -#include - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* 1 if calloc is known to be compatible with GNU calloc. This - matters if we are not also using the calloc module, which defines - HAVE_CALLOC and supports the GNU API even on non-GNU platforms. */ -#if defined HAVE_CALLOC || defined __GLIBC__ -enum { HAVE_GNU_CALLOC = 1 }; -#else -enum { HAVE_GNU_CALLOC = 0 }; -#endif - -/* Allocate N bytes of memory dynamically, with error checking. */ - -void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p && n != 0) - xalloc_die (); - return p; -} - -/* Change the size of an allocated block of memory P to N bytes, - with error checking. */ - -void * -xrealloc (void *p, size_t n) -{ - p = realloc (p, n); - if (!p && n != 0) - xalloc_die (); - return p; -} - -/* If P is null, allocate a block of at least *PN bytes; otherwise, - reallocate P so that it contains more than *PN bytes. *PN must be - nonzero unless P is null. Set *PN to the new block's size, and - return the pointer to the new block. *PN is never set to zero, and - the returned pointer is never null. */ - -void * -x2realloc (void *p, size_t *pn) -{ - return x2nrealloc (p, pn, 1); -} - -/* Allocate S bytes of zeroed memory dynamically, with error checking. - There's no need for xnzalloc (N, S), since it would be equivalent - to xcalloc (N, S). */ - -void * -xzalloc (size_t s) -{ - return memset (xmalloc (s), 0, s); -} - -/* Allocate zeroed memory for N elements of S bytes, with error - checking. S must be nonzero. */ - -void * -xcalloc (size_t n, size_t s) -{ - void *p; - /* Test for overflow, since some calloc implementations don't have - proper overflow checks. But omit overflow and size-zero tests if - HAVE_GNU_CALLOC, since GNU calloc catches overflow and never - returns NULL if successful. */ - if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s)) - || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0))) - xalloc_die (); - return p; -} - -/* Clone an object P of size S, with error checking. There's no need - for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any - need for an arithmetic overflow check. */ - -void * -xmemdup (void const *p, size_t s) -{ - return memcpy (xmalloc (s), p, s); -} - -/* Clone STRING. */ - -char * -xstrdup (char const *string) -{ - return xmemdup (string, strlen (string) + 1); -} diff --git a/src/bin/tar/lib/xsize.h b/src/bin/tar/lib/xsize.h deleted file mode 100644 index 341fb16ca7..0000000000 --- a/src/bin/tar/lib/xsize.h +++ /dev/null @@ -1,108 +0,0 @@ -/* xsize.h -- Checked size_t computations. - - Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef _XSIZE_H -#define _XSIZE_H - -/* Get size_t. */ -#include - -/* Get SIZE_MAX. */ -#include -#if HAVE_STDINT_H -# include -#endif - -/* The size of memory objects is often computed through expressions of - type size_t. Example: - void* p = malloc (header_size + n * element_size). - These computations can lead to overflow. When this happens, malloc() - returns a piece of memory that is way too small, and the program then - crashes while attempting to fill the memory. - To avoid this, the functions and macros in this file check for overflow. - The convention is that SIZE_MAX represents overflow. - malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc - implementation that uses mmap --, it's recommended to use size_overflow_p() - or size_in_bounds_p() before invoking malloc(). - The example thus becomes: - size_t size = xsum (header_size, xtimes (n, element_size)); - void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); -*/ - -/* Convert an arbitrary value >= 0 to type size_t. */ -#define xcast_size_t(N) \ - ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) - -/* Sum of two sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum (size_t size1, size_t size2) -{ - size_t sum = size1 + size2; - return (sum >= size1 ? sum : SIZE_MAX); -} - -/* Sum of three sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum3 (size_t size1, size_t size2, size_t size3) -{ - return xsum (xsum (size1, size2), size3); -} - -/* Sum of four sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) -{ - return xsum (xsum (xsum (size1, size2), size3), size4); -} - -/* Maximum of two sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xmax (size_t size1, size_t size2) -{ - /* No explicit check is needed here, because for any n: - max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ - return (size1 >= size2 ? size1 : size2); -} - -/* Multiplication of a count with an element size, with overflow check. - The count must be >= 0 and the element size must be > 0. - This is a macro, not an inline function, so that it works correctly even - when N is of a wider tupe and N > SIZE_MAX. */ -#define xtimes(N, ELSIZE) \ - ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) - -/* Check for overflow. */ -#define size_overflow_p(SIZE) \ - ((SIZE) == SIZE_MAX) -/* Check against overflow. */ -#define size_in_bounds_p(SIZE) \ - ((SIZE) != SIZE_MAX) - -#endif /* _XSIZE_H */ diff --git a/src/bin/tar/lib/xstrndup.c b/src/bin/tar/lib/xstrndup.c deleted file mode 100644 index 7ccefd798a..0000000000 --- a/src/bin/tar/lib/xstrndup.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Duplicate a bounded initial segment of a string, with out-of-memory - checking. - Copyright (C) 2003, 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Specification. */ -#include "xstrndup.h" - -#include -#include "xalloc.h" - -/* Return a newly allocated copy of at most N bytes of STRING. - In other words, return a copy of the initial segment of length N of - STRING. */ -char * -xstrndup (const char *string, size_t n) -{ - char *s = strndup (string, n); - if (! s) - xalloc_die (); - return s; -} diff --git a/src/bin/tar/lib/xstrndup.h b/src/bin/tar/lib/xstrndup.h deleted file mode 100644 index 88354cfd43..0000000000 --- a/src/bin/tar/lib/xstrndup.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Duplicate a bounded initial segment of a string, with out-of-memory - checking. - Copyright (C) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -/* Return a newly allocated copy of at most N bytes of STRING. - In other words, return a copy of the initial segment of length N of - STRING. */ -extern char *xstrndup (const char *string, size_t n); diff --git a/src/bin/tar/lib/xstrtol-error.c b/src/bin/tar/lib/xstrtol-error.c deleted file mode 100644 index 1d3d856404..0000000000 --- a/src/bin/tar/lib/xstrtol-error.c +++ /dev/null @@ -1,99 +0,0 @@ -/* A more useful interface to strtol. - - Copyright (C) 1995, 1996, 1998, 1999, 2001, 2002, 2003, 2004, 2006, 2007 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include "xstrtol.h" - -#include - -#include "error.h" -#include "exitfail.h" -#include "gettext.h" - -#define N_(msgid) msgid - -/* Report an error for an invalid integer in an option argument. - - ERR is the error code returned by one of the xstrto* functions. - - Use OPT_IDX to decide whether to print the short option string "C" - or "-C" or a long option string derived from LONG_OPTION. OPT_IDX - is -2 if the short option "C" was used, without any leading "-"; it - is -1 if the short option "-C" was used; otherwise it is an index - into LONG_OPTIONS, which should have a name preceded by two '-' - characters. - - ARG is the option-argument containing the integer. - - After reporting an error, exit with status EXIT_STATUS if it is - nonzero. */ - -static void -xstrtol_error (enum strtol_error err, - int opt_idx, char c, struct option const *long_options, - char const *arg, - int exit_status) -{ - char const *hyphens = "--"; - char const *msgid; - char const *option; - char option_buffer[2]; - - switch (err) - { - default: - abort (); - - case LONGINT_INVALID: - msgid = N_("invalid %s%s argument `%s'"); - break; - - case LONGINT_INVALID_SUFFIX_CHAR: - case LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW: - msgid = N_("invalid suffix in %s%s argument `%s'"); - break; - - case LONGINT_OVERFLOW: - msgid = N_("%s%s argument `%s' too large"); - break; - } - - if (opt_idx < 0) - { - hyphens -= opt_idx; - option_buffer[0] = c; - option_buffer[1] = '\0'; - option = option_buffer; - } - else - option = long_options[opt_idx].name; - - error (exit_failure, 0, gettext (msgid), hyphens, option, arg); -} - -/* Like xstrtol_error, except exit with a failure status. */ - -void -xstrtol_fatal (enum strtol_error err, - int opt_idx, char c, struct option const *long_options, - char const *arg) -{ - xstrtol_error (err, opt_idx, c, long_options, arg, exit_failure); - abort (); -} diff --git a/src/bin/tar/lib/xstrtol.c b/src/bin/tar/lib/xstrtol.c deleted file mode 100644 index ed5bcdd0b2..0000000000 --- a/src/bin/tar/lib/xstrtol.c +++ /dev/null @@ -1,229 +0,0 @@ -/* A more useful interface to strtol. - - Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2004, 2005, - 2006, 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Written by Jim Meyering. */ - -#ifndef __strtol -# define __strtol strtol -# define __strtol_t long int -# define __xstrtol xstrtol -# define STRTOL_T_MINIMUM LONG_MIN -# define STRTOL_T_MAXIMUM LONG_MAX -#endif - -#include - -#include "xstrtol.h" - -/* Some pre-ANSI implementations (e.g. SunOS 4) - need stderr defined if assertion checking is enabled. */ -#include - -#include -#include -#include -#include -#include -#include - -#include "intprops.h" - -static strtol_error -bkm_scale (__strtol_t *x, int scale_factor) -{ - if (TYPE_SIGNED (__strtol_t) && *x < STRTOL_T_MINIMUM / scale_factor) - { - *x = STRTOL_T_MINIMUM; - return LONGINT_OVERFLOW; - } - if (STRTOL_T_MAXIMUM / scale_factor < *x) - { - *x = STRTOL_T_MAXIMUM; - return LONGINT_OVERFLOW; - } - *x *= scale_factor; - return LONGINT_OK; -} - -static strtol_error -bkm_scale_by_power (__strtol_t *x, int base, int power) -{ - strtol_error err = LONGINT_OK; - while (power--) - err |= bkm_scale (x, base); - return err; -} - -/* FIXME: comment. */ - -strtol_error -__xstrtol (const char *s, char **ptr, int strtol_base, - __strtol_t *val, const char *valid_suffixes) -{ - char *t_ptr; - char **p; - __strtol_t tmp; - strtol_error err = LONGINT_OK; - - assert (0 <= strtol_base && strtol_base <= 36); - - p = (ptr ? ptr : &t_ptr); - - if (! TYPE_SIGNED (__strtol_t)) - { - const char *q = s; - unsigned char ch = *q; - while (isspace (ch)) - ch = *++q; - if (ch == '-') - return LONGINT_INVALID; - } - - errno = 0; - tmp = __strtol (s, p, strtol_base); - - if (*p == s) - { - /* If there is no number but there is a valid suffix, assume the - number is 1. The string is invalid otherwise. */ - if (valid_suffixes && **p && strchr (valid_suffixes, **p)) - tmp = 1; - else - return LONGINT_INVALID; - } - else if (errno != 0) - { - if (errno != ERANGE) - return LONGINT_INVALID; - err = LONGINT_OVERFLOW; - } - - /* Let valid_suffixes == NULL mean `allow any suffix'. */ - /* FIXME: update all callers except the ones that allow suffixes - after the number, changing last parameter NULL to `""'. */ - if (!valid_suffixes) - { - *val = tmp; - return err; - } - - if (**p != '\0') - { - int base = 1024; - int suffixes = 1; - strtol_error overflow; - - if (!strchr (valid_suffixes, **p)) - { - *val = tmp; - return err | LONGINT_INVALID_SUFFIX_CHAR; - } - - if (strchr (valid_suffixes, '0')) - { - /* The ``valid suffix'' '0' is a special flag meaning that - an optional second suffix is allowed, which can change - the base. A suffix "B" (e.g. "100MB") stands for a power - of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for - a power of 1024. If no suffix (e.g. "100M"), assume - power-of-1024. */ - - switch (p[0][1]) - { - case 'i': - if (p[0][2] == 'B') - suffixes += 2; - break; - - case 'B': - case 'D': /* 'D' is obsolescent */ - base = 1000; - suffixes++; - break; - } - } - - switch (**p) - { - case 'b': - overflow = bkm_scale (&tmp, 512); - break; - - case 'B': - overflow = bkm_scale (&tmp, 1024); - break; - - case 'c': - overflow = 0; - break; - - case 'E': /* exa or exbi */ - overflow = bkm_scale_by_power (&tmp, base, 6); - break; - - case 'G': /* giga or gibi */ - case 'g': /* 'g' is undocumented; for compatibility only */ - overflow = bkm_scale_by_power (&tmp, base, 3); - break; - - case 'k': /* kilo */ - case 'K': /* kibi */ - overflow = bkm_scale_by_power (&tmp, base, 1); - break; - - case 'M': /* mega or mebi */ - case 'm': /* 'm' is undocumented; for compatibility only */ - overflow = bkm_scale_by_power (&tmp, base, 2); - break; - - case 'P': /* peta or pebi */ - overflow = bkm_scale_by_power (&tmp, base, 5); - break; - - case 'T': /* tera or tebi */ - case 't': /* 't' is undocumented; for compatibility only */ - overflow = bkm_scale_by_power (&tmp, base, 4); - break; - - case 'w': - overflow = bkm_scale (&tmp, 2); - break; - - case 'Y': /* yotta or 2**80 */ - overflow = bkm_scale_by_power (&tmp, base, 8); - break; - - case 'Z': /* zetta or 2**70 */ - overflow = bkm_scale_by_power (&tmp, base, 7); - break; - - default: - *val = tmp; - return err | LONGINT_INVALID_SUFFIX_CHAR; - } - - err |= overflow; - *p += suffixes; - if (**p) - err |= LONGINT_INVALID_SUFFIX_CHAR; - } - - *val = tmp; - return err; -} diff --git a/src/bin/tar/lib/xstrtol.h b/src/bin/tar/lib/xstrtol.h deleted file mode 100644 index 336af8d6bc..0000000000 --- a/src/bin/tar/lib/xstrtol.h +++ /dev/null @@ -1,79 +0,0 @@ -/* A more useful interface to strtol. - - Copyright (C) 1995, 1996, 1998, 1999, 2001, 2002, 2003, 2004, 2006, 2007 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#ifndef XSTRTOL_H_ -# define XSTRTOL_H_ 1 - -# include -# include - -# ifndef _STRTOL_ERROR -enum strtol_error - { - LONGINT_OK = 0, - - /* These two values can be ORed together, to indicate that both - errors occurred. */ - LONGINT_OVERFLOW = 1, - LONGINT_INVALID_SUFFIX_CHAR = 2, - - LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR - | LONGINT_OVERFLOW), - LONGINT_INVALID = 4 - }; -typedef enum strtol_error strtol_error; -# endif - -# define _DECLARE_XSTRTOL(name, type) \ - strtol_error name (const char *, char **, int, type *, const char *); -_DECLARE_XSTRTOL (xstrtol, long int) -_DECLARE_XSTRTOL (xstrtoul, unsigned long int) -_DECLARE_XSTRTOL (xstrtoimax, intmax_t) -_DECLARE_XSTRTOL (xstrtoumax, uintmax_t) - -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ -# define __attribute__(x) -# endif -#endif - -#ifndef ATTRIBUTE_NORETURN -# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) -#endif - -/* Report an error for an invalid integer in an option argument. - - ERR is the error code returned by one of the xstrto* functions. - - Use OPT_IDX to decide whether to print the short option string "C" - or "-C" or a long option string derived from LONG_OPTION. OPT_IDX - is -2 if the short option "C" was used, without any leading "-"; it - is -1 if the short option "-C" was used; otherwise it is an index - into LONG_OPTIONS, which should have a name preceded by two '-' - characters. - - ARG is the option-argument containing the integer. - - After reporting an error, exit with a failure status. */ - -void xstrtol_fatal (enum strtol_error, - int, char, struct option const *, - char const *) ATTRIBUTE_NORETURN; - -#endif /* not XSTRTOL_H_ */ diff --git a/src/bin/tar/lib/xstrtoul.c b/src/bin/tar/lib/xstrtoul.c deleted file mode 100644 index 285f7b96f8..0000000000 --- a/src/bin/tar/lib/xstrtoul.c +++ /dev/null @@ -1,6 +0,0 @@ -#define __strtol strtoul -#define __strtol_t unsigned long int -#define __xstrtol xstrtoul -#define STRTOL_T_MINIMUM 0 -#define STRTOL_T_MAXIMUM ULONG_MAX -#include "xstrtol.c" diff --git a/src/bin/tar/lib/xstrtoumax.c b/src/bin/tar/lib/xstrtoumax.c deleted file mode 100644 index 9a2349f00d..0000000000 --- a/src/bin/tar/lib/xstrtoumax.c +++ /dev/null @@ -1,6 +0,0 @@ -#define __strtol strtoumax -#define __strtol_t uintmax_t -#define __xstrtol xstrtoumax -#define STRTOL_T_MINIMUM 0 -#define STRTOL_T_MAXIMUM UINTMAX_MAX -#include "xstrtol.c" diff --git a/src/bin/tar/rmt/Jamfile b/src/bin/tar/rmt/Jamfile deleted file mode 100644 index 277d5d956b..0000000000 --- a/src/bin/tar/rmt/Jamfile +++ /dev/null @@ -1,14 +0,0 @@ -SubDir HAIKU_TOP src bin tar rmt ; - -SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) lib ] ; -SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; -SubDirSysHdrs [ FDirName $(SUBDIR) ] ; - -# set some additional defines -{ - SubDirCcFlags -DHAVE_CONFIG_H -w -DLOCALEDIR=\'\"/etc/locale\"\' ; -} - -BinCommand rmt : - rmt.c - : libtar.a network : tar.rsrc ; diff --git a/src/bin/tar/rmt/rmt.c b/src/bin/tar/rmt/rmt.c deleted file mode 100644 index a043dd0c89..0000000000 --- a/src/bin/tar/rmt/rmt.c +++ /dev/null @@ -1,676 +0,0 @@ -/* Remote connection server. - - Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2003, 2004, - 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Copyright (C) 1983 Regents of the University of California. - All rights reserved. - - Redistribution and use in source and binary forms are permitted provided - that the above copyright notice and this paragraph are duplicated in all - such forms and that any documentation, advertising materials, and other - materials related to such distribution and use acknowledge that the - software was developed by the University of California, Berkeley. The - name of the University may not be used to endorse or promote products - derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ - -#include "system.h" -#include "system-ioctl.h" -#include -#include -#include -#include -#include -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free -#include -#include -#include - -#ifndef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif -#ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -#endif - -/* Maximum size of a string from the requesting program. - It must hold enough for any integer, possibly with a sign. */ -#define STRING_SIZE (UINTMAX_STRSIZE_BOUND + 1) - -const char *program_name; - -/* File descriptor of the tape device, or negative if none open. */ -static int tape = -1; - -/* Buffer containing transferred data, and its allocated size. */ -static char *record_buffer; -static size_t allocated_size; - -/* Buffer for constructing the reply. */ -static char reply_buffer[BUFSIZ]; - -/* Obstack for arbitrary-sized strings */ -struct obstack string_stk; - -/* Debugging tools. */ - -static FILE *debug_file; - -#define DEBUG(File) \ - if (debug_file) fprintf(debug_file, File) - -#define DEBUG1(File, Arg) \ - if (debug_file) fprintf(debug_file, File, Arg) - -#define DEBUG2(File, Arg1, Arg2) \ - if (debug_file) fprintf(debug_file, File, Arg1, Arg2) - -static void -report_error_message (const char *string) -{ - DEBUG1 ("rmtd: E 0 (%s)\n", string); - - sprintf (reply_buffer, "E0\n%s\n", string); - full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); -} - -static void -report_numbered_error (int num) -{ - DEBUG2 ("rmtd: E %d (%s)\n", num, strerror (num)); - - sprintf (reply_buffer, "E%d\n%s\n", num, strerror (num)); - full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); -} - -static char * -get_string (void) -{ - for (;;) - { - char c; - if (safe_read (STDIN_FILENO, &c, 1) != 1) - exit (EXIT_SUCCESS); - - if (c == '\n') - break; - - obstack_1grow (&string_stk, c); - } - obstack_1grow (&string_stk, 0); - return obstack_finish (&string_stk); -} - -static void -free_string (char *string) -{ - obstack_free (&string_stk, string); -} - -static void -get_string_n (char *string) -{ - size_t counter; - - for (counter = 0; ; counter++) - { - if (safe_read (STDIN_FILENO, string + counter, 1) != 1) - exit (EXIT_SUCCESS); - - if (string[counter] == '\n') - break; - - if (counter == STRING_SIZE - 1) - report_error_message (N_("Input string too long")); - } - string[counter] = '\0'; -} - -static long int -get_long (char const *string) -{ - char *p; - long int n; - errno = 0; - n = strtol (string, &p, 10); - if (errno == ERANGE) - { - report_numbered_error (errno); - exit (EXIT_FAILURE); - } - if (!*string || *p) - { - report_error_message (N_("Number syntax error")); - exit (EXIT_FAILURE); - } - return n; -} - -static void -prepare_input_buffer (int fd, size_t size) -{ - if (size <= allocated_size) - return; - - if (record_buffer) - free (record_buffer); - - record_buffer = malloc (size); - - if (! record_buffer) - { - DEBUG (_("rmtd: Cannot allocate buffer space\n")); - - report_error_message (N_("Cannot allocate buffer space")); - exit (EXIT_FAILURE); /* exit status used to be 4 */ - } - - allocated_size = size; - -#ifdef SO_RCVBUF - if (0 <= fd) - { - int isize = size < INT_MAX ? size : INT_MAX; - while (setsockopt (fd, SOL_SOCKET, SO_RCVBUF, - (char *) &isize, sizeof isize) - && 1024 < isize) - isize >>= 1; - } -#endif -} - -/* Decode OFLAG_STRING, which represents the 2nd argument to `open'. - OFLAG_STRING should contain an optional integer, followed by an optional - symbolic representation of an open flag using only '|' to separate its - components (e.g. "O_WRONLY|O_CREAT|O_TRUNC"). Prefer the symbolic - representation if available, falling back on the numeric - representation, or to zero if both formats are absent. - - This function should be the inverse of encode_oflag. The numeric - representation is not portable from one host to another, but it is - for backward compatibility with old-fashioned clients that do not - emit symbolic open flags. */ - -static int -decode_oflag (char const *oflag_string) -{ - char *oflag_num_end; - int numeric_oflag = strtol (oflag_string, &oflag_num_end, 10); - int symbolic_oflag = 0; - - oflag_string = oflag_num_end; - while (ISSPACE ((unsigned char) *oflag_string)) - oflag_string++; - - do - { - struct name_value_pair { char const *name; int value; }; - static struct name_value_pair const table[] = - { -#ifdef O_APPEND - {"APPEND", O_APPEND}, -#endif - {"CREAT", O_CREAT}, -#ifdef O_DSYNC - {"DSYNC", O_DSYNC}, -#endif - {"EXCL", O_EXCL}, -#ifdef O_LARGEFILE - {"LARGEFILE", O_LARGEFILE}, /* LFS extension for opening large files */ -#endif -#ifdef O_NOCTTY - {"NOCTTY", O_NOCTTY}, -#endif -#if O_NONBLOCK - {"NONBLOCK", O_NONBLOCK}, -#endif - {"RDONLY", O_RDONLY}, - {"RDWR", O_RDWR}, -#ifdef O_RSYNC - {"RSYNC", O_RSYNC}, -#endif -#ifdef O_SYNC - {"SYNC", O_SYNC}, -#endif - {"TRUNC", O_TRUNC}, - {"WRONLY", O_WRONLY} - }; - struct name_value_pair const *t; - size_t s; - - if (*oflag_string++ != 'O' || *oflag_string++ != '_') - return numeric_oflag; - - for (t = table; - (strncmp (oflag_string, t->name, s = strlen (t->name)) != 0 - || (oflag_string[s] - && strchr ("ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789", - oflag_string[s]))); - t++) - if (t == table + sizeof table / sizeof *table - 1) - return numeric_oflag; - - symbolic_oflag |= t->value; - oflag_string += s; - } - while (*oflag_string++ == '|'); - - return symbolic_oflag; -} - -static struct option const long_opts[] = -{ - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'v'}, - {0, 0, 0, 0} -}; - -/* In-line localization is used only if --help or --version are - locally used. Otherwise, the localization burden lies with tar. */ -static void -i18n_setup () -{ - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -} - -static void usage (int) __attribute__ ((noreturn)); - -static void -usage (int status) -{ - i18n_setup (); - - if (status != EXIT_SUCCESS) - fprintf (stderr, _("Try `%s --help' for more information.\n"), - program_name); - else - { - printf (_("\ -Usage: %s [OPTION]\n\ -Manipulate a tape drive, accepting commands from a remote process.\n\ -\n\ - --version Output version info.\n\ - --help Output this help.\n"), - program_name); - printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); - close_stdout (); - } - - exit (status); -} - -static void -respond (long int status) -{ - DEBUG1 ("rmtd: A %ld\n", status); - - sprintf (reply_buffer, "A%ld\n", status); - full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); -} - - - -static void -open_device (void) -{ - char *device_string = get_string (); - char *oflag_string = get_string (); - - DEBUG2 ("rmtd: O %s %s\n", device_string, oflag_string); - - if (tape >= 0) - close (tape); - - tape = open (device_string, decode_oflag (oflag_string), MODE_RW); - if (tape < 0) - report_numbered_error (errno); - else - respond (0); - free_string (device_string); - free_string (oflag_string); -} - -static void -close_device (void) -{ - free_string (get_string ()); /* discard */ - DEBUG ("rmtd: C\n"); - - if (close (tape) < 0) - report_numbered_error (errno); - else - { - tape = -1; - respond (0); - } -} - -static void -lseek_device (void) -{ - char count_string[STRING_SIZE]; - char position_string[STRING_SIZE]; - off_t count = 0; - int negative; - int whence; - char *p; - - get_string_n (count_string); - get_string_n (position_string); - DEBUG2 ("rmtd: L %s %s\n", count_string, position_string); - - /* Parse count_string, taking care to check for overflow. - We can't use standard functions, - since off_t might be longer than long. */ - - for (p = count_string; *p == ' ' || *p == '\t'; p++) - ; - - negative = *p == '-'; - p += negative || *p == '+'; - - for (; *p; p++) - { - int digit = *p - '0'; - if (9 < (unsigned) digit) - { - report_error_message (N_("Seek offset error")); - exit (EXIT_FAILURE); - } - else - { - off_t c10 = 10 * count; - off_t nc = negative ? c10 - digit : c10 + digit; - if (c10 / 10 != count || (negative ? c10 < nc : nc < c10)) - { - report_error_message (N_("Seek offset out of range")); - exit (EXIT_FAILURE); - } - count = nc; - } - } - - switch (get_long (position_string)) - { - case 0: - whence = SEEK_SET; - break; - - case 1: - whence = SEEK_CUR; - break; - - case 2: - whence = SEEK_END; - break; - - default: - report_error_message (N_("Seek direction out of range")); - exit (EXIT_FAILURE); - } - - count = lseek (tape, count, whence); - if (count < 0) - report_numbered_error (errno); - else - { - /* Convert count back to string for reply. - We can't use sprintf, since off_t might be longer - than long. */ - p = count_string + sizeof count_string; - *--p = '\0'; - do - *--p = '0' + (int) (count % 10); - while ((count /= 10) != 0); - - DEBUG1 ("rmtd: A %s\n", p); - - sprintf (reply_buffer, "A%s\n", p); - full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); - } -} - -static void -write_device (void) -{ - char count_string[STRING_SIZE]; - size_t size; - size_t counter; - size_t status = 0; - - get_string_n (count_string); - size = get_long (count_string); - DEBUG1 ("rmtd: W %s\n", count_string); - - prepare_input_buffer (STDIN_FILENO, size); - for (counter = 0; counter < size; counter += status) - { - status = safe_read (STDIN_FILENO, &record_buffer[counter], - size - counter); - if (status == SAFE_READ_ERROR || status == 0) - { - DEBUG (_("rmtd: Premature eof\n")); - - report_error_message (N_("Premature end of file")); - exit (EXIT_FAILURE); /* exit status used to be 2 */ - } - } - status = full_write (tape, record_buffer, size); - if (status != size) - report_numbered_error (errno); - else - respond (status); -} - -static void -read_device (void) -{ - char count_string[STRING_SIZE]; - size_t size; - size_t status; - - get_string_n (count_string); - DEBUG1 ("rmtd: R %s\n", count_string); - - size = get_long (count_string); - prepare_input_buffer (-1, size); - status = safe_read (tape, record_buffer, size); - if (status == SAFE_READ_ERROR) - report_numbered_error (errno); - else - { - sprintf (reply_buffer, "A%lu\n", (unsigned long int) status); - full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer)); - full_write (STDOUT_FILENO, record_buffer, status); - } -} - -static void -mtioctop (void) -{ - char operation_string[STRING_SIZE]; - char count_string[STRING_SIZE]; - - get_string_n (operation_string); - get_string_n (count_string); - DEBUG2 ("rmtd: I %s %s\n", operation_string, count_string); - -#ifdef MTIOCTOP - { - struct mtop mtop; - const char *p; - off_t count = 0; - int negative; - - /* Parse count_string, taking care to check for overflow. - We can't use standard functions, - since off_t might be longer than long. */ - - for (p = count_string; *p == ' ' || *p == '\t'; p++) - ; - - negative = *p == '-'; - p += negative || *p == '+'; - - for (;;) - { - int digit = *p++ - '0'; - if (9 < (unsigned) digit) - break; - else - { - off_t c10 = 10 * count; - off_t nc = negative ? c10 - digit : c10 + digit; - if (c10 / 10 != count - || (negative ? c10 < nc : nc < c10)) - { - report_error_message (N_("Seek offset out of range")); - exit (EXIT_FAILURE); - } - count = nc; - } - } - - mtop.mt_count = count; - if (mtop.mt_count != count) - { - report_error_message (N_("Seek offset out of range")); - exit (EXIT_FAILURE); - } - mtop.mt_op = get_long (operation_string); - - if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0) - { - report_numbered_error (errno); - return; - } - } -#endif - respond (0); -} - -static void -status_device (void) -{ - DEBUG ("rmtd: S\n"); - -#ifdef MTIOCGET - { - struct mtget operation; - - if (ioctl (tape, MTIOCGET, (char *) &operation) < 0) - report_numbered_error (errno); - else - { - respond (sizeof operation); - full_write (STDOUT_FILENO, (char *) &operation, sizeof operation); - } - } -#endif -} - -int -main (int argc, char **argv) -{ - char command; - - program_name = argv[0]; - - obstack_init (&string_stk); - - switch (getopt_long (argc, argv, "", long_opts, NULL)) - { - default: - usage (EXIT_FAILURE); - - case 'h': - usage (EXIT_SUCCESS); - - case 'v': - i18n_setup (); - version_etc (stdout, "rmt", PACKAGE_NAME, PACKAGE_VERSION, - "John Gilmore", "Jay Fenlason", (char *) NULL); - close_stdout (); - return EXIT_SUCCESS; - - case -1: - break; - } - - if (optind < argc) - { - if (optind != argc - 1) - usage (EXIT_FAILURE); - debug_file = fopen (argv[optind], "w"); - if (debug_file == 0) - { - report_numbered_error (errno); - return EXIT_FAILURE; - } - setbuf (debug_file, 0); - } - - while (1) - { - errno = 0; - - if (safe_read (STDIN_FILENO, &command, 1) != 1) - return EXIT_SUCCESS; - - switch (command) - { - case 'O': - open_device (); - break; - - case 'C': - close_device (); - break; - - case 'L': - lseek_device (); - break; - - case 'W': - write_device (); - break; - - case 'R': - read_device (); - break; - - case 'I': - mtioctop (); - break; - - case 'S': - status_device (); - break; - - default: - DEBUG1 ("rmtd: Garbage command %c\n", command); - report_error_message (N_("Garbage command")); - return EXIT_FAILURE; /* exit status used to be 3 */ - } - } -} diff --git a/src/bin/tar/src/Jamfile b/src/bin/tar/src/Jamfile deleted file mode 100644 index 8a57060e92..0000000000 --- a/src/bin/tar/src/Jamfile +++ /dev/null @@ -1,30 +0,0 @@ -SubDir HAIKU_TOP src bin tar src ; - -SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) lib ] ; -SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; -SubDirSysHdrs [ FDirName $(SUBDIR) ] ; - -# set some additional defines -SubDirCcFlags -DHAVE_CONFIG_H -w -DLOCALEDIR=\'\"/etc/locale\"\' -DDEFAULT_RMT_COMMAND=\'\"/bin/rmt\"\' ; - -local tar_rsrc = [ FGristFiles tar.rsrc ] ; -ResComp $(tar_rsrc) : [ FGristFiles tar.rdef ] ; - -BinCommand tar : - buffer.c - compare.c - create.c - delete.c - extract.c - xheader.c - incremen.c - list.c - misc.c - names.c - sparse.c - system.c - tar.c - transform.c - update.c - utf8.c - : libtar.a : tar.rsrc ; diff --git a/src/bin/tar/src/arith.h b/src/bin/tar/src/arith.h deleted file mode 100644 index bcd1c0a2f4..0000000000 --- a/src/bin/tar/src/arith.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Long integers, for GNU tar. - Copyright 1999, 2007 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Handle large integers for calculating big tape lengths and the - like. In practice, double precision does for now. On the vast - majority of machines, it counts up to 2**52 bytes without any loss - of information, and counts up to 2**62 bytes if data are always - blocked in 1 kB boundaries. We'll need arbitrary precision - arithmetic anyway once we get into the 2**64 range, so there's no - point doing anything fancy before then. */ - -#define TARLONG_FORMAT "%.0f" -typedef double tarlong; diff --git a/src/bin/tar/src/buffer.c b/src/bin/tar/src/buffer.c deleted file mode 100644 index f99dcca1b2..0000000000 --- a/src/bin/tar/src/buffer.c +++ /dev/null @@ -1,1700 +0,0 @@ -/* Buffer management for tar. - - Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - Written by John Gilmore, on 1985-08-25. - - 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include - -#include - -#include -#include -#include -#include - -#include "common.h" -#include - -/* Number of retries before giving up on read. */ -#define READ_ERROR_MAX 10 - -/* Globbing pattern to append to volume label if initial match failed. */ -#define VOLUME_LABEL_APPEND " Volume [1-9]*" - -/* Variables. */ - -static tarlong prev_written; /* bytes written on previous volumes */ -static tarlong bytes_written; /* bytes written on this volume */ -static void *record_buffer[2]; /* allocated memory */ -union block *record_buffer_aligned[2]; -static int record_index; - -/* FIXME: The following variables should ideally be static to this - module. However, this cannot be done yet. The cleanup continues! */ - -union block *record_start; /* start of record of archive */ -union block *record_end; /* last+1 block of archive record */ -union block *current_block; /* current block of archive */ -enum access_mode access_mode; /* how do we handle the archive */ -off_t records_read; /* number of records read from this archive */ -off_t records_written; /* likewise, for records written */ -extern off_t records_skipped; /* number of records skipped at the start - of the archive, defined in delete.c */ - -static off_t record_start_block; /* block ordinal at record_start */ - -/* Where we write list messages (not errors, not interactions) to. */ -FILE *stdlis; - -static void backspace_output (void); - -/* PID of child program, if compress_option or remote archive access. */ -static pid_t child_pid; - -/* Error recovery stuff */ -static int read_error_count; - -/* Have we hit EOF yet? */ -static bool hit_eof; - -/* Checkpointing counter */ -static unsigned checkpoint; - -static bool read_full_records = false; - -/* We're reading, but we just read the last block and it's time to update. - Declared in update.c - - As least EXTERN like this one as possible. (?? --gray) - FIXME: Either eliminate it or move it to common.h. -*/ -extern bool time_to_start_writing; - -bool write_archive_to_stdout; - -void (*flush_write_ptr) (size_t); -void (*flush_read_ptr) (void); - - -char *volume_label; -char *continued_file_name; -uintmax_t continued_file_size; -uintmax_t continued_file_offset; - - -static int volno = 1; /* which volume of a multi-volume tape we're - on */ -static int global_volno = 1; /* volume number to print in external - messages */ - -bool write_archive_to_stdout; - -/* Used by flush_read and flush_write to store the real info about saved - names. */ -static char *real_s_name; -static off_t real_s_totsize; -static off_t real_s_sizeleft; - - -/* Multi-volume tracking support */ -static char *save_name; /* name of the file we are currently writing */ -static off_t save_totsize; /* total size of file we are writing, only - valid if save_name is nonzero */ -static off_t save_sizeleft; /* where we are in the file we are writing, - only valid if save_name is nonzero */ - - -static struct tar_stat_info dummy; - -void -buffer_write_global_xheader () -{ - xheader_write_global (&dummy.xhdr); -} - -void -mv_begin (struct tar_stat_info *st) -{ - if (multi_volume_option) - { - assign_string (&save_name, st->orig_file_name); - save_totsize = save_sizeleft = st->stat.st_size; - } -} - -void -mv_end () -{ - if (multi_volume_option) - assign_string (&save_name, 0); -} - -void -mv_total_size (off_t size) -{ - save_totsize = size; -} - -void -mv_size_left (off_t size) -{ - save_sizeleft = size; -} - - -/* Functions. */ - -void -clear_read_error_count (void) -{ - read_error_count = 0; -} - - -/* Time-related functions */ - -double duration; - -void -set_start_time () -{ - gettime (&start_time); - volume_start_time = start_time; - last_stat_time = start_time; -} - -void -set_volume_start_time () -{ - gettime (&volume_start_time); - last_stat_time = volume_start_time; -} - -void -compute_duration () -{ - struct timespec now; - gettime (&now); - duration += ((now.tv_sec - last_stat_time.tv_sec) - + (now.tv_nsec - last_stat_time.tv_nsec) / 1e9); - gettime (&last_stat_time); -} - - -/* Compression detection */ - -enum compress_type { - ct_none, - ct_compress, - ct_gzip, - ct_bzip2 -}; - -struct zip_magic -{ - enum compress_type type; - size_t length; - char *magic; - char *program; - char *option; -}; - -static struct zip_magic const magic[] = { - { ct_none, }, - { ct_compress, 2, "\037\235", "compress", "-Z" }, - { ct_gzip, 2, "\037\213", "gzip", "-z" }, - { ct_bzip2, 3, "BZh", "bzip2", "-j" }, -}; - -#define NMAGIC (sizeof(magic)/sizeof(magic[0])) - -#define compress_option(t) magic[t].option -#define compress_program(t) magic[t].program - -/* Check if the file ARCHIVE is a compressed archive. */ -enum compress_type -check_compressed_archive () -{ - struct zip_magic const *p; - bool sfr; - bool short_file = false; - - /* Prepare global data needed for find_next_block: */ - record_end = record_start; /* set up for 1st record = # 0 */ - sfr = read_full_records; - read_full_records = true; /* Suppress fatal error on reading a partial - record */ - if (find_next_block () == 0) - short_file = true; - - /* Restore global values */ - read_full_records = sfr; - - if (tar_checksum (record_start, true) == HEADER_SUCCESS) - /* Probably a valid header */ - return ct_none; - - for (p = magic + 1; p < magic + NMAGIC; p++) - if (memcmp (record_start->buffer, p->magic, p->length) == 0) - return p->type; - - if (short_file) - ERROR ((0, 0, _("This does not look like a tar archive"))); - - return ct_none; -} - -/* Open an archive named archive_name_array[0]. Detect if it is - a compressed archive of known type and use corresponding decompression - program if so */ -int -open_compressed_archive () -{ - archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY, - MODE_RW, rsh_command_option); - if (archive == -1) - return archive; - - if (!multi_volume_option) - { - enum compress_type type = check_compressed_archive (); - - if (type == ct_none) - return archive; - - /* FD is not needed any more */ - rmtclose (archive); - - hit_eof = false; /* It might have been set by find_next_block in - check_compressed_archive */ - - /* Open compressed archive */ - use_compress_program_option = compress_program (type); - child_pid = sys_child_open_for_uncompress (); - read_full_records = true; - } - - records_read = 0; - record_end = record_start; /* set up for 1st record = # 0 */ - - return archive; -} - - -static void -print_stats (FILE *fp, const char *text, tarlong numbytes) -{ - char bytes[sizeof (tarlong) * CHAR_BIT]; - char abbr[LONGEST_HUMAN_READABLE + 1]; - char rate[LONGEST_HUMAN_READABLE + 1]; - - int human_opts = human_autoscale | human_base_1024 | human_SI | human_B; - - sprintf (bytes, TARLONG_FORMAT, numbytes); - - fprintf (fp, "%s: %s (%s, %s/s)\n", - text, bytes, - human_readable (numbytes, abbr, human_opts, 1, 1), - (0 < duration && numbytes / duration < (uintmax_t) -1 - ? human_readable (numbytes / duration, rate, human_opts, 1, 1) - : "?")); -} - -void -print_total_stats () -{ - switch (subcommand_option) - { - case CREATE_SUBCOMMAND: - case CAT_SUBCOMMAND: - case UPDATE_SUBCOMMAND: - case APPEND_SUBCOMMAND: - /* Amanda 2.4.1p1 looks for "Total bytes written: [0-9][0-9]*". */ - print_stats (stderr, _("Total bytes written"), - prev_written + bytes_written); - break; - - case DELETE_SUBCOMMAND: - { - char buf[UINTMAX_STRSIZE_BOUND]; - print_stats (stderr, _("Total bytes read"), - records_read * record_size); - print_stats (stderr, _("Total bytes written"), - prev_written + bytes_written); - fprintf (stderr, _("Total bytes deleted: %s\n"), - STRINGIFY_BIGINT ((records_read - records_skipped) - * record_size - - (prev_written + bytes_written), buf)); - } - break; - - case EXTRACT_SUBCOMMAND: - case LIST_SUBCOMMAND: - case DIFF_SUBCOMMAND: - print_stats (stderr, _("Total bytes read"), - records_read * record_size); - break; - - default: - abort (); - } -} - -/* Compute and return the block ordinal at current_block. */ -off_t -current_block_ordinal (void) -{ - return record_start_block + (current_block - record_start); -} - -/* If the EOF flag is set, reset it, as well as current_block, etc. */ -void -reset_eof (void) -{ - if (hit_eof) - { - hit_eof = false; - current_block = record_start; - record_end = record_start + blocking_factor; - access_mode = ACCESS_WRITE; - } -} - -/* Return the location of the next available input or output block. - Return zero for EOF. Once we have returned zero, we just keep returning - it, to avoid accidentally going on to the next file on the tape. */ -union block * -find_next_block (void) -{ - if (current_block == record_end) - { - if (hit_eof) - return 0; - flush_archive (); - if (current_block == record_end) - { - hit_eof = true; - return 0; - } - } - return current_block; -} - -/* Indicate that we have used all blocks up thru BLOCK. */ -void -set_next_block_after (union block *block) -{ - while (block >= current_block) - current_block++; - - /* Do *not* flush the archive here. If we do, the same argument to - set_next_block_after could mean the next block (if the input record - is exactly one block long), which is not what is intended. */ - - if (current_block > record_end) - abort (); -} - -/* Return the number of bytes comprising the space between POINTER - through the end of the current buffer of blocks. This space is - available for filling with data, or taking data from. POINTER is - usually (but not always) the result of previous find_next_block call. */ -size_t -available_space_after (union block *pointer) -{ - return record_end->buffer - pointer->buffer; -} - -/* Close file having descriptor FD, and abort if close unsuccessful. */ -void -xclose (int fd) -{ - if (close (fd) != 0) - close_error (_("(pipe)")); -} - -static void -init_buffer () -{ - if (! record_buffer_aligned[record_index]) - record_buffer_aligned[record_index] = - page_aligned_alloc (&record_buffer[record_index], record_size); - - record_start = record_buffer_aligned[record_index]; - current_block = record_start; - record_end = record_start + blocking_factor; -} - -/* Open an archive file. The argument specifies whether we are - reading or writing, or both. */ -static void -_open_archive (enum access_mode wanted_access) -{ - int backed_up_flag = 0; - - if (record_size == 0) - FATAL_ERROR ((0, 0, _("Invalid value for record_size"))); - - if (archive_names == 0) - FATAL_ERROR ((0, 0, _("No archive name given"))); - - tar_stat_destroy (¤t_stat_info); - save_name = 0; - real_s_name = 0; - - record_index = 0; - init_buffer (); - - /* When updating the archive, we start with reading. */ - access_mode = wanted_access == ACCESS_UPDATE ? ACCESS_READ : wanted_access; - - read_full_records = read_full_records_option; - - records_read = 0; - - if (use_compress_program_option) - { - switch (wanted_access) - { - case ACCESS_READ: - child_pid = sys_child_open_for_uncompress (); - read_full_records = true; - record_end = record_start; /* set up for 1st record = # 0 */ - break; - - case ACCESS_WRITE: - child_pid = sys_child_open_for_compress (); - break; - - case ACCESS_UPDATE: - abort (); /* Should not happen */ - break; - } - - if (!index_file_name - && wanted_access == ACCESS_WRITE - && strcmp (archive_name_array[0], "-") == 0) - stdlis = stderr; - } - else if (strcmp (archive_name_array[0], "-") == 0) - { - read_full_records = true; /* could be a pipe, be safe */ - if (verify_option) - FATAL_ERROR ((0, 0, _("Cannot verify stdin/stdout archive"))); - - switch (wanted_access) - { - case ACCESS_READ: - { - enum compress_type type; - - archive = STDIN_FILENO; - - type = check_compressed_archive (); - if (type != ct_none) - FATAL_ERROR ((0, 0, - _("Archive is compressed. Use %s option"), - compress_option (type))); - } - break; - - case ACCESS_WRITE: - archive = STDOUT_FILENO; - if (!index_file_name) - stdlis = stderr; - break; - - case ACCESS_UPDATE: - archive = STDIN_FILENO; - write_archive_to_stdout = true; - record_end = record_start; /* set up for 1st record = # 0 */ - if (!index_file_name) - stdlis = stderr; - break; - } - } - else if (verify_option) - archive = rmtopen (archive_name_array[0], O_RDWR | O_CREAT | O_BINARY, - MODE_RW, rsh_command_option); - else - switch (wanted_access) - { - case ACCESS_READ: - archive = open_compressed_archive (); - break; - - case ACCESS_WRITE: - if (backup_option) - { - maybe_backup_file (archive_name_array[0], 1); - backed_up_flag = 1; - } - archive = rmtcreat (archive_name_array[0], MODE_RW, - rsh_command_option); - break; - - case ACCESS_UPDATE: - archive = rmtopen (archive_name_array[0], - O_RDWR | O_CREAT | O_BINARY, - MODE_RW, rsh_command_option); - - if (check_compressed_archive () != ct_none) - FATAL_ERROR ((0, 0, - _("Cannot update compressed archives"))); - break; - } - - if (archive < 0 - || (! _isrmt (archive) && !sys_get_archive_stat ())) - { - int saved_errno = errno; - - if (backed_up_flag) - undo_last_backup (); - errno = saved_errno; - open_fatal (archive_name_array[0]); - } - - sys_detect_dev_null_output (); - sys_save_archive_dev_ino (); - SET_BINARY_MODE (archive); - - switch (wanted_access) - { - case ACCESS_READ: - find_next_block (); /* read it in, check for EOF */ - break; - - case ACCESS_UPDATE: - case ACCESS_WRITE: - records_written = 0; - break; - } -} - -static void -do_checkpoint (bool do_write) -{ - if (checkpoint_option && !(++checkpoint % checkpoint_option)) - { - switch (checkpoint_style) - { - case checkpoint_dot: - fputc ('.', stdlis); - fflush (stdlis); - break; - - case checkpoint_text: - if (do_write) - /* TRANSLATORS: This is a ``checkpoint of write operation'', - *not* ``Writing a checkpoint''. - E.g. in Spanish ``Punto de comprobaci@'on de escritura'', - *not* ``Escribiendo un punto de comprobaci@'on'' */ - WARN ((0, 0, _("Write checkpoint %u"), checkpoint)); - else - /* TRANSLATORS: This is a ``checkpoint of read operation'', - *not* ``Reading a checkpoint''. - E.g. in Spanish ``Punto de comprobaci@'on de lectura'', - *not* ``Leyendo un punto de comprobaci@'on'' */ - WARN ((0, 0, _("Read checkpoint %u"), checkpoint)); - break; - } - } -} - -/* Perform a write to flush the buffer. */ -ssize_t -_flush_write (void) -{ - ssize_t status; - - do_checkpoint (true); - if (tape_length_option && tape_length_option <= bytes_written) - { - errno = ENOSPC; - status = 0; - } - else if (dev_null_output) - status = record_size; - else - status = sys_write_archive_buffer (); - - return status; -} - -/* Handle write errors on the archive. Write errors are always fatal. - Hitting the end of a volume does not cause a write error unless the - write was the first record of the volume. */ -void -archive_write_error (ssize_t status) -{ - /* It might be useful to know how much was written before the error - occurred. */ - if (totals_option) - { - int e = errno; - print_total_stats (); - errno = e; - } - - write_fatal_details (*archive_name_cursor, status, record_size); -} - -/* Handle read errors on the archive. If the read should be retried, - return to the caller. */ -void -archive_read_error (void) -{ - read_error (*archive_name_cursor); - - if (record_start_block == 0) - FATAL_ERROR ((0, 0, _("At beginning of tape, quitting now"))); - - /* Read error in mid archive. We retry up to READ_ERROR_MAX times and - then give up on reading the archive. */ - - if (read_error_count++ > READ_ERROR_MAX) - FATAL_ERROR ((0, 0, _("Too many errors, quitting"))); - return; -} - -static void -short_read (size_t status) -{ - size_t left; /* bytes left */ - char *more; /* pointer to next byte to read */ - - more = record_start->buffer + status; - left = record_size - status; - - while (left % BLOCKSIZE != 0 - || (left && status && read_full_records)) - { - if (status) - while ((status = rmtread (archive, more, left)) == SAFE_READ_ERROR) - archive_read_error (); - - if (status == 0) - break; - - if (! read_full_records) - { - unsigned long rest = record_size - left; - - FATAL_ERROR ((0, 0, - ngettext ("Unaligned block (%lu byte) in archive", - "Unaligned block (%lu bytes) in archive", - rest), - rest)); - } - - /* User warned us about this. Fix up. */ - - left -= status; - more += status; - } - - /* FIXME: for size=0, multi-volume support. On the first record, warn - about the problem. */ - - if (!read_full_records && verbose_option > 1 - && record_start_block == 0 && status != 0) - { - unsigned long rsize = (record_size - left) / BLOCKSIZE; - WARN ((0, 0, - ngettext ("Record size = %lu block", - "Record size = %lu blocks", - rsize), - rsize)); - } - - record_end = record_start + (record_size - left) / BLOCKSIZE; - records_read++; -} - -/* Flush the current buffer to/from the archive. */ -void -flush_archive (void) -{ - size_t buffer_level = current_block->buffer - record_start->buffer; - record_start_block += record_end - record_start; - current_block = record_start; - record_end = record_start + blocking_factor; - - if (access_mode == ACCESS_READ && time_to_start_writing) - { - access_mode = ACCESS_WRITE; - time_to_start_writing = false; - backspace_output (); - } - - switch (access_mode) - { - case ACCESS_READ: - flush_read (); - break; - - case ACCESS_WRITE: - flush_write_ptr (buffer_level); - break; - - case ACCESS_UPDATE: - abort (); - } -} - -/* Backspace the archive descriptor by one record worth. If it's a - tape, MTIOCTOP will work. If it's something else, try to seek on - it. If we can't seek, we lose! */ -static void -backspace_output (void) -{ -#ifdef MTIOCTOP - { - struct mtop operation; - - operation.mt_op = MTBSR; - operation.mt_count = 1; - if (rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0) - return; - if (errno == EIO && rmtioctl (archive, MTIOCTOP, (char *) &operation) >= 0) - return; - } -#endif - - { - off_t position = rmtlseek (archive, (off_t) 0, SEEK_CUR); - - /* Seek back to the beginning of this record and start writing there. */ - - position -= record_size; - if (position < 0) - position = 0; - if (rmtlseek (archive, position, SEEK_SET) != position) - { - /* Lseek failed. Try a different method. */ - - WARN ((0, 0, - _("Cannot backspace archive file; it may be unreadable without -i"))); - - /* Replace the first part of the record with NULs. */ - - if (record_start->buffer != output_start) - memset (record_start->buffer, 0, - output_start - record_start->buffer); - } - } -} - -off_t -seek_archive (off_t size) -{ - off_t start = current_block_ordinal (); - off_t offset; - off_t nrec, nblk; - off_t skipped = (blocking_factor - (current_block - record_start)); - - size -= skipped * BLOCKSIZE; - - if (size < record_size) - return 0; - /* FIXME: flush? */ - - /* Compute number of records to skip */ - nrec = size / record_size; - offset = rmtlseek (archive, nrec * record_size, SEEK_CUR); - if (offset < 0) - return offset; - - if (offset % record_size) - FATAL_ERROR ((0, 0, _("rmtlseek not stopped at a record boundary"))); - - /* Convert to number of records */ - offset /= BLOCKSIZE; - /* Compute number of skipped blocks */ - nblk = offset - start; - - /* Update buffering info */ - records_read += nblk / blocking_factor; - record_start_block = offset - blocking_factor; - current_block = record_end; - - return nblk; -} - -/* Close the archive file. */ -void -close_archive (void) -{ - if (time_to_start_writing || access_mode == ACCESS_WRITE) - { - flush_archive (); - if (current_block > record_start) - flush_archive (); - } - - sys_drain_input_pipe (); - - compute_duration (); - if (verify_option) - verify_volume (); - - if (rmtclose (archive) != 0) - close_warn (*archive_name_cursor); - - sys_wait_for_child (child_pid); - - tar_stat_destroy (¤t_stat_info); - if (save_name) - free (save_name); - if (real_s_name) - free (real_s_name); - free (record_buffer[0]); - free (record_buffer[1]); -} - -/* Called to initialize the global volume number. */ -void -init_volume_number (void) -{ - FILE *file = fopen (volno_file_option, "r"); - - if (file) - { - if (fscanf (file, "%d", &global_volno) != 1 - || global_volno < 0) - FATAL_ERROR ((0, 0, _("%s: contains invalid volume number"), - quotearg_colon (volno_file_option))); - if (ferror (file)) - read_error (volno_file_option); - if (fclose (file) != 0) - close_error (volno_file_option); - } - else if (errno != ENOENT) - open_error (volno_file_option); -} - -/* Called to write out the closing global volume number. */ -void -closeout_volume_number (void) -{ - FILE *file = fopen (volno_file_option, "w"); - - if (file) - { - fprintf (file, "%d\n", global_volno); - if (ferror (file)) - write_error (volno_file_option); - if (fclose (file) != 0) - close_error (volno_file_option); - } - else - open_error (volno_file_option); -} - - -static void -increase_volume_number () -{ - global_volno++; - if (global_volno < 0) - FATAL_ERROR ((0, 0, _("Volume number overflow"))); - volno++; -} - -void -change_tape_menu (FILE *read_file) -{ - char *input_buffer = NULL; - size_t size = 0; - bool stop = false; - - while (!stop) - { - fputc ('\007', stderr); - fprintf (stderr, - _("Prepare volume #%d for %s and hit return: "), - global_volno + 1, quote (*archive_name_cursor)); - fflush (stderr); - - if (getline (&input_buffer, &size, read_file) <= 0) - { - WARN ((0, 0, _("EOF where user reply was expected"))); - - if (subcommand_option != EXTRACT_SUBCOMMAND - && subcommand_option != LIST_SUBCOMMAND - && subcommand_option != DIFF_SUBCOMMAND) - WARN ((0, 0, _("WARNING: Archive is incomplete"))); - - fatal_exit (); - } - - if (input_buffer[0] == '\n' - || input_buffer[0] == 'y' - || input_buffer[0] == 'Y') - break; - - switch (input_buffer[0]) - { - case '?': - { - fprintf (stderr, _("\ - n name Give a new file name for the next (and subsequent) volume(s)\n\ - q Abort tar\n\ - y or newline Continue operation\n")); - if (!restrict_option) - fprintf (stderr, _(" ! Spawn a subshell\n")); - fprintf (stderr, _(" ? Print this list\n")); - } - break; - - case 'q': - /* Quit. */ - - WARN ((0, 0, _("No new volume; exiting.\n"))); - - if (subcommand_option != EXTRACT_SUBCOMMAND - && subcommand_option != LIST_SUBCOMMAND - && subcommand_option != DIFF_SUBCOMMAND) - WARN ((0, 0, _("WARNING: Archive is incomplete"))); - - fatal_exit (); - - case 'n': - /* Get new file name. */ - - { - char *name; - char *cursor; - - for (name = input_buffer + 1; - *name == ' ' || *name == '\t'; - name++) - ; - - for (cursor = name; *cursor && *cursor != '\n'; cursor++) - ; - *cursor = '\0'; - - if (name[0]) - { - /* FIXME: the following allocation is never reclaimed. */ - *archive_name_cursor = xstrdup (name); - stop = true; - } - else - fprintf (stderr, "%s", - _("File name not specified. Try again.\n")); - } - break; - - case '!': - if (!restrict_option) - { - sys_spawn_shell (); - break; - } - /* FALL THROUGH */ - - default: - fprintf (stderr, _("Invalid input. Type ? for help.\n")); - } - } - free (input_buffer); -} - -/* We've hit the end of the old volume. Close it and open the next one. - Return nonzero on success. -*/ -static bool -new_volume (enum access_mode mode) -{ - static FILE *read_file; - static int looped; - int prompt; - - if (!read_file && !info_script_option) - /* FIXME: if fopen is used, it will never be closed. */ - read_file = archive == STDIN_FILENO ? fopen (TTY_NAME, "r") : stdin; - - if (now_verifying) - return false; - if (verify_option) - verify_volume (); - - assign_string (&volume_label, NULL); - assign_string (&continued_file_name, NULL); - continued_file_size = continued_file_offset = 0; - current_block = record_start; - - if (rmtclose (archive) != 0) - close_warn (*archive_name_cursor); - - archive_name_cursor++; - if (archive_name_cursor == archive_name_array + archive_names) - { - archive_name_cursor = archive_name_array; - looped = 1; - } - prompt = looped; - - tryagain: - if (prompt) - { - /* We have to prompt from now on. */ - - if (info_script_option) - { - if (volno_file_option) - closeout_volume_number (); - if (sys_exec_info_script (archive_name_cursor, global_volno+1)) - FATAL_ERROR ((0, 0, _("%s command failed"), - quote (info_script_option))); - } - else - change_tape_menu (read_file); - } - - if (strcmp (archive_name_cursor[0], "-") == 0) - { - read_full_records = true; - archive = STDIN_FILENO; - } - else if (verify_option) - archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW, - rsh_command_option); - else - switch (mode) - { - case ACCESS_READ: - archive = rmtopen (*archive_name_cursor, O_RDONLY, MODE_RW, - rsh_command_option); - break; - - case ACCESS_WRITE: - if (backup_option) - maybe_backup_file (*archive_name_cursor, 1); - archive = rmtcreat (*archive_name_cursor, MODE_RW, - rsh_command_option); - break; - - case ACCESS_UPDATE: - archive = rmtopen (*archive_name_cursor, O_RDWR | O_CREAT, MODE_RW, - rsh_command_option); - break; - } - - if (archive < 0) - { - open_warn (*archive_name_cursor); - if (!verify_option && mode == ACCESS_WRITE && backup_option) - undo_last_backup (); - prompt = 1; - goto tryagain; - } - - SET_BINARY_MODE (archive); - - return true; -} - -static bool -read_header0 (struct tar_stat_info *info) -{ - enum read_header rc; - - tar_stat_init (info); - rc = read_header_primitive (false, info); - if (rc == HEADER_SUCCESS) - { - set_next_block_after (current_header); - return true; - } - ERROR ((0, 0, _("This does not look like a tar archive"))); - return false; -} - -bool -try_new_volume () -{ - size_t status; - union block *header; - enum access_mode acc; - - switch (subcommand_option) - { - case APPEND_SUBCOMMAND: - case CAT_SUBCOMMAND: - case UPDATE_SUBCOMMAND: - acc = ACCESS_UPDATE; - break; - - default: - acc = ACCESS_READ; - break; - } - - if (!new_volume (acc)) - return true; - - while ((status = rmtread (archive, record_start->buffer, record_size)) - == SAFE_READ_ERROR) - archive_read_error (); - - if (status != record_size) - short_read (status); - - header = find_next_block (); - if (!header) - return false; - - switch (header->header.typeflag) - { - case XGLTYPE: - { - if (!read_header0 (&dummy)) - return false; - xheader_decode (&dummy); /* decodes values from the global header */ - tar_stat_destroy (&dummy); - if (!real_s_name) - { - /* We have read the extended header of the first member in - this volume. Put it back, so next read_header works as - expected. */ - current_block = record_start; - } - break; - } - - case GNUTYPE_VOLHDR: - if (!read_header0 (&dummy)) - return false; - tar_stat_destroy (&dummy); - assign_string (&volume_label, current_header->header.name); - set_next_block_after (header); - header = find_next_block (); - if (header->header.typeflag != GNUTYPE_MULTIVOL) - break; - /* FALL THROUGH */ - - case GNUTYPE_MULTIVOL: - if (!read_header0 (&dummy)) - return false; - tar_stat_destroy (&dummy); - assign_string (&continued_file_name, current_header->header.name); - continued_file_size = - UINTMAX_FROM_HEADER (current_header->header.size); - continued_file_offset = - UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset); - break; - - default: - break; - } - - if (real_s_name) - { - uintmax_t s; - if (!continued_file_name - || strcmp (continued_file_name, real_s_name)) - { - if ((archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT) - && strlen (real_s_name) >= NAME_FIELD_SIZE - && strncmp (continued_file_name, real_s_name, - NAME_FIELD_SIZE) == 0) - WARN ((0, 0, - _("%s is possibly continued on this volume: header contains truncated name"), - quote (real_s_name))); - else - { - WARN ((0, 0, _("%s is not continued on this volume"), - quote (real_s_name))); - return false; - } - } - - s = continued_file_size + continued_file_offset; - - if (real_s_totsize != s || s < continued_file_offset) - { - char totsizebuf[UINTMAX_STRSIZE_BOUND]; - char s1buf[UINTMAX_STRSIZE_BOUND]; - char s2buf[UINTMAX_STRSIZE_BOUND]; - - WARN ((0, 0, _("%s is the wrong size (%s != %s + %s)"), - quote (continued_file_name), - STRINGIFY_BIGINT (save_totsize, totsizebuf), - STRINGIFY_BIGINT (continued_file_size, s1buf), - STRINGIFY_BIGINT (continued_file_offset, s2buf))); - return false; - } - - if (real_s_totsize - real_s_sizeleft != continued_file_offset) - { - WARN ((0, 0, _("This volume is out of sequence"))); - return false; - } - } - - increase_volume_number (); - return true; -} - - -/* Check the LABEL block against the volume label, seen as a globbing - pattern. Return true if the pattern matches. In case of failure, - retry matching a volume sequence number before giving up in - multi-volume mode. */ -static bool -check_label_pattern (union block *label) -{ - char *string; - bool result; - - if (! memchr (label->header.name, '\0', sizeof label->header.name)) - return false; - - if (fnmatch (volume_label_option, label->header.name, 0) == 0) - return true; - - if (!multi_volume_option) - return false; - - string = xmalloc (strlen (volume_label_option) - + sizeof VOLUME_LABEL_APPEND + 1); - strcpy (string, volume_label_option); - strcat (string, VOLUME_LABEL_APPEND); - result = fnmatch (string, label->header.name, 0) == 0; - free (string); - return result; -} - -/* Check if the next block contains a volume label and if this matches - the one given in the command line */ -static void -match_volume_label (void) -{ - union block *label = find_next_block (); - - if (!label) - FATAL_ERROR ((0, 0, _("Archive not labeled to match %s"), - quote (volume_label_option))); - if (!check_label_pattern (label)) - FATAL_ERROR ((0, 0, _("Volume %s does not match %s"), - quote_n (0, label->header.name), - quote_n (1, volume_label_option))); -} - -/* Mark the archive with volume label STR. */ -static void -_write_volume_label (const char *str) -{ - if (archive_format == POSIX_FORMAT) - xheader_store ("GNU.volume.label", &dummy, str); - else - { - union block *label = find_next_block (); - - memset (label, 0, BLOCKSIZE); - - strcpy (label->header.name, volume_label_option); - assign_string (¤t_stat_info.file_name, - label->header.name); - current_stat_info.had_trailing_slash = - strip_trailing_slashes (current_stat_info.file_name); - - label->header.typeflag = GNUTYPE_VOLHDR; - TIME_TO_CHARS (start_time.tv_sec, label->header.mtime); - finish_header (¤t_stat_info, label, -1); - set_next_block_after (label); - } -} - -#define VOL_SUFFIX "Volume" - -/* Add a volume label to a part of multi-volume archive */ -static void -add_volume_label (void) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - char *p = STRINGIFY_BIGINT (volno, buf); - char *s = xmalloc (strlen (volume_label_option) + sizeof VOL_SUFFIX - + strlen (p) + 2); - sprintf (s, "%s %s %s", volume_label_option, VOL_SUFFIX, p); - _write_volume_label (s); - free (s); -} - -static void -add_chunk_header () -{ - if (archive_format == POSIX_FORMAT) - { - off_t block_ordinal; - union block *blk; - struct tar_stat_info st; - static size_t real_s_part_no; /* FIXME */ - - real_s_part_no++; - memset (&st, 0, sizeof st); - st.orig_file_name = st.file_name = real_s_name; - st.stat.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; - st.stat.st_uid = getuid (); - st.stat.st_gid = getgid (); - st.orig_file_name = xheader_format_name (&st, - "%d/GNUFileParts.%p/%f.%n", - real_s_part_no); - st.file_name = st.orig_file_name; - st.archive_file_size = st.stat.st_size = real_s_sizeleft; - - block_ordinal = current_block_ordinal (); - blk = start_header (&st); - if (!blk) - abort (); /* FIXME */ - finish_header (&st, blk, block_ordinal); - free (st.orig_file_name); - } -} - - -/* Add a volume label to the current archive */ -static void -write_volume_label (void) -{ - if (multi_volume_option) - add_volume_label (); - else - _write_volume_label (volume_label_option); -} - -/* Write GNU multi-volume header */ -static void -gnu_add_multi_volume_header (void) -{ - int tmp; - union block *block = find_next_block (); - - if (strlen (real_s_name) > NAME_FIELD_SIZE) - WARN ((0, 0, - _("%s: file name too long to be stored in a GNU multivolume header, truncated"), - quotearg_colon (real_s_name))); - - memset (block, 0, BLOCKSIZE); - - /* FIXME: Michael P Urban writes: [a long name file] is being written - when a new volume rolls around [...] Looks like the wrong value is - being preserved in real_s_name, though. */ - - strncpy (block->header.name, real_s_name, NAME_FIELD_SIZE); - block->header.typeflag = GNUTYPE_MULTIVOL; - - OFF_TO_CHARS (real_s_sizeleft, block->header.size); - OFF_TO_CHARS (real_s_totsize - real_s_sizeleft, - block->oldgnu_header.offset); - - tmp = verbose_option; - verbose_option = 0; - finish_header (¤t_stat_info, block, -1); - verbose_option = tmp; - set_next_block_after (block); -} - -/* Add a multi volume header to the current archive. The exact header format - depends on the archive format. */ -static void -add_multi_volume_header (void) -{ - if (archive_format == POSIX_FORMAT) - { - off_t d = real_s_totsize - real_s_sizeleft; - xheader_store ("GNU.volume.filename", &dummy, real_s_name); - xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft); - xheader_store ("GNU.volume.offset", &dummy, &d); - } - else - gnu_add_multi_volume_header (); -} - -/* Synchronize multi-volume globals */ -static void -multi_volume_sync () -{ - if (multi_volume_option) - { - if (save_name) - { - assign_string (&real_s_name, - safer_name_suffix (save_name, false, - absolute_names_option)); - real_s_totsize = save_totsize; - real_s_sizeleft = save_sizeleft; - } - else - { - assign_string (&real_s_name, 0); - real_s_totsize = 0; - real_s_sizeleft = 0; - } - } -} - - -/* Low-level flush functions */ - -/* Simple flush read (no multi-volume or label extensions) */ -static void -simple_flush_read (void) -{ - size_t status; /* result from system call */ - - do_checkpoint (false); - - /* Clear the count of errors. This only applies to a single call to - flush_read. */ - - read_error_count = 0; /* clear error count */ - - if (write_archive_to_stdout && record_start_block != 0) - { - archive = STDOUT_FILENO; - status = sys_write_archive_buffer (); - archive = STDIN_FILENO; - if (status != record_size) - archive_write_error (status); - } - - for (;;) - { - status = rmtread (archive, record_start->buffer, record_size); - if (status == record_size) - { - records_read++; - return; - } - if (status == SAFE_READ_ERROR) - { - archive_read_error (); - continue; /* try again */ - } - break; - } - short_read (status); -} - -/* Simple flush write (no multi-volume or label extensions) */ -static void -simple_flush_write (size_t level __attribute__((unused))) -{ - ssize_t status; - - status = _flush_write (); - if (status != record_size) - archive_write_error (status); - else - { - records_written++; - bytes_written += status; - } -} - - -/* GNU flush functions. These support multi-volume and archive labels in - GNU and PAX archive formats. */ - -static void -_gnu_flush_read (void) -{ - size_t status; /* result from system call */ - - do_checkpoint (false); - - /* Clear the count of errors. This only applies to a single call to - flush_read. */ - - read_error_count = 0; /* clear error count */ - - if (write_archive_to_stdout && record_start_block != 0) - { - archive = STDOUT_FILENO; - status = sys_write_archive_buffer (); - archive = STDIN_FILENO; - if (status != record_size) - archive_write_error (status); - } - - multi_volume_sync (); - - for (;;) - { - status = rmtread (archive, record_start->buffer, record_size); - if (status == record_size) - { - records_read++; - return; - } - - /* The condition below used to include - || (status > 0 && !read_full_records) - This is incorrect since even if new_volume() succeeds, the - subsequent call to rmtread will overwrite the chunk of data - already read in the buffer, so the processing will fail */ - if ((status == 0 - || (status == SAFE_READ_ERROR && errno == ENOSPC)) - && multi_volume_option) - { - while (!try_new_volume ()) - ; - return; - } - else if (status == SAFE_READ_ERROR) - { - archive_read_error (); - continue; - } - break; - } - short_read (status); -} - -static void -gnu_flush_read (void) -{ - flush_read_ptr = simple_flush_read; /* Avoid recursion */ - _gnu_flush_read (); - flush_read_ptr = gnu_flush_read; -} - -static void -_gnu_flush_write (size_t buffer_level) -{ - ssize_t status; - union block *header; - char *copy_ptr; - size_t copy_size; - size_t bufsize; - - status = _flush_write (); - if (status != record_size && !multi_volume_option) - archive_write_error (status); - else - { - records_written++; - bytes_written += status; - } - - if (status == record_size) - { - multi_volume_sync (); - return; - } - - /* In multi-volume mode. */ - /* ENXIO is for the UNIX PC. */ - if (status < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO) - archive_write_error (status); - - if (!new_volume (ACCESS_WRITE)) - return; - - tar_stat_destroy (&dummy); - - increase_volume_number (); - prev_written += bytes_written; - bytes_written = 0; - - copy_ptr = record_start->buffer + status; - copy_size = buffer_level - status; - /* Switch to the next buffer */ - record_index = !record_index; - init_buffer (); - - if (volume_label_option) - add_volume_label (); - - if (real_s_name) - add_multi_volume_header (); - - write_extended (true, &dummy, find_next_block ()); - tar_stat_destroy (&dummy); - - if (real_s_name) - add_chunk_header (); - header = find_next_block (); - bufsize = available_space_after (header); - while (bufsize < copy_size) - { - memcpy (header->buffer, copy_ptr, bufsize); - copy_ptr += bufsize; - copy_size -= bufsize; - set_next_block_after (header + (bufsize - 1) / BLOCKSIZE); - header = find_next_block (); - bufsize = available_space_after (header); - } - memcpy (header->buffer, copy_ptr, copy_size); - memset (header->buffer + copy_size, 0, bufsize - copy_size); - set_next_block_after (header + (copy_size - 1) / BLOCKSIZE); - find_next_block (); -} - -static void -gnu_flush_write (size_t buffer_level) -{ - flush_write_ptr = simple_flush_write; /* Avoid recursion */ - _gnu_flush_write (buffer_level); - flush_write_ptr = gnu_flush_write; -} - -void -flush_read () -{ - flush_read_ptr (); -} - -void -flush_write () -{ - flush_write_ptr (record_size); -} - -void -open_archive (enum access_mode wanted_access) -{ - flush_read_ptr = gnu_flush_read; - flush_write_ptr = gnu_flush_write; - - _open_archive (wanted_access); - switch (wanted_access) - { - case ACCESS_READ: - if (volume_label_option) - match_volume_label (); - break; - - case ACCESS_WRITE: - records_written = 0; - if (volume_label_option) - write_volume_label (); - break; - - default: - break; - } - set_volume_start_time (); -} diff --git a/src/bin/tar/src/common.h b/src/bin/tar/src/common.h deleted file mode 100644 index b158a373b0..0000000000 --- a/src/bin/tar/src/common.h +++ /dev/null @@ -1,742 +0,0 @@ -/* Common declarations for the tar program. - - Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Declare the GNU tar archive format. */ -#include "tar.h" - -/* The checksum field is filled with this while the checksum is computed. */ -#define CHKBLANKS " " /* 8 blanks, no null */ - -/* Some constants from POSIX are given names. */ -#define NAME_FIELD_SIZE 100 -#define PREFIX_FIELD_SIZE 155 -#define UNAME_FIELD_SIZE 32 -#define GNAME_FIELD_SIZE 32 - - - -/* Some various global definitions. */ - -/* Name of file to use for interacting with user. */ - -/* GLOBAL is defined to empty in tar.c only, and left alone in other *.c - modules. Here, we merely set it to "extern" if it is not already set. - GNU tar does depend on the system loader to preset all GLOBAL variables to - neutral (or zero) values, explicit initialization is usually not done. */ -#ifndef GLOBAL -# define GLOBAL extern -#endif - -#define TAREXIT_SUCCESS PAXEXIT_SUCCESS -#define TAREXIT_DIFFERS PAXEXIT_DIFFERS -#define TAREXIT_FAILURE PAXEXIT_FAILURE - - -#include "arith.h" -#include -#include -#include -#include -#include -#include -#include -#include -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free -#include - -#include - -/* Log base 2 of common values. */ -#define LG_8 3 -#define LG_64 6 -#define LG_256 8 - -/* Information gleaned from the command line. */ - -/* Name of this program. */ -GLOBAL const char *program_name; - -/* Main command option. */ - -enum subcommand -{ - UNKNOWN_SUBCOMMAND, /* none of the following */ - APPEND_SUBCOMMAND, /* -r */ - CAT_SUBCOMMAND, /* -A */ - CREATE_SUBCOMMAND, /* -c */ - DELETE_SUBCOMMAND, /* -D */ - DIFF_SUBCOMMAND, /* -d */ - EXTRACT_SUBCOMMAND, /* -x */ - LIST_SUBCOMMAND, /* -t */ - UPDATE_SUBCOMMAND /* -u */ -}; - -GLOBAL enum subcommand subcommand_option; - -/* Selected format for output archive. */ -GLOBAL enum archive_format archive_format; - -/* Either NL or NUL, as decided by the --null option. */ -GLOBAL char filename_terminator; - -/* Size of each record, once in blocks, once in bytes. Those two variables - are always related, the second being BLOCKSIZE times the first. They do - not have _option in their name, even if their values is derived from - option decoding, as these are especially important in tar. */ -GLOBAL int blocking_factor; -GLOBAL size_t record_size; - -GLOBAL bool absolute_names_option; - -/* Display file times in UTC */ -GLOBAL bool utc_option; - -/* This variable tells how to interpret newer_mtime_option, below. If zero, - files get archived if their mtime is not less than newer_mtime_option. - If nonzero, files get archived if *either* their ctime or mtime is not less - than newer_mtime_option. */ -GLOBAL int after_date_option; - -enum atime_preserve -{ - no_atime_preserve, - replace_atime_preserve, - system_atime_preserve -}; -GLOBAL enum atime_preserve atime_preserve_option; - -GLOBAL bool backup_option; - -/* Type of backups being made. */ -GLOBAL enum backup_type backup_type; - -GLOBAL bool block_number_option; - -GLOBAL unsigned checkpoint_option; - -enum checkpoint_style - { - checkpoint_text, - checkpoint_dot - }; - -GLOBAL enum checkpoint_style checkpoint_style; - -/* Specified name of compression program, or "gzip" as implied by -z. */ -GLOBAL const char *use_compress_program_option; - -GLOBAL bool dereference_option; - -/* Print a message if not all links are dumped */ -GLOBAL int check_links_option; - -/* Patterns that match file names to be excluded. */ -GLOBAL struct exclude *excluded; - -enum exclusion_tag_type - { - exclusion_tag_none, - /* Exclude the directory contents, but preserve the directory - itself and the exclusion tag file */ - exclusion_tag_contents, - /* Exclude everything below the directory, preserving the directory - itself */ - exclusion_tag_under, - /* Exclude entire directory */ - exclusion_tag_all, - }; - -/* Specified value to be put into tar file in place of stat () results, or - just -1 if such an override should not take place. */ -GLOBAL gid_t group_option; - -GLOBAL bool ignore_failed_read_option; - -GLOBAL bool ignore_zeros_option; - -GLOBAL bool incremental_option; - -/* Specified name of script to run at end of each tape change. */ -GLOBAL const char *info_script_option; - -GLOBAL bool interactive_option; - -/* If nonzero, extract only Nth occurrence of each named file */ -GLOBAL uintmax_t occurrence_option; - -enum old_files -{ - DEFAULT_OLD_FILES, /* default */ - NO_OVERWRITE_DIR_OLD_FILES, /* --no-overwrite-dir */ - OVERWRITE_OLD_FILES, /* --overwrite */ - UNLINK_FIRST_OLD_FILES, /* --unlink-first */ - KEEP_OLD_FILES, /* --keep-old-files */ - KEEP_NEWER_FILES /* --keep-newer-files */ -}; -GLOBAL enum old_files old_files_option; - -/* Specified file name for incremental list. */ -GLOBAL const char *listed_incremental_option; - -/* Specified mode change string. */ -GLOBAL struct mode_change *mode_option; - -/* Initial umask, if needed for mode change string. */ -GLOBAL mode_t initial_umask; - -GLOBAL bool multi_volume_option; - -/* Specified threshold date and time. Files having an older time stamp - do not get archived (also see after_date_option above). */ -GLOBAL struct timespec newer_mtime_option; - -/* If true, override actual mtime (see below) */ -GLOBAL bool set_mtime_option; -/* Value to be put in mtime header field instead of the actual mtime */ -GLOBAL struct timespec mtime_option; - -/* Return true if newer_mtime_option is initialized. */ -#define NEWER_OPTION_INITIALIZED(opt) (0 <= (opt).tv_nsec) - -/* Return true if the struct stat ST's M time is less than - newer_mtime_option. */ -#define OLDER_STAT_TIME(st, m) \ - (timespec_cmp (get_stat_##m##time (&(st)), newer_mtime_option) < 0) - -/* Likewise, for struct tar_stat_info ST. */ -#define OLDER_TAR_STAT_TIME(st, m) \ - (timespec_cmp ((st).m##time, newer_mtime_option) < 0) - -/* Zero if there is no recursion, otherwise FNM_LEADING_DIR. */ -GLOBAL int recursion_option; - -GLOBAL bool numeric_owner_option; - -GLOBAL bool one_file_system_option; - -/* Specified value to be put into tar file in place of stat () results, or - just -1 if such an override should not take place. */ -GLOBAL uid_t owner_option; - -GLOBAL bool recursive_unlink_option; - -GLOBAL bool read_full_records_option; - -GLOBAL bool remove_files_option; - -/* Specified rmt command. */ -GLOBAL const char *rmt_command_option; - -/* Specified remote shell command. */ -GLOBAL const char *rsh_command_option; - -GLOBAL bool same_order_option; - -/* If positive, preserve ownership when extracting. */ -GLOBAL int same_owner_option; - -/* If positive, preserve permissions when extracting. */ -GLOBAL int same_permissions_option; - -/* When set, strip the given number of file name components from the file name - before extracting */ -GLOBAL size_t strip_name_components; - -GLOBAL bool show_omitted_dirs_option; - -GLOBAL bool sparse_option; -GLOBAL unsigned tar_sparse_major; -GLOBAL unsigned tar_sparse_minor; - -GLOBAL bool starting_file_option; - -/* Specified maximum byte length of each tape volume (multiple of 1024). */ -GLOBAL tarlong tape_length_option; - -GLOBAL bool to_stdout_option; - -GLOBAL bool totals_option; - -GLOBAL bool touch_option; - -GLOBAL char *to_command_option; -GLOBAL bool ignore_command_error_option; - -/* Restrict some potentially harmful tar options */ -GLOBAL bool restrict_option; - -/* Return true if the extracted files are not being written to disk */ -#define EXTRACT_OVER_PIPE (to_stdout_option || to_command_option) - -/* Count how many times the option has been set, multiple setting yields - more verbose behavior. Value 0 means no verbosity, 1 means file name - only, 2 means file name and all attributes. More than 2 is just like 2. */ -GLOBAL int verbose_option; - -GLOBAL bool verify_option; - -/* Specified name of file containing the volume number. */ -GLOBAL const char *volno_file_option; - -/* Specified value or pattern. */ -GLOBAL const char *volume_label_option; - -/* Other global variables. */ - -/* File descriptor for archive file. */ -GLOBAL int archive; - -/* Nonzero when outputting to /dev/null. */ -GLOBAL bool dev_null_output; - -/* Timestamps: */ -GLOBAL struct timespec start_time; /* when we started execution */ -GLOBAL struct timespec volume_start_time; /* when the current volume was - opened*/ -GLOBAL struct timespec last_stat_time; /* when the statistics was last - computed */ - -GLOBAL struct tar_stat_info current_stat_info; - -/* List of tape drive names, number of such tape drives, allocated number, - and current cursor in list. */ -GLOBAL const char **archive_name_array; -GLOBAL size_t archive_names; -GLOBAL size_t allocated_archive_names; -GLOBAL const char **archive_name_cursor; - -/* Output index file name. */ -GLOBAL char const *index_file_name; - -/* Structure for keeping track of filenames and lists thereof. */ -struct name - { - struct name *next; /* Link to the next element */ - int change_dir; /* Number of the directory to change to. - Set with the -C option. */ - uintmax_t found_count; /* number of times a matching file has - been found */ - int matching_flags; /* this name is a regexp, not literal */ - char const *dir_contents; /* for incremental_option */ - - size_t length; /* cached strlen(name) */ - char name[1]; - }; - -/* Obnoxious test to see if dimwit is trying to dump the archive. */ -GLOBAL dev_t ar_dev; -GLOBAL ino_t ar_ino; - -GLOBAL bool seekable_archive; - -GLOBAL dev_t root_device; - -/* Unquote filenames */ -GLOBAL bool unquote_option; - -GLOBAL bool test_label_option; /* Test archive volume label and exit */ - -/* Show file or archive names after transformation. - In particular, when creating archive in verbose mode, list member names - as stored in the archive */ -GLOBAL bool show_transformed_names_option; - -/* Delay setting modification times and permissions of extracted directories - until the end of extraction. This variable helps correctly restore directory - timestamps from archives with an unusual member order. It is automatically - set for incremental archives. */ -GLOBAL bool delay_directory_restore_option; - -/* Warn about implicit use of the wildcards in command line arguments. - (Default for tar prior to 1.15.91, but changed afterwards */ -GLOBAL bool warn_regex_usage; - -/* Declarations for each module. */ - -/* FIXME: compare.c should not directly handle the following variable, - instead, this should be done in buffer.c only. */ - -enum access_mode -{ - ACCESS_READ, - ACCESS_WRITE, - ACCESS_UPDATE -}; -extern enum access_mode access_mode; - -/* Module buffer.c. */ - -extern FILE *stdlis; -extern bool write_archive_to_stdout; -extern char *volume_label; -extern char *continued_file_name; -extern uintmax_t continued_file_size; -extern uintmax_t continued_file_offset; - -size_t available_space_after (union block *pointer); -off_t current_block_ordinal (void); -void close_archive (void); -void closeout_volume_number (void); -void compute_duration (void); -union block *find_next_block (void); -void flush_read (void); -void flush_write (void); -void flush_archive (void); -void init_volume_number (void); -void open_archive (enum access_mode mode); -void print_total_stats (void); -void reset_eof (void); -void set_next_block_after (union block *block); -void clear_read_error_count (void); -void xclose (int fd); -void archive_write_error (ssize_t status) __attribute__ ((noreturn)); -void archive_read_error (void); -off_t seek_archive (off_t size); -void set_start_time (void); - -void mv_begin (struct tar_stat_info *st); -void mv_end (void); -void mv_total_size (off_t size); -void mv_size_left (off_t size); - -void buffer_write_global_xheader (void); - -/* Module create.c. */ - -enum dump_status - { - dump_status_ok, - dump_status_short, - dump_status_fail, - dump_status_not_implemented - }; - -void add_exclusion_tag (const char *name, enum exclusion_tag_type type, - bool (*)(const char*)); -bool cachedir_file_p (const char *name); - -bool file_dumpable_p (struct tar_stat_info *st); -void create_archive (void); -void pad_archive (off_t size_left); -void dump_file (const char *st, int top_level, dev_t parent_device); -union block *start_header (struct tar_stat_info *st); -void finish_header (struct tar_stat_info *st, union block *header, - off_t block_ordinal); -void simple_finish_header (union block *header); -union block * write_extended (bool global, struct tar_stat_info *st, - union block *old_header); -union block *start_private_header (const char *name, size_t size); -void write_eot (void); -void check_links (void); -void exclusion_tag_warning (const char *dirname, const char *tagname, - const char *message); -enum exclusion_tag_type check_exclusion_tags (char *dirname, - const char **tag_file_name); - -#define GID_TO_CHARS(val, where) gid_to_chars (val, where, sizeof (where)) -#define MAJOR_TO_CHARS(val, where) major_to_chars (val, where, sizeof (where)) -#define MINOR_TO_CHARS(val, where) minor_to_chars (val, where, sizeof (where)) -#define MODE_TO_CHARS(val, where) mode_to_chars (val, where, sizeof (where)) -#define OFF_TO_CHARS(val, where) off_to_chars (val, where, sizeof (where)) -#define SIZE_TO_CHARS(val, where) size_to_chars (val, where, sizeof (where)) -#define TIME_TO_CHARS(val, where) time_to_chars (val, where, sizeof (where)) -#define UID_TO_CHARS(val, where) uid_to_chars (val, where, sizeof (where)) -#define UINTMAX_TO_CHARS(val, where) uintmax_to_chars (val, where, sizeof (where)) -#define UNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf)) -#define GNAME_TO_CHARS(name,buf) string_to_chars (name, buf, sizeof(buf)) - -bool gid_to_chars (gid_t gid, char *buf, size_t size); -bool major_to_chars (major_t m, char *buf, size_t size); -bool minor_to_chars (minor_t m, char *buf, size_t size); -bool mode_to_chars (mode_t m, char *buf, size_t size); -bool off_to_chars (off_t off, char *buf, size_t size); -bool size_to_chars (size_t v, char *buf, size_t size); -bool time_to_chars (time_t t, char *buf, size_t size); -bool uid_to_chars (uid_t uid, char *buf, size_t size); -bool uintmax_to_chars (uintmax_t v, char *buf, size_t size); -void string_to_chars (char const *s, char *buf, size_t size); - -/* Module diffarch.c. */ - -extern bool now_verifying; - -void diff_archive (void); -void diff_init (void); -void verify_volume (void); - -/* Module extract.c. */ - -void extr_init (void); -void extract_archive (void); -void extract_finish (void); -bool rename_directory (char *src, char *dst); - -/* Module delete.c. */ - -void delete_archive_members (void); - -/* Module incremen.c. */ - -char *get_directory_contents (char *dir_name, dev_t device); -const char *append_incremental_renames (const char *dump); -void read_directory_file (void); -void write_directory_file (void); -void purge_directory (char const *directory_name); -void list_dumpdir (char *buffer, size_t size); -void update_parent_directory (const char *name); - -size_t dumpdir_size (const char *p); -bool is_dumpdir (struct tar_stat_info *stat_info); - -/* Module list.c. */ - -enum read_header -{ - HEADER_STILL_UNREAD, /* for when read_header has not been called */ - HEADER_SUCCESS, /* header successfully read and checksummed */ - HEADER_SUCCESS_EXTENDED, /* likewise, but we got an extended header */ - HEADER_ZERO_BLOCK, /* zero block where header expected */ - HEADER_END_OF_FILE, /* true end of file while header expected */ - HEADER_FAILURE /* ill-formed header, or bad checksum */ -}; - -extern union block *current_header; -extern enum archive_format current_format; -extern size_t recent_long_name_blocks; -extern size_t recent_long_link_blocks; - -void decode_header (union block *header, struct tar_stat_info *stat_info, - enum archive_format *format_pointer, int do_user_group); -char const *tartime (struct timespec t, bool full_time); - -#define GID_FROM_HEADER(where) gid_from_header (where, sizeof (where)) -#define MAJOR_FROM_HEADER(where) major_from_header (where, sizeof (where)) -#define MINOR_FROM_HEADER(where) minor_from_header (where, sizeof (where)) -#define MODE_FROM_HEADER(where) mode_from_header (where, sizeof (where)) -#define OFF_FROM_HEADER(where) off_from_header (where, sizeof (where)) -#define SIZE_FROM_HEADER(where) size_from_header (where, sizeof (where)) -#define TIME_FROM_HEADER(where) time_from_header (where, sizeof (where)) -#define UID_FROM_HEADER(where) uid_from_header (where, sizeof (where)) -#define UINTMAX_FROM_HEADER(where) uintmax_from_header (where, sizeof (where)) - -gid_t gid_from_header (const char *buf, size_t size); -major_t major_from_header (const char *buf, size_t size); -minor_t minor_from_header (const char *buf, size_t size); -mode_t mode_from_header (const char *buf, size_t size); -off_t off_from_header (const char *buf, size_t size); -size_t size_from_header (const char *buf, size_t size); -time_t time_from_header (const char *buf, size_t size); -uid_t uid_from_header (const char *buf, size_t size); -uintmax_t uintmax_from_header (const char * buf, size_t size); - -void list_archive (void); -void print_for_mkdir (char *dirname, int length, mode_t mode); -void print_header (struct tar_stat_info *st, off_t block_ordinal); -void read_and (void (*do_something) (void)); -enum read_header read_header_primitive (bool raw_extended_headers, - struct tar_stat_info *info); -enum read_header read_header (bool raw_extended_headers); -enum read_header tar_checksum (union block *header, bool silent); -void skip_file (off_t size); -void skip_member (void); - -/* Module misc.c. */ - -void assign_string (char **dest, const char *src); -char *quote_copy_string (const char *str); -int unquote_string (char *str); - -void code_ns_fraction (int ns, char *p); -char const *code_timespec (struct timespec ts, char *sbuf); -enum { BILLION = 1000000000, LOG10_BILLION = 9 }; -enum { TIMESPEC_STRSIZE_BOUND = - UINTMAX_STRSIZE_BOUND + LOG10_BILLION + sizeof "-." - 1 }; - -enum remove_option -{ - ORDINARY_REMOVE_OPTION, - RECURSIVE_REMOVE_OPTION, - - /* FIXME: The following value is never used. It seems to be intended - as a placeholder for a hypothetical option that should instruct tar - to recursively remove subdirectories in purge_directory(), - as opposed to the functionality of --recursive-unlink - (RECURSIVE_REMOVE_OPTION value), which removes them in - prepare_to_extract() phase. However, with the addition of more - meta-info to the incremental dumps, this should become unnecessary */ - WANT_DIRECTORY_REMOVE_OPTION -}; -int remove_any_file (const char *file_name, enum remove_option option); -bool maybe_backup_file (const char *file_name, bool this_is_the_archive); -void undo_last_backup (void); - -int deref_stat (bool deref, char const *name, struct stat *buf); - -int chdir_arg (char const *dir); -void chdir_do (int dir); - -void close_diag (char const *name); -void open_diag (char const *name); -void read_diag_details (char const *name, off_t offset, size_t size); -void readlink_diag (char const *name); -void savedir_diag (char const *name); -void seek_diag_details (char const *name, off_t offset); -void stat_diag (char const *name); -void write_error_details (char const *name, size_t status, size_t size); -void write_fatal (char const *name) __attribute__ ((noreturn)); -void write_fatal_details (char const *name, ssize_t status, size_t size) - __attribute__ ((noreturn)); - -pid_t xfork (void); -void xpipe (int fd[2]); - -void *page_aligned_alloc (void **ptr, size_t size); -int set_file_atime (int fd, char const *file, - struct timespec const timespec[2]); - -/* Module names.c. */ - -extern struct name *gnu_list_name; - -void gid_to_gname (gid_t gid, char **gname); -int gname_to_gid (char const *gname, gid_t *pgid); -void uid_to_uname (uid_t uid, char **uname); -int uname_to_uid (char const *uname, uid_t *puid); - -void name_init (void); -void name_add_name (const char *name, int matching_flags); -void name_add_dir (const char *name); -void name_term (void); -const char *name_next (int change_dirs); -void name_gather (void); -struct name *addname (char const *string, int change_dir); -bool name_match (const char *name); -void names_notfound (void); -void collect_and_sort_names (void); -struct name *name_scan (const char *name); -char *name_from_list (void); -void blank_name_list (void); -char *new_name (const char *dir_name, const char *name); -size_t stripped_prefix_len (char const *file_name, size_t num); -bool all_names_found (struct tar_stat_info *st); - -bool excluded_name (char const *name); - -void add_avoided_name (char const *name); -bool is_avoided_name (char const *name); -bool is_individual_file (char const *name); - -bool contains_dot_dot (char const *name); - -#define ISFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \ - (c)->found_count == occurrence_option) -#define WASFOUND(c) ((occurrence_option == 0) ? (c)->found_count : \ - (c)->found_count >= occurrence_option) - -/* Module tar.c. */ - -void usage (int); - -int confirm (const char *message_action, const char *name); -void request_stdin (const char *option); - -void tar_stat_init (struct tar_stat_info *st); -void tar_stat_destroy (struct tar_stat_info *st); -void usage (int) __attribute__ ((noreturn)); -int tar_timespec_cmp (struct timespec a, struct timespec b); -const char *archive_format_string (enum archive_format fmt); -const char *subcommand_string (enum subcommand c); - -/* Module update.c. */ - -extern char *output_start; - -void update_archive (void); - -/* Module xheader.c. */ - -void xheader_init (struct xheader *xhdr); -void xheader_decode (struct tar_stat_info *stat); -void xheader_decode_global (struct xheader *xhdr); -void xheader_store (char const *keyword, struct tar_stat_info *st, - void const *data); -void xheader_read (struct xheader *xhdr, union block *header, size_t size); -void xheader_write (char type, char *name, struct xheader *xhdr); -void xheader_write_global (struct xheader *xhdr); -void xheader_finish (struct xheader *hdr); -void xheader_destroy (struct xheader *hdr); -char *xheader_xhdr_name (struct tar_stat_info *st); -char *xheader_ghdr_name (void); -void xheader_set_option (char *string); -void xheader_string_begin (struct xheader *xhdr); -void xheader_string_add (struct xheader *xhdr, char const *s); -bool xheader_string_end (struct xheader *xhdr, char const *keyword); -bool xheader_keyword_deleted_p (const char *kw); -char *xheader_format_name (struct tar_stat_info *st, const char *fmt, - size_t n); - -/* Module system.c */ - -void sys_detect_dev_null_output (void); -void sys_save_archive_dev_ino (void); -void sys_drain_input_pipe (void); -void sys_wait_for_child (pid_t); -void sys_spawn_shell (void); -bool sys_compare_uid (struct stat *a, struct stat *b); -bool sys_compare_gid (struct stat *a, struct stat *b); -bool sys_file_is_archive (struct tar_stat_info *p); -bool sys_compare_links (struct stat *link_data, struct stat *stat_data); -int sys_truncate (int fd); -pid_t sys_child_open_for_compress (void); -pid_t sys_child_open_for_uncompress (void); -size_t sys_write_archive_buffer (void); -bool sys_get_archive_stat (void); -int sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st); -void sys_wait_command (void); -int sys_exec_info_script (const char **archive_name, int volume_number); - -/* Module compare.c */ -void report_difference (struct tar_stat_info *st, const char *message, ...); - -/* Module sparse.c */ -bool sparse_member_p (struct tar_stat_info *st); -bool sparse_fixup_header (struct tar_stat_info *st); -enum dump_status sparse_dump_file (int, struct tar_stat_info *st); -enum dump_status sparse_extract_file (int fd, struct tar_stat_info *st, - off_t *size); -enum dump_status sparse_skip_file (struct tar_stat_info *st); -bool sparse_diff_file (int, struct tar_stat_info *st); - -/* Module utf8.c */ -bool string_ascii_p (const char *str); -bool utf8_convert (bool to_utf, char const *input, char **output); - -/* Module transform.c */ -typedef enum - { - xform_regfile, - xform_link, - xform_symlink - } xform_type; - -void set_transform_expr (const char *expr); -bool transform_name (char **pinput); -bool transform_member_name (char **pinput, xform_type type); -bool transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *); diff --git a/src/bin/tar/src/compare.c b/src/bin/tar/src/compare.c deleted file mode 100644 index d0cf5f7d6c..0000000000 --- a/src/bin/tar/src/compare.c +++ /dev/null @@ -1,609 +0,0 @@ -/* Diff files from a tar archive. - - Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - Written by John Gilmore, on 1987-04-30. - - 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include - -#if HAVE_LINUX_FD_H -# include -#endif - -#include "common.h" -#include -#include -#include - -/* Nonzero if we are verifying at the moment. */ -bool now_verifying; - -/* File descriptor for the file we are diffing. */ -static int diff_handle; - -/* Area for reading file contents into. */ -static char *diff_buffer; - -/* Initialize for a diff operation. */ -void -diff_init (void) -{ - void *ptr; - diff_buffer = page_aligned_alloc (&ptr, record_size); - if (listed_incremental_option) - read_directory_file (); -} - -/* Sigh about something that differs by writing a MESSAGE to stdlis, - given MESSAGE is nonzero. Also set the exit status if not already. */ -void -report_difference (struct tar_stat_info *st, const char *fmt, ...) -{ - if (fmt) - { - va_list ap; - - fprintf (stdlis, "%s: ", quotearg_colon (st->file_name)); - va_start (ap, fmt); - vfprintf (stdlis, fmt, ap); - va_end (ap); - fprintf (stdlis, "\n"); - } - - if (exit_status == TAREXIT_SUCCESS) - exit_status = TAREXIT_DIFFERS; -} - -/* Take a buffer returned by read_and_process and do nothing with it. */ -static int -process_noop (size_t size __attribute__ ((unused)), - char *data __attribute__ ((unused))) -{ - return 1; -} - -static int -process_rawdata (size_t bytes, char *buffer) -{ - size_t status = safe_read (diff_handle, diff_buffer, bytes); - - if (status != bytes) - { - if (status == SAFE_READ_ERROR) - { - read_error (current_stat_info.file_name); - report_difference (¤t_stat_info, NULL); - } - else - { - report_difference (¤t_stat_info, - ngettext ("Could only read %lu of %lu byte", - "Could only read %lu of %lu bytes", - bytes), - (unsigned long) status, (unsigned long) bytes); - } - return 0; - } - - if (memcmp (buffer, diff_buffer, bytes)) - { - report_difference (¤t_stat_info, _("Contents differ")); - return 0; - } - - return 1; -} - -/* Some other routine wants SIZE bytes in the archive. For each chunk - of the archive, call PROCESSOR with the size of the chunk, and the - address of the chunk it can work with. The PROCESSOR should return - nonzero for success. Once it returns error, continue skipping - without calling PROCESSOR anymore. */ - -static void -read_and_process (struct tar_stat_info *st, int (*processor) (size_t, char *)) -{ - union block *data_block; - size_t data_size; - off_t size = st->stat.st_size; - - mv_begin (st); - while (size) - { - data_block = find_next_block (); - if (! data_block) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return; - } - - data_size = available_space_after (data_block); - if (data_size > size) - data_size = size; - if (!(*processor) (data_size, data_block->buffer)) - processor = process_noop; - set_next_block_after ((union block *) - (data_block->buffer + data_size - 1)); - size -= data_size; - mv_size_left (size); - } - mv_end (); -} - -/* Call either stat or lstat over STAT_DATA, depending on - --dereference (-h), for a file which should exist. Diagnose any - problem. Return nonzero for success, zero otherwise. */ -static int -get_stat_data (char const *file_name, struct stat *stat_data) -{ - int status = deref_stat (dereference_option, file_name, stat_data); - - if (status != 0) - { - if (errno == ENOENT) - stat_warn (file_name); - else - stat_error (file_name); - report_difference (¤t_stat_info, NULL); - return 0; - } - - return 1; -} - - -static void -diff_dir (void) -{ - struct stat stat_data; - - if (!get_stat_data (current_stat_info.file_name, &stat_data)) - return; - - if (!S_ISDIR (stat_data.st_mode)) - report_difference (¤t_stat_info, _("File type differs")); - else if ((current_stat_info.stat.st_mode & MODE_ALL) != - (stat_data.st_mode & MODE_ALL)) - report_difference (¤t_stat_info, _("Mode differs")); -} - -static void -diff_file (void) -{ - char const *file_name = current_stat_info.file_name; - struct stat stat_data; - - if (!get_stat_data (file_name, &stat_data)) - skip_member (); - else if (!S_ISREG (stat_data.st_mode)) - { - report_difference (¤t_stat_info, _("File type differs")); - skip_member (); - } - else - { - if ((current_stat_info.stat.st_mode & MODE_ALL) != - (stat_data.st_mode & MODE_ALL)) - report_difference (¤t_stat_info, _("Mode differs")); - - if (!sys_compare_uid (&stat_data, ¤t_stat_info.stat)) - report_difference (¤t_stat_info, _("Uid differs")); - if (!sys_compare_gid (&stat_data, ¤t_stat_info.stat)) - report_difference (¤t_stat_info, _("Gid differs")); - - if (tar_timespec_cmp (get_stat_mtime (&stat_data), - current_stat_info.mtime)) - report_difference (¤t_stat_info, _("Mod time differs")); - if (current_header->header.typeflag != GNUTYPE_SPARSE - && stat_data.st_size != current_stat_info.stat.st_size) - { - report_difference (¤t_stat_info, _("Size differs")); - skip_member (); - } - else - { - int atime_flag = - (atime_preserve_option == system_atime_preserve - ? O_NOATIME - : 0); - - diff_handle = open (file_name, O_RDONLY | O_BINARY | atime_flag); - - if (diff_handle < 0) - { - open_error (file_name); - skip_member (); - report_difference (¤t_stat_info, NULL); - } - else - { - int status; - - if (current_stat_info.is_sparse) - sparse_diff_file (diff_handle, ¤t_stat_info); - else - read_and_process (¤t_stat_info, process_rawdata); - - if (atime_preserve_option == replace_atime_preserve) - { - struct timespec ts[2]; - ts[0] = get_stat_atime (&stat_data); - ts[1] = get_stat_mtime (&stat_data); - if (set_file_atime (diff_handle, file_name, ts) != 0) - utime_error (file_name); - } - - status = close (diff_handle); - if (status != 0) - close_error (file_name); - } - } - } -} - -static void -diff_link (void) -{ - struct stat file_data; - struct stat link_data; - - if (get_stat_data (current_stat_info.file_name, &file_data) - && get_stat_data (current_stat_info.link_name, &link_data) - && !sys_compare_links (&file_data, &link_data)) - report_difference (¤t_stat_info, - _("Not linked to %s"), - quote (current_stat_info.link_name)); -} - -#ifdef HAVE_READLINK -static void -diff_symlink (void) -{ - size_t len = strlen (current_stat_info.link_name); - char *linkbuf = alloca (len + 1); - - int status = readlink (current_stat_info.file_name, linkbuf, len + 1); - - if (status < 0) - { - if (errno == ENOENT) - readlink_warn (current_stat_info.file_name); - else - readlink_error (current_stat_info.file_name); - report_difference (¤t_stat_info, NULL); - } - else if (status != len - || strncmp (current_stat_info.link_name, linkbuf, len) != 0) - report_difference (¤t_stat_info, _("Symlink differs")); -} -#endif - -static void -diff_special (void) -{ - struct stat stat_data; - - /* FIXME: deal with umask. */ - - if (!get_stat_data (current_stat_info.file_name, &stat_data)) - return; - - if (current_header->header.typeflag == CHRTYPE - ? !S_ISCHR (stat_data.st_mode) - : current_header->header.typeflag == BLKTYPE - ? !S_ISBLK (stat_data.st_mode) - : /* current_header->header.typeflag == FIFOTYPE */ - !S_ISFIFO (stat_data.st_mode)) - { - report_difference (¤t_stat_info, _("File type differs")); - return; - } - - if ((current_header->header.typeflag == CHRTYPE - || current_header->header.typeflag == BLKTYPE) - && current_stat_info.stat.st_rdev != stat_data.st_rdev) - { - report_difference (¤t_stat_info, _("Device number differs")); - return; - } - - if ((current_stat_info.stat.st_mode & MODE_ALL) != - (stat_data.st_mode & MODE_ALL)) - report_difference (¤t_stat_info, _("Mode differs")); -} - -static int -dumpdir_cmp (const char *a, const char *b) -{ - size_t len; - - while (*a) - switch (*a) - { - case 'Y': - case 'N': - if (!strchr ("YN", *b)) - return 1; - if (strcmp(a + 1, b + 1)) - return 1; - len = strlen (a) + 1; - a += len; - b += len; - break; - - case 'D': - if (strcmp(a, b)) - return 1; - len = strlen (a) + 1; - a += len; - b += len; - break; - - case 'R': - case 'T': - case 'X': - return *b; - } - return *b; -} - -static void -diff_dumpdir (void) -{ - char *dumpdir_buffer; - dev_t dev = 0; - struct stat stat_data; - - if (deref_stat (true, current_stat_info.file_name, &stat_data)) - { - if (errno == ENOENT) - stat_warn (current_stat_info.file_name); - else - stat_error (current_stat_info.file_name); - } - else - dev = stat_data.st_dev; - - dumpdir_buffer = get_directory_contents (current_stat_info.file_name, dev); - - if (dumpdir_buffer) - { - if (dumpdir_cmp (current_stat_info.dumpdir, dumpdir_buffer)) - report_difference (¤t_stat_info, _("Contents differ")); - } - else - read_and_process (¤t_stat_info, process_noop); -} - -static void -diff_multivol (void) -{ - struct stat stat_data; - int fd, status; - off_t offset; - - if (current_stat_info.had_trailing_slash) - { - diff_dir (); - return; - } - - if (!get_stat_data (current_stat_info.file_name, &stat_data)) - return; - - if (!S_ISREG (stat_data.st_mode)) - { - report_difference (¤t_stat_info, _("File type differs")); - skip_member (); - return; - } - - offset = OFF_FROM_HEADER (current_header->oldgnu_header.offset); - if (stat_data.st_size != current_stat_info.stat.st_size + offset) - { - report_difference (¤t_stat_info, _("Size differs")); - skip_member (); - return; - } - - fd = open (current_stat_info.file_name, O_RDONLY | O_BINARY); - - if (fd < 0) - { - open_error (current_stat_info.file_name); - report_difference (¤t_stat_info, NULL); - skip_member (); - return; - } - - if (lseek (fd, offset, SEEK_SET) < 0) - { - seek_error_details (current_stat_info.file_name, offset); - report_difference (¤t_stat_info, NULL); - return; - } - - read_and_process (¤t_stat_info, process_rawdata); - - status = close (fd); - if (status != 0) - close_error (current_stat_info.file_name); -} - -/* Diff a file against the archive. */ -void -diff_archive (void) -{ - - set_next_block_after (current_header); - decode_header (current_header, ¤t_stat_info, ¤t_format, 1); - - /* Print the block from current_header and current_stat_info. */ - - if (verbose_option) - { - if (now_verifying) - fprintf (stdlis, _("Verify ")); - print_header (¤t_stat_info, -1); - } - - switch (current_header->header.typeflag) - { - default: - ERROR ((0, 0, _("%s: Unknown file type `%c', diffed as normal file"), - quotearg_colon (current_stat_info.file_name), - current_header->header.typeflag)); - /* Fall through. */ - - case AREGTYPE: - case REGTYPE: - case GNUTYPE_SPARSE: - case CONTTYPE: - - /* Appears to be a file. See if it's really a directory. */ - - if (current_stat_info.had_trailing_slash) - diff_dir (); - else - diff_file (); - break; - - case LNKTYPE: - diff_link (); - break; - -#ifdef HAVE_READLINK - case SYMTYPE: - diff_symlink (); - break; -#endif - - case CHRTYPE: - case BLKTYPE: - case FIFOTYPE: - diff_special (); - break; - - case GNUTYPE_DUMPDIR: - case DIRTYPE: - if (is_dumpdir (¤t_stat_info)) - diff_dumpdir (); - diff_dir (); - break; - - case GNUTYPE_VOLHDR: - break; - - case GNUTYPE_MULTIVOL: - diff_multivol (); - } -} - -void -verify_volume (void) -{ - if (removed_prefixes_p ()) - { - WARN((0, 0, - _("Archive contains file names with leading prefixes removed."))); - WARN((0, 0, - _("Verification may fail to locate original files."))); - } - - if (!diff_buffer) - diff_init (); - - /* Verifying an archive is meant to check if the physical media got it - correctly, so try to defeat clever in-memory buffering pertaining to - this particular media. On Linux, for example, the floppy drive would - not even be accessed for the whole verification. - - The code was using fsync only when the ioctl is unavailable, but - Marty Leisner says that the ioctl does not work when not preceded by - fsync. So, until we know better, or maybe to please Marty, let's do it - the unbelievable way :-). */ - -#if HAVE_FSYNC - fsync (archive); -#endif -#ifdef FDFLUSH - ioctl (archive, FDFLUSH); -#endif - -#ifdef MTIOCTOP - { - struct mtop operation; - int status; - - operation.mt_op = MTBSF; - operation.mt_count = 1; - if (status = rmtioctl (archive, MTIOCTOP, (char *) &operation), status < 0) - { - if (errno != EIO - || (status = rmtioctl (archive, MTIOCTOP, (char *) &operation), - status < 0)) - { -#endif - if (rmtlseek (archive, (off_t) 0, SEEK_SET) != 0) - { - /* Lseek failed. Try a different method. */ - seek_warn (archive_name_array[0]); - return; - } -#ifdef MTIOCTOP - } - } - } -#endif - - access_mode = ACCESS_READ; - now_verifying = 1; - - flush_read (); - while (1) - { - enum read_header status = read_header (false); - - if (status == HEADER_FAILURE) - { - int counter = 0; - - do - { - counter++; - set_next_block_after (current_header); - status = read_header (false); - } - while (status == HEADER_FAILURE); - - ERROR ((0, 0, - ngettext ("VERIFY FAILURE: %d invalid header detected", - "VERIFY FAILURE: %d invalid headers detected", - counter), counter)); - } - if (status == HEADER_ZERO_BLOCK || status == HEADER_END_OF_FILE) - break; - - diff_archive (); - tar_stat_destroy (¤t_stat_info); - } - - access_mode = ACCESS_WRITE; - now_verifying = 0; -} diff --git a/src/bin/tar/src/create.c b/src/bin/tar/src/create.c deleted file mode 100644 index 7be10d27e6..0000000000 --- a/src/bin/tar/src/create.c +++ /dev/null @@ -1,1789 +0,0 @@ -/* Create a tar archive. - - Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - Written by John Gilmore, on 1985-08-25. - - 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include - -#include "common.h" -#include - -struct link - { - dev_t dev; - ino_t ino; - size_t nlink; - char name[1]; - }; - -struct exclusion_tag -{ - const char *name; - size_t length; - enum exclusion_tag_type type; - bool (*predicate) (const char *name); - struct exclusion_tag *next; -}; - -static struct exclusion_tag *exclusion_tags; - -void -add_exclusion_tag (const char *name, enum exclusion_tag_type type, - bool (*predicate) (const char *name)) -{ - struct exclusion_tag *tag = xmalloc (sizeof tag[0]); - tag->next = exclusion_tags; - tag->name = name; - tag->type = type; - tag->predicate = predicate; - tag->length = strlen (name); - exclusion_tags = tag; -} - -void -exclusion_tag_warning (const char *dirname, const char *tagname, - const char *message) -{ - if (verbose_option) - WARN ((0, 0, - _("%s: contains a cache directory tag %s; %s"), - quotearg_colon (dirname), - quotearg_n (1, tagname), - message)); -} - -enum exclusion_tag_type -check_exclusion_tags (char *dirname, const char **tag_file_name) -{ - static char *tagname; - static size_t tagsize; - struct exclusion_tag *tag; - size_t dlen = strlen (dirname); - int addslash = dirname[dlen-1] != '/'; - char *nptr = NULL; - - for (tag = exclusion_tags; tag; tag = tag->next) - { - size_t size = dlen + addslash + tag->length + 1; - if (size > tagsize) - { - tagsize = size; - tagname = xrealloc (tagname, tagsize); - } - - if (!nptr) - { - strcpy (tagname, dirname); - nptr = tagname + dlen; - if (addslash) - *nptr++ = '/'; - } - strcpy (nptr, tag->name); - if (access (tagname, F_OK) == 0 - && (!tag->predicate || tag->predicate (tagname))) - { - if (tag_file_name) - *tag_file_name = tag->name; - return tag->type; - } - } - - return exclusion_tag_none; -} - -/* Exclusion predicate to test if the named file (usually "CACHEDIR.TAG") - contains a valid header, as described at: - http://www.brynosaurus.com/cachedir - Applications can write this file into directories they create - for use as caches containing purely regenerable, non-precious data, - allowing us to avoid archiving them if --exclude-caches is specified. */ - -#define CACHEDIR_SIGNATURE "Signature: 8a477f597d28d172789f06886806bc55" -#define CACHEDIR_SIGNATURE_SIZE (sizeof CACHEDIR_SIGNATURE - 1) - -bool -cachedir_file_p (const char *name) -{ - bool tag_present = false; - int fd = open (name, O_RDONLY); - if (fd >= 0) - { - static char tagbuf[CACHEDIR_SIGNATURE_SIZE]; - - if (read (fd, tagbuf, CACHEDIR_SIGNATURE_SIZE) - == CACHEDIR_SIGNATURE_SIZE - && memcmp (tagbuf, CACHEDIR_SIGNATURE, CACHEDIR_SIGNATURE_SIZE) == 0) - tag_present = true; - - close (fd); - } - return tag_present; -} - - -/* The maximum uintmax_t value that can be represented with DIGITS digits, - assuming that each digit is BITS_PER_DIGIT wide. */ -#define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \ - ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \ - ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \ - : (uintmax_t) -1) - -/* The maximum uintmax_t value that can be represented with octal - digits and a trailing NUL in BUFFER. */ -#define MAX_OCTAL_VAL(buffer) MAX_VAL_WITH_DIGITS (sizeof (buffer) - 1, LG_8) - -/* Convert VALUE to an octal representation suitable for tar headers. - Output to buffer WHERE with size SIZE. - The result is undefined if SIZE is 0 or if VALUE is too large to fit. */ - -static void -to_octal (uintmax_t value, char *where, size_t size) -{ - uintmax_t v = value; - size_t i = size; - - do - { - where[--i] = '0' + (v & ((1 << LG_8) - 1)); - v >>= LG_8; - } - while (i); -} - -/* Copy at most LEN bytes from the string SRC to DST. Terminate with - NUL unless SRC is LEN or more bytes long. */ - -static void -tar_copy_str (char *dst, const char *src, size_t len) -{ - size_t i; - for (i = 0; i < len; i++) - if (! (dst[i] = src[i])) - break; -} - -/* Same as tar_copy_str, but always terminate with NUL if using - is OLDGNU format */ - -static void -tar_name_copy_str (char *dst, const char *src, size_t len) -{ - tar_copy_str (dst, src, len); - if (archive_format == OLDGNU_FORMAT) - dst[len-1] = 0; -} - -/* Convert NEGATIVE VALUE to a base-256 representation suitable for - tar headers. NEGATIVE is 1 if VALUE was negative before being cast - to uintmax_t, 0 otherwise. Output to buffer WHERE with size SIZE. - The result is undefined if SIZE is 0 or if VALUE is too large to - fit. */ - -static void -to_base256 (int negative, uintmax_t value, char *where, size_t size) -{ - uintmax_t v = value; - uintmax_t propagated_sign_bits = - ((uintmax_t) - negative << (CHAR_BIT * sizeof v - LG_256)); - size_t i = size; - - do - { - where[--i] = v & ((1 << LG_256) - 1); - v = propagated_sign_bits | (v >> LG_256); - } - while (i); -} - - -static bool -to_chars (int negative, uintmax_t value, size_t valsize, - uintmax_t (*substitute) (int *), - char *where, size_t size, const char *type); - -static bool -to_chars_subst (int negative, int gnu_format, uintmax_t value, size_t valsize, - uintmax_t (*substitute) (int *), - char *where, size_t size, const char *type) -{ - uintmax_t maxval = (gnu_format - ? MAX_VAL_WITH_DIGITS (size - 1, LG_256) - : MAX_VAL_WITH_DIGITS (size - 1, LG_8)); - char valbuf[UINTMAX_STRSIZE_BOUND + 1]; - char maxbuf[UINTMAX_STRSIZE_BOUND]; - char minbuf[UINTMAX_STRSIZE_BOUND + 1]; - char const *minval_string; - char const *maxval_string = STRINGIFY_BIGINT (maxval, maxbuf); - char const *value_string; - - if (gnu_format) - { - uintmax_t m = maxval + 1 ? maxval + 1 : maxval / 2 + 1; - char *p = STRINGIFY_BIGINT (m, minbuf + 1); - *--p = '-'; - minval_string = p; - } - else - minval_string = "0"; - - if (negative) - { - char *p = STRINGIFY_BIGINT (- value, valbuf + 1); - *--p = '-'; - value_string = p; - } - else - value_string = STRINGIFY_BIGINT (value, valbuf); - - if (substitute) - { - int negsub; - uintmax_t sub = substitute (&negsub) & maxval; - /* NOTE: This is one of the few places where GNU_FORMAT differs from - OLDGNU_FORMAT. The actual differences are: - - 1. In OLDGNU_FORMAT all strings in a tar header end in \0 - 2. Incremental archives use oldgnu_header. - - Apart from this they are completely identical. */ - uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub; - char subbuf[UINTMAX_STRSIZE_BOUND + 1]; - char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1); - if (negsub) - *--sub_string = '-'; - WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"), - value_string, type, minval_string, maxval_string, - sub_string)); - return to_chars (negsub, s, valsize, 0, where, size, type); - } - else - ERROR ((0, 0, _("value %s out of %s range %s..%s"), - value_string, type, minval_string, maxval_string)); - return false; -} - -/* Convert NEGATIVE VALUE (which was originally of size VALSIZE) to - external form, using SUBSTITUTE (...) if VALUE won't fit. Output - to buffer WHERE with size SIZE. NEGATIVE is 1 iff VALUE was - negative before being cast to uintmax_t; its original bitpattern - can be deduced from VALSIZE, its original size before casting. - TYPE is the kind of value being output (useful for diagnostics). - Prefer the POSIX format of SIZE - 1 octal digits (with leading zero - digits), followed by '\0'. If this won't work, and if GNU or - OLDGNU format is allowed, use '\200' followed by base-256, or (if - NEGATIVE is nonzero) '\377' followed by two's complement base-256. - If neither format works, use SUBSTITUTE (...) instead. Pass to - SUBSTITUTE the address of an 0-or-1 flag recording whether the - substitute value is negative. */ - -static bool -to_chars (int negative, uintmax_t value, size_t valsize, - uintmax_t (*substitute) (int *), - char *where, size_t size, const char *type) -{ - int gnu_format = (archive_format == GNU_FORMAT - || archive_format == OLDGNU_FORMAT); - - /* Generate the POSIX octal representation if the number fits. */ - if (! negative && value <= MAX_VAL_WITH_DIGITS (size - 1, LG_8)) - { - where[size - 1] = '\0'; - to_octal (value, where, size - 1); - return true; - } - else if (gnu_format) - { - /* Try to cope with the number by using traditional GNU format - methods */ - - /* Generate the base-256 representation if the number fits. */ - if (((negative ? -1 - value : value) - <= MAX_VAL_WITH_DIGITS (size - 1, LG_256))) - { - where[0] = negative ? -1 : 1 << (LG_256 - 1); - to_base256 (negative, value, where + 1, size - 1); - return true; - } - - /* Otherwise, if the number is negative, and if it would not cause - ambiguity on this host by confusing positive with negative - values, then generate the POSIX octal representation of the value - modulo 2**(field bits). The resulting tar file is - machine-dependent, since it depends on the host word size. Yuck! - But this is the traditional behavior. */ - else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8) - { - static int warned_once; - if (! warned_once) - { - warned_once = 1; - WARN ((0, 0, _("Generating negative octal headers"))); - } - where[size - 1] = '\0'; - to_octal (value & MAX_VAL_WITH_DIGITS (valsize * CHAR_BIT, 1), - where, size - 1); - return true; - } - /* Otherwise fall back to substitution, if possible: */ - } - else - substitute = NULL; /* No substitution for formats, other than GNU */ - - return to_chars_subst (negative, gnu_format, value, valsize, substitute, - where, size, type); -} - -static uintmax_t -gid_substitute (int *negative) -{ - gid_t r; -#ifdef GID_NOBODY - r = GID_NOBODY; -#else - static gid_t gid_nobody; - if (!gid_nobody && !gname_to_gid ("nobody", &gid_nobody)) - gid_nobody = -2; - r = gid_nobody; -#endif - *negative = r < 0; - return r; -} - -bool -gid_to_chars (gid_t v, char *p, size_t s) -{ - return to_chars (v < 0, (uintmax_t) v, sizeof v, gid_substitute, p, s, "gid_t"); -} - -bool -major_to_chars (major_t v, char *p, size_t s) -{ - return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t"); -} - -bool -minor_to_chars (minor_t v, char *p, size_t s) -{ - return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t"); -} - -bool -mode_to_chars (mode_t v, char *p, size_t s) -{ - /* In the common case where the internal and external mode bits are the same, - and we are not using POSIX or GNU format, - propagate all unknown bits to the external mode. - This matches historical practice. - Otherwise, just copy the bits we know about. */ - int negative; - uintmax_t u; - if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX - && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC - && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC - && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC - && archive_format != POSIX_FORMAT - && archive_format != USTAR_FORMAT - && archive_format != GNU_FORMAT - && archive_format != OLDGNU_FORMAT) - { - negative = v < 0; - u = v; - } - else - { - negative = 0; - u = ((v & S_ISUID ? TSUID : 0) - | (v & S_ISGID ? TSGID : 0) - | (v & S_ISVTX ? TSVTX : 0) - | (v & S_IRUSR ? TUREAD : 0) - | (v & S_IWUSR ? TUWRITE : 0) - | (v & S_IXUSR ? TUEXEC : 0) - | (v & S_IRGRP ? TGREAD : 0) - | (v & S_IWGRP ? TGWRITE : 0) - | (v & S_IXGRP ? TGEXEC : 0) - | (v & S_IROTH ? TOREAD : 0) - | (v & S_IWOTH ? TOWRITE : 0) - | (v & S_IXOTH ? TOEXEC : 0)); - } - return to_chars (negative, u, sizeof v, 0, p, s, "mode_t"); -} - -bool -off_to_chars (off_t v, char *p, size_t s) -{ - return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t"); -} - -bool -size_to_chars (size_t v, char *p, size_t s) -{ - return to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t"); -} - -bool -time_to_chars (time_t v, char *p, size_t s) -{ - return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t"); -} - -static uintmax_t -uid_substitute (int *negative) -{ - uid_t r; -#ifdef UID_NOBODY - r = UID_NOBODY; -#else - static uid_t uid_nobody; - if (!uid_nobody && !uname_to_uid ("nobody", &uid_nobody)) - uid_nobody = -2; - r = uid_nobody; -#endif - *negative = r < 0; - return r; -} - -bool -uid_to_chars (uid_t v, char *p, size_t s) -{ - return to_chars (v < 0, (uintmax_t) v, sizeof v, uid_substitute, p, s, "uid_t"); -} - -bool -uintmax_to_chars (uintmax_t v, char *p, size_t s) -{ - return to_chars (0, v, sizeof v, 0, p, s, "uintmax_t"); -} - -void -string_to_chars (char const *str, char *p, size_t s) -{ - tar_copy_str (p, str, s); - p[s - 1] = '\0'; -} - - -/* A file is considered dumpable if it is sparse and both --sparse and --totals - are specified. - Otherwise, it is dumpable unless any of the following conditions occur: - - a) it is empty *and* world-readable, or - b) current archive is /dev/null */ - -bool -file_dumpable_p (struct tar_stat_info *st) -{ - if (dev_null_output) - return totals_option && sparse_option && ST_IS_SPARSE (st->stat); - return !(st->archive_file_size == 0 - && (st->stat.st_mode & MODE_R) == MODE_R); -} - - -/* Writing routines. */ - -/* Write the EOT block(s). Zero at least two blocks, through the end - of the record. Old tar, as previous versions of GNU tar, writes - garbage after two zeroed blocks. */ -void -write_eot (void) -{ - union block *pointer = find_next_block (); - memset (pointer->buffer, 0, BLOCKSIZE); - set_next_block_after (pointer); - pointer = find_next_block (); - memset (pointer->buffer, 0, available_space_after (pointer)); - set_next_block_after (pointer); -} - -/* Write a "private" header */ -union block * -start_private_header (const char *name, size_t size) -{ - time_t t; - union block *header = find_next_block (); - - memset (header->buffer, 0, sizeof (union block)); - - tar_name_copy_str (header->header.name, name, NAME_FIELD_SIZE); - OFF_TO_CHARS (size, header->header.size); - - time (&t); - TIME_TO_CHARS (t, header->header.mtime); - MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode); - UID_TO_CHARS (getuid (), header->header.uid); - GID_TO_CHARS (getgid (), header->header.gid); - MAJOR_TO_CHARS (0, header->header.devmajor); - MINOR_TO_CHARS (0, header->header.devminor); - strncpy (header->header.magic, TMAGIC, TMAGLEN); - strncpy (header->header.version, TVERSION, TVERSLEN); - return header; -} - -/* Create a new header and store there at most NAME_FIELD_SIZE bytes of - the file name */ - -static union block * -write_short_name (struct tar_stat_info *st) -{ - union block *header = find_next_block (); - memset (header->buffer, 0, sizeof (union block)); - tar_name_copy_str (header->header.name, st->file_name, NAME_FIELD_SIZE); - return header; -} - -#define FILL(field,byte) do { \ - memset(field, byte, sizeof(field)-1); \ - (field)[sizeof(field)-1] = 0; \ -} while (0) - -/* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block. */ -static void -write_gnu_long_link (struct tar_stat_info *st, const char *p, char type) -{ - size_t size = strlen (p) + 1; - size_t bufsize; - union block *header; - char *tmpname; - - header = start_private_header ("././@LongLink", size); - FILL(header->header.mtime, '0'); - FILL(header->header.mode, '0'); - FILL(header->header.uid, '0'); - FILL(header->header.gid, '0'); - FILL(header->header.devmajor, 0); - FILL(header->header.devminor, 0); - uid_to_uname (0, &tmpname); - UNAME_TO_CHARS (tmpname, header->header.uname); - free (tmpname); - gid_to_gname (0, &tmpname); - GNAME_TO_CHARS (tmpname, header->header.gname); - free (tmpname); - - strcpy (header->header.magic, OLDGNU_MAGIC); - header->header.typeflag = type; - finish_header (st, header, -1); - - header = find_next_block (); - - bufsize = available_space_after (header); - - while (bufsize < size) - { - memcpy (header->buffer, p, bufsize); - p += bufsize; - size -= bufsize; - set_next_block_after (header + (bufsize - 1) / BLOCKSIZE); - header = find_next_block (); - bufsize = available_space_after (header); - } - memcpy (header->buffer, p, size); - memset (header->buffer + size, 0, bufsize - size); - set_next_block_after (header + (size - 1) / BLOCKSIZE); -} - -static size_t -split_long_name (const char *name, size_t length) -{ - size_t i; - - if (length > PREFIX_FIELD_SIZE) - length = PREFIX_FIELD_SIZE + 1; - for (i = length - 1; i > 0; i--) - if (ISSLASH (name[i])) - break; - return i; -} - -static union block * -write_ustar_long_name (const char *name) -{ - size_t length = strlen (name); - size_t i; - union block *header; - - if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1) - { - ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"), - quotearg_colon (name), - PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)); - return NULL; - } - - i = split_long_name (name, length); - if (i == 0 || length - i - 1 > NAME_FIELD_SIZE) - { - ERROR ((0, 0, - _("%s: file name is too long (cannot be split); not dumped"), - quotearg_colon (name))); - return NULL; - } - - header = find_next_block (); - memset (header->buffer, 0, sizeof (header->buffer)); - memcpy (header->header.prefix, name, i); - memcpy (header->header.name, name + i + 1, length - i - 1); - - return header; -} - -/* Write a long link name, depending on the current archive format */ -static void -write_long_link (struct tar_stat_info *st) -{ - switch (archive_format) - { - case POSIX_FORMAT: - xheader_store ("linkpath", st, NULL); - break; - - case V7_FORMAT: /* old V7 tar format */ - case USTAR_FORMAT: - case STAR_FORMAT: - ERROR ((0, 0, - _("%s: link name is too long; not dumped"), - quotearg_colon (st->link_name))); - break; - - case OLDGNU_FORMAT: - case GNU_FORMAT: - write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK); - break; - - default: - abort(); /*FIXME*/ - } -} - -static union block * -write_long_name (struct tar_stat_info *st) -{ - switch (archive_format) - { - case POSIX_FORMAT: - xheader_store ("path", st, NULL); - break; - - case V7_FORMAT: - if (strlen (st->file_name) > NAME_FIELD_SIZE-1) - { - ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"), - quotearg_colon (st->file_name), - NAME_FIELD_SIZE - 1)); - return NULL; - } - break; - - case USTAR_FORMAT: - case STAR_FORMAT: - return write_ustar_long_name (st->file_name); - - case OLDGNU_FORMAT: - case GNU_FORMAT: - write_gnu_long_link (st, st->file_name, GNUTYPE_LONGNAME); - break; - - default: - abort(); /*FIXME*/ - } - return write_short_name (st); -} - -union block * -write_extended (bool global, struct tar_stat_info *st, union block *old_header) -{ - union block *header, hp; - char *p; - int type; - - if (st->xhdr.buffer || st->xhdr.stk == NULL) - return old_header; - - xheader_finish (&st->xhdr); - memcpy (hp.buffer, old_header, sizeof (hp)); - if (global) - { - type = XGLTYPE; - p = xheader_ghdr_name (); - } - else - { - type = XHDTYPE; - p = xheader_xhdr_name (st); - } - xheader_write (type, p, &st->xhdr); - free (p); - header = find_next_block (); - memcpy (header, &hp.buffer, sizeof (hp.buffer)); - return header; -} - -static union block * -write_header_name (struct tar_stat_info *st) -{ - if (archive_format == POSIX_FORMAT && !string_ascii_p (st->file_name)) - { - xheader_store ("path", st, NULL); - return write_short_name (st); - } - else if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) - < strlen (st->file_name)) - return write_long_name (st); - else - return write_short_name (st); -} - - -/* Header handling. */ - -/* Make a header block for the file whose stat info is st, - and return its address. */ - -union block * -start_header (struct tar_stat_info *st) -{ - union block *header; - - header = write_header_name (st); - if (!header) - return NULL; - - /* Override some stat fields, if requested to do so. */ - - if (owner_option != (uid_t) -1) - st->stat.st_uid = owner_option; - if (group_option != (gid_t) -1) - st->stat.st_gid = group_option; - if (mode_option) - st->stat.st_mode = - ((st->stat.st_mode & ~MODE_ALL) - | mode_adjust (st->stat.st_mode, S_ISDIR (st->stat.st_mode) != 0, - initial_umask, mode_option, NULL)); - - /* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a) - for a few tars and came up with the following interoperability - matrix: - - WRITER - 1 2 3 4 5 6 7 8 9 READER - . . . . . . . . . 1 = SunOS 4.2 tar - # . . # # . . # # 2 = NEC SVR4.0.2 tar - . . . # # . . # . 3 = Solaris 2.1 tar - . . . . . . . . . 4 = GNU tar 1.11.1 - . . . . . . . . . 5 = HP-UX 8.07 tar - . . . . . . . . . 6 = Ultrix 4.1 - . . . . . . . . . 7 = AIX 3.2 - . . . . . . . . . 8 = Hitachi HI-UX 1.03 - . . . . . . . . . 9 = Omron UNIOS-B 4.3BSD 1.60Beta - - . = works - # = ``impossible file type'' - - The following mask for old archive removes the `#'s in column 4 - above, thus making GNU tar both a universal donor and a universal - acceptor for Paul's test. */ - - if (archive_format == V7_FORMAT || archive_format == USTAR_FORMAT) - MODE_TO_CHARS (st->stat.st_mode & MODE_ALL, header->header.mode); - else - MODE_TO_CHARS (st->stat.st_mode, header->header.mode); - - { - uid_t uid = st->stat.st_uid; - if (archive_format == POSIX_FORMAT - && MAX_OCTAL_VAL (header->header.uid) < uid) - { - xheader_store ("uid", st, NULL); - uid = 0; - } - if (!UID_TO_CHARS (uid, header->header.uid)) - return NULL; - } - - { - gid_t gid = st->stat.st_gid; - if (archive_format == POSIX_FORMAT - && MAX_OCTAL_VAL (header->header.gid) < gid) - { - xheader_store ("gid", st, NULL); - gid = 0; - } - if (!GID_TO_CHARS (gid, header->header.gid)) - return NULL; - } - - { - off_t size = st->stat.st_size; - if (archive_format == POSIX_FORMAT - && MAX_OCTAL_VAL (header->header.size) < size) - { - xheader_store ("size", st, NULL); - size = 0; - } - if (!OFF_TO_CHARS (size, header->header.size)) - return NULL; - } - - { - struct timespec mtime = set_mtime_option ? mtime_option : st->mtime; - if (archive_format == POSIX_FORMAT) - { - if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec - || mtime.tv_nsec != 0) - xheader_store ("mtime", st, &mtime); - if (MAX_OCTAL_VAL (header->header.mtime) < mtime.tv_sec) - mtime.tv_sec = 0; - } - if (!TIME_TO_CHARS (mtime.tv_sec, header->header.mtime)) - return NULL; - } - - /* FIXME */ - if (S_ISCHR (st->stat.st_mode) - || S_ISBLK (st->stat.st_mode)) - { - major_t devmajor = major (st->stat.st_rdev); - minor_t devminor = minor (st->stat.st_rdev); - - if (archive_format == POSIX_FORMAT - && MAX_OCTAL_VAL (header->header.devmajor) < devmajor) - { - xheader_store ("devmajor", st, NULL); - devmajor = 0; - } - if (!MAJOR_TO_CHARS (devmajor, header->header.devmajor)) - return NULL; - - if (archive_format == POSIX_FORMAT - && MAX_OCTAL_VAL (header->header.devminor) < devminor) - { - xheader_store ("devminor", st, NULL); - devminor = 0; - } - if (!MINOR_TO_CHARS (devminor, header->header.devminor)) - return NULL; - } - else if (archive_format != GNU_FORMAT && archive_format != OLDGNU_FORMAT) - { - if (!(MAJOR_TO_CHARS (0, header->header.devmajor) - && MINOR_TO_CHARS (0, header->header.devminor))) - return NULL; - } - - if (archive_format == POSIX_FORMAT) - { - xheader_store ("atime", st, NULL); - xheader_store ("ctime", st, NULL); - } - else if (incremental_option) - if (archive_format == OLDGNU_FORMAT || archive_format == GNU_FORMAT) - { - TIME_TO_CHARS (st->atime.tv_sec, header->oldgnu_header.atime); - TIME_TO_CHARS (st->ctime.tv_sec, header->oldgnu_header.ctime); - } - - header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE; - - switch (archive_format) - { - case V7_FORMAT: - break; - - case OLDGNU_FORMAT: - case GNU_FORMAT: /*FIXME?*/ - /* Overwrite header->header.magic and header.version in one blow. */ - strcpy (header->header.magic, OLDGNU_MAGIC); - break; - - case POSIX_FORMAT: - case USTAR_FORMAT: - strncpy (header->header.magic, TMAGIC, TMAGLEN); - strncpy (header->header.version, TVERSION, TVERSLEN); - break; - - default: - abort (); - } - - if (archive_format == V7_FORMAT || numeric_owner_option) - { - /* header->header.[ug]name are left as the empty string. */ - } - else - { - uid_to_uname (st->stat.st_uid, &st->uname); - gid_to_gname (st->stat.st_gid, &st->gname); - - if (archive_format == POSIX_FORMAT - && (strlen (st->uname) > UNAME_FIELD_SIZE - || !string_ascii_p (st->uname))) - xheader_store ("uname", st, NULL); - UNAME_TO_CHARS (st->uname, header->header.uname); - - if (archive_format == POSIX_FORMAT - && (strlen (st->gname) > GNAME_FIELD_SIZE - || !string_ascii_p (st->gname))) - xheader_store ("gname", st, NULL); - GNAME_TO_CHARS (st->gname, header->header.gname); - } - - return header; -} - -void -simple_finish_header (union block *header) -{ - size_t i; - int sum; - char *p; - - memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum); - - sum = 0; - p = header->buffer; - for (i = sizeof *header; i-- != 0; ) - /* We can't use unsigned char here because of old compilers, e.g. V7. */ - sum += 0xFF & *p++; - - /* Fill in the checksum field. It's formatted differently from the - other fields: it has [6] digits, a null, then a space -- rather than - digits, then a null. We use to_chars. - The final space is already there, from - checksumming, and to_chars doesn't modify it. - - This is a fast way to do: - - sprintf(header->header.chksum, "%6o", sum); */ - - uintmax_to_chars ((uintmax_t) sum, header->header.chksum, 7); - - set_next_block_after (header); -} - -/* Finish off a filled-in header block and write it out. We also - print the file name and/or full info if verbose is on. If BLOCK_ORDINAL - is not negative, is the block ordinal of the first record for this - file, which may be a preceding long name or long link record. */ -void -finish_header (struct tar_stat_info *st, - union block *header, off_t block_ordinal) -{ - /* Note: It is important to do this before the call to write_extended(), - so that the actual ustar header is printed */ - if (verbose_option - && header->header.typeflag != GNUTYPE_LONGLINK - && header->header.typeflag != GNUTYPE_LONGNAME - && header->header.typeflag != XHDTYPE - && header->header.typeflag != XGLTYPE) - { - /* These globals are parameters to print_header, sigh. */ - - current_header = header; - current_format = archive_format; - print_header (st, block_ordinal); - } - - header = write_extended (false, st, header); - simple_finish_header (header); -} - - -void -pad_archive (off_t size_left) -{ - union block *blk; - while (size_left > 0) - { - mv_size_left (size_left); - blk = find_next_block (); - memset (blk->buffer, 0, BLOCKSIZE); - set_next_block_after (blk); - size_left -= BLOCKSIZE; - } -} - -static enum dump_status -dump_regular_file (int fd, struct tar_stat_info *st) -{ - off_t size_left = st->stat.st_size; - off_t block_ordinal; - union block *blk; - - block_ordinal = current_block_ordinal (); - blk = start_header (st); - if (!blk) - return dump_status_fail; - - /* Mark contiguous files, if we support them. */ - if (archive_format != V7_FORMAT && S_ISCTG (st->stat.st_mode)) - blk->header.typeflag = CONTTYPE; - - finish_header (st, blk, block_ordinal); - - mv_begin (st); - while (size_left > 0) - { - size_t bufsize, count; - - mv_size_left (size_left); - - blk = find_next_block (); - - bufsize = available_space_after (blk); - - if (size_left < bufsize) - { - /* Last read -- zero out area beyond. */ - bufsize = size_left; - count = bufsize % BLOCKSIZE; - if (count) - memset (blk->buffer + size_left, 0, BLOCKSIZE - count); - } - - count = (fd < 0) ? bufsize : safe_read (fd, blk->buffer, bufsize); - if (count == SAFE_READ_ERROR) - { - read_diag_details (st->orig_file_name, - st->stat.st_size - size_left, bufsize); - pad_archive (size_left); - return dump_status_short; - } - size_left -= count; - set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE); - - if (count != bufsize) - { - char buf[UINTMAX_STRSIZE_BOUND]; - memset (blk->buffer + count, 0, bufsize - count); - WARN ((0, 0, - ngettext ("%s: File shrank by %s byte; padding with zeros", - "%s: File shrank by %s bytes; padding with zeros", - size_left), - quotearg_colon (st->orig_file_name), - STRINGIFY_BIGINT (size_left, buf))); - if (! ignore_failed_read_option) - exit_status = TAREXIT_DIFFERS; - pad_archive (size_left - (bufsize - count)); - return dump_status_short; - } - } - return dump_status_ok; -} - - -static void -dump_dir0 (char *directory, - struct tar_stat_info *st, int top_level, dev_t parent_device) -{ - dev_t our_device = st->stat.st_dev; - const char *tag_file_name; - - if (!is_avoided_name (st->orig_file_name)) - { - union block *blk = NULL; - off_t block_ordinal = current_block_ordinal (); - st->stat.st_size = 0; /* force 0 size on dir */ - - blk = start_header (st); - if (!blk) - return; - - if (incremental_option && archive_format != POSIX_FORMAT) - blk->header.typeflag = GNUTYPE_DUMPDIR; - else /* if (standard_option) */ - blk->header.typeflag = DIRTYPE; - - /* If we're gnudumping, we aren't done yet so don't close it. */ - - if (!incremental_option) - finish_header (st, blk, block_ordinal); - else if (gnu_list_name->dir_contents) - { - if (archive_format == POSIX_FORMAT) - { - xheader_store ("GNU.dumpdir", st, gnu_list_name->dir_contents); - finish_header (st, blk, block_ordinal); - } - else - { - off_t size_left; - off_t totsize; - size_t bufsize; - ssize_t count; - const char *buffer, *p_buffer; - - block_ordinal = current_block_ordinal (); - buffer = gnu_list_name->dir_contents; - if (buffer) - totsize = dumpdir_size (buffer); - else - totsize = 0; - OFF_TO_CHARS (totsize, blk->header.size); - finish_header (st, blk, block_ordinal); - p_buffer = buffer; - size_left = totsize; - - mv_begin (st); - mv_total_size (totsize); - while (size_left > 0) - { - mv_size_left (size_left); - blk = find_next_block (); - bufsize = available_space_after (blk); - if (size_left < bufsize) - { - bufsize = size_left; - count = bufsize % BLOCKSIZE; - if (count) - memset (blk->buffer + size_left, 0, BLOCKSIZE - count); - } - memcpy (blk->buffer, p_buffer, bufsize); - size_left -= bufsize; - p_buffer += bufsize; - set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE); - } - mv_end (); - } - return; - } - } - - if (!recursion_option) - return; - - if (one_file_system_option - && !top_level - && parent_device != st->stat.st_dev) - { - if (verbose_option) - WARN ((0, 0, - _("%s: file is on a different filesystem; not dumped"), - quotearg_colon (st->orig_file_name))); - } - else - { - char *name_buf; - size_t name_size; - - switch (check_exclusion_tags (st->orig_file_name, &tag_file_name)) - { - case exclusion_tag_all: - /* Handled in dump_file0 */ - break; - - case exclusion_tag_none: - { - char const *entry; - size_t entry_len; - size_t name_len; - - name_buf = xstrdup (st->orig_file_name); - name_size = name_len = strlen (name_buf); - - /* Now output all the files in the directory. */ - /* FIXME: Should speed this up by cd-ing into the dir. */ - for (entry = directory; (entry_len = strlen (entry)) != 0; - entry += entry_len + 1) - { - if (name_size < name_len + entry_len) - { - name_size = name_len + entry_len; - name_buf = xrealloc (name_buf, name_size + 1); - } - strcpy (name_buf + name_len, entry); - if (!excluded_name (name_buf)) - dump_file (name_buf, 0, our_device); - } - - free (name_buf); - } - break; - - case exclusion_tag_contents: - exclusion_tag_warning (st->orig_file_name, tag_file_name, - _("contents not dumped")); - name_size = strlen (st->orig_file_name) + strlen (tag_file_name) + 1; - name_buf = xmalloc (name_size); - strcpy (name_buf, st->orig_file_name); - strcat (name_buf, tag_file_name); - dump_file (name_buf, 0, our_device); - free (name_buf); - break; - - case exclusion_tag_under: - exclusion_tag_warning (st->orig_file_name, tag_file_name, - _("contents not dumped")); - break; - } - } -} - -/* Ensure exactly one trailing slash. */ -static void -ensure_slash (char **pstr) -{ - size_t len = strlen (*pstr); - while (len >= 1 && ISSLASH ((*pstr)[len - 1])) - len--; - if (!ISSLASH ((*pstr)[len])) - *pstr = xrealloc (*pstr, len + 2); - (*pstr)[len++] = '/'; - (*pstr)[len] = '\0'; -} - -static bool -dump_dir (int fd, struct tar_stat_info *st, int top_level, dev_t parent_device) -{ - char *directory = fdsavedir (fd); - if (!directory) - { - savedir_diag (st->orig_file_name); - return false; - } - - dump_dir0 (directory, st, top_level, parent_device); - - free (directory); - return true; -} - - -/* Main functions of this module. */ - -void -create_archive (void) -{ - const char *p; - - open_archive (ACCESS_WRITE); - buffer_write_global_xheader (); - - if (incremental_option) - { - size_t buffer_size = 1000; - char *buffer = xmalloc (buffer_size); - const char *q; - - collect_and_sort_names (); - - while ((p = name_from_list ()) != NULL) - if (!excluded_name (p)) - dump_file (p, -1, (dev_t) 0); - - blank_name_list (); - while ((p = name_from_list ()) != NULL) - if (!excluded_name (p)) - { - size_t plen = strlen (p); - if (buffer_size <= plen) - { - while ((buffer_size *= 2) <= plen) - continue; - buffer = xrealloc (buffer, buffer_size); - } - memcpy (buffer, p, plen); - if (! ISSLASH (buffer[plen - 1])) - buffer[plen++] = '/'; - q = gnu_list_name->dir_contents; - if (q) - while (*q) - { - size_t qlen = strlen (q); - if (*q == 'Y') - { - if (buffer_size < plen + qlen) - { - while ((buffer_size *=2 ) < plen + qlen) - continue; - buffer = xrealloc (buffer, buffer_size); - } - strcpy (buffer + plen, q + 1); - dump_file (buffer, -1, (dev_t) 0); - } - q += qlen + 1; - } - } - free (buffer); - } - else - { - while ((p = name_next (1)) != NULL) - if (!excluded_name (p)) - dump_file (p, 1, (dev_t) 0); - } - - write_eot (); - close_archive (); - - if (listed_incremental_option) - write_directory_file (); -} - - -/* Calculate the hash of a link. */ -static size_t -hash_link (void const *entry, size_t n_buckets) -{ - struct link const *l = entry; - uintmax_t num = l->dev ^ l->ino; - return num % n_buckets; -} - -/* Compare two links for equality. */ -static bool -compare_links (void const *entry1, void const *entry2) -{ - struct link const *link1 = entry1; - struct link const *link2 = entry2; - return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0; -} - -static void -unknown_file_error (char const *p) -{ - WARN ((0, 0, _("%s: Unknown file type; file ignored"), - quotearg_colon (p))); - if (!ignore_failed_read_option) - exit_status = TAREXIT_FAILURE; -} - - -/* Handling of hard links */ - -/* Table of all non-directories that we've written so far. Any time - we see another, we check the table and avoid dumping the data - again if we've done it once already. */ -static Hash_table *link_table; - -/* Try to dump stat as a hard link to another file in the archive. - Return true if successful. */ -static bool -dump_hard_link (struct tar_stat_info *st) -{ - if (link_table && st->stat.st_nlink > 1) - { - struct link lp; - struct link *duplicate; - off_t block_ordinal; - union block *blk; - - lp.ino = st->stat.st_ino; - lp.dev = st->stat.st_dev; - - if ((duplicate = hash_lookup (link_table, &lp))) - { - /* We found a link. */ - char const *link_name = safer_name_suffix (duplicate->name, true, - absolute_names_option); - - duplicate->nlink--; - - block_ordinal = current_block_ordinal (); - assign_string (&st->link_name, link_name); - if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) - < strlen (link_name)) - write_long_link (st); - - st->stat.st_size = 0; - blk = start_header (st); - if (!blk) - return false; - tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE); - - blk->header.typeflag = LNKTYPE; - finish_header (st, blk, block_ordinal); - - if (remove_files_option && unlink (st->orig_file_name) != 0) - unlink_error (st->orig_file_name); - - return true; - } - } - return false; -} - -static void -file_count_links (struct tar_stat_info *st) -{ - if (st->stat.st_nlink > 1) - { - struct link *duplicate; - struct link *lp = xmalloc (offsetof (struct link, name) - + strlen (st->orig_file_name) + 1); - lp->ino = st->stat.st_ino; - lp->dev = st->stat.st_dev; - lp->nlink = st->stat.st_nlink; - strcpy (lp->name, st->orig_file_name); - - if (! ((link_table - || (link_table = hash_initialize (0, 0, hash_link, - compare_links, 0))) - && (duplicate = hash_insert (link_table, lp)))) - xalloc_die (); - - if (duplicate != lp) - abort (); - lp->nlink--; - } -} - -/* For each dumped file, check if all its links were dumped. Emit - warnings if it is not so. */ -void -check_links (void) -{ - struct link *lp; - - if (!link_table) - return; - - for (lp = hash_get_first (link_table); lp; - lp = hash_get_next (link_table, lp)) - { - if (lp->nlink) - { - WARN ((0, 0, _("Missing links to %s.\n"), quote (lp->name))); - } - } -} - - -/* Dump a single file, recursing on directories. P is the file name - to dump. TOP_LEVEL tells whether this is a top-level call; zero - means no, positive means yes, and negative means the top level - of an incremental dump. PARENT_DEVICE is the device of P's - parent directory; it is examined only if TOP_LEVEL is zero. */ - -/* FIXME: One should make sure that for *every* path leading to setting - exit_status to failure, a clear diagnostic has been issued. */ - -static void -dump_file0 (struct tar_stat_info *st, const char *p, - int top_level, dev_t parent_device) -{ - union block *header; - char type; - off_t original_size; - struct timespec original_ctime; - struct timespec restore_times[2]; - off_t block_ordinal = -1; - bool is_dir; - - if (interactive_option && !confirm ("add", p)) - return; - - assign_string (&st->orig_file_name, p); - assign_string (&st->file_name, - safer_name_suffix (p, false, absolute_names_option)); - - transform_name (&st->file_name); - - if (deref_stat (dereference_option, p, &st->stat) != 0) - { - stat_diag (p); - return; - } - st->archive_file_size = original_size = st->stat.st_size; - st->atime = restore_times[0] = get_stat_atime (&st->stat); - st->mtime = restore_times[1] = get_stat_mtime (&st->stat); - st->ctime = original_ctime = get_stat_ctime (&st->stat); - -#ifdef S_ISHIDDEN - if (S_ISHIDDEN (st->stat.st_mode)) - { - char *new = (char *) alloca (strlen (p) + 2); - if (new) - { - strcpy (new, p); - strcat (new, "@"); - p = new; - } - } -#endif - - /* See if we want only new files, and check if this one is too old to - put in the archive. - - This check is omitted if incremental_option is set *and* the - requested file is not explicitely listed in the command line. */ - - if (!(incremental_option && !is_individual_file (p)) - && !S_ISDIR (st->stat.st_mode) - && OLDER_TAR_STAT_TIME (*st, m) - && (!after_date_option || OLDER_TAR_STAT_TIME (*st, c))) - { - if (!incremental_option && verbose_option) - WARN ((0, 0, _("%s: file is unchanged; not dumped"), - quotearg_colon (p))); - return; - } - - /* See if we are trying to dump the archive. */ - if (sys_file_is_archive (st)) - { - WARN ((0, 0, _("%s: file is the archive; not dumped"), - quotearg_colon (p))); - return; - } - - if (is_avoided_name (p)) - return; - - is_dir = S_ISDIR (st->stat.st_mode) != 0; - - if (!is_dir && dump_hard_link (st)) - return; - - if (is_dir || S_ISREG (st->stat.st_mode) || S_ISCTG (st->stat.st_mode)) - { - bool ok; - int fd = -1; - struct stat final_stat; - - if (is_dir || file_dumpable_p (st)) - { - fd = open (p, - (O_RDONLY | O_BINARY - | (is_dir ? O_DIRECTORY | O_NONBLOCK : 0) - | (atime_preserve_option == system_atime_preserve - ? O_NOATIME - : 0))); - if (fd < 0) - { - if (!top_level && errno == ENOENT) - WARN ((0, 0, _("%s: File removed before we read it"), - quotearg_colon (p))); - else - open_diag (p); - return; - } - } - - if (is_dir) - { - const char *tag_file_name; - ensure_slash (&st->orig_file_name); - ensure_slash (&st->file_name); - - if (check_exclusion_tags (st->orig_file_name, &tag_file_name) - == exclusion_tag_all) - { - exclusion_tag_warning (st->orig_file_name, tag_file_name, - _("directory not dumped")); - return; - } - - ok = dump_dir (fd, st, top_level, parent_device); - - /* dump_dir consumes FD if successful. */ - if (ok) - fd = -1; - } - else - { - enum dump_status status; - - if (fd != -1 && sparse_option && ST_IS_SPARSE (st->stat)) - { - status = sparse_dump_file (fd, st); - if (status == dump_status_not_implemented) - status = dump_regular_file (fd, st); - } - else - status = dump_regular_file (fd, st); - - switch (status) - { - case dump_status_ok: - case dump_status_short: - mv_end (); - break; - - case dump_status_fail: - break; - - case dump_status_not_implemented: - abort (); - } - - file_count_links (st); - - ok = status == dump_status_ok; - } - - if (ok) - { - /* If possible, reopen a directory if we are preserving - atimes, so that we can set just the atime on systems with - _FIOSATIME. */ - if (fd < 0 && is_dir - && atime_preserve_option == replace_atime_preserve) - fd = open (p, O_RDONLY | O_BINARY | O_DIRECTORY | O_NONBLOCK); - - if ((fd < 0 - ? deref_stat (dereference_option, p, &final_stat) - : fstat (fd, &final_stat)) - != 0) - { - stat_diag (p); - ok = false; - } - } - - if (ok) - { - if ((timespec_cmp (get_stat_ctime (&final_stat), original_ctime) != 0 - /* Original ctime will change if the file is a directory and - --remove-files is given */ - && !(remove_files_option && is_dir)) - || original_size < final_stat.st_size) - { - WARN ((0, 0, _("%s: file changed as we read it"), - quotearg_colon (p))); - if (exit_status == TAREXIT_SUCCESS) - exit_status = TAREXIT_DIFFERS; - } - else if (atime_preserve_option == replace_atime_preserve - && set_file_atime (fd, p, restore_times) != 0) - utime_error (p); - } - - if (0 <= fd && close (fd) != 0) - { - close_diag (p); - ok = false; - } - - if (ok && remove_files_option) - { - if (is_dir) - { - if (rmdir (p) != 0 && errno != ENOTEMPTY) - rmdir_error (p); - } - else - { - if (unlink (p) != 0) - unlink_error (p); - } - } - - return; - } -#ifdef HAVE_READLINK - else if (S_ISLNK (st->stat.st_mode)) - { - char *buffer; - int size; - size_t linklen = st->stat.st_size; - if (linklen != st->stat.st_size || linklen + 1 == 0) - xalloc_die (); - buffer = (char *) alloca (linklen + 1); - size = readlink (p, buffer, linklen + 1); - if (size < 0) - { - readlink_diag (p); - return; - } - buffer[size] = '\0'; - assign_string (&st->link_name, buffer); - if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size) - write_long_link (st); - - block_ordinal = current_block_ordinal (); - st->stat.st_size = 0; /* force 0 size on symlink */ - header = start_header (st); - if (!header) - return; - tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE); - header->header.typeflag = SYMTYPE; - finish_header (st, header, block_ordinal); - /* nothing more to do to it */ - - if (remove_files_option) - { - if (unlink (p) == -1) - unlink_error (p); - } - file_count_links (st); - return; - } -#endif - else if (S_ISCHR (st->stat.st_mode)) - type = CHRTYPE; - else if (S_ISBLK (st->stat.st_mode)) - type = BLKTYPE; - else if (S_ISFIFO (st->stat.st_mode)) - type = FIFOTYPE; - else if (S_ISSOCK (st->stat.st_mode)) - { - WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p))); - return; - } - else if (S_ISDOOR (st->stat.st_mode)) - { - WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p))); - return; - } - else - { - unknown_file_error (p); - return; - } - - if (archive_format == V7_FORMAT) - { - unknown_file_error (p); - return; - } - - block_ordinal = current_block_ordinal (); - st->stat.st_size = 0; /* force 0 size */ - header = start_header (st); - if (!header) - return; - header->header.typeflag = type; - - if (type != FIFOTYPE) - { - MAJOR_TO_CHARS (major (st->stat.st_rdev), - header->header.devmajor); - MINOR_TO_CHARS (minor (st->stat.st_rdev), - header->header.devminor); - } - - finish_header (st, header, block_ordinal); - if (remove_files_option) - { - if (unlink (p) == -1) - unlink_error (p); - } -} - -void -dump_file (const char *p, int top_level, dev_t parent_device) -{ - struct tar_stat_info st; - tar_stat_init (&st); - dump_file0 (&st, p, top_level, parent_device); - if (listed_incremental_option) - update_parent_directory (p); - tar_stat_destroy (&st); -} diff --git a/src/bin/tar/src/delete.c b/src/bin/tar/src/delete.c deleted file mode 100644 index d59a857f5f..0000000000 --- a/src/bin/tar/src/delete.c +++ /dev/null @@ -1,391 +0,0 @@ -/* Delete entries from a tar archive. - - Copyright (C) 1988, 1992, 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 it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include - -#include "common.h" -#include - -static union block *new_record; -static int new_blocks; -static bool acting_as_filter; - -/* FIXME: This module should not directly handle the following - variables, instead, the interface should be cleaned up. */ -extern union block *record_start; -extern union block *record_end; -extern union block *current_block; -extern union block *recent_long_name; -extern union block *recent_long_link; -extern off_t records_read; -extern off_t records_written; - -/* The number of records skipped at the start of the archive, when - passing over members that are not deleted. */ -off_t records_skipped; - -/* Move archive descriptor by COUNT records worth. If COUNT is - positive we move forward, else we move negative. If it's a tape, - MTIOCTOP had better work. If it's something else, we try to seek - on it. If we can't seek, we lose! */ -static void -move_archive (off_t count) -{ - if (count == 0) - return; - -#ifdef MTIOCTOP - { - struct mtop operation; - - if (count < 0 - ? (operation.mt_op = MTBSR, - operation.mt_count = -count, - operation.mt_count == -count) - : (operation.mt_op = MTFSR, - operation.mt_count = count, - operation.mt_count == count)) - { - if (0 <= rmtioctl (archive, MTIOCTOP, (char *) &operation)) - return; - - if (errno == EIO - && 0 <= rmtioctl (archive, MTIOCTOP, (char *) &operation)) - return; - } - } -#endif /* MTIOCTOP */ - - { - off_t position0 = rmtlseek (archive, (off_t) 0, SEEK_CUR); - off_t increment = record_size * (off_t) count; - off_t position = position0 + increment; - - if (increment / count != record_size - || (position < position0) != (increment < 0) - || (position = position < 0 ? 0 : position, - rmtlseek (archive, position, SEEK_SET) != position)) - seek_error_details (archive_name_array[0], position); - - return; - } -} - -/* Write out the record which has been filled. If MOVE_BACK_FLAG, - backspace to where we started. */ -static void -write_record (int move_back_flag) -{ - union block *save_record = record_start; - record_start = new_record; - - if (acting_as_filter) - { - archive = STDOUT_FILENO; - flush_write (); - archive = STDIN_FILENO; - } - else - { - move_archive ((records_written + records_skipped) - records_read); - flush_write (); - } - - record_start = save_record; - - if (move_back_flag) - { - /* Move the tape head back to where we were. */ - - if (! acting_as_filter) - move_archive (records_read - (records_written + records_skipped)); - } - - new_blocks = 0; -} - -static void -write_recent_blocks (union block *h, size_t blocks) -{ - size_t i; - for (i = 0; i < blocks; i++) - { - new_record[new_blocks++] = h[i]; - if (new_blocks == blocking_factor) - write_record (1); - } -} - -static void -write_recent_bytes (char *data, size_t bytes) -{ - size_t blocks = bytes / BLOCKSIZE; - size_t rest = bytes - blocks * BLOCKSIZE; - - write_recent_blocks ((union block *)data, blocks); - memcpy (new_record[new_blocks].buffer, data + blocks * BLOCKSIZE, rest); - if (rest < BLOCKSIZE) - memset (new_record[new_blocks].buffer + rest, 0, BLOCKSIZE - rest); - new_blocks++; - if (new_blocks == blocking_factor) - write_record (1); -} - -void -delete_archive_members (void) -{ - enum read_header logical_status = HEADER_STILL_UNREAD; - enum read_header previous_status = HEADER_STILL_UNREAD; - - /* FIXME: Should clean the routine before cleaning these variables :-( */ - struct name *name; - off_t blocks_to_skip = 0; - off_t blocks_to_keep = 0; - int kept_blocks_in_record; - - name_gather (); - open_archive (ACCESS_UPDATE); - acting_as_filter = strcmp (archive_name_array[0], "-") == 0; - - do - { - enum read_header status = read_header (true); - - switch (status) - { - case HEADER_STILL_UNREAD: - abort (); - - case HEADER_SUCCESS: - if ((name = name_scan (current_stat_info.file_name)) == NULL) - { - skip_member (); - break; - } - name->found_count++; - if (!ISFOUND(name)) - { - skip_member (); - break; - } - - /* Fall through. */ - case HEADER_SUCCESS_EXTENDED: - logical_status = status; - break; - - case HEADER_ZERO_BLOCK: - if (ignore_zeros_option) - { - set_next_block_after (current_header); - break; - } - /* Fall through. */ - case HEADER_END_OF_FILE: - logical_status = HEADER_END_OF_FILE; - break; - - case HEADER_FAILURE: - set_next_block_after (current_header); - switch (previous_status) - { - case HEADER_STILL_UNREAD: - WARN ((0, 0, _("This does not look like a tar archive"))); - /* Fall through. */ - - case HEADER_SUCCESS: - case HEADER_SUCCESS_EXTENDED: - case HEADER_ZERO_BLOCK: - ERROR ((0, 0, _("Skipping to next header"))); - /* Fall through. */ - - case HEADER_FAILURE: - break; - - case HEADER_END_OF_FILE: - abort (); - } - break; - } - - previous_status = status; - } - while (logical_status == HEADER_STILL_UNREAD); - - records_skipped = records_read - 1; - new_record = xmalloc (record_size); - - if (logical_status == HEADER_SUCCESS - || logical_status == HEADER_SUCCESS_EXTENDED) - { - write_archive_to_stdout = false; - - /* Save away blocks before this one in this record. */ - - new_blocks = current_block - record_start; - if (new_blocks) - memcpy (new_record, record_start, new_blocks * BLOCKSIZE); - - if (logical_status == HEADER_SUCCESS) - { - /* FIXME: Pheew! This is crufty code! */ - logical_status = HEADER_STILL_UNREAD; - goto flush_file; - } - - /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says: - "delete.c", line 223: warning: loop not entered at top - Reported by Bruno Haible. */ - while (1) - { - enum read_header status; - - /* Fill in a record. */ - - if (current_block == record_end) - flush_archive (); - status = read_header (false); - - xheader_decode (¤t_stat_info); - - if (status == HEADER_ZERO_BLOCK && ignore_zeros_option) - { - set_next_block_after (current_header); - continue; - } - if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK) - { - logical_status = HEADER_END_OF_FILE; - break; - } - - if (status == HEADER_FAILURE) - { - ERROR ((0, 0, _("Deleting non-header from archive"))); - set_next_block_after (current_header); - continue; - } - - /* Found another header. */ - - if ((name = name_scan (current_stat_info.file_name)) != NULL) - { - name->found_count++; - if (ISFOUND(name)) - { - flush_file: - set_next_block_after (current_header); - blocks_to_skip = (current_stat_info.stat.st_size - + BLOCKSIZE - 1) / BLOCKSIZE; - - while (record_end - current_block <= blocks_to_skip) - { - blocks_to_skip -= (record_end - current_block); - flush_archive (); - } - current_block += blocks_to_skip; - blocks_to_skip = 0; - continue; - } - } - /* Copy header. */ - - if (current_stat_info.xhdr.size) - { - write_recent_bytes (current_stat_info.xhdr.buffer, - current_stat_info.xhdr.size); - } - else - { - write_recent_blocks (recent_long_name, recent_long_name_blocks); - write_recent_blocks (recent_long_link, recent_long_link_blocks); - } - new_record[new_blocks] = *current_header; - new_blocks++; - blocks_to_keep - = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; - set_next_block_after (current_header); - if (new_blocks == blocking_factor) - write_record (1); - - /* Copy data. */ - - kept_blocks_in_record = record_end - current_block; - if (kept_blocks_in_record > blocks_to_keep) - kept_blocks_in_record = blocks_to_keep; - - while (blocks_to_keep) - { - int count; - - if (current_block == record_end) - { - flush_read (); - current_block = record_start; - kept_blocks_in_record = blocking_factor; - if (kept_blocks_in_record > blocks_to_keep) - kept_blocks_in_record = blocks_to_keep; - } - count = kept_blocks_in_record; - if (blocking_factor - new_blocks < count) - count = blocking_factor - new_blocks; - - if (! count) - abort (); - - memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE); - new_blocks += count; - current_block += count; - blocks_to_keep -= count; - kept_blocks_in_record -= count; - - if (new_blocks == blocking_factor) - write_record (1); - } - } - - if (logical_status == HEADER_END_OF_FILE) - { - /* Write the end of tape. FIXME: we can't use write_eot here, - as it gets confused when the input is at end of file. */ - - int total_zero_blocks = 0; - - do - { - int zero_blocks = blocking_factor - new_blocks; - memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks); - total_zero_blocks += zero_blocks; - write_record (total_zero_blocks < 2); - } - while (total_zero_blocks < 2); - } - - if (! acting_as_filter && ! _isrmt (archive)) - { - if (sys_truncate (archive)) - truncate_warn (archive_name_array[0]); - } - } - free (new_record); - - close_archive (); - names_notfound (); -} diff --git a/src/bin/tar/src/extract.c b/src/bin/tar/src/extract.c deleted file mode 100644 index 0d938e6379..0000000000 --- a/src/bin/tar/src/extract.c +++ /dev/null @@ -1,1379 +0,0 @@ -/* Extract files from a tar archive. - - Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, - 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - Written by John Gilmore, on 1985-11-19. - - 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include -#include -#include - -#include "common.h" - -static bool we_are_root; /* true if our effective uid == 0 */ -static mode_t newdir_umask; /* umask when creating new directories */ -static mode_t current_umask; /* current umask (which is set to 0 if -p) */ - -/* Status of the permissions of a file that we are extracting. */ -enum permstatus -{ - /* This file may have existed already; its permissions are unknown. */ - UNKNOWN_PERMSTATUS, - - /* This file was created using the permissions from the archive, - except with S_IRWXG | S_IRWXO masked out if 0 < same_owner_option. */ - ARCHIVED_PERMSTATUS, - - /* This is an intermediate directory; the archive did not specify - its permissions. */ - INTERDIR_PERMSTATUS -}; - -/* List of directories whose statuses we need to extract after we've - finished extracting their subsidiary files. If you consider each - contiguous subsequence of elements of the form [D]?[^D]*, where [D] - represents an element where AFTER_LINKS is nonzero and [^D] - represents an element where AFTER_LINKS is zero, then the head - of the subsequence has the longest name, and each non-head element - in the prefix is an ancestor (in the directory hierarchy) of the - preceding element. */ - -struct delayed_set_stat - { - struct delayed_set_stat *next; - dev_t dev; - ino_t ino; - mode_t mode; - uid_t uid; - gid_t gid; - struct timespec atime; - struct timespec mtime; - size_t file_name_len; - mode_t invert_permissions; - enum permstatus permstatus; - bool after_links; - char file_name[1]; - }; - -static struct delayed_set_stat *delayed_set_stat_head; - -/* List of links whose creation we have delayed. */ -struct delayed_link - { - /* The next delayed link in the list. */ - struct delayed_link *next; - - /* The device, inode number and last-modified time of the placeholder. */ - dev_t dev; - ino_t ino; - struct timespec mtime; - - /* True if the link is symbolic. */ - bool is_symlink; - - /* The desired owner and group of the link, if it is a symlink. */ - uid_t uid; - gid_t gid; - - /* A list of sources for this link. The sources are all to be - hard-linked together. */ - struct string_list *sources; - - /* The desired target of the desired link. */ - char target[1]; - }; - -static struct delayed_link *delayed_link_head; - -struct string_list - { - struct string_list *next; - char string[1]; - }; - -/* Set up to extract files. */ -void -extr_init (void) -{ - we_are_root = geteuid () == 0; - same_permissions_option += we_are_root; - same_owner_option += we_are_root; - - /* Option -p clears the kernel umask, so it does not affect proper - restoration of file permissions. New intermediate directories will - comply with umask at start of program. */ - - newdir_umask = umask (0); - if (0 < same_permissions_option) - current_umask = 0; - else - { - umask (newdir_umask); /* restore the kernel umask */ - current_umask = newdir_umask; - } -} - -/* If restoring permissions, restore the mode for FILE_NAME from - information given in *STAT_INFO (where *CUR_INFO gives - the current status if CUR_INFO is nonzero); otherwise invert the - INVERT_PERMISSIONS bits from the file's current permissions. - PERMSTATUS specifies the status of the file's permissions. - TYPEFLAG specifies the type of the file. */ -static void -set_mode (char const *file_name, - struct stat const *stat_info, - struct stat const *cur_info, - mode_t invert_permissions, enum permstatus permstatus, - char typeflag) -{ - mode_t mode; - - if (0 < same_permissions_option - && permstatus != INTERDIR_PERMSTATUS) - { - mode = stat_info->st_mode; - - /* If we created the file and it has a mode that we set already - with O_CREAT, then its mode is often set correctly already. - But if we are changing ownership, the mode's group and and - other permission bits were omitted originally, so it's less - likely that the mode is OK now. Also, on many hosts, some - directories inherit the setgid bits from their parents, so we - we must set directories' modes explicitly. */ - if ((permstatus == ARCHIVED_PERMSTATUS - && ! (mode & ~ (0 < same_owner_option ? S_IRWXU : MODE_RWX))) - && typeflag != DIRTYPE - && typeflag != GNUTYPE_DUMPDIR) - return; - } - else if (! invert_permissions) - return; - else - { - /* We must inspect a directory's current permissions, since the - directory may have inherited its setgid bit from its parent. - - INVERT_PERMISSIONS happens to be nonzero only for directories - that we created, so there's no point optimizing this code for - other cases. */ - struct stat st; - if (! cur_info) - { - if (stat (file_name, &st) != 0) - { - stat_error (file_name); - return; - } - cur_info = &st; - } - mode = cur_info->st_mode ^ invert_permissions; - } - - if (chmod (file_name, mode) != 0) - chmod_error_details (file_name, mode); -} - -/* Check time after successfully setting FILE_NAME's time stamp to T. */ -static void -check_time (char const *file_name, struct timespec t) -{ - if (t.tv_sec <= 0) - WARN ((0, 0, _("%s: implausibly old time stamp %s"), - file_name, tartime (t, true))); - else if (timespec_cmp (volume_start_time, t) < 0) - { - struct timespec now; - gettime (&now); - if (timespec_cmp (now, t) < 0) - { - char buf[TIMESPEC_STRSIZE_BOUND]; - struct timespec diff; - diff.tv_sec = t.tv_sec - now.tv_sec; - diff.tv_nsec = t.tv_nsec - now.tv_nsec; - if (diff.tv_nsec < 0) - { - diff.tv_nsec += BILLION; - diff.tv_sec--; - } - WARN ((0, 0, _("%s: time stamp %s is %s s in the future"), - file_name, tartime (t, true), code_timespec (diff, buf))); - } - } -} - -/* Restore stat attributes (owner, group, mode and times) for - FILE_NAME, using information given in *ST. - If CUR_INFO is nonzero, *CUR_INFO is the - file's current status. - If not restoring permissions, invert the - INVERT_PERMISSIONS bits from the file's current permissions. - PERMSTATUS specifies the status of the file's permissions. - TYPEFLAG specifies the type of the file. */ - -/* FIXME: About proper restoration of symbolic link attributes, we still do - not have it right. Pretesters' reports tell us we need further study and - probably more configuration. For now, just use lchown if it exists, and - punt for the rest. Sigh! */ - -static void -set_stat (char const *file_name, - struct tar_stat_info const *st, - struct stat const *cur_info, - mode_t invert_permissions, enum permstatus permstatus, - char typeflag) -{ - if (typeflag != SYMTYPE) - { - /* We do the utime before the chmod because some versions of utime are - broken and trash the modes of the file. */ - - if (! touch_option && permstatus != INTERDIR_PERMSTATUS) - { - /* We set the accessed time to `now', which is really the time we - started extracting files, unless incremental_option is used, in - which case .st_atime is used. */ - - /* FIXME: incremental_option should set ctime too, but how? */ - - struct timespec ts[2]; - if (incremental_option) - ts[0] = st->atime; - else - ts[0] = start_time; - ts[1] = st->mtime; - - if (utimens (file_name, ts) != 0) - utime_error (file_name); - else - { - check_time (file_name, ts[0]); - check_time (file_name, ts[1]); - } - } - - /* Some systems allow non-root users to give files away. Once this - done, it is not possible anymore to change file permissions. - However, setting file permissions now would be incorrect, since - they would apply to the wrong user, and there would be a race - condition. So, don't use systems that allow non-root users to - give files away. */ - } - - if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS) - { - /* When lchown exists, it should be used to change the attributes of - the symbolic link itself. In this case, a mere chown would change - the attributes of the file the symbolic link is pointing to, and - should be avoided. */ - int chown_result = 1; - - if (typeflag == SYMTYPE) - { -#if HAVE_LCHOWN - chown_result = lchown (file_name, st->stat.st_uid, st->stat.st_gid); -#endif - } - else - { - chown_result = chown (file_name, st->stat.st_uid, st->stat.st_gid); - } - - if (chown_result == 0) - { - /* Changing the owner can flip st_mode bits in some cases, so - ignore cur_info if it might be obsolete now. */ - if (cur_info - && cur_info->st_mode & S_IXUGO - && cur_info->st_mode & (S_ISUID | S_ISGID)) - cur_info = NULL; - } - else if (chown_result < 0) - chown_error_details (file_name, - st->stat.st_uid, st->stat.st_gid); - } - - if (typeflag != SYMTYPE) - set_mode (file_name, &st->stat, cur_info, - invert_permissions, permstatus, typeflag); -} - -/* Remember to restore stat attributes (owner, group, mode and times) - for the directory FILE_NAME, using information given in *ST, - once we stop extracting files into that directory. - If not restoring permissions, remember to invert the - INVERT_PERMISSIONS bits from the file's current permissions. - PERMSTATUS specifies the status of the file's permissions. - - NOTICE: this works only if the archive has usual member order, i.e. - directory, then the files in that directory. Incremental archive have - somewhat reversed order: first go subdirectories, then all other - members. To help cope with this case the variable - delay_directory_restore_option is set by prepare_to_extract. - - If an archive was explicitely created so that its member order is - reversed, some directory timestamps can be restored incorrectly, - e.g.: - tar --no-recursion -cf archive dir dir/file1 foo dir/file2 -*/ -static void -delay_set_stat (char const *file_name, struct tar_stat_info const *st, - mode_t invert_permissions, enum permstatus permstatus) -{ - size_t file_name_len = strlen (file_name); - struct delayed_set_stat *data = - xmalloc (offsetof (struct delayed_set_stat, file_name) - + file_name_len + 1); - data->next = delayed_set_stat_head; - data->dev = st->stat.st_dev; - data->ino = st->stat.st_ino; - data->mode = st->stat.st_mode; - data->uid = st->stat.st_uid; - data->gid = st->stat.st_gid; - data->atime = st->atime; - data->mtime = st->mtime; - data->file_name_len = file_name_len; - data->invert_permissions = invert_permissions; - data->permstatus = permstatus; - data->after_links = 0; - strcpy (data->file_name, file_name); - delayed_set_stat_head = data; -} - -/* Update the delayed_set_stat info for an intermediate directory - created within the file name of DIR. The intermediate directory turned - out to be the same as this directory, e.g. due to ".." or symbolic - links. *DIR_STAT_INFO is the status of the directory. */ -static void -repair_delayed_set_stat (char const *dir, - struct stat const *dir_stat_info) -{ - struct delayed_set_stat *data; - for (data = delayed_set_stat_head; data; data = data->next) - { - struct stat st; - if (stat (data->file_name, &st) != 0) - { - stat_error (data->file_name); - return; - } - - if (st.st_dev == dir_stat_info->st_dev - && st.st_ino == dir_stat_info->st_ino) - { - data->dev = current_stat_info.stat.st_dev; - data->ino = current_stat_info.stat.st_ino; - data->mode = current_stat_info.stat.st_mode; - data->uid = current_stat_info.stat.st_uid; - data->gid = current_stat_info.stat.st_gid; - data->atime = current_stat_info.atime; - data->mtime = current_stat_info.mtime; - data->invert_permissions = - ((current_stat_info.stat.st_mode ^ st.st_mode) - & MODE_RWX & ~ current_umask); - data->permstatus = ARCHIVED_PERMSTATUS; - return; - } - } - - ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"), - quotearg_colon (dir))); -} - -/* After a file/link/directory creation has failed, see if - it's because some required directory was not present, and if so, - create all required directories. Return non-zero if a directory - was created. */ -static int -make_directories (char *file_name) -{ - char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name); - char *cursor; /* points into the file name */ - int did_something = 0; /* did we do anything yet? */ - int mode; - int invert_permissions; - int status; - - for (cursor = cursor0; *cursor; cursor++) - { - if (! ISSLASH (*cursor)) - continue; - - /* Avoid mkdir of empty string, if leading or double '/'. */ - - if (cursor == cursor0 || ISSLASH (cursor[-1])) - continue; - - /* Avoid mkdir where last part of file name is "." or "..". */ - - if (cursor[-1] == '.' - && (cursor == cursor0 + 1 || ISSLASH (cursor[-2]) - || (cursor[-2] == '.' - && (cursor == cursor0 + 2 || ISSLASH (cursor[-3]))))) - continue; - - *cursor = '\0'; /* truncate the name there */ - mode = MODE_RWX & ~ newdir_umask; - invert_permissions = we_are_root ? 0 : MODE_WXUSR & ~ mode; - status = mkdir (file_name, mode ^ invert_permissions); - - if (status == 0) - { - /* Create a struct delayed_set_stat even if - invert_permissions is zero, because - repair_delayed_set_stat may need to update the struct. */ - delay_set_stat (file_name, - ¤t_stat_info, - invert_permissions, INTERDIR_PERMSTATUS); - - print_for_mkdir (file_name, cursor - file_name, mode); - did_something = 1; - - *cursor = '/'; - continue; - } - - *cursor = '/'; - - if (errno == EEXIST) - continue; /* Directory already exists. */ - else if ((errno == ENOSYS /* Automounted dirs on Solaris return - this. Reported by Warren Hyde - */ - || ERRNO_IS_EACCES) /* Turbo C mkdir gives a funny errno. */ - && access (file_name, W_OK) == 0) - continue; - - /* Some other error in the mkdir. We return to the caller. */ - break; - } - - return did_something; /* tell them to retry if we made one */ -} - -static bool -file_newer_p (const char *file_name, struct tar_stat_info *tar_stat) -{ - struct stat st; - - if (stat (file_name, &st)) - { - stat_warn (file_name); - /* Be on the safe side: if the file does exist assume it is newer */ - return errno != ENOENT; - } - if (!S_ISDIR (st.st_mode) - && tar_timespec_cmp (tar_stat->mtime, get_stat_mtime (&st)) <= 0) - { - return true; - } - return false; -} - -/* Attempt repairing what went wrong with the extraction. Delete an - already existing file or create missing intermediate directories. - Return nonzero if we somewhat increased our chances at a successful - extraction. errno is properly restored on zero return. */ -static int -maybe_recoverable (char *file_name, int *interdir_made) -{ - int e = errno; - - if (*interdir_made) - return 0; - - switch (errno) - { - case EEXIST: - /* Remove an old file, if the options allow this. */ - - switch (old_files_option) - { - case KEEP_OLD_FILES: - return 0; - - case KEEP_NEWER_FILES: - if (file_newer_p (file_name, ¤t_stat_info)) - { - errno = e; - return 0; - } - /* FALL THROUGH */ - - case DEFAULT_OLD_FILES: - case NO_OVERWRITE_DIR_OLD_FILES: - case OVERWRITE_OLD_FILES: - { - int r = remove_any_file (file_name, ORDINARY_REMOVE_OPTION); - errno = EEXIST; - return r; - } - - case UNLINK_FIRST_OLD_FILES: - break; - } - - case ENOENT: - /* Attempt creating missing intermediate directories. */ - if (! make_directories (file_name)) - { - errno = ENOENT; - return 0; - } - *interdir_made = 1; - return 1; - - default: - /* Just say we can't do anything about it... */ - - return 0; - } -} - -/* Fix the statuses of all directories whose statuses need fixing, and - which are not ancestors of FILE_NAME. If AFTER_LINKS is - nonzero, do this for all such directories; otherwise, stop at the - first directory that is marked to be fixed up only after delayed - links are applied. */ -static void -apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links) -{ - size_t file_name_len = strlen (file_name); - bool check_for_renamed_directories = 0; - - while (delayed_set_stat_head) - { - struct delayed_set_stat *data = delayed_set_stat_head; - bool skip_this_one = 0; - struct stat st; - struct stat const *cur_info = 0; - - check_for_renamed_directories |= data->after_links; - - if (after_links < data->after_links - || (data->file_name_len < file_name_len - && file_name[data->file_name_len] - && (ISSLASH (file_name[data->file_name_len]) - || ISSLASH (file_name[data->file_name_len - 1])) - && memcmp (file_name, data->file_name, data->file_name_len) == 0)) - break; - - if (check_for_renamed_directories) - { - cur_info = &st; - if (stat (data->file_name, &st) != 0) - { - stat_error (data->file_name); - skip_this_one = 1; - } - else if (! (st.st_dev == data->dev && st.st_ino == data->ino)) - { - ERROR ((0, 0, - _("%s: Directory renamed before its status could be extracted"), - quotearg_colon (data->file_name))); - skip_this_one = 1; - } - } - - if (! skip_this_one) - { - struct tar_stat_info sb; - sb.stat.st_mode = data->mode; - sb.stat.st_uid = data->uid; - sb.stat.st_gid = data->gid; - sb.atime = data->atime; - sb.mtime = data->mtime; - set_stat (data->file_name, &sb, cur_info, - data->invert_permissions, data->permstatus, DIRTYPE); - } - - delayed_set_stat_head = data->next; - free (data); - } -} - - - -/* Extractor functions for various member types */ - -static int -extract_dir (char *file_name, int typeflag) -{ - int status; - mode_t mode; - int interdir_made = 0; - - /* Save 'root device' to avoid purging mount points. */ - if (one_file_system_option && root_device == 0) - { - struct stat st; - char *dir = xgetcwd (); - - if (deref_stat (true, dir, &st)) - stat_diag (dir); - else - root_device = st.st_dev; - free (dir); - } - - if (incremental_option) - /* Read the entry and delete files that aren't listed in the archive. */ - purge_directory (file_name); - else if (typeflag == GNUTYPE_DUMPDIR) - skip_member (); - - mode = current_stat_info.stat.st_mode | (we_are_root ? 0 : MODE_WXUSR); - if (0 < same_owner_option || current_stat_info.stat.st_mode & ~ MODE_RWX) - mode &= S_IRWXU; - - while ((status = mkdir (file_name, mode))) - { - if (errno == EEXIST - && (interdir_made - || old_files_option == DEFAULT_OLD_FILES - || old_files_option == OVERWRITE_OLD_FILES)) - { - struct stat st; - if (stat (file_name, &st) == 0) - { - if (interdir_made) - { - repair_delayed_set_stat (file_name, &st); - return 0; - } - if (S_ISDIR (st.st_mode)) - { - mode = st.st_mode; - break; - } - } - errno = EEXIST; - } - - if (maybe_recoverable (file_name, &interdir_made)) - continue; - - if (errno != EEXIST) - { - mkdir_error (file_name); - return 1; - } - break; - } - - if (status == 0 - || old_files_option == DEFAULT_OLD_FILES - || old_files_option == OVERWRITE_OLD_FILES) - { - if (status == 0) - delay_set_stat (file_name, ¤t_stat_info, - ((mode ^ current_stat_info.stat.st_mode) - & MODE_RWX & ~ current_umask), - ARCHIVED_PERMSTATUS); - else /* For an already existing directory, invert_perms must be 0 */ - delay_set_stat (file_name, ¤t_stat_info, - 0, - UNKNOWN_PERMSTATUS); - } - return status; -} - - -static int -open_output_file (char *file_name, int typeflag, mode_t mode) -{ - int fd; - int openflag = (O_WRONLY | O_BINARY | O_CREAT - | (old_files_option == OVERWRITE_OLD_FILES - ? O_TRUNC - : O_EXCL)); - -#if O_CTG - /* Contiguous files (on the Masscomp) have to specify the size in - the open call that creates them. */ - - if (typeflag == CONTTYPE) - fd = open (file_name, openflag | O_CTG, mode, current_stat_info.stat.st_size); - else - fd = open (file_name, openflag, mode); - -#else /* not O_CTG */ - if (typeflag == CONTTYPE) - { - static int conttype_diagnosed; - - if (!conttype_diagnosed) - { - conttype_diagnosed = 1; - WARN ((0, 0, _("Extracting contiguous files as regular files"))); - } - } - fd = open (file_name, openflag, mode); - -#endif /* not O_CTG */ - - return fd; -} - -static int -extract_file (char *file_name, int typeflag) -{ - int fd; - off_t size; - union block *data_block; - int status; - size_t count; - size_t written; - int interdir_made = 0; - mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask; - mode_t invert_permissions = - 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; - - /* FIXME: deal with protection issues. */ - - if (to_stdout_option) - fd = STDOUT_FILENO; - else if (to_command_option) - { - fd = sys_exec_command (file_name, 'f', ¤t_stat_info); - if (fd < 0) - { - skip_member (); - return 0; - } - } - else - { - do - fd = open_output_file (file_name, typeflag, mode ^ invert_permissions); - while (fd < 0 && maybe_recoverable (file_name, &interdir_made)); - - if (fd < 0) - { - skip_member (); - open_error (file_name); - return 1; - } - } - - mv_begin (¤t_stat_info); - if (current_stat_info.is_sparse) - sparse_extract_file (fd, ¤t_stat_info, &size); - else - for (size = current_stat_info.stat.st_size; size > 0; ) - { - mv_size_left (size); - - /* Locate data, determine max length writeable, write it, - block that we have used the data, then check if the write - worked. */ - - data_block = find_next_block (); - if (! data_block) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - break; /* FIXME: What happens, then? */ - } - - written = available_space_after (data_block); - - if (written > size) - written = size; - errno = 0; - count = full_write (fd, data_block->buffer, written); - size -= written; - - set_next_block_after ((union block *) - (data_block->buffer + written - 1)); - if (count != written) - { - if (!to_command_option) - write_error_details (file_name, count, written); - /* FIXME: shouldn't we restore from backup? */ - break; - } - } - - skip_file (size); - - mv_end (); - - /* If writing to stdout, don't try to do anything to the filename; - it doesn't exist, or we don't want to touch it anyway. */ - - if (to_stdout_option) - return 0; - - status = close (fd); - if (status < 0) - close_error (file_name); - - if (to_command_option) - sys_wait_command (); - else - set_stat (file_name, ¤t_stat_info, NULL, invert_permissions, - (old_files_option == OVERWRITE_OLD_FILES ? - UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS), - typeflag); - - return status; -} - -/* Create a placeholder file with name FILE_NAME, which will be - replaced after other extraction is done by a symbolic link if - IS_SYMLINK is true, and by a hard link otherwise. Set - *INTERDIR_MADE if an intermediate directory is made in the - process. */ - -static int -create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made) -{ - int fd; - struct stat st; - - while ((fd = open (file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0) - if (! maybe_recoverable (file_name, interdir_made)) - break; - - if (fd < 0) - open_error (file_name); - else if (fstat (fd, &st) != 0) - { - stat_error (file_name); - close (fd); - } - else if (close (fd) != 0) - close_error (file_name); - else - { - struct delayed_set_stat *h; - struct delayed_link *p = - xmalloc (offsetof (struct delayed_link, target) - + strlen (current_stat_info.link_name) - + 1); - p->next = delayed_link_head; - delayed_link_head = p; - p->dev = st.st_dev; - p->ino = st.st_ino; - p->mtime = get_stat_mtime (&st); - p->is_symlink = is_symlink; - if (is_symlink) - { - p->uid = current_stat_info.stat.st_uid; - p->gid = current_stat_info.stat.st_gid; - } - p->sources = xmalloc (offsetof (struct string_list, string) - + strlen (file_name) + 1); - p->sources->next = 0; - strcpy (p->sources->string, file_name); - strcpy (p->target, current_stat_info.link_name); - - h = delayed_set_stat_head; - if (h && ! h->after_links - && strncmp (file_name, h->file_name, h->file_name_len) == 0 - && ISSLASH (file_name[h->file_name_len]) - && (last_component (file_name) == file_name + h->file_name_len + 1)) - { - do - { - h->after_links = 1; - - if (stat (h->file_name, &st) != 0) - stat_error (h->file_name); - else - { - h->dev = st.st_dev; - h->ino = st.st_ino; - } - } - while ((h = h->next) && ! h->after_links); - } - - return 0; - } - - return -1; -} - -static int -extract_link (char *file_name, int typeflag) -{ - int interdir_made = 0; - char const *link_name; - - transform_member_name (¤t_stat_info.link_name, xform_link); - link_name = current_stat_info.link_name; - - if (! absolute_names_option && contains_dot_dot (link_name)) - return create_placeholder_file (file_name, false, &interdir_made); - - do - { - struct stat st1, st2; - int e; - int status = link (link_name, file_name); - e = errno; - - if (status == 0) - { - struct delayed_link *ds = delayed_link_head; - if (ds && lstat (link_name, &st1) == 0) - for (; ds; ds = ds->next) - if (ds->dev == st1.st_dev - && ds->ino == st1.st_ino - && timespec_cmp (ds->mtime, get_stat_mtime (&st1)) == 0) - { - struct string_list *p = xmalloc (offsetof (struct string_list, string) - + strlen (file_name) + 1); - strcpy (p->string, file_name); - p->next = ds->sources; - ds->sources = p; - break; - } - return 0; - } - else if ((e == EEXIST && strcmp (link_name, file_name) == 0) - || (lstat (link_name, &st1) == 0 - && lstat (file_name, &st2) == 0 - && st1.st_dev == st2.st_dev - && st1.st_ino == st2.st_ino)) - return 0; - - errno = e; - } - while (maybe_recoverable (file_name, &interdir_made)); - - if (!(incremental_option && errno == EEXIST)) - { - link_error (link_name, file_name); - return 1; - } - return 0; -} - -static int -extract_symlink (char *file_name, int typeflag) -{ -#ifdef HAVE_SYMLINK - int status; - int interdir_made = 0; - - transform_member_name (¤t_stat_info.link_name, xform_symlink); - - if (! absolute_names_option - && (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name) - || contains_dot_dot (current_stat_info.link_name))) - return create_placeholder_file (file_name, true, &interdir_made); - - while ((status = symlink (current_stat_info.link_name, file_name))) - if (!maybe_recoverable (file_name, &interdir_made)) - break; - - if (status == 0) - set_stat (file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE); - else - symlink_error (current_stat_info.link_name, file_name); - return status; - -#else - static int warned_once; - - if (!warned_once) - { - warned_once = 1; - WARN ((0, 0, _("Attempting extraction of symbolic links as hard links"))); - } - return extract_link (file_name, typeflag); -#endif -} - -#if S_IFCHR || S_IFBLK -static int -extract_node (char *file_name, int typeflag) -{ - int status; - int interdir_made = 0; - mode_t mode = current_stat_info.stat.st_mode & ~ current_umask; - mode_t invert_permissions = - 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; - - do - status = mknod (file_name, mode ^ invert_permissions, - current_stat_info.stat.st_rdev); - while (status && maybe_recoverable (file_name, &interdir_made)); - - if (status != 0) - mknod_error (file_name); - else - set_stat (file_name, ¤t_stat_info, NULL, invert_permissions, - ARCHIVED_PERMSTATUS, typeflag); - return status; -} -#endif - -#if HAVE_MKFIFO || defined mkfifo -static int -extract_fifo (char *file_name, int typeflag) -{ - int status; - int interdir_made = 0; - mode_t mode = current_stat_info.stat.st_mode & ~ current_umask; - mode_t invert_permissions = - 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; - - while ((status = mkfifo (file_name, mode)) != 0) - if (!maybe_recoverable (file_name, &interdir_made)) - break; - - if (status == 0) - set_stat (file_name, ¤t_stat_info, NULL, invert_permissions, - ARCHIVED_PERMSTATUS, typeflag); - else - mkfifo_error (file_name); - return status; -} -#endif - -static int -extract_volhdr (char *file_name, int typeflag) -{ - if (verbose_option) - fprintf (stdlis, _("Reading %s\n"), quote (current_stat_info.file_name)); - skip_member (); - return 0; -} - -static int -extract_failure (char *file_name, int typeflag) -{ - return 1; -} - -typedef int (*tar_extractor_t) (char *file_name, int typeflag); - - - -/* Prepare to extract a file. Find extractor function. - Return zero if extraction should not proceed. */ - -static int -prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun) -{ - int rc = 1; - - if (EXTRACT_OVER_PIPE) - rc = 0; - - /* Select the extractor */ - switch (typeflag) - { - case GNUTYPE_SPARSE: - *fun = extract_file; - rc = 1; - break; - - case AREGTYPE: - case REGTYPE: - case CONTTYPE: - /* Appears to be a file. But BSD tar uses the convention that a slash - suffix means a directory. */ - if (current_stat_info.had_trailing_slash) - *fun = extract_dir; - else - { - *fun = extract_file; - rc = 1; - } - break; - - case SYMTYPE: - *fun = extract_symlink; - break; - - case LNKTYPE: - *fun = extract_link; - break; - -#if S_IFCHR - case CHRTYPE: - current_stat_info.stat.st_mode |= S_IFCHR; - *fun = extract_node; - break; -#endif - -#if S_IFBLK - case BLKTYPE: - current_stat_info.stat.st_mode |= S_IFBLK; - *fun = extract_node; - break; -#endif - -#if HAVE_MKFIFO || defined mkfifo - case FIFOTYPE: - *fun = extract_fifo; - break; -#endif - - case DIRTYPE: - case GNUTYPE_DUMPDIR: - *fun = extract_dir; - if (current_stat_info.is_dumpdir) - delay_directory_restore_option = true; - break; - - case GNUTYPE_VOLHDR: - *fun = extract_volhdr; - break; - - case GNUTYPE_MULTIVOL: - ERROR ((0, 0, - _("%s: Cannot extract -- file is continued from another volume"), - quotearg_colon (current_stat_info.file_name))); - *fun = extract_failure; - break; - - case GNUTYPE_LONGNAME: - case GNUTYPE_LONGLINK: - ERROR ((0, 0, _("Unexpected long name header"))); - *fun = extract_failure; - break; - - default: - WARN ((0, 0, - _("%s: Unknown file type `%c', extracted as normal file"), - quotearg_colon (file_name), typeflag)); - *fun = extract_file; - } - - /* Determine whether the extraction should proceed */ - if (rc == 0) - return 0; - - switch (old_files_option) - { - case UNLINK_FIRST_OLD_FILES: - if (!remove_any_file (file_name, - recursive_unlink_option ? RECURSIVE_REMOVE_OPTION - : ORDINARY_REMOVE_OPTION) - && errno && errno != ENOENT) - { - unlink_error (file_name); - return 0; - } - break; - - case KEEP_NEWER_FILES: - if (file_newer_p (file_name, ¤t_stat_info)) - { - WARN ((0, 0, _("Current %s is newer or same age"), - quote (file_name))); - return 0; - } - break; - - default: - break; - } - - return 1; -} - -/* Extract a file from the archive. */ -void -extract_archive (void) -{ - char typeflag; - tar_extractor_t fun; - - set_next_block_after (current_header); - decode_header (current_header, ¤t_stat_info, ¤t_format, 1); - if (!current_stat_info.file_name[0] - || (interactive_option - && !confirm ("extract", current_stat_info.file_name))) - { - skip_member (); - return; - } - - /* Print the block from current_header and current_stat. */ - if (verbose_option) - print_header (¤t_stat_info, -1); - - /* Restore stats for all non-ancestor directories, unless - it is an incremental archive. - (see NOTICE in the comment to delay_set_stat above) */ - if (!delay_directory_restore_option) - apply_nonancestor_delayed_set_stat (current_stat_info.file_name, 0); - - /* Take a safety backup of a previously existing file. */ - - if (backup_option) - if (!maybe_backup_file (current_stat_info.file_name, 0)) - { - int e = errno; - ERROR ((0, e, _("%s: Was unable to backup this file"), - quotearg_colon (current_stat_info.file_name))); - skip_member (); - return; - } - - /* Extract the archive entry according to its type. */ - /* KLUDGE */ - typeflag = sparse_member_p (¤t_stat_info) ? - GNUTYPE_SPARSE : current_header->header.typeflag; - - if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun)) - { - if (fun && (*fun) (current_stat_info.file_name, typeflag) - && backup_option) - undo_last_backup (); - } - else - skip_member (); - -} - -/* Extract the symbolic links whose final extraction were delayed. */ -static void -apply_delayed_links (void) -{ - struct delayed_link *ds; - - for (ds = delayed_link_head; ds; ) - { - struct string_list *sources = ds->sources; - char const *valid_source = 0; - - for (sources = ds->sources; sources; sources = sources->next) - { - char const *source = sources->string; - struct stat st; - - /* Make sure the placeholder file is still there. If not, - don't create a link, as the placeholder was probably - removed by a later extraction. */ - if (lstat (source, &st) == 0 - && st.st_dev == ds->dev - && st.st_ino == ds->ino - && timespec_cmp (get_stat_mtime (&st), ds->mtime) == 0) - { - /* Unlink the placeholder, then create a hard link if possible, - a symbolic link otherwise. */ - if (unlink (source) != 0) - unlink_error (source); - else if (valid_source && link (valid_source, source) == 0) - ; - else if (!ds->is_symlink) - { - if (link (ds->target, source) != 0) - link_error (ds->target, source); - } - else if (symlink (ds->target, source) != 0) - symlink_error (ds->target, source); - else - { - struct tar_stat_info st1; - st1.stat.st_uid = ds->uid; - st1.stat.st_gid = ds->gid; - set_stat (source, &st1, NULL, 0, 0, SYMTYPE); - valid_source = source; - } - } - } - - for (sources = ds->sources; sources; ) - { - struct string_list *next = sources->next; - free (sources); - sources = next; - } - - { - struct delayed_link *next = ds->next; - free (ds); - ds = next; - } - } - - delayed_link_head = 0; -} - -/* Finish the extraction of an archive. */ -void -extract_finish (void) -{ - /* First, fix the status of ordinary directories that need fixing. */ - apply_nonancestor_delayed_set_stat ("", 0); - - /* Then, apply delayed links, so that they don't affect delayed - directory status-setting for ordinary directories. */ - apply_delayed_links (); - - /* Finally, fix the status of directories that are ancestors - of delayed links. */ - apply_nonancestor_delayed_set_stat ("", 1); -} - -bool -rename_directory (char *src, char *dst) -{ - if (rename (src, dst)) - { - int e = errno; - - switch (e) - { - case ENOENT: - if (make_directories (dst)) - { - if (rename (src, dst) == 0) - return true; - e = errno; - } - break; - - case EXDEV: - /* FIXME: Fall back to recursive copying */ - - default: - break; - } - - ERROR ((0, e, _("Cannot rename %s to %s"), - quote_n (0, src), - quote_n (1, dst))); - return false; - } - return true; -} - -void -fatal_exit (void) -{ - extract_finish (); - error (TAREXIT_FAILURE, 0, _("Error is not recoverable: exiting now")); - abort (); -} - -void -xalloc_die (void) -{ - error (0, 0, "%s", _("memory exhausted")); - fatal_exit (); -} diff --git a/src/bin/tar/src/incremen.c b/src/bin/tar/src/incremen.c deleted file mode 100644 index bc5fdaded6..0000000000 --- a/src/bin/tar/src/incremen.c +++ /dev/null @@ -1,1541 +0,0 @@ -/* GNU dump extensions to tar. - - Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include -#include "common.h" - -/* Incremental dump specialities. */ - -/* Which child files to save under a directory. */ -enum children - { - NO_CHILDREN, - CHANGED_CHILDREN, - ALL_CHILDREN - }; - -#define DIRF_INIT 0x0001 /* directory structure is initialized - (procdir called at least once) */ -#define DIRF_NFS 0x0002 /* directory is mounted on nfs */ -#define DIRF_FOUND 0x0004 /* directory is found on fs */ -#define DIRF_NEW 0x0008 /* directory is new (not found - in the previous dump) */ -#define DIRF_RENAMED 0x0010 /* directory is renamed */ - -#define DIR_IS_INITED(d) ((d)->flags & DIRF_INIT) -#define DIR_IS_NFS(d) ((d)->flags & DIRF_NFS) -#define DIR_IS_FOUND(d) ((d)->flags & DIRF_FOUND) -#define DIR_IS_NEW(d) ((d)->flags & DIRF_NEW) -#define DIR_IS_RENAMED(d) ((d)->flags & DIRF_RENAMED) - -#define DIR_SET_FLAG(d,f) (d)->flags |= (f) -#define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f) - -/* Directory attributes. */ -struct directory - { - struct timespec mtime; /* Modification time */ - dev_t device_number; /* device number for directory */ - ino_t inode_number; /* inode number for directory */ - char *contents; /* Directory contents */ - char *icontents; /* Initial contents if the directory was - rescanned */ - enum children children; /* What to save under this directory */ - unsigned flags; /* See DIRF_ macros above */ - struct directory *orig; /* If the directory was renamed, points to - the original directory structure */ - const char *tagfile; /* Tag file, if the directory falls under - exclusion_tag_under */ - char name[1]; /* file name of directory */ - }; - -static Hash_table *directory_table; -static Hash_table *directory_meta_table; - -#if HAVE_ST_FSTYPE_STRING - static char const nfs_string[] = "nfs"; -# define NFS_FILE_STAT(st) (strcmp ((st).st_fstype, nfs_string) == 0) -#else -# define ST_DEV_MSB(st) (~ (dev_t) 0 << (sizeof (st).st_dev * CHAR_BIT - 1)) -# define NFS_FILE_STAT(st) (((st).st_dev & ST_DEV_MSB (st)) != 0) -#endif - -/* Calculate the hash of a directory. */ -static size_t -hash_directory_name (void const *entry, size_t n_buckets) -{ - struct directory const *directory = entry; - return hash_string (directory->name, n_buckets); -} - -/* Compare two directories for equality of their names. */ -static bool -compare_directory_names (void const *entry1, void const *entry2) -{ - struct directory const *directory1 = entry1; - struct directory const *directory2 = entry2; - return strcmp (directory1->name, directory2->name) == 0; -} - -static size_t -hash_directory_meta (void const *entry, size_t n_buckets) -{ - struct directory const *directory = entry; - /* FIXME: Work out a better algorytm */ - return (directory->device_number + directory->inode_number) % n_buckets; -} - -/* Compare two directories for equality of their device and inode numbers. */ -static bool -compare_directory_meta (void const *entry1, void const *entry2) -{ - struct directory const *directory1 = entry1; - struct directory const *directory2 = entry2; - return directory1->device_number == directory2->device_number - && directory1->inode_number == directory2->inode_number; -} - -/* Make a directory entry for given NAME */ -static struct directory * -make_directory (const char *name) -{ - size_t namelen = strlen (name); - size_t size = offsetof (struct directory, name) + namelen + 1; - struct directory *directory = xmalloc (size); - directory->contents = directory->icontents = NULL; - directory->orig = NULL; - directory->flags = false; - strcpy (directory->name, name); - if (ISSLASH (directory->name[namelen-1])) - directory->name[namelen-1] = 0; - directory->tagfile = NULL; - return directory; -} - -/* Create and link a new directory entry for directory NAME, having a - device number DEV and an inode number INO, with NFS indicating - whether it is an NFS device and FOUND indicating whether we have - found that the directory exists. */ -static struct directory * -note_directory (char const *name, struct timespec mtime, - dev_t dev, ino_t ino, bool nfs, bool found, char *contents) -{ - struct directory *directory = make_directory (name); - - directory->mtime = mtime; - directory->device_number = dev; - directory->inode_number = ino; - directory->children = CHANGED_CHILDREN; - if (nfs) - DIR_SET_FLAG (directory, DIRF_NFS); - if (found) - DIR_SET_FLAG (directory, DIRF_FOUND); - if (contents) - { - size_t size = dumpdir_size (contents); - directory->contents = xmalloc (size); - memcpy (directory->contents, contents, size); - } - else - directory->contents = NULL; - - if (! ((directory_table - || (directory_table = hash_initialize (0, 0, - hash_directory_name, - compare_directory_names, 0))) - && hash_insert (directory_table, directory))) - xalloc_die (); - - if (! ((directory_meta_table - || (directory_meta_table = hash_initialize (0, 0, - hash_directory_meta, - compare_directory_meta, - 0))) - && hash_insert (directory_meta_table, directory))) - xalloc_die (); - - return directory; -} - -/* Return a directory entry for a given file NAME, or zero if none found. */ -static struct directory * -find_directory (const char *name) -{ - if (! directory_table) - return 0; - else - { - struct directory *dir = make_directory (name); - struct directory *ret = hash_lookup (directory_table, dir); - free (dir); - return ret; - } -} - -/* Return a directory entry for a given combination of device and inode - numbers, or zero if none found. */ -static struct directory * -find_directory_meta (dev_t dev, ino_t ino) -{ - if (! directory_meta_table) - return 0; - else - { - struct directory *dir = make_directory (""); - struct directory *ret; - dir->device_number = dev; - dir->inode_number = ino; - ret = hash_lookup (directory_meta_table, dir); - free (dir); - return ret; - } -} - -void -update_parent_directory (const char *name) -{ - struct directory *directory; - char *p; - - p = dir_name (name); - directory = find_directory (p); - if (directory) - { - struct stat st; - if (deref_stat (dereference_option, p, &st) != 0) - stat_diag (name); - else - directory->mtime = get_stat_mtime (&st); - } - free (p); -} - -static struct directory * -procdir (char *name_buffer, struct stat *stat_data, - dev_t device, - enum children children, - bool verbose, - char *entry) -{ - struct directory *directory; - bool nfs = NFS_FILE_STAT (*stat_data); - - if ((directory = find_directory (name_buffer)) != NULL) - { - if (DIR_IS_INITED (directory)) - return directory; - - /* With NFS, the same file can have two different devices - if an NFS directory is mounted in multiple locations, - which is relatively common when automounting. - To avoid spurious incremental redumping of - directories, consider all NFS devices as equal, - relying on the i-node to establish differences. */ - - if (! (((DIR_IS_NFS (directory) & nfs) - || directory->device_number == stat_data->st_dev) - && directory->inode_number == stat_data->st_ino)) - { - /* FIXME: find_directory_meta ignores nfs */ - struct directory *d = find_directory_meta (stat_data->st_dev, - stat_data->st_ino); - if (d) - { - if (verbose_option) - WARN ((0, 0, _("%s: Directory has been renamed from %s"), - quotearg_colon (name_buffer), - quote_n (1, d->name))); - directory->orig = d; - DIR_SET_FLAG (directory, DIRF_RENAMED); - directory->children = CHANGED_CHILDREN; - } - else - { - if (verbose_option) - WARN ((0, 0, _("%s: Directory has been renamed"), - quotearg_colon (name_buffer))); - directory->children = ALL_CHILDREN; - directory->device_number = stat_data->st_dev; - directory->inode_number = stat_data->st_ino; - } - if (nfs) - DIR_SET_FLAG (directory, DIRF_NFS); - } - else - directory->children = CHANGED_CHILDREN; - - DIR_SET_FLAG (directory, DIRF_FOUND); - } - else - { - struct directory *d = find_directory_meta (stat_data->st_dev, - stat_data->st_ino); - - directory = note_directory (name_buffer, - get_stat_mtime(stat_data), - stat_data->st_dev, - stat_data->st_ino, - nfs, - true, - NULL); - - if (d) - { - if (verbose) - WARN ((0, 0, _("%s: Directory has been renamed from %s"), - quotearg_colon (name_buffer), - quote_n (1, d->name))); - directory->orig = d; - DIR_SET_FLAG (directory, DIRF_RENAMED); - directory->children = CHANGED_CHILDREN; - } - else - { - DIR_SET_FLAG (directory, DIRF_NEW); - if (verbose) - WARN ((0, 0, _("%s: Directory is new"), - quotearg_colon (name_buffer))); - directory->children = - (listed_incremental_option - || (OLDER_STAT_TIME (*stat_data, m) - || (after_date_option - && OLDER_STAT_TIME (*stat_data, c)))) - ? ALL_CHILDREN - : CHANGED_CHILDREN; - } - } - - /* If the directory is on another device and --one-file-system was given, - omit it... */ - if (one_file_system_option && device != stat_data->st_dev - /* ... except if it was explicitely given in the command line */ - && !is_individual_file (name_buffer)) - directory->children = NO_CHILDREN; - else if (children == ALL_CHILDREN) - directory->children = ALL_CHILDREN; - - DIR_SET_FLAG (directory, DIRF_INIT); - - { - const char *tag_file_name; - size_t len; - - switch (check_exclusion_tags (name_buffer, &tag_file_name)) - { - case exclusion_tag_all: - /* This warning can be duplicated by code in dump_file0, but only - in case when the topmost directory being archived contains - an exclusion tag. */ - exclusion_tag_warning (name_buffer, tag_file_name, - _("directory not dumped")); - if (entry) - *entry = 'N'; - directory->children = NO_CHILDREN; - break; - - case exclusion_tag_contents: - exclusion_tag_warning (name_buffer, tag_file_name, - _("contents not dumped")); - directory->children = NO_CHILDREN; - break; - - case exclusion_tag_under: - exclusion_tag_warning (name_buffer, tag_file_name, - _("contents not dumped")); - directory->tagfile = tag_file_name; - break; - - case exclusion_tag_none: - break; - } - } - - return directory; -} - -/* Locate NAME in the dumpdir array DUMP. - Return pointer to the slot in the array, or NULL if not found */ -const char * -dumpdir_locate (const char *dump, const char *name) -{ - if (dump) - while (*dump) - { - /* Ignore 'R' (rename) and 'X' (tempname) entries, since they break - alphabetical ordering. - They normally do not occur in dumpdirs from the snapshot files, - but this function is also used by purge_directory, which operates - on a dumpdir from the archive, hence the need for this test. */ - if (!strchr ("RX", *dump)) - { - int rc = strcmp (dump + 1, name); - if (rc == 0) - return dump; - if (rc > 1) - break; - } - dump += strlen (dump) + 1; - } - return NULL; -} - -/* Return size in bytes of the dumpdir array P */ -size_t -dumpdir_size (const char *p) -{ - size_t totsize = 0; - - while (*p) - { - size_t size = strlen (p) + 1; - totsize += size; - p += size; - } - return totsize + 1; -} - -static int -compare_dirnames (const void *first, const void *second) -{ - char const *const *name1 = first; - char const *const *name2 = second; - return strcmp (*name1, *name2); -} - -/* Compare dumpdir array from DIRECTORY with directory listing DIR and - build a new dumpdir template. - - DIR must be returned by a previous call to savedir(). - - File names in DIRECTORY->contents must be sorted - alphabetically. - - DIRECTORY->contents is replaced with the created template. Each entry is - prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */ - -void -makedumpdir (struct directory *directory, const char *dir) -{ - size_t i, - dirsize, /* Number of elements in DIR */ - len; /* Length of DIR, including terminating nul */ - const char *p; - char const **array; - char *new_dump, *new_dump_ptr; - const char *dump; - - if (directory->children == ALL_CHILDREN) - dump = NULL; - else if (DIR_IS_RENAMED (directory)) - dump = directory->orig->icontents ? - directory->orig->icontents : directory->orig->contents; - else - dump = directory->contents; - - /* Count the size of DIR and the number of elements it contains */ - dirsize = 0; - len = 0; - for (p = dir; *p; p += strlen (p) + 1, dirsize++) - len += strlen (p) + 2; - len++; - - /* Create a sorted directory listing */ - array = xcalloc (dirsize, sizeof array[0]); - for (i = 0, p = dir; *p; p += strlen (p) + 1, i++) - array[i] = p; - - qsort (array, dirsize, sizeof (array[0]), compare_dirnames); - - /* Prepare space for new dumpdir */ - new_dump = xmalloc (len); - new_dump_ptr = new_dump; - - /* Fill in the dumpdir template */ - for (i = 0; i < dirsize; i++) - { - const char *loc = dumpdir_locate (dump, array[i]); - if (loc) - { - if (directory->tagfile) - *new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ? - ' ' : 'I'; - else - *new_dump_ptr = ' '; - new_dump_ptr++; - dump = loc + strlen (loc) + 1; - } - else if (directory->tagfile) - *new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ? - ' ' : 'I'; - else - *new_dump_ptr++ = 'Y'; /* New entry */ - - /* Copy the file name */ - for (p = array[i]; (*new_dump_ptr++ = *p++); ) - ; - } - *new_dump_ptr = 0; - directory->icontents = directory->contents; - directory->contents = new_dump; - free (array); -} - -/* Recursively scan the given directory. */ -static char * -scan_directory (char *dir, dev_t device) -{ - char *dirp = savedir (dir); /* for scanning directory */ - char *name_buffer; /* directory, `/', and directory member */ - size_t name_buffer_size; /* allocated size of name_buffer, minus 2 */ - size_t name_length; /* used length in name_buffer */ - struct stat stat_data; - struct directory *directory; - - if (! dirp) - savedir_error (dir); - - name_buffer_size = strlen (dir) + NAME_FIELD_SIZE; - name_buffer = xmalloc (name_buffer_size + 2); - strcpy (name_buffer, dir); - if (! ISSLASH (dir[strlen (dir) - 1])) - strcat (name_buffer, "/"); - name_length = strlen (name_buffer); - - if (deref_stat (dereference_option, name_buffer, &stat_data)) - { - stat_diag (name_buffer); - /* FIXME: used to be - children = CHANGED_CHILDREN; - but changed to: */ - free (name_buffer); - free (dirp); - return NULL; - } - - directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false, - NULL); - - if (dirp && directory->children != NO_CHILDREN) - { - char *entry; /* directory entry being scanned */ - size_t entrylen; /* length of directory entry */ - - makedumpdir (directory, dirp); - - for (entry = directory->contents; - (entrylen = strlen (entry)) != 0; - entry += entrylen + 1) - { - if (name_buffer_size <= entrylen - 1 + name_length) - { - do - name_buffer_size += NAME_FIELD_SIZE; - while (name_buffer_size <= entrylen - 1 + name_length); - name_buffer = xrealloc (name_buffer, name_buffer_size + 2); - } - strcpy (name_buffer + name_length, entry + 1); - - if (*entry == 'I') /* Ignored entry */ - *entry = 'N'; - else if (excluded_name (name_buffer)) - *entry = 'N'; - else - { - if (deref_stat (dereference_option, name_buffer, &stat_data)) - { - stat_diag (name_buffer); - *entry = 'N'; - continue; - } - - if (S_ISDIR (stat_data.st_mode)) - { - *entry = 'D'; - procdir (name_buffer, &stat_data, device, - directory->children, - verbose_option, entry); - } - - else if (one_file_system_option && device != stat_data.st_dev) - *entry = 'N'; - - else if (*entry == 'Y') - /* New entry, skip further checks */; - - /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */ - - else if (OLDER_STAT_TIME (stat_data, m) - && (!after_date_option - || OLDER_STAT_TIME (stat_data, c))) - *entry = 'N'; - else - *entry = 'Y'; - } - } - } - - free (name_buffer); - if (dirp) - free (dirp); - - return directory->contents; -} - -char * -get_directory_contents (char *dir, dev_t device) -{ - return scan_directory (dir, device); -} - - -static void -obstack_code_rename (struct obstack *stk, char *from, char *to) -{ - char *s; - - s = from[0] == 0 ? from : - safer_name_suffix (from, false, absolute_names_option); - obstack_1grow (stk, 'R'); - obstack_grow (stk, s, strlen (s) + 1); - - s = to[0] == 0 ? to: - safer_name_suffix (to, false, absolute_names_option); - obstack_1grow (stk, 'T'); - obstack_grow (stk, s, strlen (s) + 1); -} - -static bool -rename_handler (void *data, void *proc_data) -{ - struct directory *dir = data; - struct obstack *stk = proc_data; - - if (DIR_IS_RENAMED (dir)) - { - struct directory *prev, *p; - - /* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries - are ignored when hit by this function next time. - If the chain forms a cycle, prev points to the entry DIR is renamed - from. In this case it still retains DIRF_RENAMED flag, which will be - cleared in the `else' branch below */ - for (prev = dir; prev && prev->orig != dir; prev = prev->orig) - DIR_CLEAR_FLAG (prev, DIRF_RENAMED); - - if (prev == NULL) - { - for (p = dir; p && p->orig; p = p->orig) - obstack_code_rename (stk, p->orig->name, p->name); - } - else - { - char *temp_name; - - DIR_CLEAR_FLAG (prev, DIRF_RENAMED); - - /* Break the cycle by using a temporary name for one of its - elements. - First, create a temp name stub entry. */ - temp_name = dir_name (dir->name); - obstack_1grow (stk, 'X'); - obstack_grow (stk, temp_name, strlen (temp_name) + 1); - - obstack_code_rename (stk, dir->name, ""); - - for (p = dir; p != prev; p = p->orig) - obstack_code_rename (stk, p->orig->name, p->name); - - obstack_code_rename (stk, "", prev->name); - } - } - return true; -} - -const char * -append_incremental_renames (const char *dump) -{ - struct obstack stk; - size_t size; - - if (directory_table == NULL) - return dump; - - obstack_init (&stk); - if (dump) - { - size = dumpdir_size (dump) - 1; - obstack_grow (&stk, dump, size); - } - else - size = 0; - - hash_do_for_each (directory_table, rename_handler, &stk); - if (obstack_object_size (&stk) != size) - { - obstack_1grow (&stk, 0); - dump = obstack_finish (&stk); - } - else - obstack_free (&stk, NULL); - return dump; -} - - - -static FILE *listed_incremental_stream; - -/* Version of incremental format snapshots (directory files) used by this - tar. Currently it is supposed to be a single decimal number. 0 means - incremental snapshots as per tar version before 1.15.2. - - The current tar version supports incremental versions from - 0 up to TAR_INCREMENTAL_VERSION, inclusive. - It is able to create only snapshots of TAR_INCREMENTAL_VERSION */ - -#define TAR_INCREMENTAL_VERSION 2 - -/* Read incremental snapshot formats 0 and 1 */ -static void -read_incr_db_01 (int version, const char *initbuf) -{ - int n; - uintmax_t u; - time_t sec; - long int nsec; - char *buf = 0; - size_t bufsize; - char *ebuf; - long lineno = 1; - - if (version == 1) - { - if (getline (&buf, &bufsize, listed_incremental_stream) <= 0) - { - read_error (listed_incremental_option); - free (buf); - return; - } - ++lineno; - } - else - { - buf = strdup (initbuf); - bufsize = strlen (buf) + 1; - } - - sec = TYPE_MINIMUM (time_t); - nsec = -1; - errno = 0; - u = strtoumax (buf, &ebuf, 10); - if (!errno && TYPE_MAXIMUM (time_t) < u) - errno = ERANGE; - if (errno || buf == ebuf) - ERROR ((0, errno, "%s:%ld: %s", - quotearg_colon (listed_incremental_option), - lineno, - _("Invalid time stamp"))); - else - { - sec = u; - - if (version == 1 && *ebuf) - { - char const *buf_ns = ebuf + 1; - errno = 0; - u = strtoumax (buf_ns, &ebuf, 10); - if (!errno && BILLION <= u) - errno = ERANGE; - if (errno || buf_ns == ebuf) - { - ERROR ((0, errno, "%s:%ld: %s", - quotearg_colon (listed_incremental_option), - lineno, - _("Invalid time stamp"))); - sec = TYPE_MINIMUM (time_t); - } - else - nsec = u; - } - else - { - /* pre-1 incremental format does not contain nanoseconds */ - nsec = 0; - } - } - newer_mtime_option.tv_sec = sec; - newer_mtime_option.tv_nsec = nsec; - - - while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream))) - { - dev_t dev; - ino_t ino; - bool nfs = buf[0] == '+'; - char *strp = buf + nfs; - struct timespec mtime; - - lineno++; - - if (buf[n - 1] == '\n') - buf[n - 1] = '\0'; - - if (version == 1) - { - errno = 0; - u = strtoumax (strp, &ebuf, 10); - if (!errno && TYPE_MAXIMUM (time_t) < u) - errno = ERANGE; - if (errno || strp == ebuf || *ebuf != ' ') - { - ERROR ((0, errno, "%s:%ld: %s", - quotearg_colon (listed_incremental_option), lineno, - _("Invalid modification time (seconds)"))); - sec = (time_t) -1; - } - else - sec = u; - strp = ebuf; - - errno = 0; - u = strtoumax (strp, &ebuf, 10); - if (!errno && BILLION <= u) - errno = ERANGE; - if (errno || strp == ebuf || *ebuf != ' ') - { - ERROR ((0, errno, "%s:%ld: %s", - quotearg_colon (listed_incremental_option), lineno, - _("Invalid modification time (nanoseconds)"))); - nsec = -1; - } - else - nsec = u; - mtime.tv_sec = sec; - mtime.tv_nsec = nsec; - strp = ebuf; - } - else - memset (&mtime, 0, sizeof mtime); - - errno = 0; - u = strtoumax (strp, &ebuf, 10); - if (!errno && TYPE_MAXIMUM (dev_t) < u) - errno = ERANGE; - if (errno || strp == ebuf || *ebuf != ' ') - { - ERROR ((0, errno, "%s:%ld: %s", - quotearg_colon (listed_incremental_option), lineno, - _("Invalid device number"))); - dev = (dev_t) -1; - } - else - dev = u; - strp = ebuf; - - errno = 0; - u = strtoumax (strp, &ebuf, 10); - if (!errno && TYPE_MAXIMUM (ino_t) < u) - errno = ERANGE; - if (errno || strp == ebuf || *ebuf != ' ') - { - ERROR ((0, errno, "%s:%ld: %s", - quotearg_colon (listed_incremental_option), lineno, - _("Invalid inode number"))); - ino = (ino_t) -1; - } - else - ino = u; - strp = ebuf; - - strp++; - unquote_string (strp); - note_directory (strp, mtime, dev, ino, nfs, false, NULL); - } - free (buf); -} - -/* Read a nul-terminated string from FP and store it in STK. - Store the number of bytes read (including nul terminator) in PCOUNT. - - Return the last character read or EOF on end of file. */ -static int -read_obstack (FILE *fp, struct obstack *stk, size_t *pcount) -{ - int c; - size_t i; - - for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++) - obstack_1grow (stk, c); - obstack_1grow (stk, 0); - - *pcount = i; - return c; -} - -/* Read from file FP a nul-terminated string and convert it to - intmax_t. Return the resulting value in PVAL. Assume '-' has - already been read. - - Throw a fatal error if the string cannot be converted or if the - converted value is less than MIN_VAL. */ - -static void -read_negative_num (FILE *fp, intmax_t min_val, intmax_t *pval) -{ - int c; - size_t i; - char buf[INT_BUFSIZE_BOUND (intmax_t)]; - char *ep; - buf[0] = '-'; - - for (i = 1; ISDIGIT (c = getc (fp)); i++) - { - if (i == sizeof buf - 1) - FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file"))); - buf[i] = c; - } - - if (c < 0) - { - if (ferror (fp)) - FATAL_ERROR ((0, errno, _("Read error in snapshot file"))); - else - FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file"))); - } - - buf[i] = 0; - errno = 0; - *pval = strtoimax (buf, &ep, 10); - if (c || errno || *pval < min_val) - FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file"))); -} - -/* Read from file FP a nul-terminated string and convert it to - uintmax_t. Return the resulting value in PVAL. Assume C has - already been read. - - Throw a fatal error if the string cannot be converted or if the - converted value exceeds MAX_VAL. - - Return the last character read or EOF on end of file. */ - -static int -read_unsigned_num (int c, FILE *fp, uintmax_t max_val, uintmax_t *pval) -{ - size_t i; - char buf[UINTMAX_STRSIZE_BOUND], *ep; - - for (i = 0; ISDIGIT (c); i++) - { - if (i == sizeof buf - 1) - FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file"))); - buf[i] = c; - c = getc (fp); - } - - if (c < 0) - { - if (ferror (fp)) - FATAL_ERROR ((0, errno, _("Read error in snapshot file"))); - else if (i == 0) - return c; - else - FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file"))); - } - - buf[i] = 0; - errno = 0; - *pval = strtoumax (buf, &ep, 10); - if (c || errno || max_val < *pval) - FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file"))); - return c; -} - -/* Read from file FP a nul-terminated string and convert it to - uintmax_t. Return the resulting value in PVAL. - - Throw a fatal error if the string cannot be converted or if the - converted value exceeds MAX_VAL. - - Return the last character read or EOF on end of file. */ - -static int -read_num (FILE *fp, uintmax_t max_val, uintmax_t *pval) -{ - return read_unsigned_num (getc (fp), fp, max_val, pval); -} - -/* Read from FP two NUL-terminated strings representing a struct - timespec. Return the resulting value in PVAL. - - Throw a fatal error if the string cannot be converted. */ - -static void -read_timespec (FILE *fp, struct timespec *pval) -{ - int c = getc (fp); - intmax_t i; - uintmax_t u; - - if (c == '-') - { - read_negative_num (fp, TYPE_MINIMUM (time_t), &i); - c = 0; - pval->tv_sec = i; - } - else - { - c = read_unsigned_num (c, fp, TYPE_MAXIMUM (time_t), &u); - pval->tv_sec = u; - } - - if (c || read_num (fp, BILLION - 1, &u)) - FATAL_ERROR ((0, 0, "%s: %s", - quotearg_colon (listed_incremental_option), - _("Unexpected EOF in snapshot file"))); - pval->tv_nsec = u; -} - -/* Read incremental snapshot format 2 */ -static void -read_incr_db_2 () -{ - uintmax_t u; - struct obstack stk; - - obstack_init (&stk); - - read_timespec (listed_incremental_stream, &newer_mtime_option); - - for (;;) - { - struct timespec mtime; - dev_t dev; - ino_t ino; - bool nfs; - char *name; - char *content; - size_t s; - - if (read_num (listed_incremental_stream, 1, &u)) - return; /* Normal return */ - - nfs = u; - - read_timespec (listed_incremental_stream, &mtime); - - if (read_num (listed_incremental_stream, TYPE_MAXIMUM (dev_t), &u)) - break; - dev = u; - - if (read_num (listed_incremental_stream, TYPE_MAXIMUM (ino_t), &u)) - break; - ino = u; - - if (read_obstack (listed_incremental_stream, &stk, &s)) - break; - - name = obstack_finish (&stk); - - while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1) - ; - if (getc (listed_incremental_stream) != 0) - FATAL_ERROR ((0, 0, "%s: %s", - quotearg_colon (listed_incremental_option), - _("Missing record terminator"))); - - content = obstack_finish (&stk); - note_directory (name, mtime, dev, ino, nfs, false, content); - obstack_free (&stk, content); - } - FATAL_ERROR ((0, 0, "%s: %s", - quotearg_colon (listed_incremental_option), - _("Unexpected EOF in snapshot file"))); -} - -/* Read incremental snapshot file (directory file). - If the file has older incremental version, make sure that it is processed - correctly and that tar will use the most conservative backup method among - possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN, - etc.) This ensures that the snapshots are updated to the recent version - without any loss of data. */ -void -read_directory_file (void) -{ - int fd; - char *buf = 0; - size_t bufsize; - - /* Open the file for both read and write. That way, we can write - it later without having to reopen it, and don't have to worry if - we chdir in the meantime. */ - fd = open (listed_incremental_option, O_RDWR | O_CREAT, MODE_RW); - if (fd < 0) - { - open_error (listed_incremental_option); - return; - } - - listed_incremental_stream = fdopen (fd, "r+"); - if (! listed_incremental_stream) - { - open_error (listed_incremental_option); - close (fd); - return; - } - - if (0 < getline (&buf, &bufsize, listed_incremental_stream)) - { - char *ebuf; - uintmax_t incremental_version; - - if (strncmp (buf, PACKAGE_NAME, sizeof PACKAGE_NAME - 1) == 0) - { - ebuf = buf + sizeof PACKAGE_NAME - 1; - if (*ebuf++ != '-') - ERROR((1, 0, _("Bad incremental file format"))); - for (; *ebuf != '-'; ebuf++) - if (!*ebuf) - ERROR((1, 0, _("Bad incremental file format"))); - - incremental_version = strtoumax (ebuf + 1, NULL, 10); - } - else - incremental_version = 0; - - switch (incremental_version) - { - case 0: - case 1: - read_incr_db_01 (incremental_version, buf); - break; - - case TAR_INCREMENTAL_VERSION: - read_incr_db_2 (); - break; - - default: - ERROR ((1, 0, _("Unsupported incremental format version: %"PRIuMAX), - incremental_version)); - } - - } - - if (ferror (listed_incremental_stream)) - read_error (listed_incremental_option); - if (buf) - free (buf); -} - -/* Output incremental data for the directory ENTRY to the file DATA. - Return nonzero if successful, preserving errno on write failure. */ -static bool -write_directory_file_entry (void *entry, void *data) -{ - struct directory const *directory = entry; - FILE *fp = data; - - if (DIR_IS_FOUND (directory)) - { - char buf[UINTMAX_STRSIZE_BOUND]; - char *s; - - s = DIR_IS_NFS (directory) ? "1" : "0"; - fwrite (s, 2, 1, fp); - s = (TYPE_SIGNED (time_t) - ? imaxtostr (directory->mtime.tv_sec, buf) - : umaxtostr (directory->mtime.tv_sec, buf)); - fwrite (s, strlen (s) + 1, 1, fp); - s = umaxtostr (directory->mtime.tv_nsec, buf); - fwrite (s, strlen (s) + 1, 1, fp); - s = umaxtostr (directory->device_number, buf); - fwrite (s, strlen (s) + 1, 1, fp); - s = umaxtostr (directory->inode_number, buf); - fwrite (s, strlen (s) + 1, 1, fp); - - fwrite (directory->name, strlen (directory->name) + 1, 1, fp); - if (directory->contents) - { - char *p; - for (p = directory->contents; *p; p += strlen (p) + 1) - { - if (strchr ("YND", *p)) - fwrite (p, strlen (p) + 1, 1, fp); - } - } - fwrite ("\0\0", 2, 1, fp); - } - - return ! ferror (fp); -} - -void -write_directory_file (void) -{ - FILE *fp = listed_incremental_stream; - char buf[UINTMAX_STRSIZE_BOUND]; - char *s; - - if (! fp) - return; - - if (fseek (fp, 0L, SEEK_SET) != 0) - seek_error (listed_incremental_option); - if (sys_truncate (fileno (fp)) != 0) - truncate_error (listed_incremental_option); - - fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION, - TAR_INCREMENTAL_VERSION); - - s = (TYPE_SIGNED (time_t) - ? imaxtostr (start_time.tv_sec, buf) - : umaxtostr (start_time.tv_sec, buf)); - fwrite (s, strlen (s) + 1, 1, fp); - s = umaxtostr (start_time.tv_nsec, buf); - fwrite (s, strlen (s) + 1, 1, fp); - - if (! ferror (fp) && directory_table) - hash_do_for_each (directory_table, write_directory_file_entry, fp); - - if (ferror (fp)) - write_error (listed_incremental_option); - if (fclose (fp) != 0) - close_error (listed_incremental_option); -} - - -/* Restoration of incremental dumps. */ - -static void -get_gnu_dumpdir (struct tar_stat_info *stat_info) -{ - size_t size; - size_t copied; - union block *data_block; - char *to; - char *archive_dir; - - size = stat_info->stat.st_size; - - archive_dir = xmalloc (size); - to = archive_dir; - - set_next_block_after (current_header); - mv_begin (stat_info); - - for (; size > 0; size -= copied) - { - mv_size_left (size); - data_block = find_next_block (); - if (!data_block) - ERROR ((1, 0, _("Unexpected EOF in archive"))); - copied = available_space_after (data_block); - if (copied > size) - copied = size; - memcpy (to, data_block->buffer, copied); - to += copied; - set_next_block_after ((union block *) - (data_block->buffer + copied - 1)); - } - - mv_end (); - - stat_info->dumpdir = archive_dir; - stat_info->skipped = true; /* For skip_member() and friends - to work correctly */ -} - -/* Return T if STAT_INFO represents a dumpdir archive member. - Note: can invalidate current_header. It happens if flush_archive() - gets called within get_gnu_dumpdir() */ -bool -is_dumpdir (struct tar_stat_info *stat_info) -{ - if (stat_info->is_dumpdir && !stat_info->dumpdir) - get_gnu_dumpdir (stat_info); - return stat_info->is_dumpdir; -} - -static bool -dumpdir_ok (char *dumpdir) -{ - char *p; - int has_tempdir = 0; - int expect = 0; - - for (p = dumpdir; *p; p += strlen (p) + 1) - { - if (expect && *p != expect) - { - ERROR ((0, 0, - _("Malformed dumpdir: expected '%c' but found %#3o"), - expect, *p)); - return false; - } - switch (*p) - { - case 'X': - if (has_tempdir) - { - ERROR ((0, 0, - _("Malformed dumpdir: 'X' duplicated"))); - return false; - } - else - has_tempdir = 1; - break; - - case 'R': - if (p[1] == 0) - { - if (!has_tempdir) - { - ERROR ((0, 0, - _("Malformed dumpdir: empty name in 'R'"))); - return false; - } - else - has_tempdir = 0; - } - expect = 'T'; - break; - - case 'T': - if (expect != 'T') - { - ERROR ((0, 0, - _("Malformed dumpdir: 'T' not preceeded by 'R'"))); - return false; - } - if (p[1] == 0 && !has_tempdir) - { - ERROR ((0, 0, - _("Malformed dumpdir: empty name in 'T'"))); - return false; - } - expect = 0; - break; - - case 'N': - case 'Y': - case 'D': - break; - - default: - /* FIXME: bail out? */ - break; - } - } - - if (expect) - { - ERROR ((0, 0, - _("Malformed dumpdir: expected '%c' but found end of data"), - expect)); - return false; - } - - if (has_tempdir) - WARN ((0, 0, _("Malformed dumpdir: 'X' never used"))); - - return true; -} - -/* Examine the directories under directory_name and delete any - files that were not there at the time of the back-up. */ -static bool -try_purge_directory (char const *directory_name) -{ - char *current_dir; - char *cur, *arc, *p; - char *temp_stub = NULL; - - if (!is_dumpdir (¤t_stat_info)) - return false; - - current_dir = savedir (directory_name); - - if (!current_dir) - /* The directory doesn't exist now. It'll be created. In any - case, we don't have to delete any files out of it. */ - return false; - - /* Verify if dump directory is sane */ - if (!dumpdir_ok (current_stat_info.dumpdir)) - return false; - - /* Process renames */ - for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1) - { - if (*arc == 'X') - { -#define TEMP_DIR_TEMPLATE "tar.XXXXXX" - size_t len = strlen (arc + 1); - temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE); - memcpy (temp_stub, arc + 1, len); - temp_stub[len] = '/'; - memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE, - sizeof TEMP_DIR_TEMPLATE); - if (!mkdtemp (temp_stub)) - { - ERROR ((0, errno, - _("Cannot create temporary directory using template %s"), - quote (temp_stub))); - free (temp_stub); - free (current_dir); - return false; - } - } - else if (*arc == 'R') - { - char *src, *dst; - src = arc + 1; - arc += strlen (arc) + 1; - dst = arc + 1; - - /* Ensure that neither source nor destination are absolute file - names (unless permitted by -P option), and that they do not - contain dubious parts (e.g. ../). - - This is an extra safety precaution. Besides, it might be - necessary to extract from archives created with tar versions - prior to 1.19. */ - - if (*src) - src = safer_name_suffix (src, false, absolute_names_option); - if (*dst) - dst = safer_name_suffix (dst, false, absolute_names_option); - - if (*src == 0) - src = temp_stub; - else if (*dst == 0) - dst = temp_stub; - - if (!rename_directory (src, dst)) - { - free (temp_stub); - free (current_dir); - /* FIXME: Make sure purge_directory(dst) will return - immediately */ - return false; - } - } - } - - free (temp_stub); - - /* Process deletes */ - p = NULL; - for (cur = current_dir; *cur; cur += strlen (cur) + 1) - { - const char *entry; - struct stat st; - if (p) - free (p); - p = new_name (directory_name, cur); - - if (deref_stat (false, p, &st)) - { - if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed - dirs and check it here? */ - { - stat_diag (p); - WARN ((0, 0, _("%s: Not purging directory: unable to stat"), - quotearg_colon (p))); - } - continue; - } - - if (!(entry = dumpdir_locate (current_stat_info.dumpdir, cur)) - || (*entry == 'D' && !S_ISDIR (st.st_mode)) - || (*entry == 'Y' && S_ISDIR (st.st_mode))) - { - if (one_file_system_option && st.st_dev != root_device) - { - WARN ((0, 0, - _("%s: directory is on a different device: not purging"), - quotearg_colon (p))); - continue; - } - - if (! interactive_option || confirm ("delete", p)) - { - if (verbose_option) - fprintf (stdlis, _("%s: Deleting %s\n"), - program_name, quote (p)); - if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION)) - { - int e = errno; - ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p))); - } - } - } - } - free (p); - - free (current_dir); - return true; -} - -void -purge_directory (char const *directory_name) -{ - if (!try_purge_directory (directory_name)) - skip_member (); -} - -void -list_dumpdir (char *buffer, size_t size) -{ - int state = 0; - while (size) - { - switch (*buffer) - { - case 'Y': - case 'N': - case 'D': - case 'R': - case 'T': - case 'X': - fprintf (stdlis, "%c", *buffer); - if (state == 0) - { - fprintf (stdlis, " "); - state = 1; - } - buffer++; - size--; - break; - - case 0: - fputc ('\n', stdlis); - buffer++; - size--; - state = 0; - break; - - default: - fputc (*buffer, stdlis); - buffer++; - size--; - } - } -} diff --git a/src/bin/tar/src/list.c b/src/bin/tar/src/list.c deleted file mode 100644 index c9cdf8246f..0000000000 --- a/src/bin/tar/src/list.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* List a tar archive, with support routines for reading a tar archive. - - Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, - 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - Written by John Gilmore, on 1985-08-26. - - 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include - -#include "common.h" - -#define max(a, b) ((a) < (b) ? (b) : (a)) - -union block *current_header; /* points to current archive header */ -enum archive_format current_format; /* recognized format */ -union block *recent_long_name; /* recent long name header and contents */ -union block *recent_long_link; /* likewise, for long link */ -size_t recent_long_name_blocks; /* number of blocks in recent_long_name */ -size_t recent_long_link_blocks; /* likewise, for long link */ - -static uintmax_t from_header (const char *, size_t, const char *, - uintmax_t, uintmax_t, bool, bool); - -/* Base 64 digits; see Internet RFC 2045 Table 1. */ -static char const base_64_digits[64] = -{ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' -}; - -/* Table of base-64 digit values indexed by unsigned chars. - The value is 64 for unsigned chars that are not base-64 digits. */ -static char base64_map[UCHAR_MAX + 1]; - -static void -base64_init (void) -{ - int i; - memset (base64_map, 64, sizeof base64_map); - for (i = 0; i < 64; i++) - base64_map[(int) base_64_digits[i]] = i; -} - -/* Main loop for reading an archive. */ -void -read_and (void (*do_something) (void)) -{ - enum read_header status = HEADER_STILL_UNREAD; - enum read_header prev_status; - struct timespec mtime; - - base64_init (); - name_gather (); - - open_archive (ACCESS_READ); - do - { - prev_status = status; - tar_stat_destroy (¤t_stat_info); - - status = read_header (false); - switch (status) - { - case HEADER_STILL_UNREAD: - case HEADER_SUCCESS_EXTENDED: - abort (); - - case HEADER_SUCCESS: - - /* Valid header. We should decode next field (mode) first. - Ensure incoming names are null terminated. */ - - if (! name_match (current_stat_info.file_name) - || (NEWER_OPTION_INITIALIZED (newer_mtime_option) - /* FIXME: We get mtime now, and again later; this causes - duplicate diagnostics if header.mtime is bogus. */ - && ((mtime.tv_sec - = TIME_FROM_HEADER (current_header->header.mtime)), - /* FIXME: Grab fractional time stamps from - extended header. */ - mtime.tv_nsec = 0, - current_stat_info.mtime = mtime, - OLDER_TAR_STAT_TIME (current_stat_info, m))) - || excluded_name (current_stat_info.file_name)) - { - switch (current_header->header.typeflag) - { - case GNUTYPE_VOLHDR: - case GNUTYPE_MULTIVOL: - break; - - case DIRTYPE: - if (show_omitted_dirs_option) - WARN ((0, 0, _("%s: Omitting"), - quotearg_colon (current_stat_info.file_name))); - /* Fall through. */ - default: - decode_header (current_header, - ¤t_stat_info, ¤t_format, 0); - skip_member (); - continue; - } - } - - (*do_something) (); - continue; - - case HEADER_ZERO_BLOCK: - if (block_number_option) - { - char buf[UINTMAX_STRSIZE_BOUND]; - fprintf (stdlis, _("block %s: ** Block of NULs **\n"), - STRINGIFY_BIGINT (current_block_ordinal (), buf)); - } - - set_next_block_after (current_header); - - if (!ignore_zeros_option) - { - char buf[UINTMAX_STRSIZE_BOUND]; - - status = read_header (false); - if (status == HEADER_ZERO_BLOCK) - break; - WARN ((0, 0, _("A lone zero block at %s"), - STRINGIFY_BIGINT (current_block_ordinal (), buf))); - break; - } - status = prev_status; - continue; - - case HEADER_END_OF_FILE: - if (block_number_option) - { - char buf[UINTMAX_STRSIZE_BOUND]; - fprintf (stdlis, _("block %s: ** End of File **\n"), - STRINGIFY_BIGINT (current_block_ordinal (), buf)); - } - break; - - case HEADER_FAILURE: - /* If the previous header was good, tell them that we are - skipping bad ones. */ - set_next_block_after (current_header); - switch (prev_status) - { - case HEADER_STILL_UNREAD: - ERROR ((0, 0, _("This does not look like a tar archive"))); - /* Fall through. */ - - case HEADER_ZERO_BLOCK: - case HEADER_SUCCESS: - if (block_number_option) - { - char buf[UINTMAX_STRSIZE_BOUND]; - off_t block_ordinal = current_block_ordinal (); - block_ordinal -= recent_long_name_blocks; - block_ordinal -= recent_long_link_blocks; - fprintf (stdlis, _("block %s: "), - STRINGIFY_BIGINT (block_ordinal, buf)); - } - ERROR ((0, 0, _("Skipping to next header"))); - break; - - case HEADER_END_OF_FILE: - case HEADER_FAILURE: - /* We are in the middle of a cascade of errors. */ - break; - - case HEADER_SUCCESS_EXTENDED: - abort (); - } - continue; - } - break; - } - while (!all_names_found (¤t_stat_info)); - - close_archive (); - names_notfound (); /* print names not found */ -} - -/* Print a header block, based on tar options. */ -void -list_archive (void) -{ - off_t block_ordinal = current_block_ordinal (); - /* Print the header block. */ - - decode_header (current_header, ¤t_stat_info, ¤t_format, 0); - if (verbose_option) - print_header (¤t_stat_info, block_ordinal); - - if (incremental_option) - { - if (verbose_option > 2) - { - if (is_dumpdir (¤t_stat_info)) - list_dumpdir (current_stat_info.dumpdir, - dumpdir_size (current_stat_info.dumpdir)); - } - } - - skip_member (); -} - -/* Check header checksum */ -/* The standard BSD tar sources create the checksum by adding up the - bytes in the header as type char. I think the type char was unsigned - on the PDP-11, but it's signed on the Next and Sun. It looks like the - sources to BSD tar were never changed to compute the checksum - correctly, so both the Sun and Next add the bytes of the header as - signed chars. This doesn't cause a problem until you get a file with - a name containing characters with the high bit set. So tar_checksum - computes two checksums -- signed and unsigned. */ - -enum read_header -tar_checksum (union block *header, bool silent) -{ - size_t i; - int unsigned_sum = 0; /* the POSIX one :-) */ - int signed_sum = 0; /* the Sun one :-( */ - int recorded_sum; - uintmax_t parsed_sum; - char *p; - - p = header->buffer; - for (i = sizeof *header; i-- != 0;) - { - unsigned_sum += (unsigned char) *p; - signed_sum += (signed char) (*p++); - } - - if (unsigned_sum == 0) - return HEADER_ZERO_BLOCK; - - /* Adjust checksum to count the "chksum" field as blanks. */ - - for (i = sizeof header->header.chksum; i-- != 0;) - { - unsigned_sum -= (unsigned char) header->header.chksum[i]; - signed_sum -= (signed char) (header->header.chksum[i]); - } - unsigned_sum += ' ' * sizeof header->header.chksum; - signed_sum += ' ' * sizeof header->header.chksum; - - parsed_sum = from_header (header->header.chksum, - sizeof header->header.chksum, 0, - (uintmax_t) 0, - (uintmax_t) TYPE_MAXIMUM (int), true, silent); - if (parsed_sum == (uintmax_t) -1) - return HEADER_FAILURE; - - recorded_sum = parsed_sum; - - if (unsigned_sum != recorded_sum && signed_sum != recorded_sum) - return HEADER_FAILURE; - - return HEADER_SUCCESS; -} - -/* Read a block that's supposed to be a header block. Return its - address in "current_header", and if it is good, the file's size - and names (file name, link name) in *info. - - Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a - block full of zeros (EOF marker). - - If RAW_EXTENDED_HEADERS is nonzero, do not automagically fold the - GNU long name and link headers into later headers. - - You must always set_next_block_after(current_header) to skip past - the header which this routine reads. */ - -enum read_header -read_header_primitive (bool raw_extended_headers, struct tar_stat_info *info) -{ - union block *header; - union block *header_copy; - char *bp; - union block *data_block; - size_t size, written; - union block *next_long_name = 0; - union block *next_long_link = 0; - size_t next_long_name_blocks; - size_t next_long_link_blocks; - - while (1) - { - enum read_header status; - - header = find_next_block (); - current_header = header; - if (!header) - return HEADER_END_OF_FILE; - - if ((status = tar_checksum (header, false)) != HEADER_SUCCESS) - return status; - - /* Good block. Decode file size and return. */ - - if (header->header.typeflag == LNKTYPE) - info->stat.st_size = 0; /* links 0 size on tape */ - else - info->stat.st_size = OFF_FROM_HEADER (header->header.size); - - if (header->header.typeflag == GNUTYPE_LONGNAME - || header->header.typeflag == GNUTYPE_LONGLINK - || header->header.typeflag == XHDTYPE - || header->header.typeflag == XGLTYPE - || header->header.typeflag == SOLARIS_XHDTYPE) - { - if (raw_extended_headers) - return HEADER_SUCCESS_EXTENDED; - else if (header->header.typeflag == GNUTYPE_LONGNAME - || header->header.typeflag == GNUTYPE_LONGLINK) - { - size_t name_size = info->stat.st_size; - size_t n = name_size % BLOCKSIZE; - size = name_size + BLOCKSIZE; - if (n) - size += BLOCKSIZE - n; - - if (name_size != info->stat.st_size || size < name_size) - xalloc_die (); - - header_copy = xmalloc (size + 1); - - if (header->header.typeflag == GNUTYPE_LONGNAME) - { - if (next_long_name) - free (next_long_name); - next_long_name = header_copy; - next_long_name_blocks = size / BLOCKSIZE; - } - else - { - if (next_long_link) - free (next_long_link); - next_long_link = header_copy; - next_long_link_blocks = size / BLOCKSIZE; - } - - set_next_block_after (header); - *header_copy = *header; - bp = header_copy->buffer + BLOCKSIZE; - - for (size -= BLOCKSIZE; size > 0; size -= written) - { - data_block = find_next_block (); - if (! data_block) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - break; - } - written = available_space_after (data_block); - if (written > size) - written = size; - - memcpy (bp, data_block->buffer, written); - bp += written; - set_next_block_after ((union block *) - (data_block->buffer + written - 1)); - } - - *bp = '\0'; - } - else if (header->header.typeflag == XHDTYPE - || header->header.typeflag == SOLARIS_XHDTYPE) - xheader_read (&info->xhdr, header, - OFF_FROM_HEADER (header->header.size)); - else if (header->header.typeflag == XGLTYPE) - { - struct xheader xhdr; - memset (&xhdr, 0, sizeof xhdr); - xheader_read (&xhdr, header, - OFF_FROM_HEADER (header->header.size)); - xheader_decode_global (&xhdr); - xheader_destroy (&xhdr); - } - - /* Loop! */ - - } - else - { - char const *name; - struct posix_header const *h = ¤t_header->header; - char namebuf[sizeof h->prefix + 1 + NAME_FIELD_SIZE + 1]; - - if (recent_long_name) - free (recent_long_name); - - if (next_long_name) - { - name = next_long_name->buffer + BLOCKSIZE; - recent_long_name = next_long_name; - recent_long_name_blocks = next_long_name_blocks; - } - else - { - /* Accept file names as specified by POSIX.1-1996 - section 10.1.1. */ - char *np = namebuf; - - if (h->prefix[0] && strcmp (h->magic, TMAGIC) == 0) - { - memcpy (np, h->prefix, sizeof h->prefix); - np[sizeof h->prefix] = '\0'; - np += strlen (np); - *np++ = '/'; - } - memcpy (np, h->name, sizeof h->name); - np[sizeof h->name] = '\0'; - name = namebuf; - recent_long_name = 0; - recent_long_name_blocks = 0; - } - assign_string (&info->orig_file_name, name); - assign_string (&info->file_name, name); - info->had_trailing_slash = strip_trailing_slashes (info->file_name); - - if (recent_long_link) - free (recent_long_link); - - if (next_long_link) - { - name = next_long_link->buffer + BLOCKSIZE; - recent_long_link = next_long_link; - recent_long_link_blocks = next_long_link_blocks; - } - else - { - memcpy (namebuf, h->linkname, sizeof h->linkname); - namebuf[sizeof h->linkname] = '\0'; - name = namebuf; - recent_long_link = 0; - recent_long_link_blocks = 0; - } - assign_string (&info->link_name, name); - - return HEADER_SUCCESS; - } - } -} - -enum read_header -read_header (bool raw_extended_headers) -{ - return read_header_primitive (raw_extended_headers, ¤t_stat_info); -} - -static char * -decode_xform (char *file_name, void *data) -{ - xform_type type = *(xform_type*)data; - - switch (type) - { - case xform_symlink: - /* FIXME: It is not quite clear how and to which extent are the symbolic - links subject to filename transformation. In the absence of another - solution, symbolic links are exempt from component stripping and - name suffix normalization, but subject to filename transformation - proper. */ - return file_name; - - case xform_link: - file_name = safer_name_suffix (file_name, true, absolute_names_option); - break; - - case xform_regfile: - file_name = safer_name_suffix (file_name, false, absolute_names_option); - break; - } - - if (strip_name_components) - { - size_t prefix_len = stripped_prefix_len (file_name, - strip_name_components); - if (prefix_len == (size_t) -1) - prefix_len = strlen (file_name); - file_name += prefix_len; - } - return file_name; -} - -bool -transform_member_name (char **pinput, xform_type type) -{ - return transform_name_fp (pinput, decode_xform, &type); -} - -#define ISOCTAL(c) ((c)>='0'&&(c)<='7') - -/* Decode things from a file HEADER block into STAT_INFO, also setting - *FORMAT_POINTER depending on the header block format. If - DO_USER_GROUP, decode the user/group information (this is useful - for extraction, but waste time when merely listing). - - read_header() has already decoded the checksum and length, so we don't. - - This routine should *not* be called twice for the same block, since - the two calls might use different DO_USER_GROUP values and thus - might end up with different uid/gid for the two calls. If anybody - wants the uid/gid they should decode it first, and other callers - should decode it without uid/gid before calling a routine, - e.g. print_header, that assumes decoded data. */ -void -decode_header (union block *header, struct tar_stat_info *stat_info, - enum archive_format *format_pointer, int do_user_group) -{ - enum archive_format format; - - if (strcmp (header->header.magic, TMAGIC) == 0) - { - if (header->star_header.prefix[130] == 0 - && ISOCTAL (header->star_header.atime[0]) - && header->star_header.atime[11] == ' ' - && ISOCTAL (header->star_header.ctime[0]) - && header->star_header.ctime[11] == ' ') - format = STAR_FORMAT; - else if (stat_info->xhdr.size) - format = POSIX_FORMAT; - else - format = USTAR_FORMAT; - } - else if (strcmp (header->header.magic, OLDGNU_MAGIC) == 0) - format = OLDGNU_FORMAT; - else - format = V7_FORMAT; - *format_pointer = format; - - stat_info->stat.st_mode = MODE_FROM_HEADER (header->header.mode); - stat_info->mtime.tv_sec = TIME_FROM_HEADER (header->header.mtime); - stat_info->mtime.tv_nsec = 0; - assign_string (&stat_info->uname, - header->header.uname[0] ? header->header.uname : NULL); - assign_string (&stat_info->gname, - header->header.gname[0] ? header->header.gname : NULL); - - if (format == OLDGNU_FORMAT && incremental_option) - { - stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime); - stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.ctime); - stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0; - } - else if (format == STAR_FORMAT) - { - stat_info->atime.tv_sec = TIME_FROM_HEADER (header->star_header.atime); - stat_info->ctime.tv_sec = TIME_FROM_HEADER (header->star_header.ctime); - stat_info->atime.tv_nsec = stat_info->ctime.tv_nsec = 0; - } - else - stat_info->atime = stat_info->ctime = start_time; - - if (format == V7_FORMAT) - { - stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid); - stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid); - stat_info->stat.st_rdev = 0; - } - else - { - if (do_user_group) - { - /* FIXME: Decide if this should somewhat depend on -p. */ - - if (numeric_owner_option - || !*header->header.uname - || !uname_to_uid (header->header.uname, &stat_info->stat.st_uid)) - stat_info->stat.st_uid = UID_FROM_HEADER (header->header.uid); - - if (numeric_owner_option - || !*header->header.gname - || !gname_to_gid (header->header.gname, &stat_info->stat.st_gid)) - stat_info->stat.st_gid = GID_FROM_HEADER (header->header.gid); - } - - switch (header->header.typeflag) - { - case BLKTYPE: - case CHRTYPE: - stat_info->stat.st_rdev = - makedev (MAJOR_FROM_HEADER (header->header.devmajor), - MINOR_FROM_HEADER (header->header.devminor)); - break; - - default: - stat_info->stat.st_rdev = 0; - } - } - - stat_info->archive_file_size = stat_info->stat.st_size; - xheader_decode (stat_info); - - if (sparse_member_p (stat_info)) - { - sparse_fixup_header (stat_info); - stat_info->is_sparse = true; - } - else - { - stat_info->is_sparse = false; - if (((current_format == GNU_FORMAT - || current_format == OLDGNU_FORMAT) - && current_header->header.typeflag == GNUTYPE_DUMPDIR) - || stat_info->dumpdir) - stat_info->is_dumpdir = true; - } - - transform_member_name (&stat_info->file_name, xform_regfile); -} - -/* Convert buffer at WHERE0 of size DIGS from external format to - uintmax_t. DIGS must be positive. If TYPE is nonnull, the data - are of type TYPE. The buffer must represent a value in the range - -MINUS_MINVAL through MAXVAL. If OCTAL_ONLY, allow only octal - numbers instead of the other GNU extensions. Return -1 on error, - diagnosing the error if TYPE is nonnull and if !SILENT. */ -static uintmax_t -from_header (char const *where0, size_t digs, char const *type, - uintmax_t minus_minval, uintmax_t maxval, - bool octal_only, bool silent) -{ - uintmax_t value; - char const *where = where0; - char const *lim = where + digs; - int negative = 0; - - /* Accommodate buggy tar of unknown vintage, which outputs leading - NUL if the previous field overflows. */ - where += !*where; - - /* Accommodate older tars, which output leading spaces. */ - for (;;) - { - if (where == lim) - { - if (type && !silent) - ERROR ((0, 0, - /* TRANSLATORS: %s is type of the value (gid_t, uid_t, etc.) */ - _("Blanks in header where numeric %s value expected"), - type)); - return -1; - } - if (!ISSPACE ((unsigned char) *where)) - break; - where++; - } - - value = 0; - if (ISODIGIT (*where)) - { - char const *where1 = where; - uintmax_t overflow = 0; - - for (;;) - { - value += *where++ - '0'; - if (where == lim || ! ISODIGIT (*where)) - break; - overflow |= value ^ (value << LG_8 >> LG_8); - value <<= LG_8; - } - - /* Parse the output of older, unportable tars, which generate - negative values in two's complement octal. If the leading - nonzero digit is 1, we can't recover the original value - reliably; so do this only if the digit is 2 or more. This - catches the common case of 32-bit negative time stamps. */ - if ((overflow || maxval < value) && '2' <= *where1 && type) - { - /* Compute the negative of the input value, assuming two's - complement. */ - int digit = (*where1 - '0') | 4; - overflow = 0; - value = 0; - where = where1; - for (;;) - { - value += 7 - digit; - where++; - if (where == lim || ! ISODIGIT (*where)) - break; - digit = *where - '0'; - overflow |= value ^ (value << LG_8 >> LG_8); - value <<= LG_8; - } - value++; - overflow |= !value; - - if (!overflow && value <= minus_minval) - { - if (!silent) - WARN ((0, 0, - /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */ - _("Archive octal value %.*s is out of %s range; assuming two's complement"), - (int) (where - where1), where1, type)); - negative = 1; - } - } - - if (overflow) - { - if (type && !silent) - ERROR ((0, 0, - /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */ - _("Archive octal value %.*s is out of %s range"), - (int) (where - where1), where1, type)); - return -1; - } - } - else if (octal_only) - { - /* Suppress the following extensions. */ - } - else if (*where == '-' || *where == '+') - { - /* Parse base-64 output produced only by tar test versions - 1.13.6 (1999-08-11) through 1.13.11 (1999-08-23). - Support for this will be withdrawn in future releases. */ - int dig; - if (!silent) - { - static bool warned_once; - if (! warned_once) - { - warned_once = true; - WARN ((0, 0, _("Archive contains obsolescent base-64 headers"))); - } - } - negative = *where++ == '-'; - while (where != lim - && (dig = base64_map[(unsigned char) *where]) < 64) - { - if (value << LG_64 >> LG_64 != value) - { - char *string = alloca (digs + 1); - memcpy (string, where0, digs); - string[digs] = '\0'; - if (type && !silent) - ERROR ((0, 0, - _("Archive signed base-64 string %s is out of %s range"), - quote (string), type)); - return -1; - } - value = (value << LG_64) | dig; - where++; - } - } - else if (*where == '\200' /* positive base-256 */ - || *where == '\377' /* negative base-256 */) - { - /* Parse base-256 output. A nonnegative number N is - represented as (256**DIGS)/2 + N; a negative number -N is - represented as (256**DIGS) - N, i.e. as two's complement. - The representation guarantees that the leading bit is - always on, so that we don't confuse this format with the - others (assuming ASCII bytes of 8 bits or more). */ - int signbit = *where & (1 << (LG_256 - 2)); - uintmax_t topbits = (((uintmax_t) - signbit) - << (CHAR_BIT * sizeof (uintmax_t) - - LG_256 - (LG_256 - 2))); - value = (*where++ & ((1 << (LG_256 - 2)) - 1)) - signbit; - for (;;) - { - value = (value << LG_256) + (unsigned char) *where++; - if (where == lim) - break; - if (((value << LG_256 >> LG_256) | topbits) != value) - { - if (type && !silent) - ERROR ((0, 0, - _("Archive base-256 value is out of %s range"), - type)); - return -1; - } - } - negative = signbit; - if (negative) - value = -value; - } - - if (where != lim && *where && !ISSPACE ((unsigned char) *where)) - { - if (type) - { - char buf[1000]; /* Big enough to represent any header. */ - static struct quoting_options *o; - - if (!o) - { - o = clone_quoting_options (0); - set_quoting_style (o, locale_quoting_style); - } - - while (where0 != lim && ! lim[-1]) - lim--; - quotearg_buffer (buf, sizeof buf, where0, lim - where, o); - if (!silent) - ERROR ((0, 0, - /* TRANSLATORS: Second %s is a type name (gid_t,uid_t,etc.) */ - _("Archive contains %.*s where numeric %s value expected"), - (int) sizeof buf, buf, type)); - } - - return -1; - } - - if (value <= (negative ? minus_minval : maxval)) - return negative ? -value : value; - - if (type && !silent) - { - char minval_buf[UINTMAX_STRSIZE_BOUND + 1]; - char maxval_buf[UINTMAX_STRSIZE_BOUND]; - char value_buf[UINTMAX_STRSIZE_BOUND + 1]; - char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1); - char *value_string = STRINGIFY_BIGINT (value, value_buf + 1); - if (negative) - *--value_string = '-'; - if (minus_minval) - *--minval_string = '-'; - /* TRANSLATORS: Second %s is type name (gid_t,uid_t,etc.) */ - ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"), - value_string, type, - minval_string, STRINGIFY_BIGINT (maxval, maxval_buf))); - } - - return -1; -} - -gid_t -gid_from_header (const char *p, size_t s) -{ - return from_header (p, s, "gid_t", - - (uintmax_t) TYPE_MINIMUM (gid_t), - (uintmax_t) TYPE_MAXIMUM (gid_t), - false, false); -} - -major_t -major_from_header (const char *p, size_t s) -{ - return from_header (p, s, "major_t", - - (uintmax_t) TYPE_MINIMUM (major_t), - (uintmax_t) TYPE_MAXIMUM (major_t), false, false); -} - -minor_t -minor_from_header (const char *p, size_t s) -{ - return from_header (p, s, "minor_t", - - (uintmax_t) TYPE_MINIMUM (minor_t), - (uintmax_t) TYPE_MAXIMUM (minor_t), false, false); -} - -mode_t -mode_from_header (const char *p, size_t s) -{ - /* Do not complain about unrecognized mode bits. */ - unsigned u = from_header (p, s, "mode_t", - - (uintmax_t) TYPE_MINIMUM (mode_t), - TYPE_MAXIMUM (uintmax_t), false, false); - return ((u & TSUID ? S_ISUID : 0) - | (u & TSGID ? S_ISGID : 0) - | (u & TSVTX ? S_ISVTX : 0) - | (u & TUREAD ? S_IRUSR : 0) - | (u & TUWRITE ? S_IWUSR : 0) - | (u & TUEXEC ? S_IXUSR : 0) - | (u & TGREAD ? S_IRGRP : 0) - | (u & TGWRITE ? S_IWGRP : 0) - | (u & TGEXEC ? S_IXGRP : 0) - | (u & TOREAD ? S_IROTH : 0) - | (u & TOWRITE ? S_IWOTH : 0) - | (u & TOEXEC ? S_IXOTH : 0)); -} - -off_t -off_from_header (const char *p, size_t s) -{ - /* Negative offsets are not allowed in tar files, so invoke - from_header with minimum value 0, not TYPE_MINIMUM (off_t). */ - return from_header (p, s, "off_t", (uintmax_t) 0, - (uintmax_t) TYPE_MAXIMUM (off_t), false, false); -} - -size_t -size_from_header (const char *p, size_t s) -{ - return from_header (p, s, "size_t", (uintmax_t) 0, - (uintmax_t) TYPE_MAXIMUM (size_t), false, false); -} - -time_t -time_from_header (const char *p, size_t s) -{ - return from_header (p, s, "time_t", - - (uintmax_t) TYPE_MINIMUM (time_t), - (uintmax_t) TYPE_MAXIMUM (time_t), false, false); -} - -uid_t -uid_from_header (const char *p, size_t s) -{ - return from_header (p, s, "uid_t", - - (uintmax_t) TYPE_MINIMUM (uid_t), - (uintmax_t) TYPE_MAXIMUM (uid_t), false, false); -} - -uintmax_t -uintmax_from_header (const char *p, size_t s) -{ - return from_header (p, s, "uintmax_t", (uintmax_t) 0, - TYPE_MAXIMUM (uintmax_t), false, false); -} - - -/* Return a printable representation of T. The result points to - static storage that can be reused in the next call to this - function, to ctime, or to asctime. If FULL_TIME, then output the - time stamp to its full resolution; otherwise, just output it to - 1-minute resolution. */ -char const * -tartime (struct timespec t, bool full_time) -{ - enum { fraclen = sizeof ".FFFFFFFFF" - 1 }; - static char buffer[max (UINTMAX_STRSIZE_BOUND + 1, - INT_STRLEN_BOUND (int) + 16) - + fraclen]; - struct tm *tm; - time_t s = t.tv_sec; - int ns = t.tv_nsec; - bool negative = s < 0; - char *p; - - if (negative && ns != 0) - { - s++; - ns = 1000000000 - ns; - } - - tm = utc_option ? gmtime (&s) : localtime (&s); - if (tm) - { - if (full_time) - { - sprintf (buffer, "%04ld-%02d-%02d %02d:%02d:%02d", - tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - code_ns_fraction (ns, buffer + strlen (buffer)); - } - else - sprintf (buffer, "%04ld-%02d-%02d %02d:%02d", - tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min); - return buffer; - } - - /* The time stamp cannot be broken down, most likely because it - is out of range. Convert it as an integer, - right-adjusted in a field with the same width as the usual - 4-year ISO time format. */ - p = umaxtostr (negative ? - (uintmax_t) s : s, - buffer + sizeof buffer - UINTMAX_STRSIZE_BOUND - fraclen); - if (negative) - *--p = '-'; - while ((buffer + sizeof buffer - sizeof "YYYY-MM-DD HH:MM" - + (full_time ? sizeof ":SS.FFFFFFFFF" - 1 : 0)) - < p) - *--p = ' '; - if (full_time) - code_ns_fraction (ns, buffer + sizeof buffer - 1 - fraclen); - return p; -} - -/* Actually print it. - - Plain and fancy file header block logging. Non-verbose just prints - the name, e.g. for "tar t" or "tar x". This should just contain - file names, so it can be fed back into tar with xargs or the "-T" - option. The verbose option can give a bunch of info, one line per - file. I doubt anybody tries to parse its format, or if they do, - they shouldn't. Unix tar is pretty random here anyway. */ - - -/* FIXME: Note that print_header uses the globals HEAD, HSTAT, and - HEAD_STANDARD, which must be set up in advance. Not very clean.. */ - -/* Width of "user/group size", with initial value chosen - heuristically. This grows as needed, though this may cause some - stairstepping in the output. Make it too small and the output will - almost always look ragged. Make it too large and the output will - be spaced out too far. */ -static int ugswidth = 19; - -/* Width of printed time stamps. It grows if longer time stamps are - found (typically, those with nanosecond resolution). Like - USGWIDTH, some stairstepping may occur. */ -static int datewidth = sizeof "YYYY-MM-DD HH:MM" - 1; - -void -print_header (struct tar_stat_info *st, off_t block_ordinal) -{ - char modes[11]; - char const *time_stamp; - int time_stamp_len; - char *temp_name; - - /* These hold formatted ints. */ - char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND]; - char *user, *group; - char size[2 * UINTMAX_STRSIZE_BOUND]; - /* holds formatted size or major,minor */ - char uintbuf[UINTMAX_STRSIZE_BOUND]; - int pad; - int sizelen; - - if (test_label_option && current_header->header.typeflag != GNUTYPE_VOLHDR) - return; - - if (show_transformed_names_option) - temp_name = st->file_name ? st->file_name : st->orig_file_name; - else - temp_name = st->orig_file_name ? st->orig_file_name : st->file_name; - - if (block_number_option) - { - char buf[UINTMAX_STRSIZE_BOUND]; - if (block_ordinal < 0) - block_ordinal = current_block_ordinal (); - block_ordinal -= recent_long_name_blocks; - block_ordinal -= recent_long_link_blocks; - fprintf (stdlis, _("block %s: "), - STRINGIFY_BIGINT (block_ordinal, buf)); - } - - if (verbose_option <= 1) - { - /* Just the fax, mam. */ - fprintf (stdlis, "%s\n", quotearg (temp_name)); - } - else - { - /* File type and modes. */ - - modes[0] = '?'; - switch (current_header->header.typeflag) - { - case GNUTYPE_VOLHDR: - modes[0] = 'V'; - break; - - case GNUTYPE_MULTIVOL: - modes[0] = 'M'; - break; - - case GNUTYPE_LONGNAME: - case GNUTYPE_LONGLINK: - modes[0] = 'L'; - ERROR ((0, 0, _("Unexpected long name header"))); - break; - - case GNUTYPE_SPARSE: - case REGTYPE: - case AREGTYPE: - modes[0] = '-'; - if (temp_name[strlen (temp_name) - 1] == '/') - modes[0] = 'd'; - break; - case LNKTYPE: - modes[0] = 'h'; - break; - case GNUTYPE_DUMPDIR: - modes[0] = 'd'; - break; - case DIRTYPE: - modes[0] = 'd'; - break; - case SYMTYPE: - modes[0] = 'l'; - break; - case BLKTYPE: - modes[0] = 'b'; - break; - case CHRTYPE: - modes[0] = 'c'; - break; - case FIFOTYPE: - modes[0] = 'p'; - break; - case CONTTYPE: - modes[0] = 'C'; - break; - } - - pax_decode_mode (st->stat.st_mode, modes + 1); - - /* Time stamp. */ - - time_stamp = tartime (st->mtime, false); - time_stamp_len = strlen (time_stamp); - if (datewidth < time_stamp_len) - datewidth = time_stamp_len; - - /* User and group names. */ - - if (st->uname - && st->uname[0] - && current_format != V7_FORMAT - && !numeric_owner_option) - user = st->uname; - else - { - /* Try parsing it as an unsigned integer first, and as a - uid_t if that fails. This method can list positive user - ids that are too large to fit in a uid_t. */ - uintmax_t u = from_header (current_header->header.uid, - sizeof current_header->header.uid, 0, - (uintmax_t) 0, - (uintmax_t) TYPE_MAXIMUM (uintmax_t), - false, false); - if (u != -1) - user = STRINGIFY_BIGINT (u, uform); - else - { - sprintf (uform, "%ld", - (long) UID_FROM_HEADER (current_header->header.uid)); - user = uform; - } - } - - if (st->gname - && st->gname[0] - && current_format != V7_FORMAT - && !numeric_owner_option) - group = st->gname; - else - { - /* Try parsing it as an unsigned integer first, and as a - gid_t if that fails. This method can list positive group - ids that are too large to fit in a gid_t. */ - uintmax_t g = from_header (current_header->header.gid, - sizeof current_header->header.gid, 0, - (uintmax_t) 0, - (uintmax_t) TYPE_MAXIMUM (uintmax_t), - false, false); - if (g != -1) - group = STRINGIFY_BIGINT (g, gform); - else - { - sprintf (gform, "%ld", - (long) GID_FROM_HEADER (current_header->header.gid)); - group = gform; - } - } - - /* Format the file size or major/minor device numbers. */ - - switch (current_header->header.typeflag) - { - case CHRTYPE: - case BLKTYPE: - strcpy (size, - STRINGIFY_BIGINT (major (st->stat.st_rdev), uintbuf)); - strcat (size, ","); - strcat (size, - STRINGIFY_BIGINT (minor (st->stat.st_rdev), uintbuf)); - break; - - default: - /* st->stat.st_size keeps stored file size */ - strcpy (size, STRINGIFY_BIGINT (st->stat.st_size, uintbuf)); - break; - } - - /* Figure out padding and print the whole line. */ - - sizelen = strlen (size); - pad = strlen (user) + 1 + strlen (group) + 1 + sizelen; - if (pad > ugswidth) - ugswidth = pad; - - fprintf (stdlis, "%s %s/%s %*s %-*s", - modes, user, group, ugswidth - pad + sizelen, size, - datewidth, time_stamp); - - fprintf (stdlis, " %s", quotearg (temp_name)); - - switch (current_header->header.typeflag) - { - case SYMTYPE: - fprintf (stdlis, " -> %s\n", quotearg (st->link_name)); - break; - - case LNKTYPE: - fprintf (stdlis, _(" link to %s\n"), quotearg (st->link_name)); - break; - - default: - { - char type_string[2]; - type_string[0] = current_header->header.typeflag; - type_string[1] = '\0'; - fprintf (stdlis, _(" unknown file type %s\n"), - quote (type_string)); - } - break; - - case AREGTYPE: - case REGTYPE: - case GNUTYPE_SPARSE: - case CHRTYPE: - case BLKTYPE: - case DIRTYPE: - case FIFOTYPE: - case CONTTYPE: - case GNUTYPE_DUMPDIR: - putc ('\n', stdlis); - break; - - case GNUTYPE_LONGLINK: - fprintf (stdlis, _("--Long Link--\n")); - break; - - case GNUTYPE_LONGNAME: - fprintf (stdlis, _("--Long Name--\n")); - break; - - case GNUTYPE_VOLHDR: - fprintf (stdlis, _("--Volume Header--\n")); - break; - - case GNUTYPE_MULTIVOL: - strcpy (size, - STRINGIFY_BIGINT - (UINTMAX_FROM_HEADER (current_header->oldgnu_header.offset), - uintbuf)); - fprintf (stdlis, _("--Continued at byte %s--\n"), size); - break; - } - } - fflush (stdlis); -} - -/* Print a similar line when we make a directory automatically. */ -void -print_for_mkdir (char *dirname, int length, mode_t mode) -{ - char modes[11]; - - if (verbose_option > 1) - { - /* File type and modes. */ - - modes[0] = 'd'; - pax_decode_mode (mode, modes + 1); - - if (block_number_option) - { - char buf[UINTMAX_STRSIZE_BOUND]; - fprintf (stdlis, _("block %s: "), - STRINGIFY_BIGINT (current_block_ordinal (), buf)); - } - - fprintf (stdlis, "%s %*s %.*s\n", modes, ugswidth + 1 + datewidth, - _("Creating directory:"), length, quotearg (dirname)); - } -} - -/* Skip over SIZE bytes of data in blocks in the archive. */ -void -skip_file (off_t size) -{ - union block *x; - - /* FIXME: Make sure mv_begin is always called before it */ - - if (seekable_archive) - { - off_t nblk = seek_archive (size); - if (nblk >= 0) - size -= nblk * BLOCKSIZE; - else - seekable_archive = false; - } - - mv_size_left (size); - - while (size > 0) - { - x = find_next_block (); - if (! x) - FATAL_ERROR ((0, 0, _("Unexpected EOF in archive"))); - - set_next_block_after (x); - size -= BLOCKSIZE; - mv_size_left (size); - } -} - -/* Skip the current member in the archive. - NOTE: Current header must be decoded before calling this function. */ -void -skip_member (void) -{ - if (!current_stat_info.skipped) - { - char save_typeflag = current_header->header.typeflag; - set_next_block_after (current_header); - - mv_begin (¤t_stat_info); - - if (current_stat_info.is_sparse) - sparse_skip_file (¤t_stat_info); - else if (save_typeflag != DIRTYPE) - skip_file (current_stat_info.stat.st_size); - - mv_end (); - } -} diff --git a/src/bin/tar/src/misc.c b/src/bin/tar/src/misc.c deleted file mode 100644 index 951449eb0c..0000000000 --- a/src/bin/tar/src/misc.c +++ /dev/null @@ -1,748 +0,0 @@ -/* Miscellaneous functions, not really specific to GNU tar. - - Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include "common.h" -#include -#include -#include -#include -#include - -#if HAVE_STROPTS_H -# include -#endif -#if HAVE_SYS_FILIO_H -# include -#endif - - -/* Handling strings. */ - -/* Assign STRING to a copy of VALUE if not zero, or to zero. If - STRING was nonzero, it is freed first. */ -void -assign_string (char **string, const char *value) -{ - if (*string) - free (*string); - *string = value ? xstrdup (value) : 0; -} - -/* Allocate a copy of the string quoted as in C, and returns that. If - the string does not have to be quoted, it returns a null pointer. - The allocated copy should normally be freed with free() after the - caller is done with it. - - This is used in one context only: generating the directory file in - incremental dumps. The quoted string is not intended for human - consumption; it is intended only for unquote_string. The quoting - is locale-independent, so that users needn't worry about locale - when reading directory files. This means that we can't use - quotearg, as quotearg is locale-dependent and is meant for human - consumption. */ -char * -quote_copy_string (const char *string) -{ - const char *source = string; - char *destination = 0; - char *buffer = 0; - int copying = 0; - - while (*source) - { - int character = *source++; - - switch (character) - { - case '\n': case '\\': - if (!copying) - { - size_t length = (source - string) - 1; - - copying = 1; - buffer = xmalloc (length + 2 + 2 * strlen (source) + 1); - memcpy (buffer, string, length); - destination = buffer + length; - } - *destination++ = '\\'; - *destination++ = character == '\\' ? '\\' : 'n'; - break; - - default: - if (copying) - *destination++ = character; - break; - } - } - if (copying) - { - *destination = '\0'; - return buffer; - } - return 0; -} - -/* Takes a quoted C string (like those produced by quote_copy_string) - and turns it back into the un-quoted original. This is done in - place. Returns 0 only if the string was not properly quoted, but - completes the unquoting anyway. - - This is used for reading the saved directory file in incremental - dumps. It is used for decoding old `N' records (demangling names). - But also, it is used for decoding file arguments, would they come - from the shell or a -T file, and for decoding the --exclude - argument. */ -int -unquote_string (char *string) -{ - int result = 1; - char *source = string; - char *destination = string; - - /* Escape sequences other than \\ and \n are no longer generated by - quote_copy_string, but accept them for backwards compatibility, - and also because unquote_string is used for purposes other than - parsing the output of quote_copy_string. */ - - while (*source) - if (*source == '\\') - switch (*++source) - { - case '\\': - *destination++ = '\\'; - source++; - break; - - case 'a': - *destination++ = '\a'; - source++; - break; - - case 'b': - *destination++ = '\b'; - source++; - break; - - case 'f': - *destination++ = '\f'; - source++; - break; - - case 'n': - *destination++ = '\n'; - source++; - break; - - case 'r': - *destination++ = '\r'; - source++; - break; - - case 't': - *destination++ = '\t'; - source++; - break; - - case 'v': - *destination++ = '\v'; - source++; - break; - - case '?': - *destination++ = 0177; - source++; - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - int value = *source++ - '0'; - - if (*source < '0' || *source > '7') - { - *destination++ = value; - break; - } - value = value * 8 + *source++ - '0'; - if (*source < '0' || *source > '7') - { - *destination++ = value; - break; - } - value = value * 8 + *source++ - '0'; - *destination++ = value; - break; - } - - default: - result = 0; - *destination++ = '\\'; - if (*source) - *destination++ = *source++; - break; - } - else if (source != destination) - *destination++ = *source++; - else - source++, destination++; - - if (source != destination) - *destination = '\0'; - return result; -} - -/* Handling numbers. */ - -/* Output fraction and trailing digits appropriate for a nanoseconds - count equal to NS, but don't output unnecessary '.' or trailing - zeros. */ - -void -code_ns_fraction (int ns, char *p) -{ - if (ns == 0) - *p = '\0'; - else - { - int i = 9; - *p++ = '.'; - - while (ns % 10 == 0) - { - ns /= 10; - i--; - } - - p[i] = '\0'; - - for (;;) - { - p[--i] = '0' + ns % 10; - if (i == 0) - break; - ns /= 10; - } - } -} - -char const * -code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND]) -{ - time_t s = t.tv_sec; - int ns = t.tv_nsec; - char *np; - bool negative = s < 0; - - if (negative && ns != 0) - { - s++; - ns = BILLION - ns; - } - - np = umaxtostr (negative ? - (uintmax_t) s : (uintmax_t) s, sbuf + 1); - if (negative) - *--np = '-'; - code_ns_fraction (ns, sbuf + UINTMAX_STRSIZE_BOUND); - return np; -} - -/* File handling. */ - -/* Saved names in case backup needs to be undone. */ -static char *before_backup_name; -static char *after_backup_name; - -/* Return 1 if FILE_NAME is obviously "." or "/". */ -static bool -must_be_dot_or_slash (char const *file_name) -{ - file_name += FILE_SYSTEM_PREFIX_LEN (file_name); - - if (ISSLASH (file_name[0])) - { - for (;;) - if (ISSLASH (file_name[1])) - file_name++; - else if (file_name[1] == '.' - && ISSLASH (file_name[2 + (file_name[2] == '.')])) - file_name += 2 + (file_name[2] == '.'); - else - return ! file_name[1]; - } - else - { - while (file_name[0] == '.' && ISSLASH (file_name[1])) - { - file_name += 2; - while (ISSLASH (*file_name)) - file_name++; - } - - return ! file_name[0] || (file_name[0] == '.' && ! file_name[1]); - } -} - -/* Some implementations of rmdir let you remove '.' or '/'. - Report an error with errno set to zero for obvious cases of this; - otherwise call rmdir. */ -static int -safer_rmdir (const char *file_name) -{ - if (must_be_dot_or_slash (file_name)) - { - errno = 0; - return -1; - } - - return rmdir (file_name); -} - -/* Remove FILE_NAME, returning 1 on success. If FILE_NAME is a directory, - then if OPTION is RECURSIVE_REMOVE_OPTION is set remove FILE_NAME - recursively; otherwise, remove it only if it is empty. If FILE_NAME is - a directory that cannot be removed (e.g., because it is nonempty) - and if OPTION is WANT_DIRECTORY_REMOVE_OPTION, then return -1. - Return 0 on error, with errno set; if FILE_NAME is obviously the working - directory return zero with errno set to zero. */ -int -remove_any_file (const char *file_name, enum remove_option option) -{ - /* Try unlink first if we cannot unlink directories, as this saves - us a system call in the common case where we're removing a - non-directory. */ - bool try_unlink_first = cannot_unlink_dir (); - - if (try_unlink_first) - { - if (unlink (file_name) == 0) - return 1; - - /* POSIX 1003.1-2001 requires EPERM when attempting to unlink a - directory without appropriate privileges, but many Linux - kernels return the more-sensible EISDIR. */ - if (errno != EPERM && errno != EISDIR) - return 0; - } - - if (safer_rmdir (file_name) == 0) - return 1; - - switch (errno) - { - case ENOTDIR: - return !try_unlink_first && unlink (file_name) == 0; - - case 0: - case EEXIST: -#if defined ENOTEMPTY && ENOTEMPTY != EEXIST - case ENOTEMPTY: -#endif - switch (option) - { - case ORDINARY_REMOVE_OPTION: - break; - - case WANT_DIRECTORY_REMOVE_OPTION: - return -1; - - case RECURSIVE_REMOVE_OPTION: - { - char *directory = savedir (file_name); - char const *entry; - size_t entrylen; - - if (! directory) - return 0; - - for (entry = directory; - (entrylen = strlen (entry)) != 0; - entry += entrylen + 1) - { - char *file_name_buffer = new_name (file_name, entry); - int r = remove_any_file (file_name_buffer, - RECURSIVE_REMOVE_OPTION); - int e = errno; - free (file_name_buffer); - - if (! r) - { - free (directory); - errno = e; - return 0; - } - } - - free (directory); - return safer_rmdir (file_name) == 0; - } - } - break; - } - - return 0; -} - -/* Check if FILE_NAME already exists and make a backup of it right now. - Return success (nonzero) only if the backup is either unneeded, or - successful. For now, directories are considered to never need - backup. If THIS_IS_THE_ARCHIVE is nonzero, this is the archive and - so, we do not have to backup block or character devices, nor remote - entities. */ -bool -maybe_backup_file (const char *file_name, bool this_is_the_archive) -{ - struct stat file_stat; - - /* Check if we really need to backup the file. */ - - if (this_is_the_archive && _remdev (file_name)) - return true; - - if (stat (file_name, &file_stat)) - { - if (errno == ENOENT) - return true; - - stat_error (file_name); - return false; - } - - if (S_ISDIR (file_stat.st_mode)) - return true; - - if (this_is_the_archive - && (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode))) - return true; - - assign_string (&before_backup_name, file_name); - - /* A run situation may exist between Emacs or other GNU programs trying to - make a backup for the same file simultaneously. If theoretically - possible, real problems are unlikely. Doing any better would require a - convention, GNU-wide, for all programs doing backups. */ - - assign_string (&after_backup_name, 0); - after_backup_name = find_backup_file_name (file_name, backup_type); - if (! after_backup_name) - xalloc_die (); - - if (rename (before_backup_name, after_backup_name) == 0) - { - if (verbose_option) - fprintf (stdlis, _("Renaming %s to %s\n"), - quote_n (0, before_backup_name), - quote_n (1, after_backup_name)); - return true; - } - else - { - /* The backup operation failed. */ - int e = errno; - ERROR ((0, e, _("%s: Cannot rename to %s"), - quotearg_colon (before_backup_name), - quote_n (1, after_backup_name))); - assign_string (&after_backup_name, 0); - return false; - } -} - -/* Try to restore the recently backed up file to its original name. - This is usually only needed after a failed extraction. */ -void -undo_last_backup (void) -{ - if (after_backup_name) - { - if (rename (after_backup_name, before_backup_name) != 0) - { - int e = errno; - ERROR ((0, e, _("%s: Cannot rename to %s"), - quotearg_colon (after_backup_name), - quote_n (1, before_backup_name))); - } - if (verbose_option) - fprintf (stdlis, _("Renaming %s back to %s\n"), - quote_n (0, after_backup_name), - quote_n (1, before_backup_name)); - assign_string (&after_backup_name, 0); - } -} - -/* Depending on DEREF, apply either stat or lstat to (NAME, BUF). */ -int -deref_stat (bool deref, char const *name, struct stat *buf) -{ - return deref ? stat (name, buf) : lstat (name, buf); -} - -/* Set FD's (i.e., FILE's) access time to TIMESPEC[0]. If that's not - possible to do by itself, set its access and data modification - times to TIMESPEC[0] and TIMESPEC[1], respectively. */ -int -set_file_atime (int fd, char const *file, struct timespec const timespec[2]) -{ -#ifdef _FIOSATIME - if (0 <= fd) - { - struct timeval timeval; - timeval.tv_sec = timespec[0].tv_sec; - timeval.tv_usec = timespec[0].tv_nsec / 1000; - if (ioctl (fd, _FIOSATIME, &timeval) == 0) - return 0; - } -#endif - - return gl_futimens (fd, file, timespec); -} - -/* A description of a working directory. */ -struct wd -{ - char const *name; - int saved; - struct saved_cwd saved_cwd; -}; - -/* A vector of chdir targets. wd[0] is the initial working directory. */ -static struct wd *wd; - -/* The number of working directories in the vector. */ -static size_t wds; - -/* The allocated size of the vector. */ -static size_t wd_alloc; - -/* DIR is the operand of a -C option; add it to vector of chdir targets, - and return the index of its location. */ -int -chdir_arg (char const *dir) -{ - if (wds == wd_alloc) - { - if (wd_alloc == 0) - { - wd_alloc = 2; - wd = xmalloc (sizeof *wd * wd_alloc); - } - else - wd = x2nrealloc (wd, &wd_alloc, sizeof *wd); - - if (! wds) - { - wd[wds].name = "."; - wd[wds].saved = 0; - wds++; - } - } - - /* Optimize the common special case of the working directory, - or the working directory as a prefix. */ - if (dir[0]) - { - while (dir[0] == '.' && ISSLASH (dir[1])) - for (dir += 2; ISSLASH (*dir); dir++) - continue; - if (! dir[dir[0] == '.']) - return wds - 1; - } - - wd[wds].name = dir; - wd[wds].saved = 0; - return wds++; -} - -/* Change to directory I. If I is 0, change to the initial working - directory; otherwise, I must be a value returned by chdir_arg. */ -void -chdir_do (int i) -{ - static int previous; - - if (previous != i) - { - struct wd *prev = &wd[previous]; - struct wd *curr = &wd[i]; - - if (! prev->saved) - { - int err = 0; - prev->saved = 1; - if (save_cwd (&prev->saved_cwd) != 0) - err = errno; - else if (0 <= prev->saved_cwd.desc) - { - /* Make sure we still have at least one descriptor available. */ - int fd1 = prev->saved_cwd.desc; - int fd2 = dup (fd1); - if (0 <= fd2) - close (fd2); - else if (errno == EMFILE) - { - /* Force restore_cwd to use chdir_long. */ - close (fd1); - prev->saved_cwd.desc = -1; - prev->saved_cwd.name = xgetcwd (); - } - else - err = errno; - } - - if (err) - FATAL_ERROR ((0, err, _("Cannot save working directory"))); - } - - if (curr->saved) - { - if (restore_cwd (&curr->saved_cwd)) - FATAL_ERROR ((0, 0, _("Cannot change working directory"))); - } - else - { - if (i && ! ISSLASH (curr->name[0])) - chdir_do (i - 1); - if (chdir (curr->name) != 0) - chdir_fatal (curr->name); - } - - previous = i; - } -} - -void -close_diag (char const *name) -{ - if (ignore_failed_read_option) - close_warn (name); - else - close_error (name); -} - -void -open_diag (char const *name) -{ - if (ignore_failed_read_option) - open_warn (name); - else - open_error (name); -} - -void -read_diag_details (char const *name, off_t offset, size_t size) -{ - if (ignore_failed_read_option) - read_warn_details (name, offset, size); - else - read_error_details (name, offset, size); -} - -void -readlink_diag (char const *name) -{ - if (ignore_failed_read_option) - readlink_warn (name); - else - readlink_error (name); -} - -void -savedir_diag (char const *name) -{ - if (ignore_failed_read_option) - savedir_warn (name); - else - savedir_error (name); -} - -void -seek_diag_details (char const *name, off_t offset) -{ - if (ignore_failed_read_option) - seek_warn_details (name, offset); - else - seek_error_details (name, offset); -} - -void -stat_diag (char const *name) -{ - if (ignore_failed_read_option) - stat_warn (name); - else - stat_error (name); -} - -void -write_fatal_details (char const *name, ssize_t status, size_t size) -{ - write_error_details (name, status, size); - fatal_exit (); -} - -/* Fork, aborting if unsuccessful. */ -pid_t -xfork (void) -{ - pid_t p = fork (); - if (p == (pid_t) -1) - call_arg_fatal ("fork", _("child process")); - return p; -} - -/* Create a pipe, aborting if unsuccessful. */ -void -xpipe (int fd[2]) -{ - if (pipe (fd) < 0) - call_arg_fatal ("pipe", _("interprocess channel")); -} - -/* Return PTR, aligned upward to the next multiple of ALIGNMENT. - ALIGNMENT must be nonzero. The caller must arrange for ((char *) - PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable - locations. */ - -static inline void * -ptr_align (void *ptr, size_t alignment) -{ - char *p0 = ptr; - char *p1 = p0 + alignment - 1; - return p1 - (size_t) p1 % alignment; -} - -/* Return the address of a page-aligned buffer of at least SIZE bytes. - The caller should free *PTR when done with the buffer. */ - -void * -page_aligned_alloc (void **ptr, size_t size) -{ - size_t alignment = getpagesize (); - size_t size1 = size + alignment; - if (size1 < size) - xalloc_die (); - *ptr = xmalloc (size1); - return ptr_align (*ptr, alignment); -} diff --git a/src/bin/tar/src/names.c b/src/bin/tar/src/names.c deleted file mode 100644 index 585ad39ba7..0000000000 --- a/src/bin/tar/src/names.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* Various processing of names. - - Copyright (C) 1988, 1992, 1994, 1996, 1997, 1998, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include -#include -#include - -#include "common.h" - -/* User and group names. */ - -struct group *getgrnam (); -struct passwd *getpwnam (); -#if ! HAVE_DECL_GETPWUID -struct passwd *getpwuid (); -#endif -#if ! HAVE_DECL_GETGRGID -struct group *getgrgid (); -#endif - -/* Make sure you link with the proper libraries if you are running the - Yellow Peril (thanks for the good laugh, Ian J.!), or, euh... NIS. - This code should also be modified for non-UNIX systems to do something - reasonable. */ - -static char *cached_uname; -static char *cached_gname; - -static uid_t cached_uid; /* valid only if cached_uname is not empty */ -static gid_t cached_gid; /* valid only if cached_gname is not empty */ - -/* These variables are valid only if nonempty. */ -static char *cached_no_such_uname; -static char *cached_no_such_gname; - -/* These variables are valid only if nonzero. It's not worth optimizing - the case for weird systems where 0 is not a valid uid or gid. */ -static uid_t cached_no_such_uid; -static gid_t cached_no_such_gid; - -static void register_individual_file (char const *name); - -/* Given UID, find the corresponding UNAME. */ -void -uid_to_uname (uid_t uid, char **uname) -{ - struct passwd *passwd; - - if (uid != 0 && uid == cached_no_such_uid) - { - *uname = xstrdup (""); - return; - } - - if (!cached_uname || uid != cached_uid) - { - passwd = getpwuid (uid); - if (passwd) - { - cached_uid = uid; - assign_string (&cached_uname, passwd->pw_name); - } - else - { - cached_no_such_uid = uid; - *uname = xstrdup (""); - return; - } - } - *uname = xstrdup (cached_uname); -} - -/* Given GID, find the corresponding GNAME. */ -void -gid_to_gname (gid_t gid, char **gname) -{ - struct group *group; - - if (gid != 0 && gid == cached_no_such_gid) - { - *gname = xstrdup (""); - return; - } - - if (!cached_gname || gid != cached_gid) - { - group = getgrgid (gid); - if (group) - { - cached_gid = gid; - assign_string (&cached_gname, group->gr_name); - } - else - { - cached_no_such_gid = gid; - *gname = xstrdup (""); - return; - } - } - *gname = xstrdup (cached_gname); -} - -/* Given UNAME, set the corresponding UID and return 1, or else, return 0. */ -int -uname_to_uid (char const *uname, uid_t *uidp) -{ - struct passwd *passwd; - - if (cached_no_such_uname - && strcmp (uname, cached_no_such_uname) == 0) - return 0; - - if (!cached_uname - || uname[0] != cached_uname[0] - || strcmp (uname, cached_uname) != 0) - { - passwd = getpwnam (uname); - if (passwd) - { - cached_uid = passwd->pw_uid; - assign_string (&cached_uname, passwd->pw_name); - } - else - { - assign_string (&cached_no_such_uname, uname); - return 0; - } - } - *uidp = cached_uid; - return 1; -} - -/* Given GNAME, set the corresponding GID and return 1, or else, return 0. */ -int -gname_to_gid (char const *gname, gid_t *gidp) -{ - struct group *group; - - if (cached_no_such_gname - && strcmp (gname, cached_no_such_gname) == 0) - return 0; - - if (!cached_gname - || gname[0] != cached_gname[0] - || strcmp (gname, cached_gname) != 0) - { - group = getgrnam (gname); - if (group) - { - cached_gid = group->gr_gid; - assign_string (&cached_gname, gname); - } - else - { - assign_string (&cached_no_such_gname, gname); - return 0; - } - } - *gidp = cached_gid; - return 1; -} - - -/* Names from the command call. */ - -static struct name *namelist; /* first name in list, if any */ -static struct name **nametail = &namelist; /* end of name list */ - -/* File name arguments are processed in two stages: first a - name_array (see below) is filled, then the names from it - are moved into the namelist. - - This awkward process is needed only to implement --same-order option, - which is meant to help process large archives on machines with - limited memory. With this option on, namelist contains at most one - entry, which diminishes the memory consumption. - - However, I very much doubt if we still need this -- Sergey */ - -/* A name_array element contains entries of three types: */ - -#define NELT_NAME 0 /* File name */ -#define NELT_CHDIR 1 /* Change directory request */ -#define NELT_FMASK 2 /* Change fnmatch options request */ - -struct name_elt /* A name_array element. */ -{ - char type; /* Element type, see NELT_* constants above */ - union - { - const char *name; /* File or directory name */ - int matching_flags;/* fnmatch options if type == NELT_FMASK */ - } v; -}; - -static struct name_elt *name_array; /* store an array of names */ -static size_t allocated_names; /* how big is the array? */ -static size_t names; /* how many entries does it have? */ -static size_t name_index; /* how many of the entries have we scanned? */ - -/* Check the size of name_array, reallocating it as necessary. */ -static void -check_name_alloc () -{ - if (names == allocated_names) - { - if (allocated_names == 0) - allocated_names = 10; /* Set initial allocation */ - name_array = x2nrealloc (name_array, &allocated_names, - sizeof (name_array[0])); - } -} - -/* Add to name_array the file NAME with fnmatch options MATCHING_FLAGS */ -void -name_add_name (const char *name, int matching_flags) -{ - static int prev_flags = 0; /* FIXME: Or EXCLUDE_ANCHORED? */ - struct name_elt *ep; - - check_name_alloc (); - ep = &name_array[names++]; - if (prev_flags != matching_flags) - { - ep->type = NELT_FMASK; - ep->v.matching_flags = matching_flags; - prev_flags = matching_flags; - check_name_alloc (); - ep = &name_array[names++]; - } - ep->type = NELT_NAME; - ep->v.name = name; -} - -/* Add to name_array a chdir request for the directory NAME */ -void -name_add_dir (const char *name) -{ - struct name_elt *ep; - check_name_alloc (); - ep = &name_array[names++]; - ep->type = NELT_CHDIR; - ep->v.name = name; -} - - -/* Names from external name file. */ - -static char *name_buffer; /* buffer to hold the current file name */ -static size_t name_buffer_length; /* allocated length of name_buffer */ - -/* Set up to gather file names for tar. They can either come from a - file or were saved from decoding arguments. */ -void -name_init (void) -{ - name_buffer = xmalloc (NAME_FIELD_SIZE + 2); - name_buffer_length = NAME_FIELD_SIZE; -} - -void -name_term (void) -{ - free (name_buffer); - free (name_array); -} - -static int matching_flags; /* exclude_fnmatch options */ - -/* Get the next NELT_NAME element from name_array. Result is in - static storage and can't be relied upon across two calls. - - If CHANGE_DIRS is true, treat any entries of type NELT_CHDIR as - the request to change to the given directory. If filename_terminator - is NUL, CHANGE_DIRS is effectively always false. - - Entries of type NELT_FMASK cause updates of the matching_flags - value. */ -struct name_elt * -name_next_elt (int change_dirs) -{ - static struct name_elt entry; - const char *source; - char *cursor; - - if (filename_terminator == '\0') - change_dirs = 0; - - while (name_index != names) - { - struct name_elt *ep; - size_t source_len; - - ep = &name_array[name_index++]; - if (ep->type == NELT_FMASK) - { - matching_flags = ep->v.matching_flags; - continue; - } - - source = ep->v.name; - source_len = strlen (source); - if (name_buffer_length < source_len) - { - do - { - name_buffer_length *= 2; - if (! name_buffer_length) - xalloc_die (); - } - while (name_buffer_length < source_len); - - free (name_buffer); - name_buffer = xmalloc (name_buffer_length + 2); - } - strcpy (name_buffer, source); - - /* Zap trailing slashes. */ - - cursor = name_buffer + strlen (name_buffer) - 1; - while (cursor > name_buffer && ISSLASH (*cursor)) - *cursor-- = '\0'; - - if (change_dirs && ep->type == NELT_CHDIR) - { - if (chdir (name_buffer) < 0) - chdir_fatal (name_buffer); - } - else - { - if (unquote_option) - unquote_string (name_buffer); - if (incremental_option) - register_individual_file (name_buffer); - entry.type = ep->type; - entry.v.name = name_buffer; - return &entry; - } - } - - return NULL; -} - -const char * -name_next (int change_dirs) -{ - struct name_elt *nelt = name_next_elt (change_dirs); - return nelt ? nelt->v.name : NULL; -} - -/* Gather names in a list for scanning. Could hash them later if we - really care. - - If the names are already sorted to match the archive, we just read - them one by one. name_gather reads the first one, and it is called - by name_match as appropriate to read the next ones. At EOF, the - last name read is just left in the buffer. This option lets users - of small machines extract an arbitrary number of files by doing - "tar t" and editing down the list of files. */ - -void -name_gather (void) -{ - /* Buffer able to hold a single name. */ - static struct name *buffer; - static size_t allocated_size; - - struct name_elt *ep; - - if (same_order_option) - { - static int change_dir; - - if (allocated_size == 0) - { - allocated_size = offsetof (struct name, name) + NAME_FIELD_SIZE + 1; - buffer = xmalloc (allocated_size); - /* FIXME: This memset is overkill, and ugly... */ - memset (buffer, 0, allocated_size); - } - - while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR) - change_dir = chdir_arg (xstrdup (ep->v.name)); - - if (ep) - { - size_t needed_size; - - buffer->length = strlen (ep->v.name); - needed_size = offsetof (struct name, name) + buffer->length + 1; - if (allocated_size < needed_size) - { - do - { - allocated_size *= 2; - if (! allocated_size) - xalloc_die (); - } - while (allocated_size < needed_size); - - buffer = xrealloc (buffer, allocated_size); - } - buffer->change_dir = change_dir; - strcpy (buffer->name, ep->v.name); - buffer->next = 0; - buffer->found_count = 0; - buffer->matching_flags = matching_flags; - - namelist = buffer; - nametail = &namelist->next; - } - else if (change_dir) - addname (0, change_dir); - } - else - { - /* Non sorted names -- read them all in. */ - int change_dir = 0; - - for (;;) - { - int change_dir0 = change_dir; - while ((ep = name_next_elt (0)) && ep->type == NELT_CHDIR) - change_dir = chdir_arg (xstrdup (ep->v.name)); - - if (ep) - addname (ep->v.name, change_dir); - else - { - if (change_dir != change_dir0) - addname (0, change_dir); - break; - } - } - } -} - -/* Add a name to the namelist. */ -struct name * -addname (char const *string, int change_dir) -{ - size_t length = string ? strlen (string) : 0; - struct name *name = xmalloc (offsetof (struct name, name) + length + 1); - - if (string) - strcpy (name->name, string); - else - name->name[0] = 0; - - name->next = NULL; - name->length = length; - name->found_count = 0; - name->matching_flags = matching_flags; - name->change_dir = change_dir; - name->dir_contents = NULL; - - *nametail = name; - nametail = &name->next; - return name; -} - -/* Find a match for FILE_NAME (whose string length is LENGTH) in the name - list. */ -static struct name * -namelist_match (char const *file_name, size_t length) -{ - struct name *p; - - for (p = namelist; p; p = p->next) - { - if (p->name[0] - && exclude_fnmatch (p->name, file_name, p->matching_flags)) - return p; - } - - return NULL; -} - -/* Return true if and only if name FILE_NAME (from an archive) matches any - name from the namelist. */ -bool -name_match (const char *file_name) -{ - size_t length = strlen (file_name); - - while (1) - { - struct name *cursor = namelist; - - if (!cursor) - return true; - - if (cursor->name[0] == 0) - { - chdir_do (cursor->change_dir); - namelist = 0; - nametail = &namelist; - return true; - } - - cursor = namelist_match (file_name, length); - if (cursor) - { - if (!(ISSLASH (file_name[cursor->length]) && recursion_option) - || cursor->found_count == 0) - cursor->found_count++; /* remember it matched */ - if (starting_file_option) - { - free (namelist); - namelist = 0; - nametail = &namelist; - } - chdir_do (cursor->change_dir); - - /* We got a match. */ - return ISFOUND (cursor); - } - - /* Filename from archive not found in namelist. If we have the whole - namelist here, just return 0. Otherwise, read the next name in and - compare it. If this was the last name, namelist->found_count will - remain on. If not, we loop to compare the newly read name. */ - - if (same_order_option && namelist->found_count) - { - name_gather (); /* read one more */ - if (namelist->found_count) - return false; - } - else - return false; - } -} - -/* Returns true if all names from the namelist were processed. - P is the stat_info of the most recently processed entry. - The decision is postponed until the next entry is read if: - - 1) P ended with a slash (i.e. it was a directory) - 2) P matches any entry from the namelist *and* represents a subdirectory - or a file lying under this entry (in the terms of directory structure). - - This is necessary to handle contents of directories. */ -bool -all_names_found (struct tar_stat_info *p) -{ - struct name const *cursor; - size_t len; - - if (test_label_option) - return true; - if (!p->file_name || occurrence_option == 0 || p->had_trailing_slash) - return false; - len = strlen (p->file_name); - for (cursor = namelist; cursor; cursor = cursor->next) - { - if ((cursor->name[0] && !WASFOUND (cursor)) - || (len >= cursor->length && ISSLASH (p->file_name[cursor->length]))) - return false; - } - return true; -} - -static inline int -is_pattern (const char *string) -{ - return strchr (string, '*') || strchr (string, '[') || strchr (string, '?'); -} - -static void -regex_usage_warning (const char *name) -{ - static int warned_once = 0; - - if (warn_regex_usage && is_pattern (name)) - { - warned_once = 1; - WARN ((0, 0, - /* TRANSLATORS: The following three msgids form a single sentence. - */ - _("Pattern matching characters used in file names. Please,"))); - WARN ((0, 0, - _("use --wildcards to enable pattern matching, or --no-wildcards to"))); - WARN ((0, 0, - _("suppress this warning."))); - } -} - -/* Print the names of things in the namelist that were not matched. */ -void -names_notfound (void) -{ - struct name const *cursor; - - for (cursor = namelist; cursor; cursor = cursor->next) - if (!WASFOUND (cursor) && cursor->name[0]) - { - regex_usage_warning (cursor->name); - if (cursor->found_count == 0) - ERROR ((0, 0, _("%s: Not found in archive"), - quotearg_colon (cursor->name))); - else - ERROR ((0, 0, _("%s: Required occurrence not found in archive"), - quotearg_colon (cursor->name))); - } - - /* Don't bother freeing the name list; we're about to exit. */ - namelist = 0; - nametail = &namelist; - - if (same_order_option) - { - const char *name; - - while ((name = name_next (1)) != NULL) - { - regex_usage_warning (name); - ERROR ((0, 0, _("%s: Not found in archive"), - quotearg_colon (name))); - } - } -} - -/* Sorting name lists. */ - -/* Sort linked LIST of names, of given LENGTH, using COMPARE to order - names. Return the sorted list. Apart from the type `struct name' - and the definition of SUCCESSOR, this is a generic list-sorting - function, but it's too painful to make it both generic and portable - in C. */ - -static struct name * -merge_sort (struct name *list, int length, - int (*compare) (struct name const*, struct name const*)) -{ - struct name *first_list; - struct name *second_list; - int first_length; - int second_length; - struct name *result; - struct name **merge_point; - struct name *cursor; - int counter; - -# define SUCCESSOR(name) ((name)->next) - - if (length == 1) - return list; - - if (length == 2) - { - if ((*compare) (list, SUCCESSOR (list)) > 0) - { - result = SUCCESSOR (list); - SUCCESSOR (result) = list; - SUCCESSOR (list) = 0; - return result; - } - return list; - } - - first_list = list; - first_length = (length + 1) / 2; - second_length = length / 2; - for (cursor = list, counter = first_length - 1; - counter; - cursor = SUCCESSOR (cursor), counter--) - continue; - second_list = SUCCESSOR (cursor); - SUCCESSOR (cursor) = 0; - - first_list = merge_sort (first_list, first_length, compare); - second_list = merge_sort (second_list, second_length, compare); - - merge_point = &result; - while (first_list && second_list) - if ((*compare) (first_list, second_list) < 0) - { - cursor = SUCCESSOR (first_list); - *merge_point = first_list; - merge_point = &SUCCESSOR (first_list); - first_list = cursor; - } - else - { - cursor = SUCCESSOR (second_list); - *merge_point = second_list; - merge_point = &SUCCESSOR (second_list); - second_list = cursor; - } - if (first_list) - *merge_point = first_list; - else - *merge_point = second_list; - - return result; - -#undef SUCCESSOR -} - -/* A comparison function for sorting names. Put found names last; - break ties by string comparison. */ - -static int -compare_names (struct name const *n1, struct name const *n2) -{ - int found_diff = WASFOUND(n2) - WASFOUND(n1); - return found_diff ? found_diff : strcmp (n1->name, n2->name); -} - -/* Add all the dirs under NAME, which names a directory, to the namelist. - If any of the files is a directory, recurse on the subdirectory. - DEVICE is the device not to leave, if the -l option is specified. */ - -static void -add_hierarchy_to_namelist (struct name *name, dev_t device) -{ - char *file_name = name->name; - char *buffer = get_directory_contents (file_name, device); - - if (! buffer) - name->dir_contents = "\0\0\0\0"; - else - { - size_t name_length = name->length; - size_t allocated_length = (name_length >= NAME_FIELD_SIZE - ? name_length + NAME_FIELD_SIZE - : NAME_FIELD_SIZE); - char *namebuf = xmalloc (allocated_length + 1); - /* FIXME: + 2 above? */ - char *string; - size_t string_length; - int change_dir = name->change_dir; - - name->dir_contents = buffer; - strcpy (namebuf, file_name); - if (! ISSLASH (namebuf[name_length - 1])) - { - namebuf[name_length++] = '/'; - namebuf[name_length] = '\0'; - } - - for (string = buffer; *string; string += string_length + 1) - { - string_length = strlen (string); - if (*string == 'D') - { - struct name *np; - - if (allocated_length <= name_length + string_length) - { - do - { - allocated_length *= 2; - if (! allocated_length) - xalloc_die (); - } - while (allocated_length <= name_length + string_length); - - namebuf = xrealloc (namebuf, allocated_length + 1); - } - strcpy (namebuf + name_length, string + 1); - np = addname (namebuf, change_dir); - add_hierarchy_to_namelist (np, device); - } - } - - free (namebuf); - } -} - -/* Collect all the names from argv[] (or whatever), expand them into a - directory tree, and sort them. This gets only subdirectories, not - all files. */ - -void -collect_and_sort_names (void) -{ - struct name *name; - struct name *next_name; - int num_names; - struct stat statbuf; - - name_gather (); - - if (listed_incremental_option) - read_directory_file (); - - if (!namelist) - addname (".", 0); - - for (name = namelist; name; name = next_name) - { - next_name = name->next; - if (name->found_count || name->dir_contents) - continue; - if (name->matching_flags & EXCLUDE_WILDCARDS) - /* NOTE: EXCLUDE_ANCHORED is not relevant here */ - /* FIXME: just skip regexps for now */ - continue; - chdir_do (name->change_dir); - if (name->name[0] == 0) - continue; - - if (deref_stat (dereference_option, name->name, &statbuf) != 0) - { - stat_diag (name->name); - continue; - } - if (S_ISDIR (statbuf.st_mode)) - { - name->found_count++; - add_hierarchy_to_namelist (name, statbuf.st_dev); - } - } - - num_names = 0; - for (name = namelist; name; name = name->next) - num_names++; - namelist = merge_sort (namelist, num_names, compare_names); - - for (name = namelist; name; name = name->next) - name->found_count = 0; - - if (listed_incremental_option) - { - for (name = namelist; name && name->name[0] == 0; name++) - ; - if (name) - name->dir_contents = append_incremental_renames (name->dir_contents); - } -} - -/* This is like name_match, except that - 1. It returns a pointer to the name it matched, and doesn't set FOUND - in structure. The caller will have to do that if it wants to. - 2. If the namelist is empty, it returns null, unlike name_match, which - returns TRUE. */ -struct name * -name_scan (const char *file_name) -{ - size_t length = strlen (file_name); - - while (1) - { - struct name *cursor = namelist_match (file_name, length); - if (cursor) - return cursor; - - /* Filename from archive not found in namelist. If we have the whole - namelist here, just return 0. Otherwise, read the next name in and - compare it. If this was the last name, namelist->found_count will - remain on. If not, we loop to compare the newly read name. */ - - if (same_order_option && namelist && namelist->found_count) - { - name_gather (); /* read one more */ - if (namelist->found_count) - return 0; - } - else - return 0; - } -} - -/* This returns a name from the namelist which doesn't have ->found - set. It sets ->found before returning, so successive calls will - find and return all the non-found names in the namelist. */ -struct name *gnu_list_name; - -char * -name_from_list (void) -{ - if (!gnu_list_name) - gnu_list_name = namelist; - while (gnu_list_name - && (gnu_list_name->found_count || gnu_list_name->name[0] == 0)) - gnu_list_name = gnu_list_name->next; - if (gnu_list_name) - { - gnu_list_name->found_count++; - chdir_do (gnu_list_name->change_dir); - return gnu_list_name->name; - } - return 0; -} - -void -blank_name_list (void) -{ - struct name *name; - - gnu_list_name = 0; - for (name = namelist; name; name = name->next) - name->found_count = 0; -} - -/* Yield a newly allocated file name consisting of FILE_NAME concatenated to - NAME, with an intervening slash if FILE_NAME does not already end in one. */ -char * -new_name (const char *file_name, const char *name) -{ - size_t file_name_len = strlen (file_name); - size_t namesize = strlen (name) + 1; - int slash = file_name_len && ! ISSLASH (file_name[file_name_len - 1]); - char *buffer = xmalloc (file_name_len + slash + namesize); - memcpy (buffer, file_name, file_name_len); - buffer[file_name_len] = '/'; - memcpy (buffer + file_name_len + slash, name, namesize); - return buffer; -} - -/* Return nonzero if file NAME is excluded. */ -bool -excluded_name (char const *name) -{ - return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name)); -} - -/* Names to avoid dumping. */ -static Hash_table *avoided_name_table; - -/* Remember to not archive NAME. */ -void -add_avoided_name (char const *name) -{ - hash_string_insert (&avoided_name_table, name); -} - -/* Should NAME be avoided when archiving? */ -bool -is_avoided_name (char const *name) -{ - return hash_string_lookup (avoided_name_table, name); -} - - -static Hash_table *individual_file_table; - -static void -register_individual_file (char const *name) -{ - struct stat st; - - if (deref_stat (dereference_option, name, &st) != 0) - return; /* Will be complained about later */ - if (S_ISDIR (st.st_mode)) - return; - - hash_string_insert (&individual_file_table, name); -} - -bool -is_individual_file (char const *name) -{ - return hash_string_lookup (individual_file_table, name); -} - - - -/* Return the size of the prefix of FILE_NAME that is removed after - stripping NUM leading file name components. NUM must be - positive. */ - -size_t -stripped_prefix_len (char const *file_name, size_t num) -{ - char const *p = file_name + FILE_SYSTEM_PREFIX_LEN (file_name); - while (ISSLASH (*p)) - p++; - while (*p) - { - bool slash = ISSLASH (*p); - p++; - if (slash) - { - if (--num == 0) - return p - file_name; - while (ISSLASH (*p)) - p++; - } - } - return -1; -} - -/* Return nonzero if NAME contains ".." as a file name component. */ -bool -contains_dot_dot (char const *name) -{ - char const *p = name + FILE_SYSTEM_PREFIX_LEN (name); - - for (;; p++) - { - if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) - return 1; - - while (! ISSLASH (*p)) - { - if (! *p++) - return 0; - } - } -} diff --git a/src/bin/tar/src/sparse.c b/src/bin/tar/src/sparse.c deleted file mode 100644 index 9fde5080d5..0000000000 --- a/src/bin/tar/src/sparse.c +++ /dev/null @@ -1,1175 +0,0 @@ -/* Functions for dealing with sparse files - - Copyright (C) 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include -#include "common.h" - -struct tar_sparse_file; -static bool sparse_select_optab (struct tar_sparse_file *file); - -enum sparse_scan_state - { - scan_begin, - scan_block, - scan_end - }; - -struct tar_sparse_optab -{ - bool (*init) (struct tar_sparse_file *); - bool (*done) (struct tar_sparse_file *); - bool (*sparse_member_p) (struct tar_sparse_file *); - bool (*dump_header) (struct tar_sparse_file *); - bool (*fixup_header) (struct tar_sparse_file *); - bool (*decode_header) (struct tar_sparse_file *); - bool (*scan_block) (struct tar_sparse_file *, enum sparse_scan_state, - void *); - bool (*dump_region) (struct tar_sparse_file *, size_t); - bool (*extract_region) (struct tar_sparse_file *, size_t); -}; - -struct tar_sparse_file -{ - int fd; /* File descriptor */ - bool seekable; /* Is fd seekable? */ - off_t offset; /* Current offset in fd if seekable==false. - Otherwise unused */ - off_t dumped_size; /* Number of bytes actually written - to the archive */ - struct tar_stat_info *stat_info; /* Information about the file */ - struct tar_sparse_optab const *optab; /* Operation table */ - void *closure; /* Any additional data optab calls might - require */ -}; - -/* Dump zeros to file->fd until offset is reached. It is used instead of - lseek if the output file is not seekable */ -static bool -dump_zeros (struct tar_sparse_file *file, off_t offset) -{ - static char const zero_buf[BLOCKSIZE]; - - if (offset < file->offset) - { - errno = EINVAL; - return false; - } - - while (file->offset < offset) - { - size_t size = (BLOCKSIZE < offset - file->offset - ? BLOCKSIZE - : offset - file->offset); - ssize_t wrbytes; - - wrbytes = write (file->fd, zero_buf, size); - if (wrbytes <= 0) - { - if (wrbytes == 0) - errno = EINVAL; - return false; - } - file->offset += wrbytes; - } - - return true; -} - -static bool -tar_sparse_member_p (struct tar_sparse_file *file) -{ - if (file->optab->sparse_member_p) - return file->optab->sparse_member_p (file); - return false; -} - -static bool -tar_sparse_init (struct tar_sparse_file *file) -{ - memset (file, 0, sizeof *file); - - if (!sparse_select_optab (file)) - return false; - - if (file->optab->init) - return file->optab->init (file); - - return true; -} - -static bool -tar_sparse_done (struct tar_sparse_file *file) -{ - if (file->optab->done) - return file->optab->done (file); - return true; -} - -static bool -tar_sparse_scan (struct tar_sparse_file *file, enum sparse_scan_state state, - void *block) -{ - if (file->optab->scan_block) - return file->optab->scan_block (file, state, block); - return true; -} - -static bool -tar_sparse_dump_region (struct tar_sparse_file *file, size_t i) -{ - if (file->optab->dump_region) - return file->optab->dump_region (file, i); - return false; -} - -static bool -tar_sparse_extract_region (struct tar_sparse_file *file, size_t i) -{ - if (file->optab->extract_region) - return file->optab->extract_region (file, i); - return false; -} - -static bool -tar_sparse_dump_header (struct tar_sparse_file *file) -{ - if (file->optab->dump_header) - return file->optab->dump_header (file); - return false; -} - -static bool -tar_sparse_decode_header (struct tar_sparse_file *file) -{ - if (file->optab->decode_header) - return file->optab->decode_header (file); - return true; -} - -static bool -tar_sparse_fixup_header (struct tar_sparse_file *file) -{ - if (file->optab->fixup_header) - return file->optab->fixup_header (file); - return true; -} - - -static bool -lseek_or_error (struct tar_sparse_file *file, off_t offset) -{ - if (file->seekable - ? lseek (file->fd, offset, SEEK_SET) < 0 - : ! dump_zeros (file, offset)) - { - seek_diag_details (file->stat_info->orig_file_name, offset); - return false; - } - return true; -} - -/* Takes a blockful of data and basically cruises through it to see if - it's made *entirely* of zeros, returning a 0 the instant it finds - something that is a nonzero, i.e., useful data. */ -static bool -zero_block_p (char const *buffer, size_t size) -{ - while (size--) - if (*buffer++) - return false; - return true; -} - -static void -sparse_add_map (struct tar_stat_info *st, struct sp_array const *sp) -{ - struct sp_array *sparse_map = st->sparse_map; - size_t avail = st->sparse_map_avail; - if (avail == st->sparse_map_size) - st->sparse_map = sparse_map = - x2nrealloc (sparse_map, &st->sparse_map_size, sizeof *sparse_map); - sparse_map[avail] = *sp; - st->sparse_map_avail = avail + 1; -} - -/* Scan the sparse file and create its map */ -static bool -sparse_scan_file (struct tar_sparse_file *file) -{ - struct tar_stat_info *st = file->stat_info; - int fd = file->fd; - char buffer[BLOCKSIZE]; - size_t count; - off_t offset = 0; - struct sp_array sp = {0, 0}; - - if (!lseek_or_error (file, 0)) - return false; - - st->archive_file_size = 0; - - if (!tar_sparse_scan (file, scan_begin, NULL)) - return false; - - while ((count = safe_read (fd, buffer, sizeof buffer)) != 0 - && count != SAFE_READ_ERROR) - { - /* Analyze the block. */ - if (zero_block_p (buffer, count)) - { - if (sp.numbytes) - { - sparse_add_map (st, &sp); - sp.numbytes = 0; - if (!tar_sparse_scan (file, scan_block, NULL)) - return false; - } - } - else - { - if (sp.numbytes == 0) - sp.offset = offset; - sp.numbytes += count; - st->archive_file_size += count; - if (!tar_sparse_scan (file, scan_block, buffer)) - return false; - } - - offset += count; - } - - if (sp.numbytes == 0) - sp.offset = offset; - - sparse_add_map (st, &sp); - st->archive_file_size += count; - return tar_sparse_scan (file, scan_end, NULL); -} - -static struct tar_sparse_optab const oldgnu_optab; -static struct tar_sparse_optab const star_optab; -static struct tar_sparse_optab const pax_optab; - -static bool -sparse_select_optab (struct tar_sparse_file *file) -{ - switch (current_format == DEFAULT_FORMAT ? archive_format : current_format) - { - case V7_FORMAT: - case USTAR_FORMAT: - return false; - - case OLDGNU_FORMAT: - case GNU_FORMAT: /*FIXME: This one should disappear? */ - file->optab = &oldgnu_optab; - break; - - case POSIX_FORMAT: - file->optab = &pax_optab; - break; - - case STAR_FORMAT: - file->optab = &star_optab; - break; - - default: - return false; - } - return true; -} - -static bool -sparse_dump_region (struct tar_sparse_file *file, size_t i) -{ - union block *blk; - off_t bytes_left = file->stat_info->sparse_map[i].numbytes; - - if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset)) - return false; - - while (bytes_left > 0) - { - size_t bufsize = (bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left; - size_t bytes_read; - - blk = find_next_block (); - bytes_read = safe_read (file->fd, blk->buffer, bufsize); - if (bytes_read == SAFE_READ_ERROR) - { - read_diag_details (file->stat_info->orig_file_name, - (file->stat_info->sparse_map[i].offset - + file->stat_info->sparse_map[i].numbytes - - bytes_left), - bufsize); - return false; - } - - memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read); - bytes_left -= bytes_read; - file->dumped_size += bytes_read; - mv_size_left (file->stat_info->archive_file_size - file->dumped_size); - set_next_block_after (blk); - } - - return true; -} - -static bool -sparse_extract_region (struct tar_sparse_file *file, size_t i) -{ - size_t write_size; - - if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset)) - return false; - - write_size = file->stat_info->sparse_map[i].numbytes; - - if (write_size == 0) - { - /* Last block of the file is a hole */ - if (file->seekable && sys_truncate (file->fd)) - truncate_warn (file->stat_info->orig_file_name); - } - else while (write_size > 0) - { - size_t count; - size_t wrbytes = (write_size > BLOCKSIZE) ? BLOCKSIZE : write_size; - union block *blk = find_next_block (); - if (!blk) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return false; - } - set_next_block_after (blk); - count = full_write (file->fd, blk->buffer, wrbytes); - write_size -= count; - file->dumped_size += count; - mv_size_left (file->stat_info->archive_file_size - file->dumped_size); - file->offset += count; - if (count != wrbytes) - { - write_error_details (file->stat_info->orig_file_name, - count, wrbytes); - return false; - } - } - return true; -} - - - -/* Interface functions */ -enum dump_status -sparse_dump_file (int fd, struct tar_stat_info *st) -{ - bool rc; - struct tar_sparse_file file; - - if (!tar_sparse_init (&file)) - return dump_status_not_implemented; - - file.stat_info = st; - file.fd = fd; - file.seekable = true; /* File *must* be seekable for dump to work */ - - rc = sparse_scan_file (&file); - if (rc && file.optab->dump_region) - { - tar_sparse_dump_header (&file); - - if (fd >= 0) - { - size_t i; - - mv_begin (file.stat_info); - for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++) - rc = tar_sparse_dump_region (&file, i); - mv_end (); - } - } - - pad_archive (file.stat_info->archive_file_size - file.dumped_size); - return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short; -} - -bool -sparse_member_p (struct tar_stat_info *st) -{ - struct tar_sparse_file file; - - if (!tar_sparse_init (&file)) - return false; - file.stat_info = st; - return tar_sparse_member_p (&file); -} - -bool -sparse_fixup_header (struct tar_stat_info *st) -{ - struct tar_sparse_file file; - - if (!tar_sparse_init (&file)) - return false; - file.stat_info = st; - return tar_sparse_fixup_header (&file); -} - -enum dump_status -sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size) -{ - bool rc = true; - struct tar_sparse_file file; - size_t i; - - if (!tar_sparse_init (&file)) - return dump_status_not_implemented; - - file.stat_info = st; - file.fd = fd; - file.seekable = lseek (fd, 0, SEEK_SET) == 0; - file.offset = 0; - - rc = tar_sparse_decode_header (&file); - for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++) - rc = tar_sparse_extract_region (&file, i); - *size = file.stat_info->archive_file_size - file.dumped_size; - return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short; -} - -enum dump_status -sparse_skip_file (struct tar_stat_info *st) -{ - bool rc = true; - struct tar_sparse_file file; - - if (!tar_sparse_init (&file)) - return dump_status_not_implemented; - - file.stat_info = st; - file.fd = -1; - - rc = tar_sparse_decode_header (&file); - skip_file (file.stat_info->archive_file_size - file.dumped_size); - return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short; -} - - -static bool -check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end) -{ - if (!lseek_or_error (file, beg)) - return false; - - while (beg < end) - { - size_t bytes_read; - size_t rdsize = BLOCKSIZE < end - beg ? BLOCKSIZE : end - beg; - char diff_buffer[BLOCKSIZE]; - - bytes_read = safe_read (file->fd, diff_buffer, rdsize); - if (bytes_read == SAFE_READ_ERROR) - { - read_diag_details (file->stat_info->orig_file_name, - beg, - rdsize); - return false; - } - if (!zero_block_p (diff_buffer, bytes_read)) - { - char begbuf[INT_BUFSIZE_BOUND (off_t)]; - report_difference (file->stat_info, - _("File fragment at %s is not a hole"), - offtostr (beg, begbuf)); - return false; - } - - beg += bytes_read; - } - return true; -} - -static bool -check_data_region (struct tar_sparse_file *file, size_t i) -{ - size_t size_left; - - if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset)) - return false; - size_left = file->stat_info->sparse_map[i].numbytes; - mv_size_left (file->stat_info->archive_file_size - file->dumped_size); - - while (size_left > 0) - { - size_t bytes_read; - size_t rdsize = (size_left > BLOCKSIZE) ? BLOCKSIZE : size_left; - char diff_buffer[BLOCKSIZE]; - - union block *blk = find_next_block (); - if (!blk) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return false; - } - set_next_block_after (blk); - bytes_read = safe_read (file->fd, diff_buffer, rdsize); - if (bytes_read == SAFE_READ_ERROR) - { - read_diag_details (file->stat_info->orig_file_name, - (file->stat_info->sparse_map[i].offset - + file->stat_info->sparse_map[i].numbytes - - size_left), - rdsize); - return false; - } - file->dumped_size += bytes_read; - size_left -= bytes_read; - mv_size_left (file->stat_info->archive_file_size - file->dumped_size); - if (memcmp (blk->buffer, diff_buffer, rdsize)) - { - report_difference (file->stat_info, _("Contents differ")); - return false; - } - } - return true; -} - -bool -sparse_diff_file (int fd, struct tar_stat_info *st) -{ - bool rc = true; - struct tar_sparse_file file; - size_t i; - off_t offset = 0; - - if (!tar_sparse_init (&file)) - return dump_status_not_implemented; - - file.stat_info = st; - file.fd = fd; - file.seekable = true; /* File *must* be seekable for compare to work */ - - rc = tar_sparse_decode_header (&file); - mv_begin (st); - for (i = 0; rc && i < file.stat_info->sparse_map_avail; i++) - { - rc = check_sparse_region (&file, - offset, file.stat_info->sparse_map[i].offset) - && check_data_region (&file, i); - offset = file.stat_info->sparse_map[i].offset - + file.stat_info->sparse_map[i].numbytes; - } - - if (!rc) - skip_file (file.stat_info->archive_file_size - file.dumped_size); - mv_end (); - - tar_sparse_done (&file); - return rc; -} - - -/* Old GNU Format. The sparse file information is stored in the - oldgnu_header in the following manner: - - The header is marked with type 'S'. Its `size' field contains - the cumulative size of all non-empty blocks of the file. The - actual file size is stored in `realsize' member of oldgnu_header. - - The map of the file is stored in a list of `struct sparse'. - Each struct contains offset to the block of data and its - size (both as octal numbers). The first file header contains - at most 4 such structs (SPARSES_IN_OLDGNU_HEADER). If the map - contains more structs, then the field `isextended' of the main - header is set to 1 (binary) and the `struct sparse_header' - header follows, containing at most 21 following structs - (SPARSES_IN_SPARSE_HEADER). If more structs follow, `isextended' - field of the extended header is set and next next extension header - follows, etc... */ - -enum oldgnu_add_status - { - add_ok, - add_finish, - add_fail - }; - -static bool -oldgnu_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused))) -{ - return current_header->header.typeflag == GNUTYPE_SPARSE; -} - -/* Add a sparse item to the sparse file and its obstack */ -static enum oldgnu_add_status -oldgnu_add_sparse (struct tar_sparse_file *file, struct sparse *s) -{ - struct sp_array sp; - - if (s->numbytes[0] == '\0') - return add_finish; - sp.offset = OFF_FROM_HEADER (s->offset); - sp.numbytes = SIZE_FROM_HEADER (s->numbytes); - if (sp.offset < 0 - || file->stat_info->stat.st_size < sp.offset + sp.numbytes - || file->stat_info->archive_file_size < 0) - return add_fail; - - sparse_add_map (file->stat_info, &sp); - return add_ok; -} - -static bool -oldgnu_fixup_header (struct tar_sparse_file *file) -{ - /* NOTE! st_size was initialized from the header - which actually contains archived size. The following fixes it */ - file->stat_info->archive_file_size = file->stat_info->stat.st_size; - file->stat_info->stat.st_size = - OFF_FROM_HEADER (current_header->oldgnu_header.realsize); - return true; -} - -/* Convert old GNU format sparse data to internal representation */ -static bool -oldgnu_get_sparse_info (struct tar_sparse_file *file) -{ - size_t i; - union block *h = current_header; - int ext_p; - enum oldgnu_add_status rc; - - file->stat_info->sparse_map_avail = 0; - for (i = 0; i < SPARSES_IN_OLDGNU_HEADER; i++) - { - rc = oldgnu_add_sparse (file, &h->oldgnu_header.sp[i]); - if (rc != add_ok) - break; - } - - for (ext_p = h->oldgnu_header.isextended; - rc == add_ok && ext_p; ext_p = h->sparse_header.isextended) - { - h = find_next_block (); - if (!h) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return false; - } - set_next_block_after (h); - for (i = 0; i < SPARSES_IN_SPARSE_HEADER && rc == add_ok; i++) - rc = oldgnu_add_sparse (file, &h->sparse_header.sp[i]); - } - - if (rc == add_fail) - { - ERROR ((0, 0, _("%s: invalid sparse archive member"), - file->stat_info->orig_file_name)); - return false; - } - return true; -} - -static void -oldgnu_store_sparse_info (struct tar_sparse_file *file, size_t *pindex, - struct sparse *sp, size_t sparse_size) -{ - for (; *pindex < file->stat_info->sparse_map_avail - && sparse_size > 0; sparse_size--, sp++, ++*pindex) - { - OFF_TO_CHARS (file->stat_info->sparse_map[*pindex].offset, - sp->offset); - SIZE_TO_CHARS (file->stat_info->sparse_map[*pindex].numbytes, - sp->numbytes); - } -} - -static bool -oldgnu_dump_header (struct tar_sparse_file *file) -{ - off_t block_ordinal = current_block_ordinal (); - union block *blk; - size_t i; - - blk = start_header (file->stat_info); - blk->header.typeflag = GNUTYPE_SPARSE; - if (file->stat_info->sparse_map_avail > SPARSES_IN_OLDGNU_HEADER) - blk->oldgnu_header.isextended = 1; - - /* Store the real file size */ - OFF_TO_CHARS (file->stat_info->stat.st_size, blk->oldgnu_header.realsize); - /* Store the effective (shrunken) file size */ - OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size); - - i = 0; - oldgnu_store_sparse_info (file, &i, - blk->oldgnu_header.sp, - SPARSES_IN_OLDGNU_HEADER); - blk->oldgnu_header.isextended = i < file->stat_info->sparse_map_avail; - finish_header (file->stat_info, blk, block_ordinal); - - while (i < file->stat_info->sparse_map_avail) - { - blk = find_next_block (); - memset (blk->buffer, 0, BLOCKSIZE); - oldgnu_store_sparse_info (file, &i, - blk->sparse_header.sp, - SPARSES_IN_SPARSE_HEADER); - if (i < file->stat_info->sparse_map_avail) - blk->sparse_header.isextended = 1; - set_next_block_after (blk); - } - return true; -} - -static struct tar_sparse_optab const oldgnu_optab = { - NULL, /* No init function */ - NULL, /* No done function */ - oldgnu_sparse_member_p, - oldgnu_dump_header, - oldgnu_fixup_header, - oldgnu_get_sparse_info, - NULL, /* No scan_block function */ - sparse_dump_region, - sparse_extract_region, -}; - - -/* Star */ - -static bool -star_sparse_member_p (struct tar_sparse_file *file __attribute__ ((unused))) -{ - return current_header->header.typeflag == GNUTYPE_SPARSE; -} - -static bool -star_fixup_header (struct tar_sparse_file *file) -{ - /* NOTE! st_size was initialized from the header - which actually contains archived size. The following fixes it */ - file->stat_info->archive_file_size = file->stat_info->stat.st_size; - file->stat_info->stat.st_size = - OFF_FROM_HEADER (current_header->star_in_header.realsize); - return true; -} - -/* Convert STAR format sparse data to internal representation */ -static bool -star_get_sparse_info (struct tar_sparse_file *file) -{ - size_t i; - union block *h = current_header; - int ext_p; - enum oldgnu_add_status rc = add_ok; - - file->stat_info->sparse_map_avail = 0; - - if (h->star_in_header.prefix[0] == '\0' - && h->star_in_header.sp[0].offset[10] != '\0') - { - /* Old star format */ - for (i = 0; i < SPARSES_IN_STAR_HEADER; i++) - { - rc = oldgnu_add_sparse (file, &h->star_in_header.sp[i]); - if (rc != add_ok) - break; - } - ext_p = h->star_in_header.isextended; - } - else - ext_p = 1; - - for (; rc == add_ok && ext_p; ext_p = h->star_ext_header.isextended) - { - h = find_next_block (); - if (!h) - { - ERROR ((0, 0, _("Unexpected EOF in archive"))); - return false; - } - set_next_block_after (h); - for (i = 0; i < SPARSES_IN_STAR_EXT_HEADER && rc == add_ok; i++) - rc = oldgnu_add_sparse (file, &h->star_ext_header.sp[i]); - } - - if (rc == add_fail) - { - ERROR ((0, 0, _("%s: invalid sparse archive member"), - file->stat_info->orig_file_name)); - return false; - } - return true; -} - - -static struct tar_sparse_optab const star_optab = { - NULL, /* No init function */ - NULL, /* No done function */ - star_sparse_member_p, - NULL, - star_fixup_header, - star_get_sparse_info, - NULL, /* No scan_block function */ - NULL, /* No dump region function */ - sparse_extract_region, -}; - - -/* GNU PAX sparse file format. There are several versions: - - * 0.0 - - The initial version of sparse format used by tar 1.14-1.15.1. - The sparse file map is stored in x header: - - GNU.sparse.size Real size of the stored file - GNU.sparse.numblocks Number of blocks in the sparse map - repeat numblocks time - GNU.sparse.offset Offset of the next data block - GNU.sparse.numbytes Size of the next data block - end repeat - - This has been reported as conflicting with the POSIX specs. The reason is - that offsets and sizes of non-zero data blocks were stored in multiple - instances of GNU.sparse.offset/GNU.sparse.numbytes variables, whereas - POSIX requires the latest occurrence of the variable to override all - previous occurrences. - - To avoid this incompatibility two following versions were introduced. - - * 0.1 - - Used by tar 1.15.2 -- 1.15.91 (alpha releases). - - The sparse file map is stored in - x header: - - GNU.sparse.size Real size of the stored file - GNU.sparse.numblocks Number of blocks in the sparse map - GNU.sparse.map Map of non-null data chunks. A string consisting - of comma-separated values "offset,size[,offset,size]..." - - The resulting GNU.sparse.map string can be *very* long. While POSIX does not - impose any limit on the length of a x header variable, this can confuse some - tars. - - * 1.0 - - Starting from this version, the exact sparse format version is specified - explicitely in the header using the following variables: - - GNU.sparse.major Major version - GNU.sparse.minor Minor version - - X header keeps the following variables: - - GNU.sparse.name Real file name of the sparse file - GNU.sparse.realsize Real size of the stored file (corresponds to the old - GNU.sparse.size variable) - - The name field of the ustar header is constructed using the pattern - "%d/GNUSparseFile.%p/%f". - - The sparse map itself is stored in the file data block, preceding the actual - file data. It consists of a series of octal numbers of arbitrary length, - delimited by newlines. The map is padded with nulls to the nearest block - boundary. - - The first number gives the number of entries in the map. Following are map - entries, each one consisting of two numbers giving the offset and size of - the data block it describes. - - The format is designed in such a way that non-posix aware tars and tars not - supporting GNU.sparse.* keywords will extract each sparse file in its - condensed form with the file map attached and will place it into a separate - directory. Then, using a simple program it would be possible to expand the - file to its original form even without GNU tar. - - Bu default, v.1.0 archives are created. To use other formats, - --sparse-version option is provided. Additionally, v.0.0 can be obtained - by deleting GNU.sparse.map from 0.1 format: --sparse-version 0.1 - --pax-option delete=GNU.sparse.map -*/ - -static bool -pax_sparse_member_p (struct tar_sparse_file *file) -{ - return file->stat_info->sparse_map_avail > 0 - || file->stat_info->sparse_major > 0; -} - -static bool -pax_dump_header_0 (struct tar_sparse_file *file) -{ - off_t block_ordinal = current_block_ordinal (); - union block *blk; - size_t i; - char nbuf[UINTMAX_STRSIZE_BOUND]; - struct sp_array *map = file->stat_info->sparse_map; - char *save_file_name = NULL; - - /* Store the real file size */ - xheader_store ("GNU.sparse.size", file->stat_info, NULL); - xheader_store ("GNU.sparse.numblocks", file->stat_info, NULL); - - if (xheader_keyword_deleted_p ("GNU.sparse.map") - || tar_sparse_minor == 0) - { - for (i = 0; i < file->stat_info->sparse_map_avail; i++) - { - xheader_store ("GNU.sparse.offset", file->stat_info, &i); - xheader_store ("GNU.sparse.numbytes", file->stat_info, &i); - } - } - else - { - xheader_store ("GNU.sparse.name", file->stat_info, NULL); - save_file_name = file->stat_info->file_name; - file->stat_info->file_name = xheader_format_name (file->stat_info, - "%d/GNUSparseFile.%p/%f", 0); - - xheader_string_begin (&file->stat_info->xhdr); - for (i = 0; i < file->stat_info->sparse_map_avail; i++) - { - if (i) - xheader_string_add (&file->stat_info->xhdr, ","); - xheader_string_add (&file->stat_info->xhdr, - umaxtostr (map[i].offset, nbuf)); - xheader_string_add (&file->stat_info->xhdr, ","); - xheader_string_add (&file->stat_info->xhdr, - umaxtostr (map[i].numbytes, nbuf)); - } - if (!xheader_string_end (&file->stat_info->xhdr, - "GNU.sparse.map")) - { - free (file->stat_info->file_name); - file->stat_info->file_name = save_file_name; - return false; - } - } - blk = start_header (file->stat_info); - /* Store the effective (shrunken) file size */ - OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size); - finish_header (file->stat_info, blk, block_ordinal); - if (save_file_name) - { - free (file->stat_info->file_name); - file->stat_info->file_name = save_file_name; - } - return true; -} - -static bool -pax_dump_header_1 (struct tar_sparse_file *file) -{ - off_t block_ordinal = current_block_ordinal (); - union block *blk; - char *p, *q; - size_t i; - char nbuf[UINTMAX_STRSIZE_BOUND]; - off_t size = 0; - struct sp_array *map = file->stat_info->sparse_map; - char *save_file_name = file->stat_info->file_name; - -#define COPY_STRING(b,dst,src) do \ - { \ - char *endp = b->buffer + BLOCKSIZE; \ - char *srcp = src; \ - while (*srcp) \ - { \ - if (dst == endp) \ - { \ - set_next_block_after (b); \ - b = find_next_block (); \ - dst = b->buffer; \ - endp = b->buffer + BLOCKSIZE; \ - } \ - *dst++ = *srcp++; \ - } \ - } while (0) - - /* Compute stored file size */ - p = umaxtostr (file->stat_info->sparse_map_avail, nbuf); - size += strlen (p) + 1; - for (i = 0; i < file->stat_info->sparse_map_avail; i++) - { - p = umaxtostr (map[i].offset, nbuf); - size += strlen (p) + 1; - p = umaxtostr (map[i].numbytes, nbuf); - size += strlen (p) + 1; - } - size = (size + BLOCKSIZE - 1) / BLOCKSIZE; - file->stat_info->archive_file_size += size * BLOCKSIZE; - file->dumped_size += size * BLOCKSIZE; - - /* Store sparse file identification */ - xheader_store ("GNU.sparse.major", file->stat_info, NULL); - xheader_store ("GNU.sparse.minor", file->stat_info, NULL); - xheader_store ("GNU.sparse.name", file->stat_info, NULL); - xheader_store ("GNU.sparse.realsize", file->stat_info, NULL); - - file->stat_info->file_name = xheader_format_name (file->stat_info, - "%d/GNUSparseFile.%p/%f", 0); - - blk = start_header (file->stat_info); - /* Store the effective (shrunken) file size */ - OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size); - finish_header (file->stat_info, blk, block_ordinal); - free (file->stat_info->file_name); - file->stat_info->file_name = save_file_name; - - blk = find_next_block (); - q = blk->buffer; - p = umaxtostr (file->stat_info->sparse_map_avail, nbuf); - COPY_STRING (blk, q, p); - COPY_STRING (blk, q, "\n"); - for (i = 0; i < file->stat_info->sparse_map_avail; i++) - { - p = umaxtostr (map[i].offset, nbuf); - COPY_STRING (blk, q, p); - COPY_STRING (blk, q, "\n"); - p = umaxtostr (map[i].numbytes, nbuf); - COPY_STRING (blk, q, p); - COPY_STRING (blk, q, "\n"); - } - memset (q, 0, BLOCKSIZE - (q - blk->buffer)); - set_next_block_after (blk); - return true; -} - -static bool -pax_dump_header (struct tar_sparse_file *file) -{ - file->stat_info->sparse_major = tar_sparse_major; - file->stat_info->sparse_minor = tar_sparse_minor; - - return (file->stat_info->sparse_major == 0) ? - pax_dump_header_0 (file) : pax_dump_header_1 (file); -} - -static bool -decode_num (uintmax_t *num, char const *arg, uintmax_t maxval) -{ - uintmax_t u; - char *arg_lim; - - if (!ISDIGIT (*arg)) - return false; - - u = strtoumax (arg, &arg_lim, 10); - - if (! (u <= maxval && errno != ERANGE) || *arg_lim) - return false; - - *num = u; - return true; -} - -static bool -pax_decode_header (struct tar_sparse_file *file) -{ - if (file->stat_info->sparse_major > 0) - { - uintmax_t u; - char nbuf[UINTMAX_STRSIZE_BOUND]; - union block *blk; - char *p; - size_t i; - -#define COPY_BUF(b,buf,src) do \ - { \ - char *endp = b->buffer + BLOCKSIZE; \ - char *dst = buf; \ - do \ - { \ - if (dst == buf + UINTMAX_STRSIZE_BOUND -1) \ - { \ - ERROR ((0, 0, _("%s: numeric overflow in sparse archive member"), \ - file->stat_info->orig_file_name)); \ - return false; \ - } \ - if (src == endp) \ - { \ - set_next_block_after (b); \ - file->dumped_size += BLOCKSIZE; \ - b = find_next_block (); \ - src = b->buffer; \ - endp = b->buffer + BLOCKSIZE; \ - } \ - *dst = *src++; \ - } \ - while (*dst++ != '\n'); \ - dst[-1] = 0; \ - } while (0) - - set_next_block_after (current_header); - file->dumped_size += BLOCKSIZE; - blk = find_next_block (); - p = blk->buffer; - COPY_BUF (blk,nbuf,p); - if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t))) - { - ERROR ((0, 0, _("%s: malformed sparse archive member"), - file->stat_info->orig_file_name)); - return false; - } - file->stat_info->sparse_map_size = u; - file->stat_info->sparse_map = xcalloc (file->stat_info->sparse_map_size, - sizeof (*file->stat_info->sparse_map)); - file->stat_info->sparse_map_avail = 0; - for (i = 0; i < file->stat_info->sparse_map_size; i++) - { - struct sp_array sp; - - COPY_BUF (blk,nbuf,p); - if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t))) - { - ERROR ((0, 0, _("%s: malformed sparse archive member"), - file->stat_info->orig_file_name)); - return false; - } - sp.offset = u; - COPY_BUF (blk,nbuf,p); - if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t))) - { - ERROR ((0, 0, _("%s: malformed sparse archive member"), - file->stat_info->orig_file_name)); - return false; - } - sp.numbytes = u; - sparse_add_map (file->stat_info, &sp); - } - set_next_block_after (blk); - } - - return true; -} - -static struct tar_sparse_optab const pax_optab = { - NULL, /* No init function */ - NULL, /* No done function */ - pax_sparse_member_p, - pax_dump_header, - NULL, - pax_decode_header, - NULL, /* No scan_block function */ - sparse_dump_region, - sparse_extract_region, -}; diff --git a/src/bin/tar/src/system.c b/src/bin/tar/src/system.c deleted file mode 100644 index ba1d191e08..0000000000 --- a/src/bin/tar/src/system.c +++ /dev/null @@ -1,843 +0,0 @@ -/* System-dependent calls for tar. - - Copyright (C) 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include - -#include "common.h" -#include -#include - -#if MSDOS - -bool -sys_get_archive_stat (void) -{ - return 0; -} - -bool -sys_file_is_archive (struct tar_stat_info *p) -{ - return false; -} - -void -sys_save_archive_dev_ino (void) -{ -} - -void -sys_detect_dev_null_output (void) -{ - static char const dev_null[] = "nul"; - - dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0 - || (! _isrmt (archive))); -} - -void -sys_drain_input_pipe (void) -{ -} - -void -sys_wait_for_child (pid_t child_pid) -{ -} - -void -sys_spawn_shell (void) -{ - spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0); -} - -/* stat() in djgpp's C library gives a constant number of 42 as the - uid and gid of a file. So, comparing an FTP'ed archive just after - unpack would fail on MSDOS. */ - -bool -sys_compare_uid (struct stat *a, struct stat *b) -{ - return true; -} - -bool -sys_compare_gid (struct stat *a, struct stat *b) -{ - return true; -} - -void -sys_compare_links (struct stat *link_data, struct stat *stat_data) -{ - return true; -} - -int -sys_truncate (int fd) -{ - return write (fd, "", 0); -} - -size_t -sys_write_archive_buffer (void) -{ - return full_write (archive, record_start->buffer, record_size); -} - -/* Set ARCHIVE for writing, then compressing an archive. */ -void -sys_child_open_for_compress (void) -{ - FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives"))); -} - -/* Set ARCHIVE for uncompressing, then reading an archive. */ -void -sys_child_open_for_uncompress (void) -{ - FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives"))); -} - -#else - -extern union block *record_start; /* FIXME */ - -static struct stat archive_stat; /* stat block for archive file */ - -bool -sys_get_archive_stat (void) -{ - return fstat (archive, &archive_stat) == 0; -} - -bool -sys_file_is_archive (struct tar_stat_info *p) -{ - return (ar_dev && p->stat.st_dev == ar_dev && p->stat.st_ino == ar_ino); -} - -/* Save archive file inode and device numbers */ -void -sys_save_archive_dev_ino (void) -{ - if (!_isrmt (archive) && S_ISREG (archive_stat.st_mode)) - { - ar_dev = archive_stat.st_dev; - ar_ino = archive_stat.st_ino; - } - else - ar_dev = 0; -} - -/* Detect if outputting to "/dev/null". */ -void -sys_detect_dev_null_output (void) -{ - static char const dev_null[] = "/dev/null"; - struct stat dev_null_stat; - - dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0 - || (! _isrmt (archive) - && S_ISCHR (archive_stat.st_mode) - && stat (dev_null, &dev_null_stat) == 0 - && archive_stat.st_dev == dev_null_stat.st_dev - && archive_stat.st_ino == dev_null_stat.st_ino)); -} - -/* Manage to fully drain a pipe we might be reading, so to not break it on - the producer after the EOF block. FIXME: one of these days, GNU tar - might become clever enough to just stop working, once there is no more - work to do, we might have to revise this area in such time. */ - -void -sys_drain_input_pipe (void) -{ - size_t r; - - if (access_mode == ACCESS_READ - && ! _isrmt (archive) - && (S_ISFIFO (archive_stat.st_mode) || S_ISSOCK (archive_stat.st_mode))) - while ((r = rmtread (archive, record_start->buffer, record_size)) != 0 - && r != SAFE_READ_ERROR) - continue; -} - -void -sys_wait_for_child (pid_t child_pid) -{ - if (child_pid) - { - int wait_status; - - while (waitpid (child_pid, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (use_compress_program_option); - break; - } - - if (WIFSIGNALED (wait_status)) - ERROR ((0, 0, _("Child died with signal %d"), - WTERMSIG (wait_status))); - else if (WEXITSTATUS (wait_status) != 0) - ERROR ((0, 0, _("Child returned status %d"), - WEXITSTATUS (wait_status))); - } -} - -void -sys_spawn_shell (void) -{ - pid_t child; - const char *shell = getenv ("SHELL"); - if (! shell) - shell = "/bin/sh"; - child = xfork (); - if (child == 0) - { - execlp (shell, "-sh", "-i", (char *) 0); - exec_fatal (shell); - } - else - { - int wait_status; - while (waitpid (child, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (shell); - break; - } - } -} - -bool -sys_compare_uid (struct stat *a, struct stat *b) -{ - return a->st_uid == b->st_uid; -} - -bool -sys_compare_gid (struct stat *a, struct stat *b) -{ - return a->st_gid == b->st_gid; -} - -bool -sys_compare_links (struct stat *link_data, struct stat *stat_data) -{ - return stat_data->st_dev == link_data->st_dev - && stat_data->st_ino == link_data->st_ino; -} - -int -sys_truncate (int fd) -{ - off_t pos = lseek (fd, (off_t) 0, SEEK_CUR); - return pos < 0 ? -1 : ftruncate (fd, pos); -} - -/* Return nonzero if NAME is the name of a regular file, or if the file - does not exist (so it would be created as a regular file). */ -static int -is_regular_file (const char *name) -{ - struct stat stbuf; - - if (stat (name, &stbuf) == 0) - return S_ISREG (stbuf.st_mode); - else - return errno == ENOENT; -} - -size_t -sys_write_archive_buffer (void) -{ - return rmtwrite (archive, record_start->buffer, record_size); -} - -#define PREAD 0 /* read file descriptor from pipe() */ -#define PWRITE 1 /* write file descriptor from pipe() */ - -/* Duplicate file descriptor FROM into becoming INTO. - INTO is closed first and has to be the next available slot. */ -static void -xdup2 (int from, int into) -{ - if (from != into) - { - int status = close (into); - - if (status != 0 && errno != EBADF) - { - int e = errno; - FATAL_ERROR ((0, e, _("Cannot close"))); - } - status = dup (from); - if (status != into) - { - if (status < 0) - { - int e = errno; - FATAL_ERROR ((0, e, _("Cannot dup"))); - } - abort (); - } - xclose (from); - } -} - -/* Set ARCHIVE for writing, then compressing an archive. */ -pid_t -sys_child_open_for_compress (void) -{ - int parent_pipe[2]; - int child_pipe[2]; - pid_t grandchild_pid; - pid_t child_pid; - int wait_status; - - xpipe (parent_pipe); - child_pid = xfork (); - - if (child_pid > 0) - { - /* The parent tar is still here! Just clean up. */ - - archive = parent_pipe[PWRITE]; - xclose (parent_pipe[PREAD]); - return child_pid; - } - - /* The new born child tar is here! */ - - program_name = _("tar (child)"); - - xdup2 (parent_pipe[PREAD], STDIN_FILENO); - xclose (parent_pipe[PWRITE]); - - /* Check if we need a grandchild tar. This happens only if either: - a) the file is to be accessed by rmt: compressor doesn't know how; - b) the file is not a plain file. */ - - if (!_remdev (archive_name_array[0]) - && is_regular_file (archive_name_array[0])) - { - if (backup_option) - maybe_backup_file (archive_name_array[0], 1); - - /* We don't need a grandchild tar. Open the archive and launch the - compressor. */ - if (strcmp (archive_name_array[0], "-")) - { - archive = creat (archive_name_array[0], MODE_RW); - if (archive < 0) - { - int saved_errno = errno; - - if (backup_option) - undo_last_backup (); - errno = saved_errno; - open_fatal (archive_name_array[0]); - } - xdup2 (archive, STDOUT_FILENO); - } - execlp (use_compress_program_option, use_compress_program_option, NULL); - exec_fatal (use_compress_program_option); - } - - /* We do need a grandchild tar. */ - - xpipe (child_pipe); - grandchild_pid = xfork (); - - if (grandchild_pid == 0) - { - /* The newborn grandchild tar is here! Launch the compressor. */ - - program_name = _("tar (grandchild)"); - - xdup2 (child_pipe[PWRITE], STDOUT_FILENO); - xclose (child_pipe[PREAD]); - execlp (use_compress_program_option, use_compress_program_option, - (char *) 0); - exec_fatal (use_compress_program_option); - } - - /* The child tar is still here! */ - - /* Prepare for reblocking the data from the compressor into the archive. */ - - xdup2 (child_pipe[PREAD], STDIN_FILENO); - xclose (child_pipe[PWRITE]); - - if (strcmp (archive_name_array[0], "-") == 0) - archive = STDOUT_FILENO; - else - { - archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option); - if (archive < 0) - open_fatal (archive_name_array[0]); - } - - /* Let's read out of the stdin pipe and write an archive. */ - - while (1) - { - size_t status = 0; - char *cursor; - size_t length; - - /* Assemble a record. */ - - for (length = 0, cursor = record_start->buffer; - length < record_size; - length += status, cursor += status) - { - size_t size = record_size - length; - - status = safe_read (STDIN_FILENO, cursor, size); - if (status == SAFE_READ_ERROR) - read_fatal (use_compress_program_option); - if (status == 0) - break; - } - - /* Copy the record. */ - - if (status == 0) - { - /* We hit the end of the file. Write last record at - full length, as the only role of the grandchild is - doing proper reblocking. */ - - if (length > 0) - { - memset (record_start->buffer + length, 0, record_size - length); - status = sys_write_archive_buffer (); - if (status != record_size) - archive_write_error (status); - } - - /* There is nothing else to read, break out. */ - break; - } - - status = sys_write_archive_buffer (); - if (status != record_size) - archive_write_error (status); - } - - /* Propagate any failure of the grandchild back to the parent. */ - - while (waitpid (grandchild_pid, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (use_compress_program_option); - break; - } - - if (WIFSIGNALED (wait_status)) - { - kill (child_pid, WTERMSIG (wait_status)); - exit_status = TAREXIT_FAILURE; - } - else if (WEXITSTATUS (wait_status) != 0) - exit_status = WEXITSTATUS (wait_status); - - exit (exit_status); -} - -/* Set ARCHIVE for uncompressing, then reading an archive. */ -pid_t -sys_child_open_for_uncompress (void) -{ - int parent_pipe[2]; - int child_pipe[2]; - pid_t grandchild_pid; - pid_t child_pid; - int wait_status; - - xpipe (parent_pipe); - child_pid = xfork (); - - if (child_pid > 0) - { - /* The parent tar is still here! Just clean up. */ - - archive = parent_pipe[PREAD]; - xclose (parent_pipe[PWRITE]); - return child_pid; - } - - /* The newborn child tar is here! */ - - program_name = _("tar (child)"); - - xdup2 (parent_pipe[PWRITE], STDOUT_FILENO); - xclose (parent_pipe[PREAD]); - - /* Check if we need a grandchild tar. This happens only if either: - a) we're reading stdin: to force unblocking; - b) the file is to be accessed by rmt: compressor doesn't know how; - c) the file is not a plain file. */ - - if (strcmp (archive_name_array[0], "-") != 0 - && !_remdev (archive_name_array[0]) - && is_regular_file (archive_name_array[0])) - { - /* We don't need a grandchild tar. Open the archive and lauch the - uncompressor. */ - - archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW); - if (archive < 0) - open_fatal (archive_name_array[0]); - xdup2 (archive, STDIN_FILENO); - execlp (use_compress_program_option, use_compress_program_option, - "-d", (char *) 0); - exec_fatal (use_compress_program_option); - } - - /* We do need a grandchild tar. */ - - xpipe (child_pipe); - grandchild_pid = xfork (); - - if (grandchild_pid == 0) - { - /* The newborn grandchild tar is here! Launch the uncompressor. */ - - program_name = _("tar (grandchild)"); - - xdup2 (child_pipe[PREAD], STDIN_FILENO); - xclose (child_pipe[PWRITE]); - execlp (use_compress_program_option, use_compress_program_option, - "-d", (char *) 0); - exec_fatal (use_compress_program_option); - } - - /* The child tar is still here! */ - - /* Prepare for unblocking the data from the archive into the - uncompressor. */ - - xdup2 (child_pipe[PWRITE], STDOUT_FILENO); - xclose (child_pipe[PREAD]); - - if (strcmp (archive_name_array[0], "-") == 0) - archive = STDIN_FILENO; - else - archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY, - MODE_RW, rsh_command_option); - if (archive < 0) - open_fatal (archive_name_array[0]); - - /* Let's read the archive and pipe it into stdout. */ - - while (1) - { - char *cursor; - size_t maximum; - size_t count; - size_t status; - - clear_read_error_count (); - - error_loop: - status = rmtread (archive, record_start->buffer, record_size); - if (status == SAFE_READ_ERROR) - { - archive_read_error (); - goto error_loop; - } - if (status == 0) - break; - cursor = record_start->buffer; - maximum = status; - while (maximum) - { - count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE; - if (full_write (STDOUT_FILENO, cursor, count) != count) - write_error (use_compress_program_option); - cursor += count; - maximum -= count; - } - } - - xclose (STDOUT_FILENO); - - /* Propagate any failure of the grandchild back to the parent. */ - - while (waitpid (grandchild_pid, &wait_status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (use_compress_program_option); - break; - } - - if (WIFSIGNALED (wait_status)) - { - kill (child_pid, WTERMSIG (wait_status)); - exit_status = TAREXIT_FAILURE; - } - else if (WEXITSTATUS (wait_status) != 0) - exit_status = WEXITSTATUS (wait_status); - - exit (exit_status); -} - - - -static void -dec_to_env (char *envar, uintmax_t num) -{ - char buf[UINTMAX_STRSIZE_BOUND]; - char *numstr; - - numstr = STRINGIFY_BIGINT (num, buf); - if (setenv (envar, numstr, 1) != 0) - xalloc_die (); -} - -static void -time_to_env (char *envar, struct timespec t) -{ - char buf[TIMESPEC_STRSIZE_BOUND]; - if (setenv (envar, code_timespec (t, buf), 1) != 0) - xalloc_die (); -} - -static void -oct_to_env (char *envar, unsigned long num) -{ - char buf[1+1+(sizeof(unsigned long)*CHAR_BIT+2)/3]; - - snprintf (buf, sizeof buf, "0%lo", num); - if (setenv (envar, buf, 1) != 0) - xalloc_die (); -} - -static void -str_to_env (char *envar, char const *str) -{ - if (str) - { - if (setenv (envar, str, 1) != 0) - xalloc_die (); - } - else - unsetenv (envar); -} - -static void -chr_to_env (char *envar, char c) -{ - char buf[2]; - buf[0] = c; - buf[1] = 0; - if (setenv (envar, buf, 1) != 0) - xalloc_die (); -} - -static void -stat_to_env (char *name, char type, struct tar_stat_info *st) -{ - str_to_env ("TAR_VERSION", PACKAGE_VERSION); - chr_to_env ("TAR_FILETYPE", type); - oct_to_env ("TAR_MODE", st->stat.st_mode); - str_to_env ("TAR_FILENAME", name); - str_to_env ("TAR_REALNAME", st->file_name); - str_to_env ("TAR_UNAME", st->uname); - str_to_env ("TAR_GNAME", st->gname); - time_to_env ("TAR_ATIME", st->atime); - time_to_env ("TAR_MTIME", st->mtime); - time_to_env ("TAR_CTIME", st->ctime); - dec_to_env ("TAR_SIZE", st->stat.st_size); - dec_to_env ("TAR_UID", st->stat.st_uid); - dec_to_env ("TAR_GID", st->stat.st_gid); - - switch (type) - { - case 'b': - case 'c': - dec_to_env ("TAR_MINOR", minor (st->stat.st_rdev)); - dec_to_env ("TAR_MAJOR", major (st->stat.st_rdev)); - unsetenv ("TAR_LINKNAME"); - break; - - case 'l': - case 'h': - unsetenv ("TAR_MINOR"); - unsetenv ("TAR_MAJOR"); - str_to_env ("TAR_LINKNAME", st->link_name); - break; - - default: - unsetenv ("TAR_MINOR"); - unsetenv ("TAR_MAJOR"); - unsetenv ("TAR_LINKNAME"); - break; - } -} - -static pid_t global_pid; -static RETSIGTYPE (*pipe_handler) (int sig); - -int -sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st) -{ - int p[2]; - char *argv[4]; - - xpipe (p); - pipe_handler = signal (SIGPIPE, SIG_IGN); - global_pid = xfork (); - - if (global_pid != 0) - { - xclose (p[PREAD]); - return p[PWRITE]; - } - - /* Child */ - xdup2 (p[PREAD], STDIN_FILENO); - xclose (p[PWRITE]); - - stat_to_env (file_name, typechar, st); - - argv[0] = "/bin/sh"; - argv[1] = "-c"; - argv[2] = to_command_option; - argv[3] = NULL; - - execv ("/bin/sh", argv); - - exec_fatal (file_name); -} - -void -sys_wait_command (void) -{ - int status; - - if (global_pid < 0) - return; - - signal (SIGPIPE, pipe_handler); - while (waitpid (global_pid, &status, 0) == -1) - if (errno != EINTR) - { - global_pid = -1; - waitpid_error (to_command_option); - return; - } - - if (WIFEXITED (status)) - { - if (!ignore_command_error_option && WEXITSTATUS (status)) - ERROR ((0, 0, _("%lu: Child returned status %d"), - (unsigned long) global_pid, WEXITSTATUS (status))); - } - else if (WIFSIGNALED (status)) - { - WARN ((0, 0, _("%lu: Child terminated on signal %d"), - (unsigned long) global_pid, WTERMSIG (status))); - } - else - ERROR ((0, 0, _("%lu: Child terminated on unknown reason"), - (unsigned long) global_pid)); - - global_pid = -1; -} - -int -sys_exec_info_script (const char **archive_name, int volume_number) -{ - pid_t pid; - char *argv[4]; - char uintbuf[UINTMAX_STRSIZE_BOUND]; - int p[2]; - - xpipe (p); - pipe_handler = signal (SIGPIPE, SIG_IGN); - - pid = xfork (); - - if (pid != 0) - { - /* Master */ - - int rc; - int status; - char *buf; - size_t size = 0; - FILE *fp; - - xclose (p[PWRITE]); - fp = fdopen (p[PREAD], "r"); - rc = getline (&buf, &size, fp); - fclose (fp); - - if (rc > 0 && buf[rc-1] == '\n') - buf[--rc] = 0; - - while (waitpid (pid, &status, 0) == -1) - if (errno != EINTR) - { - waitpid_error (info_script_option); - return -1; - } - - if (WIFEXITED (status)) - { - if (WEXITSTATUS (status) == 0 && rc > 0) - *archive_name = buf; - else - free (buf); - return WEXITSTATUS (status); - } - - free (buf); - return -1; - } - - /* Child */ - setenv ("TAR_VERSION", PACKAGE_VERSION, 1); - setenv ("TAR_ARCHIVE", *archive_name, 1); - setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1); - setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1); - setenv ("TAR_FORMAT", - archive_format_string (current_format == DEFAULT_FORMAT ? - archive_format : current_format), 1); - setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1); - - xclose (p[PREAD]); - - argv[0] = "/bin/sh"; - argv[1] = "-c"; - argv[2] = (char*) info_script_option; - argv[3] = NULL; - - execv (argv[0], argv); - - exec_fatal (info_script_option); -} - - -#endif /* not MSDOS */ diff --git a/src/bin/tar/src/tar.c b/src/bin/tar/src/tar.c deleted file mode 100644 index a1e2936fbc..0000000000 --- a/src/bin/tar/src/tar.c +++ /dev/null @@ -1,2465 +0,0 @@ -/* A tar (tape archiver) program. - - Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, - 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. - - Written by John Gilmore, starting 1985-08-25. - - 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include -#include -#include -#include - -#include -#if ! defined SIGCHLD && defined SIGCLD -# define SIGCHLD SIGCLD -#endif - -/* The following causes "common.h" to produce definitions of all the global - variables, rather than just "extern" declarations of them. GNU tar does - depend on the system loader to preset all GLOBAL variables to neutral (or - zero) values; explicit initialization is usually not done. */ -#define GLOBAL -#include "common.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Local declarations. */ - -#ifndef DEFAULT_ARCHIVE_FORMAT -# define DEFAULT_ARCHIVE_FORMAT GNU_FORMAT -#endif - -#ifndef DEFAULT_ARCHIVE -# define DEFAULT_ARCHIVE "tar.out" -#endif - -#ifndef DEFAULT_BLOCKING -# define DEFAULT_BLOCKING 20 -#endif - - -/* Miscellaneous. */ - -/* Name of option using stdin. */ -static const char *stdin_used_by; - -/* Doesn't return if stdin already requested. */ -void -request_stdin (const char *option) -{ - if (stdin_used_by) - USAGE_ERROR ((0, 0, _("Options `-%s' and `-%s' both want standard input"), - stdin_used_by, option)); - - stdin_used_by = option; -} - -extern int rpmatch (char const *response); - -/* Returns true if and only if the user typed an affirmative response. */ -int -confirm (const char *message_action, const char *message_name) -{ - static FILE *confirm_file; - static int confirm_file_EOF; - bool status = false; - - if (!confirm_file) - { - if (archive == 0 || stdin_used_by) - { - confirm_file = fopen (TTY_NAME, "r"); - if (! confirm_file) - open_fatal (TTY_NAME); - } - else - { - request_stdin ("-w"); - confirm_file = stdin; - } - } - - fprintf (stdlis, "%s %s?", message_action, quote (message_name)); - fflush (stdlis); - - if (!confirm_file_EOF) - { - char *response = NULL; - size_t response_size = 0; - if (getline (&response, &response_size, confirm_file) < 0) - confirm_file_EOF = 1; - else - status = rpmatch (response) > 0; - free (response); - } - - if (confirm_file_EOF) - { - fputc ('\n', stdlis); - fflush (stdlis); - } - - return status; -} - -static struct fmttab { - char const *name; - enum archive_format fmt; -} const fmttab[] = { - { "v7", V7_FORMAT }, - { "oldgnu", OLDGNU_FORMAT }, - { "ustar", USTAR_FORMAT }, - { "posix", POSIX_FORMAT }, -#if 0 /* not fully supported yet */ - { "star", STAR_FORMAT }, -#endif - { "gnu", GNU_FORMAT }, - { "pax", POSIX_FORMAT }, /* An alias for posix */ - { NULL, 0 } -}; - -static void -set_archive_format (char const *name) -{ - struct fmttab const *p; - - for (p = fmttab; strcmp (p->name, name) != 0; ) - if (! (++p)->name) - USAGE_ERROR ((0, 0, _("%s: Invalid archive format"), - quotearg_colon (name))); - - archive_format = p->fmt; -} - -const char * -archive_format_string (enum archive_format fmt) -{ - struct fmttab const *p; - - for (p = fmttab; p->name; p++) - if (p->fmt == fmt) - return p->name; - return "unknown?"; -} - -#define FORMAT_MASK(n) (1<<(n)) - -static void -assert_format(unsigned fmt_mask) -{ - if ((FORMAT_MASK (archive_format) & fmt_mask) == 0) - USAGE_ERROR ((0, 0, - _("GNU features wanted on incompatible archive format"))); -} - -const char * -subcommand_string (enum subcommand c) -{ - switch (c) - { - case UNKNOWN_SUBCOMMAND: - return "unknown?"; - - case APPEND_SUBCOMMAND: - return "-r"; - - case CAT_SUBCOMMAND: - return "-A"; - - case CREATE_SUBCOMMAND: - return "-c"; - - case DELETE_SUBCOMMAND: - return "-D"; - - case DIFF_SUBCOMMAND: - return "-d"; - - case EXTRACT_SUBCOMMAND: - return "-x"; - - case LIST_SUBCOMMAND: - return "-t"; - - case UPDATE_SUBCOMMAND: - return "-u"; - - default: - abort (); - } -} - -void -tar_list_quoting_styles (argp_fmtstream_t fs, char *prefix) -{ - int i; - - for (i = 0; quoting_style_args[i]; i++) - argp_fmtstream_printf (fs, "%s%s\n", prefix, quoting_style_args[i]); -} - -void -tar_set_quoting_style (char *arg) -{ - int i; - - for (i = 0; quoting_style_args[i]; i++) - if (strcmp (arg, quoting_style_args[i]) == 0) - { - set_quoting_style (NULL, i); - return; - } - FATAL_ERROR ((0, 0, - _("Unknown quoting style `%s'. Try `%s --quoting-style=help' to get a list."), arg, program_invocation_short_name)); -} - - -/* Options. */ - -enum -{ - ANCHORED_OPTION = CHAR_MAX + 1, - ATIME_PRESERVE_OPTION, - BACKUP_OPTION, - CHECKPOINT_OPTION, - DELAY_DIRECTORY_RESTORE_OPTION, - DELETE_OPTION, - EXCLUDE_CACHES_OPTION, - EXCLUDE_CACHES_UNDER_OPTION, - EXCLUDE_CACHES_ALL_OPTION, - EXCLUDE_OPTION, - EXCLUDE_TAG_OPTION, - EXCLUDE_TAG_UNDER_OPTION, - EXCLUDE_TAG_ALL_OPTION, - EXCLUDE_VCS_OPTION, - FORCE_LOCAL_OPTION, - GROUP_OPTION, - HANG_OPTION, - IGNORE_CASE_OPTION, - IGNORE_COMMAND_ERROR_OPTION, - IGNORE_FAILED_READ_OPTION, - INDEX_FILE_OPTION, - KEEP_NEWER_FILES_OPTION, - MODE_OPTION, - MTIME_OPTION, - NEWER_MTIME_OPTION, - NO_ANCHORED_OPTION, - NO_DELAY_DIRECTORY_RESTORE_OPTION, - NO_IGNORE_CASE_OPTION, - NO_IGNORE_COMMAND_ERROR_OPTION, - NO_OVERWRITE_DIR_OPTION, - NO_QUOTE_CHARS_OPTION, - NO_RECURSION_OPTION, - NO_SAME_OWNER_OPTION, - NO_SAME_PERMISSIONS_OPTION, - NO_UNQUOTE_OPTION, - NO_WILDCARDS_MATCH_SLASH_OPTION, - NO_WILDCARDS_OPTION, - NULL_OPTION, - NUMERIC_OWNER_OPTION, - OCCURRENCE_OPTION, - OLD_ARCHIVE_OPTION, - ONE_FILE_SYSTEM_OPTION, - OVERWRITE_DIR_OPTION, - OVERWRITE_OPTION, - OWNER_OPTION, - PAX_OPTION, - POSIX_OPTION, - PRESERVE_OPTION, - QUOTE_CHARS_OPTION, - QUOTING_STYLE_OPTION, - RECORD_SIZE_OPTION, - RECURSION_OPTION, - RECURSIVE_UNLINK_OPTION, - REMOVE_FILES_OPTION, - RESTRICT_OPTION, - RMT_COMMAND_OPTION, - RSH_COMMAND_OPTION, - SAME_OWNER_OPTION, - SHOW_DEFAULTS_OPTION, - SHOW_OMITTED_DIRS_OPTION, - SHOW_TRANSFORMED_NAMES_OPTION, - SPARSE_VERSION_OPTION, - STRIP_COMPONENTS_OPTION, - SUFFIX_OPTION, - TEST_LABEL_OPTION, - TOTALS_OPTION, - TO_COMMAND_OPTION, - TRANSFORM_OPTION, - UNQUOTE_OPTION, - USAGE_OPTION, - USE_COMPRESS_PROGRAM_OPTION, - UTC_OPTION, - VERSION_OPTION, - VOLNO_FILE_OPTION, - WILDCARDS_MATCH_SLASH_OPTION, - WILDCARDS_OPTION -}; - -const char *argp_program_version = "tar (" PACKAGE_NAME ") " VERSION; -const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; -static char const doc[] = N_("\ -GNU `tar' saves many files together into a single tape or disk archive, \ -and can restore individual files from the archive.\n\ -\n\ -Examples:\n\ - tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.\n\ - tar -tvf archive.tar # List all files in archive.tar verbosely.\n\ - tar -xf archive.tar # Extract all files from archive.tar.\n") -"\v" -N_("The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\ -The version control may be set with --backup or VERSION_CONTROL, values are:\n\n\ - none, off never make backups\n\ - t, numbered make numbered backups\n\ - nil, existing numbered if numbered backups exist, simple otherwise\n\ - never, simple always make simple backups\n"); - - -/* NOTE: - - Available option letters are DEIJQY and aeqy. Consider the following - assignments: - - [For Solaris tar compatibility =/= Is it important at all?] - e exit immediately with a nonzero exit status if unexpected errors occur - E use extended headers (--format=posix) - - [q alias for --occurrence=1 =/= this would better be used for quiet?] - [I same as T =/= will harm star compatibility] - - y per-file gzip compression - Y per-block gzip compression */ - -static struct argp_option options[] = { -#define GRID 10 - {NULL, 0, NULL, 0, - N_("Main operation mode:"), GRID }, - - {"list", 't', 0, 0, - N_("list the contents of an archive"), GRID+1 }, - {"extract", 'x', 0, 0, - N_("extract files from an archive"), GRID+1 }, - {"get", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"create", 'c', 0, 0, - N_("create a new archive"), GRID+1 }, - {"diff", 'd', 0, 0, - N_("find differences between archive and file system"), GRID+1 }, - {"compare", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"append", 'r', 0, 0, - N_("append files to the end of an archive"), GRID+1 }, - {"update", 'u', 0, 0, - N_("only append files newer than copy in archive"), GRID+1 }, - {"catenate", 'A', 0, 0, - N_("append tar files to an archive"), GRID+1 }, - {"concatenate", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"delete", DELETE_OPTION, 0, 0, - N_("delete from the archive (not on mag tapes!)"), GRID+1 }, - {"test-label", TEST_LABEL_OPTION, NULL, 0, - N_("test the archive volume label and exit"), GRID+1 }, -#undef GRID - -#define GRID 20 - {NULL, 0, NULL, 0, - N_("Operation modifiers:"), GRID }, - - {"sparse", 'S', 0, 0, - N_("handle sparse files efficiently"), GRID+1 }, - {"sparse-version", SPARSE_VERSION_OPTION, N_("MAJOR[.MINOR]"), 0, - N_("set version of the sparse format to use (implies --sparse)"), GRID+1}, - {"incremental", 'G', 0, 0, - N_("handle old GNU-format incremental backup"), GRID+1 }, - {"listed-incremental", 'g', N_("FILE"), 0, - N_("handle new GNU-format incremental backup"), GRID+1 }, - {"ignore-failed-read", IGNORE_FAILED_READ_OPTION, 0, 0, - N_("do not exit with nonzero on unreadable files"), GRID+1 }, - {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL, - N_("process only the NUMBERth occurrence of each file in the archive;" - " this option is valid only in conjunction with one of the subcommands" - " --delete, --diff, --extract or --list and when a list of files" - " is given either on the command line or via the -T option;" - " NUMBER defaults to 1"), GRID+1 }, - {"seek", 'n', NULL, 0, - N_("archive is seekable"), GRID+1 }, -#undef GRID - -#define GRID 30 - {NULL, 0, NULL, 0, - N_("Overwrite control:"), GRID }, - - {"verify", 'W', 0, 0, - N_("attempt to verify the archive after writing it"), GRID+1 }, - {"remove-files", REMOVE_FILES_OPTION, 0, 0, - N_("remove files after adding them to the archive"), GRID+1 }, - {"keep-old-files", 'k', 0, 0, - N_("don't replace existing files when extracting"), GRID+1 }, - {"keep-newer-files", KEEP_NEWER_FILES_OPTION, 0, 0, - N_("don't replace existing files that are newer than their archive copies"), GRID+1 }, - {"overwrite", OVERWRITE_OPTION, 0, 0, - N_("overwrite existing files when extracting"), GRID+1 }, - {"unlink-first", 'U', 0, 0, - N_("remove each file prior to extracting over it"), GRID+1 }, - {"recursive-unlink", RECURSIVE_UNLINK_OPTION, 0, 0, - N_("empty hierarchies prior to extracting directory"), GRID+1 }, - {"no-overwrite-dir", NO_OVERWRITE_DIR_OPTION, 0, 0, - N_("preserve metadata of existing directories"), GRID+1 }, - {"overwrite-dir", OVERWRITE_DIR_OPTION, 0, 0, - N_("overwrite metadata of existing directories when extracting (default)"), - GRID+1 }, -#undef GRID - -#define GRID 40 - {NULL, 0, NULL, 0, - N_("Select output stream:"), GRID }, - - {"to-stdout", 'O', 0, 0, - N_("extract files to standard output"), GRID+1 }, - {"to-command", TO_COMMAND_OPTION, N_("COMMAND"), 0, - N_("pipe extracted files to another program"), GRID+1 }, - {"ignore-command-error", IGNORE_COMMAND_ERROR_OPTION, 0, 0, - N_("ignore exit codes of children"), GRID+1 }, - {"no-ignore-command-error", NO_IGNORE_COMMAND_ERROR_OPTION, 0, 0, - N_("treat non-zero exit codes of children as error"), GRID+1 }, -#undef GRID - -#define GRID 50 - {NULL, 0, NULL, 0, - N_("Handling of file attributes:"), GRID }, - - {"owner", OWNER_OPTION, N_("NAME"), 0, - N_("force NAME as owner for added files"), GRID+1 }, - {"group", GROUP_OPTION, N_("NAME"), 0, - N_("force NAME as group for added files"), GRID+1 }, - {"mtime", MTIME_OPTION, N_("DATE-OR-FILE"), 0, - N_("set mtime for added files from DATE-OR-FILE"), GRID+1 }, - {"mode", MODE_OPTION, N_("CHANGES"), 0, - N_("force (symbolic) mode CHANGES for added files"), GRID+1 }, - {"atime-preserve", ATIME_PRESERVE_OPTION, - N_("METHOD"), OPTION_ARG_OPTIONAL, - N_("preserve access times on dumped files, either by restoring the times" - " after reading (METHOD='replace'; default) or by not setting the times" - " in the first place (METHOD='system')"), GRID+1 }, - {"touch", 'm', 0, 0, - N_("don't extract file modified time"), GRID+1 }, - {"same-owner", SAME_OWNER_OPTION, 0, 0, - N_("try extracting files with the same ownership"), GRID+1 }, - {"no-same-owner", NO_SAME_OWNER_OPTION, 0, 0, - N_("extract files as yourself"), GRID+1 }, - {"numeric-owner", NUMERIC_OWNER_OPTION, 0, 0, - N_("always use numbers for user/group names"), GRID+1 }, - {"preserve-permissions", 'p', 0, 0, - N_("extract information about file permissions (default for superuser)"), - GRID+1 }, - {"same-permissions", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"no-same-permissions", NO_SAME_PERMISSIONS_OPTION, 0, 0, - N_("apply the user's umask when extracting permissions from the archive (default for ordinary users)"), GRID+1 }, - {"preserve-order", 's', 0, 0, - N_("sort names to extract to match archive"), GRID+1 }, - {"same-order", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"preserve", PRESERVE_OPTION, 0, 0, - N_("same as both -p and -s"), GRID+1 }, - {"delay-directory-restore", DELAY_DIRECTORY_RESTORE_OPTION, 0, 0, - N_("delay setting modification times and permissions of extracted" - " directories until the end of extraction"), GRID+1 }, - {"no-delay-directory-restore", NO_DELAY_DIRECTORY_RESTORE_OPTION, 0, 0, - N_("cancel the effect of --delay-directory-restore option"), GRID+1 }, -#undef GRID - -#define GRID 60 - {NULL, 0, NULL, 0, - N_("Device selection and switching:"), GRID }, - - {"file", 'f', N_("ARCHIVE"), 0, - N_("use archive file or device ARCHIVE"), GRID+1 }, - {"force-local", FORCE_LOCAL_OPTION, 0, 0, - N_("archive file is local even if it has a colon"), GRID+1 }, - {"rmt-command", RMT_COMMAND_OPTION, N_("COMMAND"), 0, - N_("use given rmt COMMAND instead of rmt"), GRID+1 }, - {"rsh-command", RSH_COMMAND_OPTION, N_("COMMAND"), 0, - N_("use remote COMMAND instead of rsh"), GRID+1 }, -#ifdef DEVICE_PREFIX - {"-[0-7][lmh]", 0, NULL, OPTION_DOC, /* It is OK, since `name' will never be - translated */ - N_("specify drive and density"), GRID+1 }, -#endif - {NULL, '0', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '1', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '2', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '3', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '4', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '5', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '6', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '7', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '8', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - {NULL, '9', NULL, OPTION_HIDDEN, NULL, GRID+1 }, - - {"multi-volume", 'M', 0, 0, - N_("create/list/extract multi-volume archive"), GRID+1 }, - {"tape-length", 'L', N_("NUMBER"), 0, - N_("change tape after writing NUMBER x 1024 bytes"), GRID+1 }, - {"info-script", 'F', N_("NAME"), 0, - N_("run script at end of each tape (implies -M)"), GRID+1 }, - {"new-volume-script", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"volno-file", VOLNO_FILE_OPTION, N_("FILE"), 0, - N_("use/update the volume number in FILE"), GRID+1 }, -#undef GRID - -#define GRID 70 - {NULL, 0, NULL, 0, - N_("Device blocking:"), GRID }, - - {"blocking-factor", 'b', N_("BLOCKS"), 0, - N_("BLOCKS x 512 bytes per record"), GRID+1 }, - {"record-size", RECORD_SIZE_OPTION, N_("NUMBER"), 0, - N_("NUMBER of bytes per record, multiple of 512"), GRID+1 }, - {"ignore-zeros", 'i', 0, 0, - N_("ignore zeroed blocks in archive (means EOF)"), GRID+1 }, - {"read-full-records", 'B', 0, 0, - N_("reblock as we read (for 4.2BSD pipes)"), GRID+1 }, -#undef GRID - -#define GRID 80 - {NULL, 0, NULL, 0, - N_("Archive format selection:"), GRID }, - - {"format", 'H', N_("FORMAT"), 0, - N_("create archive of the given format"), GRID+1 }, - - {NULL, 0, NULL, 0, N_("FORMAT is one of the following:"), GRID+2 }, - {" v7", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("old V7 tar format"), - GRID+3 }, - {" oldgnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, - N_("GNU format as per tar <= 1.12"), GRID+3 }, - {" gnu", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, - N_("GNU tar 1.13.x format"), GRID+3 }, - {" ustar", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, - N_("POSIX 1003.1-1988 (ustar) format"), GRID+3 }, - {" pax", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, - N_("POSIX 1003.1-2001 (pax) format"), GRID+3 }, - {" posix", 0, NULL, OPTION_DOC|OPTION_NO_TRANS, N_("same as pax"), GRID+3 }, - - {"old-archive", OLD_ARCHIVE_OPTION, 0, 0, /* FIXME */ - N_("same as --format=v7"), GRID+8 }, - {"portability", 0, 0, OPTION_ALIAS, NULL, GRID+8 }, - {"posix", POSIX_OPTION, 0, 0, - N_("same as --format=posix"), GRID+8 }, - {"pax-option", PAX_OPTION, N_("keyword[[:]=value][,keyword[[:]=value]]..."), 0, - N_("control pax keywords"), GRID+8 }, - {"label", 'V', N_("TEXT"), 0, - N_("create archive with volume name TEXT; at list/extract time, use TEXT as a globbing pattern for volume name"), GRID+8 }, - {"bzip2", 'j', 0, 0, - N_("filter the archive through bzip2"), GRID+8 }, - {"gzip", 'z', 0, 0, - N_("filter the archive through gzip"), GRID+8 }, - {"gunzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 }, - {"ungzip", 0, 0, OPTION_ALIAS, NULL, GRID+8 }, - {"compress", 'Z', 0, 0, - N_("filter the archive through compress"), GRID+8 }, - {"uncompress", 0, 0, OPTION_ALIAS, NULL, GRID+8 }, - {"use-compress-program", USE_COMPRESS_PROGRAM_OPTION, N_("PROG"), 0, - N_("filter through PROG (must accept -d)"), GRID+8 }, -#undef GRID - -#define GRID 90 - {NULL, 0, NULL, 0, - N_("Local file selection:"), GRID }, - - {"add-file", ARGP_KEY_ARG, N_("FILE"), 0, - N_("add given FILE to the archive (useful if its name starts with a dash)"), GRID+1 }, - {"directory", 'C', N_("DIR"), 0, - N_("change to directory DIR"), GRID+1 }, - {"files-from", 'T', N_("FILE"), 0, - N_("get names to extract or create from FILE"), GRID+1 }, - {"null", NULL_OPTION, 0, 0, - N_("-T reads null-terminated names, disable -C"), GRID+1 }, - {"unquote", UNQUOTE_OPTION, 0, 0, - N_("unquote filenames read with -T (default)"), GRID+1 }, - {"no-unquote", NO_UNQUOTE_OPTION, 0, 0, - N_("do not unquote filenames read with -T"), GRID+1 }, - {"exclude", EXCLUDE_OPTION, N_("PATTERN"), 0, - N_("exclude files, given as a PATTERN"), GRID+1 }, - {"exclude-from", 'X', N_("FILE"), 0, - N_("exclude patterns listed in FILE"), GRID+1 }, - {"exclude-caches", EXCLUDE_CACHES_OPTION, 0, 0, - N_("exclude contents of directories containing CACHEDIR.TAG, " - "except for the tag file itself"), GRID+1 }, - {"exclude-caches-under", EXCLUDE_CACHES_UNDER_OPTION, 0, 0, - N_("exclude everything under directories containing CACHEDIR.TAG"), - GRID+1 }, - {"exclude-caches-all", EXCLUDE_CACHES_ALL_OPTION, 0, 0, - N_("exclude directories containing CACHEDIR.TAG"), GRID+1 }, - {"exclude-tag", EXCLUDE_TAG_OPTION, N_("FILE"), 0, - N_("exclude contents of directories containing FILE, except" - " for FILE itself"), GRID+1 }, - {"exclude-tag-under", EXCLUDE_TAG_UNDER_OPTION, N_("FILE"), 0, - N_("exclude everything under directories containing FILE"), GRID+1 }, - {"exclude-tag-all", EXCLUDE_TAG_ALL_OPTION, N_("FILE"), 0, - N_("exclude directories containing FILE"), GRID+1 }, - {"exclude-vcs", EXCLUDE_VCS_OPTION, NULL, 0, - N_("exclude version control system directories"), GRID+1 }, - {"no-recursion", NO_RECURSION_OPTION, 0, 0, - N_("avoid descending automatically in directories"), GRID+1 }, - {"one-file-system", ONE_FILE_SYSTEM_OPTION, 0, 0, - N_("stay in local file system when creating archive"), GRID+1 }, - {"recursion", RECURSION_OPTION, 0, 0, - N_("recurse into directories (default)"), GRID+1 }, - {"absolute-names", 'P', 0, 0, - N_("don't strip leading `/'s from file names"), GRID+1 }, - {"dereference", 'h', 0, 0, - N_("follow symlinks; archive and dump the files they point to"), GRID+1 }, - {"starting-file", 'K', N_("MEMBER-NAME"), 0, - N_("begin at member MEMBER-NAME in the archive"), GRID+1 }, - {"newer", 'N', N_("DATE-OR-FILE"), 0, - N_("only store files newer than DATE-OR-FILE"), GRID+1 }, - {"after-date", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"newer-mtime", NEWER_MTIME_OPTION, N_("DATE"), 0, - N_("compare date and time when data changed only"), GRID+1 }, - {"backup", BACKUP_OPTION, N_("CONTROL"), OPTION_ARG_OPTIONAL, - N_("backup before removal, choose version CONTROL"), GRID+1 }, - {"suffix", SUFFIX_OPTION, N_("STRING"), 0, - N_("backup before removal, override usual suffix ('~' unless overridden by environment variable SIMPLE_BACKUP_SUFFIX)"), GRID+1 }, -#undef GRID - -#define GRID 92 - {NULL, 0, NULL, 0, - N_("File name transformations:"), GRID }, - {"strip-components", STRIP_COMPONENTS_OPTION, N_("NUMBER"), 0, - N_("strip NUMBER leading components from file names on extraction"), - GRID+1 }, - {"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0, - N_("use sed replace EXPRESSION to transform file names"), GRID+1 }, -#undef GRID - -#define GRID 95 - {NULL, 0, NULL, 0, - N_("File name matching options (affect both exclude and include patterns):"), - GRID }, - {"ignore-case", IGNORE_CASE_OPTION, 0, 0, - N_("ignore case"), GRID+1 }, - {"anchored", ANCHORED_OPTION, 0, 0, - N_("patterns match file name start"), GRID+1 }, - {"no-anchored", NO_ANCHORED_OPTION, 0, 0, - N_("patterns match after any `/' (default for exclusion)"), GRID+1 }, - {"no-ignore-case", NO_IGNORE_CASE_OPTION, 0, 0, - N_("case sensitive matching (default)"), GRID+1 }, - {"wildcards", WILDCARDS_OPTION, 0, 0, - N_("use wildcards (default for exclusion)"), GRID+1 }, - {"no-wildcards", NO_WILDCARDS_OPTION, 0, 0, - N_("verbatim string matching"), GRID+1 }, - {"no-wildcards-match-slash", NO_WILDCARDS_MATCH_SLASH_OPTION, 0, 0, - N_("wildcards do not match `/'"), GRID+1 }, - {"wildcards-match-slash", WILDCARDS_MATCH_SLASH_OPTION, 0, 0, - N_("wildcards match `/' (default for exclusion)"), GRID+1 }, -#undef GRID - -#define GRID 100 - {NULL, 0, NULL, 0, - N_("Informative output:"), GRID }, - - {"verbose", 'v', 0, 0, - N_("verbosely list files processed"), GRID+1 }, - {"checkpoint", CHECKPOINT_OPTION, N_("[.]NUMBER"), OPTION_ARG_OPTIONAL, - N_("display progress messages every NUMBERth record (default 10)"), - GRID+1 }, - {"check-links", 'l', 0, 0, - N_("print a message if not all links are dumped"), GRID+1 }, - {"totals", TOTALS_OPTION, N_("SIGNAL"), OPTION_ARG_OPTIONAL, - N_("print total bytes after processing the archive; " - "with an argument - print total bytes when this SIGNAL is delivered; " - "Allowed signals are: SIGHUP, SIGQUIT, SIGINT, SIGUSR1 and SIGUSR2; " - "the names without SIG prefix are also accepted"), GRID+1 }, - {"utc", UTC_OPTION, 0, 0, - N_("print file modification dates in UTC"), GRID+1 }, - {"index-file", INDEX_FILE_OPTION, N_("FILE"), 0, - N_("send verbose output to FILE"), GRID+1 }, - {"block-number", 'R', 0, 0, - N_("show block number within archive with each message"), GRID+1 }, - {"interactive", 'w', 0, 0, - N_("ask for confirmation for every action"), GRID+1 }, - {"confirmation", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"show-defaults", SHOW_DEFAULTS_OPTION, 0, 0, - N_("show tar defaults"), GRID+1 }, - {"show-omitted-dirs", SHOW_OMITTED_DIRS_OPTION, 0, 0, - N_("when listing or extracting, list each directory that does not match search criteria"), GRID+1 }, - {"show-transformed-names", SHOW_TRANSFORMED_NAMES_OPTION, 0, 0, - N_("show file or archive names after transformation"), - GRID+1 }, - {"show-stored-names", 0, 0, OPTION_ALIAS, NULL, GRID+1 }, - {"quoting-style", QUOTING_STYLE_OPTION, N_("STYLE"), 0, - N_("set name quoting style; see below for valid STYLE values"), GRID+1 }, - {"quote-chars", QUOTE_CHARS_OPTION, N_("STRING"), 0, - N_("additionally quote characters from STRING"), GRID+1 }, - {"no-quote-chars", NO_QUOTE_CHARS_OPTION, N_("STRING"), 0, - N_("disable quoting for characters from STRING"), GRID+1 }, -#undef GRID - -#define GRID 110 - {NULL, 0, NULL, 0, - N_("Compatibility options:"), GRID }, - - {NULL, 'o', 0, 0, - N_("when creating, same as --old-archive; when extracting, same as --no-same-owner"), GRID+1 }, -#undef GRID - -#define GRID 120 - {NULL, 0, NULL, 0, - N_("Other options:"), GRID }, - - {"restrict", RESTRICT_OPTION, 0, 0, - N_("disable use of some potentially harmful options"), -1 }, - - {"help", '?', 0, 0, N_("give this help list"), -1}, - {"usage", USAGE_OPTION, 0, 0, N_("give a short usage message"), -1}, - {"version", VERSION_OPTION, 0, 0, N_("print program version"), -1}, - /* FIXME -V (--label) conflicts with the default short option for - --version */ - {"HANG", HANG_OPTION, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN, - N_("hang for SECS seconds (default 3600)"), 0}, -#undef GRID - - {0, 0, 0, 0, 0, 0} -}; - -static char const *const atime_preserve_args[] = -{ - "replace", "system", NULL -}; - -static enum atime_preserve const atime_preserve_types[] = -{ - replace_atime_preserve, system_atime_preserve -}; - -/* Make sure atime_preserve_types has as much entries as atime_preserve_args - (minus 1 for NULL guard) */ -ARGMATCH_VERIFY (atime_preserve_args, atime_preserve_types); - -/* Wildcard matching settings */ -enum wildcards - { - default_wildcards, /* For exclusion == enable_wildcards, - for inclusion == disable_wildcards */ - disable_wildcards, - enable_wildcards - }; - -struct tar_args /* Variables used during option parsing */ -{ - struct textual_date *textual_date; /* Keeps the arguments to --newer-mtime - and/or --date option if they are - textual dates */ - enum wildcards wildcards; /* Wildcard settings (--wildcards/ - --no-wildcards) */ - int matching_flags; /* exclude_fnmatch options */ - int include_anchored; /* Pattern anchoring options used for - file inclusion */ - bool o_option; /* True if -o option was given */ - bool pax_option; /* True if --pax-option was given */ - char const *backup_suffix_string; /* --suffix option argument */ - char const *version_control_string; /* --backup option argument */ - bool input_files; /* True if some input files where given */ -}; - - -#define MAKE_EXCL_OPTIONS(args) \ - ((((args)->wildcards != disable_wildcards) ? EXCLUDE_WILDCARDS : 0) \ - | (args)->matching_flags \ - | recursion_option) - -#define MAKE_INCL_OPTIONS(args) \ - ((((args)->wildcards == enable_wildcards) ? EXCLUDE_WILDCARDS : 0) \ - | (args)->include_anchored \ - | (args)->matching_flags \ - | recursion_option) - -void -exclude_vcs_files () -{ - int i; - static char *vcs_file[] = { - /* CVS: */ - "CVS", - ".cvsignore", - /* RCS: */ - "RCS", - /* SCCS: */ - "SCCS", - /* SVN: */ - ".svn", - /* git: */ - ".git", - ".gitignore", - /* Arch: */ - ".arch-ids", - "{arch}", - "=RELEASE-ID", - "=meta-update", - "=update", - NULL - }; - - for (i = 0; vcs_file[i]; i++) - add_exclude (excluded, vcs_file[i], 0); -} - - -#ifdef REMOTE_SHELL -# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \ -{ \ - printer (stream, \ - "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \ - archive_format_string (DEFAULT_ARCHIVE_FORMAT), \ - DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \ - quoting_style_args[DEFAULT_QUOTING_STYLE], \ - DEFAULT_RMT_COMMAND); \ - printer (stream, " --rsh-command=%s", REMOTE_SHELL); \ - printer (stream, "\n"); \ -} -#else -# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer) \ -{ \ - printer (stream, \ - "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s", \ - archive_format_string (DEFAULT_ARCHIVE_FORMAT), \ - DEFAULT_ARCHIVE, DEFAULT_BLOCKING, \ - quoting_style_args[DEFAULT_QUOTING_STYLE], \ - DEFAULT_RMT_COMMAND); \ - printer (stream, "\n"); \ -} -#endif - -static void -show_default_settings (FILE *fp) - DECL_SHOW_DEFAULT_SETTINGS(fp, fprintf) - -static void -show_default_settings_fs (argp_fmtstream_t fs) - DECL_SHOW_DEFAULT_SETTINGS(fs, argp_fmtstream_printf) - -static void -set_subcommand_option (enum subcommand subcommand) -{ - if (subcommand_option != UNKNOWN_SUBCOMMAND - && subcommand_option != subcommand) - USAGE_ERROR ((0, 0, - _("You may not specify more than one `-Acdtrux' option"))); - - subcommand_option = subcommand; -} - -static void -set_use_compress_program_option (const char *string) -{ - if (use_compress_program_option - && strcmp (use_compress_program_option, string) != 0) - USAGE_ERROR ((0, 0, _("Conflicting compression options"))); - - use_compress_program_option = string; -} - -static RETSIGTYPE -sigstat (int signo) -{ - compute_duration (); - print_total_stats (); -#ifndef HAVE_SIGACTION - signal (signo, sigstat); -#endif -} - -static void -stat_on_signal (int signo) -{ -#ifdef HAVE_SIGACTION - struct sigaction act; - act.sa_handler = sigstat; - sigemptyset (&act.sa_mask); - act.sa_flags = 0; - sigaction (signo, &act, NULL); -#else - signal (signo, sigstat); -#endif -} - -void -set_stat_signal (const char *name) -{ - static struct sigtab - { - char *name; - int signo; - } sigtab[] = { - { "SIGUSR1", SIGUSR1 }, - { "USR1", SIGUSR1 }, - { "SIGUSR2", SIGUSR2 }, - { "USR2", SIGUSR2 }, - { "SIGHUP", SIGHUP }, - { "HUP", SIGHUP }, - { "SIGINT", SIGINT }, - { "INT", SIGINT }, - { "SIGQUIT", SIGQUIT }, - { "QUIT", SIGQUIT } - }; - struct sigtab *p; - - for (p = sigtab; p < sigtab + sizeof (sigtab) / sizeof (sigtab[0]); p++) - if (strcmp (p->name, name) == 0) - { - stat_on_signal (p->signo); - return; - } - FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name)); -} - - -struct textual_date -{ - struct textual_date *next; - struct timespec *ts; - const char *option; - const char *date; -}; - -static void -get_date_or_file (struct tar_args *args, const char *option, - const char *str, struct timespec *ts) -{ - if (FILE_SYSTEM_PREFIX_LEN (str) != 0 - || ISSLASH (*str) - || *str == '.') - { - struct stat st; - if (deref_stat (dereference_option, str, &st) != 0) - { - stat_error (str); - USAGE_ERROR ((0, 0, _("Date sample file not found"))); - } - *ts = get_stat_mtime (&st); - } - else - { - if (! get_date (ts, str, NULL)) - { - WARN ((0, 0, _("Substituting %s for unknown date format %s"), - tartime (*ts, false), quote (str))); - ts->tv_nsec = 0; - } - else - { - struct textual_date *p = xmalloc (sizeof (*p)); - p->ts = ts; - p->option = option; - p->date = str; - p->next = args->textual_date; - args->textual_date = p; - } - } -} - -static void -report_textual_dates (struct tar_args *args) -{ - struct textual_date *p; - for (p = args->textual_date; p; ) - { - struct textual_date *next = p->next; - char const *treated_as = tartime (*p->ts, true); - if (strcmp (p->date, treated_as) != 0) - WARN ((0, 0, _("Option %s: Treating date `%s' as %s"), - p->option, p->date, treated_as)); - free (p); - p = next; - } -} - - -static volatile int _argp_hang; - -enum read_file_list_state /* Result of reading file name from the list file */ - { - file_list_success, /* OK, name read successfully */ - file_list_end, /* End of list file */ - file_list_zero, /* Zero separator encountered where it should not */ - file_list_skip /* Empty (zero-length) entry encountered, skip it */ - }; - -/* Read from FP a sequence of characters up to FILENAME_TERMINATOR and put them - into STK. - */ -static enum read_file_list_state -read_name_from_file (FILE *fp, struct obstack *stk) -{ - int c; - size_t counter = 0; - - for (c = getc (fp); c != EOF && c != filename_terminator; c = getc (fp)) - { - if (c == 0) - { - /* We have read a zero separator. The file possibly is - zero-separated */ - return file_list_zero; - } - obstack_1grow (stk, c); - counter++; - } - - if (counter == 0 && c != EOF) - return file_list_skip; - - obstack_1grow (stk, 0); - - return (counter == 0 && c == EOF) ? file_list_end : file_list_success; -} - - -static bool files_from_option; /* When set, tar will not refuse to create - empty archives */ -static struct obstack argv_stk; /* Storage for additional command line options - read using -T option */ - -/* Prevent recursive inclusion of the same file */ -struct file_id_list -{ - struct file_id_list *next; - ino_t ino; - dev_t dev; -}; - -static struct file_id_list *file_id_list; - -static void -add_file_id (const char *filename) -{ - struct file_id_list *p; - struct stat st; - - if (stat (filename, &st)) - stat_fatal (filename); - for (p = file_id_list; p; p = p->next) - if (p->ino == st.st_ino && p->dev == st.st_dev) - { - FATAL_ERROR ((0, 0, _("%s: file list already read"), - quotearg_colon (filename))); - } - p = xmalloc (sizeof *p); - p->next = file_id_list; - p->ino = st.st_ino; - p->dev = st.st_dev; - file_id_list = p; -} - -/* Default density numbers for [0-9][lmh] device specifications */ - -#ifndef LOW_DENSITY_NUM -# define LOW_DENSITY_NUM 0 -#endif - -#ifndef MID_DENSITY_NUM -# define MID_DENSITY_NUM 8 -#endif - -#ifndef HIGH_DENSITY_NUM -# define HIGH_DENSITY_NUM 16 -#endif - -static void -update_argv (const char *filename, struct argp_state *state) -{ - FILE *fp; - size_t count = 0, i; - char *start, *p; - char **new_argv; - size_t new_argc; - bool is_stdin = false; - enum read_file_list_state read_state; - - if (!strcmp (filename, "-")) - { - is_stdin = true; - request_stdin ("-T"); - fp = stdin; - } - else - { - add_file_id (filename); - if ((fp = fopen (filename, "r")) == NULL) - open_fatal (filename); - } - - while ((read_state = read_name_from_file (fp, &argv_stk)) != file_list_end) - { - switch (read_state) - { - case file_list_success: - count++; - break; - - case file_list_end: /* won't happen, just to pacify gcc */ - break; - - case file_list_zero: - { - size_t size; - - WARN ((0, 0, N_("%s: file name read contains nul character"), - quotearg_colon (filename))); - - /* Prepare new stack contents */ - size = obstack_object_size (&argv_stk); - p = obstack_finish (&argv_stk); - for (; size > 0; size--, p++) - if (*p) - obstack_1grow (&argv_stk, *p); - else - obstack_1grow (&argv_stk, '\n'); - obstack_1grow (&argv_stk, 0); - count = 1; - /* Read rest of files using new filename terminator */ - filename_terminator = 0; - break; - } - - case file_list_skip: - break; - } - } - - if (!is_stdin) - fclose (fp); - - if (count == 0) - return; - - start = obstack_finish (&argv_stk); - - if (filename_terminator == 0) - for (p = start; *p; p += strlen (p) + 1) - if (p[0] == '-') - count++; - - new_argc = state->argc + count; - new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1)); - memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1)); - state->argv = new_argv; - memmove (&state->argv[state->next + count], &state->argv[state->next], - (state->argc - state->next + 1) * sizeof (state->argv[0])); - - state->argc = new_argc; - - for (i = state->next, p = start; *p; p += strlen (p) + 1, i++) - { - if (filename_terminator == 0 && p[0] == '-') - state->argv[i++] = "--add-file"; - state->argv[i] = p; - } -} - - -static void -tar_help (struct argp_state *state) -{ - argp_fmtstream_t fs; - state->flags |= ARGP_NO_EXIT; - argp_state_help (state, state->out_stream, - ARGP_HELP_STD_HELP & ~ARGP_HELP_BUG_ADDR); - /* FIXME: use struct uparams.rmargin (from argp-help.c) instead of 79 */ - fs = argp_make_fmtstream (state->out_stream, 0, 79, 0); - - argp_fmtstream_printf (fs, "\n%s\n\n", - _("Valid arguments for --quoting-style options are:")); - tar_list_quoting_styles (fs, " "); - - argp_fmtstream_puts (fs, _("\n*This* tar defaults to:\n")); - show_default_settings_fs (fs); - argp_fmtstream_putc (fs, '\n'); - argp_fmtstream_printf (fs, _("Report bugs to %s.\n"), - argp_program_bug_address); - argp_fmtstream_free (fs); -} - -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - struct tar_args *args = state->input; - - switch (key) - { - case ARGP_KEY_ARG: - /* File name or non-parsed option, because of ARGP_IN_ORDER */ - name_add_name (arg, MAKE_INCL_OPTIONS (args)); - args->input_files = true; - break; - - case 'A': - set_subcommand_option (CAT_SUBCOMMAND); - break; - - case 'b': - { - uintmax_t u; - if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK - && u == (blocking_factor = u) - && 0 < blocking_factor - && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE)) - USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg), - _("Invalid blocking factor"))); - } - break; - - case 'B': - /* Try to reblock input records. For reading 4.2BSD pipes. */ - - /* It would surely make sense to exchange -B and -R, but it seems - that -B has been used for a long while in Sun tar and most - BSD-derived systems. This is a consequence of the block/record - terminology confusion. */ - - read_full_records_option = true; - break; - - case 'c': - set_subcommand_option (CREATE_SUBCOMMAND); - break; - - case 'C': - name_add_dir (arg); - break; - - case 'd': - set_subcommand_option (DIFF_SUBCOMMAND); - break; - - case 'f': - if (archive_names == allocated_archive_names) - archive_name_array = x2nrealloc (archive_name_array, - &allocated_archive_names, - sizeof (archive_name_array[0])); - - archive_name_array[archive_names++] = arg; - break; - - case 'F': - /* Since -F is only useful with -M, make it implied. Run this - script at the end of each tape. */ - - info_script_option = arg; - multi_volume_option = true; - break; - - case 'g': - listed_incremental_option = arg; - after_date_option = true; - /* Fall through. */ - - case 'G': - /* We are making an incremental dump (FIXME: are we?); save - directories at the beginning of the archive, and include in each - directory its contents. */ - - incremental_option = true; - break; - - case 'h': - /* Follow symbolic links. */ - dereference_option = true; - break; - - case 'i': - /* Ignore zero blocks (eofs). This can't be the default, - because Unix tar writes two blocks of zeros, then pads out - the record with garbage. */ - - ignore_zeros_option = true; - break; - - case 'I': - USAGE_ERROR ((0, 0, - _("Warning: the -I option is not supported;" - " perhaps you meant -j or -T?"))); - break; - - case 'j': - set_use_compress_program_option ("bzip2"); - break; - - case 'k': - /* Don't replace existing files. */ - old_files_option = KEEP_OLD_FILES; - break; - - case 'K': - starting_file_option = true; - addname (arg, 0); - break; - - case ONE_FILE_SYSTEM_OPTION: - /* When dumping directories, don't dump files/subdirectories - that are on other filesystems. */ - one_file_system_option = true; - break; - - case 'l': - check_links_option = 1; - break; - - case 'L': - { - uintmax_t u; - if (xstrtoumax (arg, 0, 10, &u, "") != LONGINT_OK) - USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg), - _("Invalid tape length"))); - tape_length_option = 1024 * (tarlong) u; - multi_volume_option = true; - } - break; - - case 'm': - touch_option = true; - break; - - case 'M': - /* Make multivolume archive: when we can't write any more into - the archive, re-open it, and continue writing. */ - - multi_volume_option = true; - break; - - case MTIME_OPTION: - get_date_or_file (args, "--mtime", arg, &mtime_option); - set_mtime_option = true; - break; - - case 'n': - seekable_archive = true; - break; - - case 'N': - after_date_option = true; - /* Fall through. */ - - case NEWER_MTIME_OPTION: - if (NEWER_OPTION_INITIALIZED (newer_mtime_option)) - USAGE_ERROR ((0, 0, _("More than one threshold date"))); - get_date_or_file (args, - key == NEWER_MTIME_OPTION ? "--newer-mtime" - : "--after-date", arg, &newer_mtime_option); - break; - - case 'o': - args->o_option = true; - break; - - case 'O': - to_stdout_option = true; - break; - - case 'p': - same_permissions_option = true; - break; - - case 'P': - absolute_names_option = true; - break; - - case 'r': - set_subcommand_option (APPEND_SUBCOMMAND); - break; - - case 'R': - /* Print block numbers for debugging bad tar archives. */ - - /* It would surely make sense to exchange -B and -R, but it seems - that -B has been used for a long while in Sun tar and most - BSD-derived systems. This is a consequence of the block/record - terminology confusion. */ - - block_number_option = true; - break; - - case 's': - /* Names to extract are sorted. */ - - same_order_option = true; - break; - - case 'S': - sparse_option = true; - break; - - case SPARSE_VERSION_OPTION: - sparse_option = true; - { - char *p; - tar_sparse_major = strtoul (arg, &p, 10); - if (*p) - { - if (*p != '.') - USAGE_ERROR ((0, 0, _("Invalid sparse version value"))); - tar_sparse_minor = strtoul (p + 1, &p, 10); - if (*p) - USAGE_ERROR ((0, 0, _("Invalid sparse version value"))); - } - } - break; - - case 't': - set_subcommand_option (LIST_SUBCOMMAND); - verbose_option++; - break; - - case TEST_LABEL_OPTION: - set_subcommand_option (LIST_SUBCOMMAND); - test_label_option = true; - break; - - case 'T': - update_argv (arg, state); - /* Indicate we've been given -T option. This is for backward - compatibility only, so that `tar cfT archive /dev/null will - succeed */ - files_from_option = true; - break; - - case 'u': - set_subcommand_option (UPDATE_SUBCOMMAND); - break; - - case 'U': - old_files_option = UNLINK_FIRST_OLD_FILES; - break; - - case UTC_OPTION: - utc_option = true; - break; - - case 'v': - verbose_option++; - break; - - case 'V': - volume_label_option = arg; - break; - - case 'w': - interactive_option = true; - break; - - case 'W': - verify_option = true; - break; - - case 'x': - set_subcommand_option (EXTRACT_SUBCOMMAND); - break; - - case 'X': - if (add_exclude_file (add_exclude, excluded, arg, - MAKE_EXCL_OPTIONS (args), '\n') - != 0) - { - int e = errno; - FATAL_ERROR ((0, e, "%s", quotearg_colon (arg))); - } - break; - - case 'z': - set_use_compress_program_option ("gzip"); - break; - - case 'Z': - set_use_compress_program_option ("compress"); - break; - - case ANCHORED_OPTION: - args->matching_flags |= EXCLUDE_ANCHORED; - break; - - case ATIME_PRESERVE_OPTION: - atime_preserve_option = - (arg - ? XARGMATCH ("--atime-preserve", arg, - atime_preserve_args, atime_preserve_types) - : replace_atime_preserve); - if (! O_NOATIME && atime_preserve_option == system_atime_preserve) - FATAL_ERROR ((0, 0, - _("--atime-preserve='system' is not supported" - " on this platform"))); - break; - - case CHECKPOINT_OPTION: - if (arg) - { - char *p; - - if (*arg == '.') - { - checkpoint_style = checkpoint_dot; - arg++; - } - checkpoint_option = strtoul (arg, &p, 0); - if (*p) - FATAL_ERROR ((0, 0, - _("--checkpoint value is not an integer"))); - } - else - checkpoint_option = 10; - break; - - case BACKUP_OPTION: - backup_option = true; - if (arg) - args->version_control_string = arg; - break; - - case DELAY_DIRECTORY_RESTORE_OPTION: - delay_directory_restore_option = true; - break; - - case NO_DELAY_DIRECTORY_RESTORE_OPTION: - delay_directory_restore_option = false; - break; - - case DELETE_OPTION: - set_subcommand_option (DELETE_SUBCOMMAND); - break; - - case EXCLUDE_OPTION: - add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args)); - break; - - case EXCLUDE_CACHES_OPTION: - add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents, - cachedir_file_p); - break; - - case EXCLUDE_CACHES_UNDER_OPTION: - add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under, - cachedir_file_p); - break; - - case EXCLUDE_CACHES_ALL_OPTION: - add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all, - cachedir_file_p); - break; - - case EXCLUDE_TAG_OPTION: - add_exclusion_tag (arg, exclusion_tag_contents, NULL); - break; - - case EXCLUDE_TAG_UNDER_OPTION: - add_exclusion_tag (arg, exclusion_tag_under, NULL); - break; - - case EXCLUDE_TAG_ALL_OPTION: - add_exclusion_tag (arg, exclusion_tag_all, NULL); - break; - - case EXCLUDE_VCS_OPTION: - exclude_vcs_files (); - break; - - case FORCE_LOCAL_OPTION: - force_local_option = true; - break; - - case 'H': - set_archive_format (arg); - break; - - case INDEX_FILE_OPTION: - index_file_name = arg; - break; - - case IGNORE_CASE_OPTION: - args->matching_flags |= FNM_CASEFOLD; - break; - - case IGNORE_COMMAND_ERROR_OPTION: - ignore_command_error_option = true; - break; - - case IGNORE_FAILED_READ_OPTION: - ignore_failed_read_option = true; - break; - - case KEEP_NEWER_FILES_OPTION: - old_files_option = KEEP_NEWER_FILES; - break; - - case GROUP_OPTION: - if (! (strlen (arg) < GNAME_FIELD_SIZE - && gname_to_gid (arg, &group_option))) - { - uintmax_t g; - if (xstrtoumax (arg, 0, 10, &g, "") == LONGINT_OK - && g == (gid_t) g) - group_option = g; - else - FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg), - _("%s: Invalid group"))); - } - break; - - case MODE_OPTION: - mode_option = mode_compile (arg); - if (!mode_option) - FATAL_ERROR ((0, 0, _("Invalid mode given on option"))); - initial_umask = umask (0); - umask (initial_umask); - break; - - case NO_ANCHORED_OPTION: - args->include_anchored = 0; /* Clear the default for comman line args */ - args->matching_flags &= ~ EXCLUDE_ANCHORED; - break; - - case NO_IGNORE_CASE_OPTION: - args->matching_flags &= ~ FNM_CASEFOLD; - break; - - case NO_IGNORE_COMMAND_ERROR_OPTION: - ignore_command_error_option = false; - break; - - case NO_OVERWRITE_DIR_OPTION: - old_files_option = NO_OVERWRITE_DIR_OLD_FILES; - break; - - case NO_QUOTE_CHARS_OPTION: - for (;*arg; arg++) - set_char_quoting (NULL, *arg, 0); - break; - - case NO_WILDCARDS_OPTION: - args->wildcards = disable_wildcards; - break; - - case NO_WILDCARDS_MATCH_SLASH_OPTION: - args->matching_flags |= FNM_FILE_NAME; - break; - - case NULL_OPTION: - filename_terminator = '\0'; - break; - - case NUMERIC_OWNER_OPTION: - numeric_owner_option = true; - break; - - case OCCURRENCE_OPTION: - if (!arg) - occurrence_option = 1; - else - { - uintmax_t u; - if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK) - occurrence_option = u; - else - FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg), - _("Invalid number"))); - } - break; - - case OVERWRITE_DIR_OPTION: - old_files_option = DEFAULT_OLD_FILES; - break; - - case OVERWRITE_OPTION: - old_files_option = OVERWRITE_OLD_FILES; - break; - - case OWNER_OPTION: - if (! (strlen (arg) < UNAME_FIELD_SIZE - && uname_to_uid (arg, &owner_option))) - { - uintmax_t u; - if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK - && u == (uid_t) u) - owner_option = u; - else - FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg), - _("Invalid owner"))); - } - break; - - case QUOTE_CHARS_OPTION: - for (;*arg; arg++) - set_char_quoting (NULL, *arg, 1); - break; - - case QUOTING_STYLE_OPTION: - tar_set_quoting_style (arg); - break; - - case PAX_OPTION: - args->pax_option = true; - xheader_set_option (arg); - break; - - case POSIX_OPTION: - set_archive_format ("posix"); - break; - - case PRESERVE_OPTION: - /* FIXME: What it is good for? */ - same_permissions_option = true; - same_order_option = true; - break; - - case RECORD_SIZE_OPTION: - { - uintmax_t u; - if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK - && u == (size_t) u)) - USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg), - _("Invalid record size"))); - record_size = u; - if (record_size % BLOCKSIZE != 0) - USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."), - BLOCKSIZE)); - blocking_factor = record_size / BLOCKSIZE; - } - break; - - case RECURSIVE_UNLINK_OPTION: - recursive_unlink_option = true; - break; - - case REMOVE_FILES_OPTION: - remove_files_option = true; - break; - - case RESTRICT_OPTION: - restrict_option = true; - break; - - case RMT_COMMAND_OPTION: - rmt_command = arg; - break; - - case RSH_COMMAND_OPTION: - rsh_command_option = arg; - break; - - case SHOW_DEFAULTS_OPTION: - show_default_settings (stdout); - close_stdout (); - exit (0); - - case STRIP_COMPONENTS_OPTION: - { - uintmax_t u; - if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK - && u == (size_t) u)) - USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg), - _("Invalid number of elements"))); - strip_name_components = u; - } - break; - - case SHOW_OMITTED_DIRS_OPTION: - show_omitted_dirs_option = true; - break; - - case SHOW_TRANSFORMED_NAMES_OPTION: - show_transformed_names_option = true; - break; - - case SUFFIX_OPTION: - backup_option = true; - args->backup_suffix_string = arg; - break; - - case TO_COMMAND_OPTION: - if (to_command_option) - USAGE_ERROR ((0, 0, _("Only one --to-command option allowed"))); - to_command_option = arg; - break; - - case TOTALS_OPTION: - if (arg) - set_stat_signal (arg); - else - totals_option = true; - break; - - case TRANSFORM_OPTION: - set_transform_expr (arg); - break; - - case USE_COMPRESS_PROGRAM_OPTION: - set_use_compress_program_option (arg); - break; - - case VOLNO_FILE_OPTION: - volno_file_option = arg; - break; - - case WILDCARDS_OPTION: - args->wildcards = enable_wildcards; - break; - - case WILDCARDS_MATCH_SLASH_OPTION: - args->matching_flags &= ~ FNM_FILE_NAME; - break; - - case NO_RECURSION_OPTION: - recursion_option = 0; - break; - - case NO_SAME_OWNER_OPTION: - same_owner_option = -1; - break; - - case NO_SAME_PERMISSIONS_OPTION: - same_permissions_option = -1; - break; - - case RECURSION_OPTION: - recursion_option = FNM_LEADING_DIR; - break; - - case SAME_OWNER_OPTION: - same_owner_option = 1; - break; - - case UNQUOTE_OPTION: - unquote_option = true; - break; - - case NO_UNQUOTE_OPTION: - unquote_option = false; - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - -#ifdef DEVICE_PREFIX - { - int device = key - '0'; - int density; - static char buf[sizeof DEVICE_PREFIX + 10]; - char *cursor; - - if (arg[1]) - argp_error (state, _("Malformed density argument: %s"), quote (arg)); - - strcpy (buf, DEVICE_PREFIX); - cursor = buf + strlen (buf); - -#ifdef DENSITY_LETTER - - sprintf (cursor, "%d%c", device, arg[0]); - -#else /* not DENSITY_LETTER */ - - switch (arg[0]) - { - case 'l': - device += LOW_DENSITY_NUM; - break; - - case 'm': - device += MID_DENSITY_NUM; - break; - - case 'h': - device += HIGH_DENSITY_NUM; - break; - - default: - argp_error (state, _("Unknown density: `%c'"), arg[0]); - } - sprintf (cursor, "%d", device); - -#endif /* not DENSITY_LETTER */ - - if (archive_names == allocated_archive_names) - archive_name_array = x2nrealloc (archive_name_array, - &allocated_archive_names, - sizeof (archive_name_array[0])); - archive_name_array[archive_names++] = xstrdup (buf); - } - break; - -#else /* not DEVICE_PREFIX */ - - argp_error (state, - _("Options `-[0-7][lmh]' not supported by *this* tar")); - -#endif /* not DEVICE_PREFIX */ - - case '?': - tar_help (state); - close_stdout (); - exit (0); - - case USAGE_OPTION: - argp_state_help (state, state->out_stream, ARGP_HELP_USAGE); - close_stdout (); - exit (0); - - case VERSION_OPTION: - version_etc (state->out_stream, "tar", PACKAGE_NAME, VERSION, - "John Gilmore", "Jay Fenlason", (char *) NULL); - close_stdout (); - exit (0); - - case HANG_OPTION: - _argp_hang = atoi (arg ? arg : "3600"); - while (_argp_hang-- > 0) - sleep (1); - break; - - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static struct argp argp = { - options, - parse_opt, - N_("[FILE]..."), - doc, - NULL, - NULL, - NULL -}; - -void -usage (int status) -{ - argp_help (&argp, stderr, ARGP_HELP_SEE, (char*) program_name); - close_stdout (); - exit (status); -} - -/* Parse the options for tar. */ - -static struct argp_option * -find_argp_option (struct argp_option *o, int letter) -{ - for (; - !(o->name == NULL - && o->key == 0 - && o->arg == 0 - && o->flags == 0 - && o->doc == NULL); o++) - if (o->key == letter) - return o; - return NULL; -} - -static void -decode_options (int argc, char **argv) -{ - int idx; - struct tar_args args; - - /* Set some default option values. */ - args.textual_date = NULL; - args.wildcards = default_wildcards; - args.matching_flags = 0; - args.include_anchored = EXCLUDE_ANCHORED; - args.o_option = false; - args.pax_option = false; - args.backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - args.version_control_string = 0; - args.input_files = false; - - subcommand_option = UNKNOWN_SUBCOMMAND; - archive_format = DEFAULT_FORMAT; - blocking_factor = DEFAULT_BLOCKING; - record_size = DEFAULT_BLOCKING * BLOCKSIZE; - excluded = new_exclude (); - newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t); - newer_mtime_option.tv_nsec = -1; - recursion_option = FNM_LEADING_DIR; - unquote_option = true; - tar_sparse_major = 1; - tar_sparse_minor = 0; - - owner_option = -1; - group_option = -1; - - /* Convert old-style tar call by exploding option element and rearranging - options accordingly. */ - - if (argc > 1 && argv[1][0] != '-') - { - int new_argc; /* argc value for rearranged arguments */ - char **new_argv; /* argv value for rearranged arguments */ - char *const *in; /* cursor into original argv */ - char **out; /* cursor into rearranged argv */ - const char *letter; /* cursor into old option letters */ - char buffer[3]; /* constructed option buffer */ - - /* Initialize a constructed option. */ - - buffer[0] = '-'; - buffer[2] = '\0'; - - /* Allocate a new argument array, and copy program name in it. */ - - new_argc = argc - 1 + strlen (argv[1]); - new_argv = xmalloc ((new_argc + 1) * sizeof (char *)); - in = argv; - out = new_argv; - *out++ = *in++; - - /* Copy each old letter option as a separate option, and have the - corresponding argument moved next to it. */ - - for (letter = *in++; *letter; letter++) - { - struct argp_option *opt; - - buffer[1] = *letter; - *out++ = xstrdup (buffer); - opt = find_argp_option (options, *letter); - if (opt && opt->arg) - { - if (in < argv + argc) - *out++ = *in++; - else - USAGE_ERROR ((0, 0, _("Old option `%c' requires an argument."), - *letter)); - } - } - - /* Copy all remaining options. */ - - while (in < argv + argc) - *out++ = *in++; - *out = 0; - - /* Replace the old option list by the new one. */ - - argc = new_argc; - argv = new_argv; - } - - /* Parse all options and non-options as they appear. */ - - prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv); - - if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP, - &idx, &args)) - exit (TAREXIT_FAILURE); - - - /* Special handling for 'o' option: - - GNU tar used to say "output old format". - UNIX98 tar says don't chown files after extracting (we use - "--no-same-owner" for this). - - The old GNU tar semantics is retained when used with --create - option, otherwise UNIX98 semantics is assumed */ - - if (args.o_option) - { - if (subcommand_option == CREATE_SUBCOMMAND) - { - /* GNU Tar <= 1.13 compatibility */ - set_archive_format ("v7"); - } - else - { - /* UNIX98 compatibility */ - same_owner_option = -1; - } - } - - /* Handle operands after any "--" argument. */ - for (; idx < argc; idx++) - { - name_add_name (argv[idx], MAKE_INCL_OPTIONS (&args)); - args.input_files = true; - } - - /* Warn about implicit use of the wildcards in command line arguments. - See TODO */ - warn_regex_usage = args.wildcards == default_wildcards; - - /* Derive option values and check option consistency. */ - - if (archive_format == DEFAULT_FORMAT) - { - if (args.pax_option) - archive_format = POSIX_FORMAT; - else - archive_format = DEFAULT_ARCHIVE_FORMAT; - } - - if ((volume_label_option && subcommand_option == CREATE_SUBCOMMAND) - || incremental_option - || multi_volume_option - || sparse_option) - assert_format (FORMAT_MASK (OLDGNU_FORMAT) - | FORMAT_MASK (GNU_FORMAT) - | FORMAT_MASK (POSIX_FORMAT)); - - if (occurrence_option) - { - if (!args.input_files) - USAGE_ERROR ((0, 0, - _("--occurrence is meaningless without a file list"))); - if (subcommand_option != DELETE_SUBCOMMAND - && subcommand_option != DIFF_SUBCOMMAND - && subcommand_option != EXTRACT_SUBCOMMAND - && subcommand_option != LIST_SUBCOMMAND) - USAGE_ERROR ((0, 0, - _("--occurrence cannot be used in the requested operation mode"))); - } - - if (seekable_archive && subcommand_option == DELETE_SUBCOMMAND) - { - /* The current code in delete.c is based on the assumption that - skip_member() reads all data from the archive. So, we should - make sure it won't use seeks. On the other hand, the same code - depends on the ability to backspace a record in the archive, - so setting seekable_archive to false is technically incorrect. - However, it is tested only in skip_member(), so it's not a - problem. */ - seekable_archive = false; - } - - if (archive_names == 0) - { - /* If no archive file name given, try TAPE from the environment, or - else, DEFAULT_ARCHIVE from the configuration process. */ - - archive_names = 1; - archive_name_array[0] = getenv ("TAPE"); - if (! archive_name_array[0]) - archive_name_array[0] = DEFAULT_ARCHIVE; - } - - /* Allow multiple archives only with `-M'. */ - - if (archive_names > 1 && !multi_volume_option) - USAGE_ERROR ((0, 0, - _("Multiple archive files require `-M' option"))); - - if (listed_incremental_option - && NEWER_OPTION_INITIALIZED (newer_mtime_option)) - USAGE_ERROR ((0, 0, - _("Cannot combine --listed-incremental with --newer"))); - - if (volume_label_option) - { - if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT) - { - size_t volume_label_max_len = - (sizeof current_header->header.name - - 1 /* for trailing '\0' */ - - (multi_volume_option - ? (sizeof " Volume " - - 1 /* for null at end of " Volume " */ - + INT_STRLEN_BOUND (int) /* for volume number */ - - 1 /* for sign, as 0 <= volno */) - : 0)); - if (volume_label_max_len < strlen (volume_label_option)) - USAGE_ERROR ((0, 0, - ngettext ("%s: Volume label is too long (limit is %lu byte)", - "%s: Volume label is too long (limit is %lu bytes)", - volume_label_max_len), - quotearg_colon (volume_label_option), - (unsigned long) volume_label_max_len)); - } - /* else FIXME - Label length in PAX format is limited by the volume size. */ - } - - if (verify_option) - { - if (multi_volume_option) - USAGE_ERROR ((0, 0, _("Cannot verify multi-volume archives"))); - if (use_compress_program_option) - USAGE_ERROR ((0, 0, _("Cannot verify compressed archives"))); - } - - if (use_compress_program_option) - { - if (multi_volume_option) - USAGE_ERROR ((0, 0, _("Cannot use multi-volume compressed archives"))); - if (subcommand_option == UPDATE_SUBCOMMAND - || subcommand_option == APPEND_SUBCOMMAND - || subcommand_option == DELETE_SUBCOMMAND) - USAGE_ERROR ((0, 0, _("Cannot update compressed archives"))); - if (subcommand_option == CAT_SUBCOMMAND) - USAGE_ERROR ((0, 0, _("Cannot concatenate compressed archives"))); - } - - /* It is no harm to use --pax-option on non-pax archives in archive - reading mode. It may even be useful, since it allows to override - file attributes from tar headers. Therefore I allow such usage. - --gray */ - if (args.pax_option - && archive_format != POSIX_FORMAT - && (subcommand_option != EXTRACT_SUBCOMMAND - || subcommand_option != DIFF_SUBCOMMAND - || subcommand_option != LIST_SUBCOMMAND)) - USAGE_ERROR ((0, 0, _("--pax-option can be used only on POSIX archives"))); - - /* If ready to unlink hierarchies, so we are for simpler files. */ - if (recursive_unlink_option) - old_files_option = UNLINK_FIRST_OLD_FILES; - - - if (test_label_option) - { - /* --test-label is silent if the user has specified the label name to - compare against. */ - if (!args.input_files) - verbose_option++; - } - else if (utc_option) - verbose_option = 2; - - /* Forbid using -c with no input files whatsoever. Check that `-f -', - explicit or implied, is used correctly. */ - - switch (subcommand_option) - { - case CREATE_SUBCOMMAND: - if (!args.input_files && !files_from_option) - USAGE_ERROR ((0, 0, - _("Cowardly refusing to create an empty archive"))); - break; - - case EXTRACT_SUBCOMMAND: - case LIST_SUBCOMMAND: - case DIFF_SUBCOMMAND: - for (archive_name_cursor = archive_name_array; - archive_name_cursor < archive_name_array + archive_names; - archive_name_cursor++) - if (!strcmp (*archive_name_cursor, "-")) - request_stdin ("-f"); - break; - - case CAT_SUBCOMMAND: - case UPDATE_SUBCOMMAND: - case APPEND_SUBCOMMAND: - for (archive_name_cursor = archive_name_array; - archive_name_cursor < archive_name_array + archive_names; - archive_name_cursor++) - if (!strcmp (*archive_name_cursor, "-")) - USAGE_ERROR ((0, 0, - _("Options `-Aru' are incompatible with `-f -'"))); - - default: - break; - } - - /* Initialize stdlis */ - if (index_file_name) - { - stdlis = fopen (index_file_name, "w"); - if (! stdlis) - open_error (index_file_name); - } - else - stdlis = to_stdout_option ? stderr : stdout; - - archive_name_cursor = archive_name_array; - - /* Prepare for generating backup names. */ - - if (args.backup_suffix_string) - simple_backup_suffix = xstrdup (args.backup_suffix_string); - - if (backup_option) - { - backup_type = xget_version ("--backup", args.version_control_string); - /* No backup is needed either if explicitely disabled or if - the extracted files are not being written to disk. */ - if (backup_type == no_backups || EXTRACT_OVER_PIPE) - backup_option = false; - } - - if (verbose_option) - report_textual_dates (&args); -} - - -/* Tar proper. */ - -/* Main routine for tar. */ -int -main (int argc, char **argv) -{ - set_start_time (); - program_name = argv[0]; - - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - exit_failure = TAREXIT_FAILURE; - exit_status = TAREXIT_SUCCESS; - filename_terminator = '\n'; - set_quoting_style (0, DEFAULT_QUOTING_STYLE); - - /* Make sure we have first three descriptors available */ - stdopen (); - - /* Pre-allocate a few structures. */ - - allocated_archive_names = 10; - archive_name_array = - xmalloc (sizeof (const char *) * allocated_archive_names); - archive_names = 0; - - obstack_init (&argv_stk); - -#ifdef SIGCHLD - /* System V fork+wait does not work if SIGCHLD is ignored. */ - signal (SIGCHLD, SIG_DFL); -#endif - - /* Decode options. */ - - decode_options (argc, argv); - - name_init (); - - /* Main command execution. */ - - if (volno_file_option) - init_volume_number (); - - switch (subcommand_option) - { - case UNKNOWN_SUBCOMMAND: - USAGE_ERROR ((0, 0, - _("You must specify one of the `-Acdtrux' options"))); - - case CAT_SUBCOMMAND: - case UPDATE_SUBCOMMAND: - case APPEND_SUBCOMMAND: - update_archive (); - break; - - case DELETE_SUBCOMMAND: - delete_archive_members (); - break; - - case CREATE_SUBCOMMAND: - create_archive (); - break; - - case EXTRACT_SUBCOMMAND: - extr_init (); - read_and (extract_archive); - - /* FIXME: should extract_finish () even if an ordinary signal is - received. */ - extract_finish (); - - break; - - case LIST_SUBCOMMAND: - read_and (list_archive); - break; - - case DIFF_SUBCOMMAND: - diff_init (); - read_and (diff_archive); - break; - } - - if (totals_option) - print_total_stats (); - - if (check_links_option) - check_links (); - - if (volno_file_option) - closeout_volume_number (); - - /* Dispose of allocated memory, and return. */ - - free (archive_name_array); - name_term (); - - if (exit_status == TAREXIT_FAILURE) - error (0, 0, _("Error exit delayed from previous errors")); - - if (stdlis == stdout) - close_stdout (); - else if (ferror (stderr) || fclose (stderr) != 0) - exit_status = TAREXIT_FAILURE; - - return exit_status; -} - -void -tar_stat_init (struct tar_stat_info *st) -{ - memset (st, 0, sizeof (*st)); -} - -void -tar_stat_destroy (struct tar_stat_info *st) -{ - free (st->orig_file_name); - free (st->file_name); - free (st->link_name); - free (st->uname); - free (st->gname); - free (st->sparse_map); - free (st->dumpdir); - xheader_destroy (&st->xhdr); - memset (st, 0, sizeof (*st)); -} - -/* Format mask for all available formats that support nanosecond - timestamp resolution. */ -#define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT) - -/* Same as timespec_cmp, but ignore nanoseconds if current archive - format does not provide sufficient resolution. */ -int -tar_timespec_cmp (struct timespec a, struct timespec b) -{ - if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK)) - a.tv_nsec = b.tv_nsec = 0; - return timespec_cmp (a, b); -} diff --git a/src/bin/tar/src/tar.h b/src/bin/tar/src/tar.h deleted file mode 100644 index 7f72f3ef72..0000000000 --- a/src/bin/tar/src/tar.h +++ /dev/null @@ -1,331 +0,0 @@ -/* GNU tar Archive Format description. - - Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 2000, 2001, 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* tar Header Block, from POSIX 1003.1-1990. */ - -/* POSIX header. */ - -struct posix_header -{ /* byte offset */ - char name[100]; /* 0 */ - char mode[8]; /* 100 */ - char uid[8]; /* 108 */ - char gid[8]; /* 116 */ - char size[12]; /* 124 */ - char mtime[12]; /* 136 */ - char chksum[8]; /* 148 */ - char typeflag; /* 156 */ - char linkname[100]; /* 157 */ - char magic[6]; /* 257 */ - char version[2]; /* 263 */ - char uname[32]; /* 265 */ - char gname[32]; /* 297 */ - char devmajor[8]; /* 329 */ - char devminor[8]; /* 337 */ - char prefix[155]; /* 345 */ - /* 500 */ -}; - -#define TMAGIC "ustar" /* ustar and a null */ -#define TMAGLEN 6 -#define TVERSION "00" /* 00 and no null */ -#define TVERSLEN 2 - -/* Values used in typeflag field. */ -#define REGTYPE '0' /* regular file */ -#define AREGTYPE '\0' /* regular file */ -#define LNKTYPE '1' /* link */ -#define SYMTYPE '2' /* reserved */ -#define CHRTYPE '3' /* character special */ -#define BLKTYPE '4' /* block special */ -#define DIRTYPE '5' /* directory */ -#define FIFOTYPE '6' /* FIFO special */ -#define CONTTYPE '7' /* reserved */ - -#define XHDTYPE 'x' /* Extended header referring to the - next file in the archive */ -#define XGLTYPE 'g' /* Global extended header */ - -/* Bits used in the mode field, values in octal. */ -#define TSUID 04000 /* set UID on execution */ -#define TSGID 02000 /* set GID on execution */ -#define TSVTX 01000 /* reserved */ - /* file permissions */ -#define TUREAD 00400 /* read by owner */ -#define TUWRITE 00200 /* write by owner */ -#define TUEXEC 00100 /* execute/search by owner */ -#define TGREAD 00040 /* read by group */ -#define TGWRITE 00020 /* write by group */ -#define TGEXEC 00010 /* execute/search by group */ -#define TOREAD 00004 /* read by other */ -#define TOWRITE 00002 /* write by other */ -#define TOEXEC 00001 /* execute/search by other */ - -/* tar Header Block, GNU extensions. */ - -/* In GNU tar, SYMTYPE is for to symbolic links, and CONTTYPE is for - contiguous files, so maybe disobeying the `reserved' comment in POSIX - header description. I suspect these were meant to be used this way, and - should not have really been `reserved' in the published standards. */ - -/* *BEWARE* *BEWARE* *BEWARE* that the following information is still - boiling, and may change. Even if the OLDGNU format description should be - accurate, the so-called GNU format is not yet fully decided. It is - surely meant to use only extensions allowed by POSIX, but the sketch - below repeats some ugliness from the OLDGNU format, which should rather - go away. Sparse files should be saved in such a way that they do *not* - require two passes at archive creation time. Huge files get some POSIX - fields to overflow, alternate solutions have to be sought for this. */ - -/* Descriptor for a single file hole. */ - -struct sparse -{ /* byte offset */ - char offset[12]; /* 0 */ - char numbytes[12]; /* 12 */ - /* 24 */ -}; - -/* Sparse files are not supported in POSIX ustar format. For sparse files - with a POSIX header, a GNU extra header is provided which holds overall - sparse information and a few sparse descriptors. When an old GNU header - replaces both the POSIX header and the GNU extra header, it holds some - sparse descriptors too. Whether POSIX or not, if more sparse descriptors - are still needed, they are put into as many successive sparse headers as - necessary. The following constants tell how many sparse descriptors fit - in each kind of header able to hold them. */ - -#define SPARSES_IN_EXTRA_HEADER 16 -#define SPARSES_IN_OLDGNU_HEADER 4 -#define SPARSES_IN_SPARSE_HEADER 21 - -/* Extension header for sparse files, used immediately after the GNU extra - header, and used only if all sparse information cannot fit into that - extra header. There might even be many such extension headers, one after - the other, until all sparse information has been recorded. */ - -struct sparse_header -{ /* byte offset */ - struct sparse sp[SPARSES_IN_SPARSE_HEADER]; - /* 0 */ - char isextended; /* 504 */ - /* 505 */ -}; - -/* The old GNU format header conflicts with POSIX format in such a way that - POSIX archives may fool old GNU tar's, and POSIX tar's might well be - fooled by old GNU tar archives. An old GNU format header uses the space - used by the prefix field in a POSIX header, and cumulates information - normally found in a GNU extra header. With an old GNU tar header, we - never see any POSIX header nor GNU extra header. Supplementary sparse - headers are allowed, however. */ - -struct oldgnu_header -{ /* byte offset */ - char unused_pad1[345]; /* 0 */ - char atime[12]; /* 345 Incr. archive: atime of the file */ - char ctime[12]; /* 357 Incr. archive: ctime of the file */ - char offset[12]; /* 369 Multivolume archive: the offset of - the start of this volume */ - char longnames[4]; /* 381 Not used */ - char unused_pad2; /* 385 */ - struct sparse sp[SPARSES_IN_OLDGNU_HEADER]; - /* 386 */ - char isextended; /* 482 Sparse file: Extension sparse header - follows */ - char realsize[12]; /* 483 Sparse file: Real size*/ - /* 495 */ -}; - -/* OLDGNU_MAGIC uses both magic and version fields, which are contiguous. - Found in an archive, it indicates an old GNU header format, which will be - hopefully become obsolescent. With OLDGNU_MAGIC, uname and gname are - valid, though the header is not truly POSIX conforming. */ -#define OLDGNU_MAGIC "ustar " /* 7 chars and a null */ - -/* The standards committee allows only capital A through capital Z for - user-defined expansion. Other letters in use include: - - 'A' Solaris Access Control List - 'E' Solaris Extended Attribute File - 'I' Inode only, as in 'star' - 'N' Obsolete GNU tar, for file names that do not fit into the main header. - 'X' POSIX 1003.1-2001 eXtended (VU version) */ - -/* This is a dir entry that contains the names of files that were in the - dir at the time the dump was made. */ -#define GNUTYPE_DUMPDIR 'D' - -/* Identifies the *next* file on the tape as having a long linkname. */ -#define GNUTYPE_LONGLINK 'K' - -/* Identifies the *next* file on the tape as having a long name. */ -#define GNUTYPE_LONGNAME 'L' - -/* This is the continuation of a file that began on another volume. */ -#define GNUTYPE_MULTIVOL 'M' - -/* This is for sparse files. */ -#define GNUTYPE_SPARSE 'S' - -/* This file is a tape/volume header. Ignore it on extraction. */ -#define GNUTYPE_VOLHDR 'V' - -/* Solaris extended header */ -#define SOLARIS_XHDTYPE 'X' - -/* J@"org Schilling star header */ - -struct star_header -{ /* byte offset */ - char name[100]; /* 0 */ - char mode[8]; /* 100 */ - char uid[8]; /* 108 */ - char gid[8]; /* 116 */ - char size[12]; /* 124 */ - char mtime[12]; /* 136 */ - char chksum[8]; /* 148 */ - char typeflag; /* 156 */ - char linkname[100]; /* 157 */ - char magic[6]; /* 257 */ - char version[2]; /* 263 */ - char uname[32]; /* 265 */ - char gname[32]; /* 297 */ - char devmajor[8]; /* 329 */ - char devminor[8]; /* 337 */ - char prefix[131]; /* 345 */ - char atime[12]; /* 476 */ - char ctime[12]; /* 488 */ - /* 500 */ -}; - -#define SPARSES_IN_STAR_HEADER 4 -#define SPARSES_IN_STAR_EXT_HEADER 21 - -struct star_in_header -{ - char fill[345]; /* 0 Everything that is before t_prefix */ - char prefix[1]; /* 345 t_name prefix */ - char fill2; /* 346 */ - char fill3[8]; /* 347 */ - char isextended; /* 355 */ - struct sparse sp[SPARSES_IN_STAR_HEADER]; /* 356 */ - char realsize[12]; /* 452 Actual size of the file */ - char offset[12]; /* 464 Offset of multivolume contents */ - char atime[12]; /* 476 */ - char ctime[12]; /* 488 */ - char mfill[8]; /* 500 */ - char xmagic[4]; /* 508 "tar" */ -}; - -struct star_ext_header -{ - struct sparse sp[SPARSES_IN_STAR_EXT_HEADER]; - char isextended; -}; - -/* END */ - - -/* tar Header Block, overall structure. */ - -/* tar files are made in basic blocks of this size. */ -#define BLOCKSIZE 512 - -enum archive_format -{ - DEFAULT_FORMAT, /* format to be decided later */ - V7_FORMAT, /* old V7 tar format */ - OLDGNU_FORMAT, /* GNU format as per before tar 1.12 */ - USTAR_FORMAT, /* POSIX.1-1988 (ustar) format */ - POSIX_FORMAT, /* POSIX.1-2001 format */ - STAR_FORMAT, /* Star format defined in 1994 */ - GNU_FORMAT /* Same as OLDGNU_FORMAT with one exception: - see FIXME note for to_chars() function - (create.c:189) */ -}; - -/* Information about a sparse file. */ -struct sp_array -{ - off_t offset; - size_t numbytes; -}; - -struct xheader -{ - struct obstack *stk; - size_t size; - char *buffer; - uintmax_t string_length; -}; - -struct tar_stat_info -{ - char *orig_file_name; /* name of file read from the archive header */ - char *file_name; /* name of file for the current archive entry - after being normalized. */ - bool had_trailing_slash; /* true if the current archive entry had a - trailing slash before it was normalized. */ - char *link_name; /* name of link for the current archive entry. */ - - char *uname; /* user name of owner */ - char *gname; /* group name of owner */ - struct stat stat; /* regular filesystem stat */ - - /* STAT doesn't always have access, data modification, and status - change times in a convenient form, so store them separately. */ - struct timespec atime; - struct timespec mtime; - struct timespec ctime; - - off_t archive_file_size; /* Size of file as stored in the archive. - Equals stat.st_size for non-sparse files */ - - bool is_sparse; /* Is the file sparse */ - - /* For sparse files: */ - unsigned sparse_major; - unsigned sparse_minor; - size_t sparse_map_avail; /* Index to the first unused element in - sparse_map array. Zero if the file is - not sparse */ - size_t sparse_map_size; /* Size of the sparse map */ - struct sp_array *sparse_map; - - /* Extended headers */ - struct xheader xhdr; - - /* For dumpdirs */ - bool is_dumpdir; /* Is the member a dumpdir? */ - bool skipped; /* The member contents is already read - (for GNUTYPE_DUMPDIR) */ - char *dumpdir; /* Contents of the dump directory */ -}; - -union block -{ - char buffer[BLOCKSIZE]; - struct posix_header header; - struct star_header star_header; - struct oldgnu_header oldgnu_header; - struct sparse_header sparse_header; - struct star_in_header star_in_header; - struct star_ext_header star_ext_header; -}; diff --git a/src/bin/tar/src/tar.rdef b/src/bin/tar/src/tar.rdef deleted file mode 100644 index 0128c5c34c..0000000000 --- a/src/bin/tar/src/tar.rdef +++ /dev/null @@ -1,11 +0,0 @@ -resource app_version -{ - major = 1, - middle = 19, - minor = 0, - variety = 1, - internal = 0, - short_info = "1.19", - long_info = "1.19 ©2007 The Free Software Foundation" -}; - diff --git a/src/bin/tar/src/transform.c b/src/bin/tar/src/transform.c deleted file mode 100644 index 349a0d59e2..0000000000 --- a/src/bin/tar/src/transform.c +++ /dev/null @@ -1,527 +0,0 @@ -/* This file is part of GNU tar. - Copyright (C) 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include "common.h" - -static enum transform_type - { - transform_none, - transform_first, - transform_global - } -transform_type = transform_none; -static unsigned match_number = 0; -static regex_t regex; -static struct obstack stk; - -enum replace_segm_type - { - segm_literal, /* Literal segment */ - segm_backref, /* Back-reference segment */ - segm_case_ctl /* Case control segment (GNU extension) */ - }; - -enum case_ctl_type - { - ctl_stop, /* Stop case conversion */ - ctl_upcase_next,/* Turn the next character to uppercase */ - ctl_locase_next,/* Turn the next character to lowercase */ - ctl_upcase, /* Turn the replacement to uppercase until ctl_stop */ - ctl_locase /* Turn the replacement to lowercase until ctl_stop */ - }; - -struct replace_segm -{ - struct replace_segm *next; - enum replace_segm_type type; - union - { - struct - { - char *ptr; - size_t size; - } literal; /* type == segm_literal */ - size_t ref; /* type == segm_backref */ - enum case_ctl_type ctl; /* type == segm_case_ctl */ - } v; -}; - -/* Compiled replacement expression */ -static struct replace_segm *repl_head, *repl_tail; -static size_t segm_count; /* Number of elements in the above list */ - -static struct replace_segm * -add_segment (void) -{ - struct replace_segm *segm = xmalloc (sizeof *segm); - segm->next = NULL; - if (repl_tail) - repl_tail->next = segm; - else - repl_head = segm; - repl_tail = segm; - segm_count++; - return segm; -} - -static void -add_literal_segment (char *str, char *end) -{ - size_t len = end - str; - if (len) - { - struct replace_segm *segm = add_segment (); - segm->type = segm_literal; - segm->v.literal.ptr = xmalloc (len + 1); - memcpy (segm->v.literal.ptr, str, len); - segm->v.literal.ptr[len] = 0; - segm->v.literal.size = len; - } -} - -static void -add_char_segment (int chr) -{ - struct replace_segm *segm = add_segment (); - segm->type = segm_literal; - segm->v.literal.ptr = xmalloc (2); - segm->v.literal.ptr[0] = chr; - segm->v.literal.ptr[1] = 0; - segm->v.literal.size = 1; -} - -static void -add_backref_segment (size_t ref) -{ - struct replace_segm *segm = add_segment (); - segm->type = segm_backref; - segm->v.ref = ref; -} - -static void -add_case_ctl_segment (enum case_ctl_type ctl) -{ - struct replace_segm *segm = add_segment (); - segm->type = segm_case_ctl; - segm->v.ctl = ctl; -} - -void -set_transform_expr (const char *expr) -{ - int delim; - int i, j, rc; - char *str, *beg, *cur; - const char *p; - int cflags = 0; - - if (transform_type == transform_none) - obstack_init (&stk); - else - { - /* Redefinition of the transform expression */ - regfree (®ex); - } - - if (expr[0] != 's') - USAGE_ERROR ((0, 0, _("Invalid transform expression"))); - - delim = expr[1]; - - /* Scan regular expression */ - for (i = 2; expr[i] && expr[i] != delim; i++) - if (expr[i] == '\\' && expr[i+1]) - i++; - - if (expr[i] != delim) - USAGE_ERROR ((0, 0, _("Invalid transform expression"))); - - /* Scan replacement expression */ - for (j = i + 1; expr[j] && expr[j] != delim; j++) - if (expr[j] == '\\' && expr[j+1]) - j++; - - if (expr[j] != delim) - USAGE_ERROR ((0, 0, _("Invalid transform expression"))); - - /* Check flags */ - transform_type = transform_first; - for (p = expr + j + 1; *p; p++) - switch (*p) - { - case 'g': - transform_type = transform_global; - break; - - case 'i': - cflags |= REG_ICASE; - break; - - case 'x': - cflags |= REG_EXTENDED; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - match_number = strtoul (p, (char**) &p, 0); - p--; - break; - - default: - USAGE_ERROR ((0, 0, _("Unknown flag in transform expression"))); - } - - /* Extract and compile regex */ - str = xmalloc (i - 1); - memcpy (str, expr + 2, i - 2); - str[i - 2] = 0; - - rc = regcomp (®ex, str, cflags); - - if (rc) - { - char errbuf[512]; - regerror (rc, ®ex, errbuf, sizeof (errbuf)); - USAGE_ERROR ((0, 0, _("Invalid transform expression: %s"), errbuf)); - } - - if (str[0] == '^' || str[strlen (str) - 1] == '$') - transform_type = transform_first; - - free (str); - - /* Extract and compile replacement expr */ - i++; - str = xmalloc (j - i + 1); - memcpy (str, expr + i, j - i); - str[j - i] = 0; - - for (cur = beg = str; *cur;) - { - if (*cur == '\\') - { - size_t n; - - add_literal_segment (beg, cur); - switch (*++cur) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = strtoul (cur, &cur, 10); - if (n > regex.re_nsub) - USAGE_ERROR ((0, 0, _("Invalid transform replacement: back reference out of range"))); - add_backref_segment (n); - break; - - case '\\': - add_char_segment ('\\'); - cur++; - break; - - case 'a': - add_char_segment ('\a'); - cur++; - break; - - case 'b': - add_char_segment ('\b'); - cur++; - break; - - case 'f': - add_char_segment ('\f'); - cur++; - break; - - case 'n': - add_char_segment ('\n'); - cur++; - break; - - case 'r': - add_char_segment ('\r'); - cur++; - break; - - case 't': - add_char_segment ('\t'); - cur++; - break; - - case 'v': - add_char_segment ('\v'); - cur++; - break; - - case '&': - add_char_segment ('&'); - cur++; - break; - - case 'L': - /* Turn the replacement to lowercase until a `\U' or `\E' - is found, */ - add_case_ctl_segment (ctl_locase); - cur++; - break; - - case 'l': - /* Turn the next character to lowercase, */ - add_case_ctl_segment (ctl_locase_next); - cur++; - break; - - case 'U': - /* Turn the replacement to uppercase until a `\L' or `\E' - is found, */ - add_case_ctl_segment (ctl_upcase); - cur++; - break; - - case 'u': - /* Turn the next character to uppercase, */ - add_case_ctl_segment (ctl_upcase_next); - cur++; - break; - - case 'E': - /* Stop case conversion started by `\L' or `\U'. */ - add_case_ctl_segment (ctl_stop); - cur++; - break; - - default: - /* Try to be nice */ - { - char buf[2]; - buf[0] = '\\'; - buf[1] = *cur; - add_literal_segment (buf, buf + 2); - } - cur++; - break; - } - beg = cur; - } - else if (*cur == '&') - { - add_literal_segment (beg, cur); - add_backref_segment (0); - beg = ++cur; - } - else - cur++; - } - add_literal_segment (beg, cur); - -} - -/* Run case conversion specified by CASE_CTL on array PTR of SIZE - characters. Returns pointer to statically allocated storage. */ -static char * -run_case_conv (enum case_ctl_type case_ctl, char *ptr, size_t size) -{ - static char *case_ctl_buffer; - static size_t case_ctl_bufsize; - char *p; - - if (case_ctl_bufsize < size) - { - case_ctl_bufsize = size; - case_ctl_buffer = xrealloc (case_ctl_buffer, case_ctl_bufsize); - } - memcpy (case_ctl_buffer, ptr, size); - switch (case_ctl) - { - case ctl_upcase_next: - case_ctl_buffer[0] = toupper (case_ctl_buffer[0]); - break; - - case ctl_locase_next: - case_ctl_buffer[0] = tolower (case_ctl_buffer[0]); - break; - - case ctl_upcase: - for (p = case_ctl_buffer; p < case_ctl_buffer + size; p++) - *p = toupper (*p); - break; - - case ctl_locase: - for (p = case_ctl_buffer; p < case_ctl_buffer + size; p++) - *p = tolower (*p); - break; - - case ctl_stop: - break; - } - return case_ctl_buffer; -} - -bool -_transform_name_to_obstack (char *input) -{ - regmatch_t *rmp; - int rc; - size_t nmatches = 0; - enum case_ctl_type case_ctl = ctl_stop, /* Current case conversion op */ - save_ctl = ctl_stop; /* Saved case_ctl for \u and \l */ - - /* Reset case conversion after a single-char operation */ -#define CASE_CTL_RESET() if (case_ctl == ctl_upcase_next \ - || case_ctl == ctl_locase_next) \ - { \ - case_ctl = save_ctl; \ - save_ctl = ctl_stop; \ - } - - if (transform_type == transform_none) - return false; - - rmp = xmalloc ((regex.re_nsub + 1) * sizeof (*rmp)); - - while (*input) - { - size_t disp; - char *ptr; - - rc = regexec (®ex, input, regex.re_nsub + 1, rmp, 0); - - if (rc == 0) - { - struct replace_segm *segm; - - disp = rmp[0].rm_eo; - - if (rmp[0].rm_so) - obstack_grow (&stk, input, rmp[0].rm_so); - - nmatches++; - if (match_number && nmatches < match_number) - { - obstack_grow (&stk, input, disp); - input += disp; - continue; - } - - for (segm = repl_head; segm; segm = segm->next) - { - switch (segm->type) - { - case segm_literal: /* Literal segment */ - if (case_ctl == ctl_stop) - ptr = segm->v.literal.ptr; - else - { - ptr = run_case_conv (case_ctl, - segm->v.literal.ptr, - segm->v.literal.size); - CASE_CTL_RESET(); - } - obstack_grow (&stk, ptr, segm->v.literal.size); - break; - - case segm_backref: /* Back-reference segment */ - if (rmp[segm->v.ref].rm_so != -1 - && rmp[segm->v.ref].rm_eo != -1) - { - size_t size = rmp[segm->v.ref].rm_eo - - rmp[segm->v.ref].rm_so; - ptr = input + rmp[segm->v.ref].rm_so; - if (case_ctl != ctl_stop) - { - ptr = run_case_conv (case_ctl, ptr, size); - CASE_CTL_RESET(); - } - - obstack_grow (&stk, ptr, size); - } - break; - - case segm_case_ctl: - switch (segm->v.ctl) - { - case ctl_upcase_next: - case ctl_locase_next: - switch (save_ctl) - { - case ctl_stop: - case ctl_upcase: - case ctl_locase: - save_ctl = case_ctl; - default: - break; - } - /*FALL THROUGH*/ - - case ctl_upcase: - case ctl_locase: - case ctl_stop: - case_ctl = segm->v.ctl; - } - } - } - } - else - { - disp = strlen (input); - obstack_grow (&stk, input, disp); - } - - input += disp; - - if (transform_type == transform_first) - { - obstack_grow (&stk, input, strlen (input)); - break; - } - } - - obstack_1grow (&stk, 0); - free (rmp); - return true; -} - -bool -transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat) -{ - char *str; - bool ret = _transform_name_to_obstack (*pinput); - if (ret) - { - str = obstack_finish (&stk); - assign_string (pinput, fun ? fun (str, dat) : str); - obstack_free (&stk, str); - } - else if (fun) - { - str = *pinput; - *pinput = NULL; - assign_string (pinput, fun (str, dat)); - free (str); - ret = true; - } - return ret; -} - -bool -transform_name (char **pinput) -{ - return transform_name_fp (pinput, NULL, NULL); -} - diff --git a/src/bin/tar/src/update.c b/src/bin/tar/src/update.c deleted file mode 100644 index fa161935ae..0000000000 --- a/src/bin/tar/src/update.c +++ /dev/null @@ -1,210 +0,0 @@ -/* Update a tar archive. - - Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003, - 2004, 2005, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -/* Implement the 'r', 'u' and 'A' options for tar. 'A' means that the - file names are tar files, and they should simply be appended to the end - of the archive. No attempt is made to record the reads from the args; if - they're on raw tape or something like that, it'll probably lose... */ - -#include -#include -#include "common.h" - -/* FIXME: This module should not directly handle the following variable, - instead, this should be done in buffer.c only. */ -extern union block *current_block; - -/* We've hit the end of the old stuff, and its time to start writing new - stuff to the tape. This involves seeking back one record and - re-writing the current record (which has been changed). - FIXME: Either eliminate it or move it to common.h. -*/ -bool time_to_start_writing; - -/* Pointer to where we started to write in the first record we write out. - This is used if we can't backspace the output and have to null out the - first part of the record. */ -char *output_start; - -/* Catenate file FILE_NAME to the archive without creating a header for it. - It had better be a tar file or the archive is screwed. */ -static void -append_file (char *file_name) -{ - int handle = open (file_name, O_RDONLY | O_BINARY); - struct stat stat_data; - - if (handle < 0) - { - open_error (file_name); - return; - } - - if (fstat (handle, &stat_data) != 0) - stat_error (file_name); - else - { - off_t bytes_left = stat_data.st_size; - - while (bytes_left > 0) - { - union block *start = find_next_block (); - size_t buffer_size = available_space_after (start); - size_t status; - char buf[UINTMAX_STRSIZE_BOUND]; - - if (bytes_left < buffer_size) - { - buffer_size = bytes_left; - status = buffer_size % BLOCKSIZE; - if (status) - memset (start->buffer + bytes_left, 0, BLOCKSIZE - status); - } - - status = safe_read (handle, start->buffer, buffer_size); - if (status == SAFE_READ_ERROR) - read_fatal_details (file_name, stat_data.st_size - bytes_left, - buffer_size); - if (status == 0) - FATAL_ERROR ((0, 0, - ngettext ("%s: File shrank by %s byte", - "%s: File shrank by %s bytes", - bytes_left), - quotearg_colon (file_name), - STRINGIFY_BIGINT (bytes_left, buf))); - - bytes_left -= status; - - set_next_block_after (start + (status - 1) / BLOCKSIZE); - } - } - - if (close (handle) != 0) - close_error (file_name); -} - -/* Implement the 'r' (add files to end of archive), and 'u' (add files - to end of archive if they aren't there, or are more up to date than - the version in the archive) commands. */ -void -update_archive (void) -{ - enum read_header previous_status = HEADER_STILL_UNREAD; - bool found_end = false; - - name_gather (); - open_archive (ACCESS_UPDATE); - buffer_write_global_xheader (); - - while (!found_end) - { - enum read_header status = read_header (false); - - switch (status) - { - case HEADER_STILL_UNREAD: - case HEADER_SUCCESS_EXTENDED: - abort (); - - case HEADER_SUCCESS: - { - struct name *name; - - decode_header (current_header, ¤t_stat_info, - ¤t_format, 0); - archive_format = current_format; - - if (subcommand_option == UPDATE_SUBCOMMAND - && (name = name_scan (current_stat_info.file_name)) != NULL) - { - struct stat s; - - chdir_do (name->change_dir); - if (deref_stat (dereference_option, - current_stat_info.file_name, &s) == 0 - && (tar_timespec_cmp (get_stat_mtime (&s), - current_stat_info.mtime) - <= 0)) - add_avoided_name (current_stat_info.file_name); - } - - skip_member (); - break; - } - - case HEADER_ZERO_BLOCK: - current_block = current_header; - found_end = true; - break; - - case HEADER_END_OF_FILE: - found_end = true; - break; - - case HEADER_FAILURE: - set_next_block_after (current_header); - switch (previous_status) - { - case HEADER_STILL_UNREAD: - WARN ((0, 0, _("This does not look like a tar archive"))); - /* Fall through. */ - - case HEADER_SUCCESS: - case HEADER_ZERO_BLOCK: - ERROR ((0, 0, _("Skipping to next header"))); - /* Fall through. */ - - case HEADER_FAILURE: - break; - - case HEADER_END_OF_FILE: - case HEADER_SUCCESS_EXTENDED: - abort (); - } - break; - } - - tar_stat_destroy (¤t_stat_info); - previous_status = status; - } - - reset_eof (); - time_to_start_writing = true; - output_start = current_block->buffer; - - { - char *file_name; - - while ((file_name = name_from_list ()) != NULL) - { - if (excluded_name (file_name)) - continue; - if (interactive_option && !confirm ("add", file_name)) - continue; - if (subcommand_option == CAT_SUBCOMMAND) - append_file (file_name); - else - dump_file (file_name, 1, (dev_t) 0); - } - } - - write_eot (); - close_archive (); - names_notfound (); -} diff --git a/src/bin/tar/src/utf8.c b/src/bin/tar/src/utf8.c deleted file mode 100644 index d5e5963863..0000000000 --- a/src/bin/tar/src/utf8.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Charset handling for GNU tar. - - Copyright (C) 2004, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include -#include -#include -#include "common.h" -#ifdef HAVE_ICONV_H -# include -#endif - -#ifndef ICONV_CONST -# define ICONV_CONST -#endif - -#ifndef HAVE_ICONV - -# undef iconv_open -# define iconv_open(tocode, fromcode) ((iconv_t) -1) - -# undef iconv -# define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ((size_t) 0) - -# undef iconv_close -# define iconv_close(cd) 0 - -#endif - - - - -static iconv_t conv_desc[2] = { (iconv_t) -1, (iconv_t) -1 }; - -static iconv_t -utf8_init (bool to_utf) -{ - if (conv_desc[(int) to_utf] == (iconv_t) -1) - { - if (to_utf) - conv_desc[(int) to_utf] = iconv_open ("UTF-8", locale_charset ()); - else - conv_desc[(int) to_utf] = iconv_open (locale_charset (), "UTF-8"); - } - return conv_desc[(int) to_utf]; -} - -bool -utf8_convert (bool to_utf, char const *input, char **output) -{ - char ICONV_CONST *ib; - char *ob; - size_t inlen; - size_t outlen; - size_t rc; - iconv_t cd = utf8_init (to_utf); - - if (cd == 0) - { - *output = xstrdup (input); - return true; - } - else if (cd == (iconv_t)-1) - return false; - - inlen = strlen (input) + 1; - outlen = inlen * MB_LEN_MAX + 1; - ob = *output = xmalloc (outlen); - ib = (char ICONV_CONST *) input; - rc = iconv (cd, &ib, &inlen, &ob, &outlen); - *ob = 0; - return rc != -1; -} - - -bool -string_ascii_p (char const *p) -{ - for (; *p; p++) - if (! (0 <= *p && *p <= 127)) - return false; - return true; -} diff --git a/src/bin/tar/src/xheader.c b/src/bin/tar/src/xheader.c deleted file mode 100644 index 9be0a2fe30..0000000000 --- a/src/bin/tar/src/xheader.c +++ /dev/null @@ -1,1516 +0,0 @@ -/* POSIX extended headers for tar. - - Copyright (C) 2003, 2004, 2005, 2006, 2007 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, 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - -#include - -#include -#include -#include -#include - -#include "common.h" - -#include - -static bool xheader_protected_pattern_p (char const *pattern); -static bool xheader_protected_keyword_p (char const *keyword); -static void xheader_set_single_keyword (char *) __attribute__ ((noreturn)); - -/* Used by xheader_finish() */ -static void code_string (char const *string, char const *keyword, - struct xheader *xhdr); - -/* Number of global headers written so far. */ -static size_t global_header_count; -/* FIXME: Possibly it should be reset after changing the volume. - POSIX %n specification says that it is expanded to the sequence - number of current global header in *the* archive. However, for - multi-volume archives this will yield duplicate header names - in different volumes, which I'd like to avoid. The best way - to solve this would be to use per-archive header count as required - by POSIX *and* set globexthdr.name to, say, - $TMPDIR/GlobalHead.%p.$NUMVOLUME.%n. - - However it should wait until buffer.c is finally rewritten */ - - -/* Interface functions to obstacks */ - -static void -x_obstack_grow (struct xheader *xhdr, const char *ptr, size_t length) -{ - obstack_grow (xhdr->stk, ptr, length); - xhdr->size += length; -} - -static void -x_obstack_1grow (struct xheader *xhdr, char c) -{ - obstack_1grow (xhdr->stk, c); - xhdr->size++; -} - -static void -x_obstack_blank (struct xheader *xhdr, size_t length) -{ - obstack_blank (xhdr->stk, length); - xhdr->size += length; -} - - -/* Keyword options */ - -struct keyword_list -{ - struct keyword_list *next; - char *pattern; - char *value; -}; - - -/* List of keyword patterns set by delete= option */ -static struct keyword_list *keyword_pattern_list; - -/* List of keyword/value pairs set by `keyword=value' option */ -static struct keyword_list *keyword_global_override_list; - -/* List of keyword/value pairs set by `keyword:=value' option */ -static struct keyword_list *keyword_override_list; - -/* List of keyword/value pairs decoded from the last 'g' type header */ -static struct keyword_list *global_header_override_list; - -/* Template for the name field of an 'x' type header */ -static char *exthdr_name; - -/* Template for the name field of a 'g' type header */ -static char *globexthdr_name; - -bool -xheader_keyword_deleted_p (const char *kw) -{ - struct keyword_list *kp; - - for (kp = keyword_pattern_list; kp; kp = kp->next) - if (fnmatch (kp->pattern, kw, 0) == 0) - return true; - return false; -} - -static bool -xheader_keyword_override_p (const char *keyword) -{ - struct keyword_list *kp; - - for (kp = keyword_override_list; kp; kp = kp->next) - if (strcmp (kp->pattern, keyword) == 0) - return true; - return false; -} - -static void -xheader_list_append (struct keyword_list **root, char const *kw, - char const *value) -{ - struct keyword_list *kp = xmalloc (sizeof *kp); - kp->pattern = xstrdup (kw); - kp->value = value ? xstrdup (value) : NULL; - kp->next = *root; - *root = kp; -} - -static void -xheader_list_destroy (struct keyword_list **root) -{ - if (root) - { - struct keyword_list *kw = *root; - while (kw) - { - struct keyword_list *next = kw->next; - free (kw->pattern); - free (kw->value); - free (kw); - kw = next; - } - *root = NULL; - } -} - -static void -xheader_set_single_keyword (char *kw) -{ - USAGE_ERROR ((0, 0, _("Keyword %s is unknown or not yet implemented"), kw)); -} - -static void -xheader_set_keyword_equal (char *kw, char *eq) -{ - bool global = true; - char *p = eq; - - if (eq[-1] == ':') - { - p--; - global = false; - } - - while (p > kw && isspace (*p)) - p--; - - *p = 0; - - for (p = eq + 1; *p && isspace (*p); p++) - ; - - if (strcmp (kw, "delete") == 0) - { - if (xheader_protected_pattern_p (p)) - USAGE_ERROR ((0, 0, _("Pattern %s cannot be used"), quote (p))); - xheader_list_append (&keyword_pattern_list, p, NULL); - } - else if (strcmp (kw, "exthdr.name") == 0) - assign_string (&exthdr_name, p); - else if (strcmp (kw, "globexthdr.name") == 0) - assign_string (&globexthdr_name, p); - else - { - if (xheader_protected_keyword_p (kw)) - USAGE_ERROR ((0, 0, _("Keyword %s cannot be overridden"), kw)); - if (global) - xheader_list_append (&keyword_global_override_list, kw, p); - else - xheader_list_append (&keyword_override_list, kw, p); - } -} - -void -xheader_set_option (char *string) -{ - char *token; - for (token = strtok (string, ","); token; token = strtok (NULL, ",")) - { - char *p = strchr (token, '='); - if (!p) - xheader_set_single_keyword (token); - else - xheader_set_keyword_equal (token, p); - } -} - -/* - string Includes: Replaced By: - %d The directory name of the file, - equivalent to the result of the - dirname utility on the translated - file name. - %f The filename of the file, equivalent - to the result of the basename - utility on the translated file name. - %p The process ID of the pax process. - %n The value of the 3rd argument. - %% A '%' character. */ - -char * -xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n) -{ - char *buf; - size_t len = strlen (fmt); - char *q; - const char *p; - char *dirp = NULL; - char *dir = NULL; - char *base = NULL; - char pidbuf[UINTMAX_STRSIZE_BOUND]; - char const *pptr; - char nbuf[UINTMAX_STRSIZE_BOUND]; - char const *nptr = NULL; - - for (p = fmt; *p && (p = strchr (p, '%')); ) - { - switch (p[1]) - { - case '%': - len--; - break; - - case 'd': - if (st) - { - if (!dirp) - dirp = dir_name (st->orig_file_name); - dir = safer_name_suffix (dirp, false, absolute_names_option); - len += strlen (dir) - 2; - } - break; - - case 'f': - if (st) - { - base = last_component (st->orig_file_name); - len += strlen (base) - 2; - } - break; - - case 'p': - pptr = umaxtostr (getpid (), pidbuf); - len += pidbuf + sizeof pidbuf - 1 - pptr - 2; - break; - - case 'n': - nptr = umaxtostr (n, nbuf); - len += nbuf + sizeof nbuf - 1 - nptr - 2; - break; - } - p++; - } - - buf = xmalloc (len + 1); - for (q = buf, p = fmt; *p; ) - { - if (*p == '%') - { - switch (p[1]) - { - case '%': - *q++ = *p++; - p++; - break; - - case 'd': - if (dir) - q = stpcpy (q, dir); - p += 2; - break; - - case 'f': - if (base) - q = stpcpy (q, base); - p += 2; - break; - - case 'p': - q = stpcpy (q, pptr); - p += 2; - break; - - case 'n': - if (nptr) - { - q = stpcpy (q, nptr); - p += 2; - break; - } - /* else fall through */ - - default: - *q++ = *p++; - if (*p) - *q++ = *p++; - } - } - else - *q++ = *p++; - } - - free (dirp); - - /* Do not allow it to end in a slash */ - while (q > buf && ISSLASH (q[-1])) - q--; - *q = 0; - return buf; -} - -char * -xheader_xhdr_name (struct tar_stat_info *st) -{ - if (!exthdr_name) - assign_string (&exthdr_name, "%d/PaxHeaders.%p/%f"); - return xheader_format_name (st, exthdr_name, 0); -} - -#define GLOBAL_HEADER_TEMPLATE "/GlobalHead.%p.%n" - -char * -xheader_ghdr_name (void) -{ - if (!globexthdr_name) - { - size_t len; - const char *tmp = getenv ("TMPDIR"); - if (!tmp) - tmp = "/tmp"; - len = strlen (tmp) + sizeof (GLOBAL_HEADER_TEMPLATE); /* Includes nul */ - globexthdr_name = xmalloc (len); - strcpy(globexthdr_name, tmp); - strcat(globexthdr_name, GLOBAL_HEADER_TEMPLATE); - } - - return xheader_format_name (NULL, globexthdr_name, global_header_count + 1); -} - -void -xheader_write (char type, char *name, struct xheader *xhdr) -{ - union block *header; - size_t size; - char *p; - - size = xhdr->size; - header = start_private_header (name, size); - header->header.typeflag = type; - - simple_finish_header (header); - - p = xhdr->buffer; - - do - { - size_t len; - - header = find_next_block (); - len = BLOCKSIZE; - if (len > size) - len = size; - memcpy (header->buffer, p, len); - if (len < BLOCKSIZE) - memset (header->buffer + len, 0, BLOCKSIZE - len); - p += len; - size -= len; - set_next_block_after (header); - } - while (size > 0); - xheader_destroy (xhdr); - - if (type == XGLTYPE) - global_header_count++; -} - -void -xheader_write_global (struct xheader *xhdr) -{ - char *name; - struct keyword_list *kp; - - if (!keyword_global_override_list) - return; - - xheader_init (xhdr); - for (kp = keyword_global_override_list; kp; kp = kp->next) - code_string (kp->value, kp->pattern, xhdr); - xheader_finish (xhdr); - xheader_write (XGLTYPE, name = xheader_ghdr_name (), xhdr); - free (name); -} - - -/* General Interface */ - -struct xhdr_tab -{ - char const *keyword; - void (*coder) (struct tar_stat_info const *, char const *, - struct xheader *, void const *data); - void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t); - bool protect; -}; - -/* This declaration must be extern, because ISO C99 section 6.9.2 - prohibits a tentative definition that has both internal linkage and - incomplete type. If we made it static, we'd have to declare its - size which would be a maintenance pain; if we put its initializer - here, we'd need a boatload of forward declarations, which would be - even more of a pain. */ -extern struct xhdr_tab const xhdr_tab[]; - -static struct xhdr_tab const * -locate_handler (char const *keyword) -{ - struct xhdr_tab const *p; - - for (p = xhdr_tab; p->keyword; p++) - if (strcmp (p->keyword, keyword) == 0) - return p; - return NULL; -} - -static bool -xheader_protected_pattern_p (const char *pattern) -{ - struct xhdr_tab const *p; - - for (p = xhdr_tab; p->keyword; p++) - if (p->protect && fnmatch (pattern, p->keyword, 0) == 0) - return true; - return false; -} - -static bool -xheader_protected_keyword_p (const char *keyword) -{ - struct xhdr_tab const *p; - - for (p = xhdr_tab; p->keyword; p++) - if (p->protect && strcmp (p->keyword, keyword) == 0) - return true; - return false; -} - -/* Decode a single extended header record, advancing *PTR to the next record. - Return true on success, false otherwise. */ -static bool -decode_record (struct xheader *xhdr, - char **ptr, - void (*handler) (void *, char const *, char const *, size_t), - void *data) -{ - char *start = *ptr; - char *p = start; - uintmax_t u; - size_t len; - char *len_lim; - char const *keyword; - char *nextp; - size_t len_max = xhdr->buffer + xhdr->size - start; - - while (*p == ' ' || *p == '\t') - p++; - - if (! ISDIGIT (*p)) - { - if (*p) - ERROR ((0, 0, _("Malformed extended header: missing length"))); - return false; - } - - errno = 0; - len = u = strtoumax (p, &len_lim, 10); - if (len != u || errno == ERANGE) - { - ERROR ((0, 0, _("Extended header length is out of allowed range"))); - return false; - } - - if (len_max < len) - { - int len_len = len_lim - p; - ERROR ((0, 0, _("Extended header length %*s is out of range"), - len_len, p)); - return false; - } - - nextp = start + len; - - for (p = len_lim; *p == ' ' || *p == '\t'; p++) - continue; - if (p == len_lim) - { - ERROR ((0, 0, - _("Malformed extended header: missing blank after length"))); - return false; - } - - keyword = p; - p = strchr (p, '='); - if (! (p && p < nextp)) - { - ERROR ((0, 0, _("Malformed extended header: missing equal sign"))); - return false; - } - - if (nextp[-1] != '\n') - { - ERROR ((0, 0, _("Malformed extended header: missing newline"))); - return false; - } - - *p = nextp[-1] = '\0'; - handler (data, keyword, p + 1, nextp - p - 2); /* '=' + trailing '\n' */ - *p = '='; - nextp[-1] = '\n'; - *ptr = nextp; - return true; -} - -static void -run_override_list (struct keyword_list *kp, struct tar_stat_info *st) -{ - for (; kp; kp = kp->next) - { - struct xhdr_tab const *t = locate_handler (kp->pattern); - if (t) - t->decoder (st, t->keyword, kp->value, strlen (kp->value)); - } -} - -static void -decx (void *data, char const *keyword, char const *value, size_t size) -{ - struct xhdr_tab const *t; - struct tar_stat_info *st = data; - - if (xheader_keyword_deleted_p (keyword) - || xheader_keyword_override_p (keyword)) - return; - - t = locate_handler (keyword); - if (t) - t->decoder (st, keyword, value, size); - else - WARN((0, 0, _("Ignoring unknown extended header keyword `%s'"), - keyword)); -} - -void -xheader_decode (struct tar_stat_info *st) -{ - run_override_list (keyword_global_override_list, st); - run_override_list (global_header_override_list, st); - - if (st->xhdr.size) - { - char *p = st->xhdr.buffer + BLOCKSIZE; - while (decode_record (&st->xhdr, &p, decx, st)) - continue; - } - run_override_list (keyword_override_list, st); -} - -static void -decg (void *data, char const *keyword, char const *value, - size_t size __attribute__((unused))) -{ - struct keyword_list **kwl = data; - xheader_list_append (kwl, keyword, value); -} - -void -xheader_decode_global (struct xheader *xhdr) -{ - if (xhdr->size) - { - char *p = xhdr->buffer + BLOCKSIZE; - - xheader_list_destroy (&global_header_override_list); - while (decode_record (xhdr, &p, decg, &global_header_override_list)) - continue; - } -} - -void -xheader_init (struct xheader *xhdr) -{ - if (!xhdr->stk) - { - xhdr->stk = xmalloc (sizeof *xhdr->stk); - obstack_init (xhdr->stk); - } -} - -void -xheader_store (char const *keyword, struct tar_stat_info *st, - void const *data) -{ - struct xhdr_tab const *t; - - if (st->xhdr.buffer) - return; - t = locate_handler (keyword); - if (!t || !t->coder) - return; - if (xheader_keyword_deleted_p (keyword) - || xheader_keyword_override_p (keyword)) - return; - xheader_init (&st->xhdr); - t->coder (st, keyword, &st->xhdr, data); -} - -void -xheader_read (struct xheader *xhdr, union block *p, size_t size) -{ - size_t j = 0; - - xheader_init (xhdr); - size += BLOCKSIZE; - xhdr->size = size; - xhdr->buffer = xmalloc (size + 1); - xhdr->buffer[size] = '\0'; - - do - { - size_t len = size; - - if (len > BLOCKSIZE) - len = BLOCKSIZE; - - memcpy (&xhdr->buffer[j], p->buffer, len); - set_next_block_after (p); - - p = find_next_block (); - - j += len; - size -= len; - } - while (size > 0); -} - -static void -xheader_print_n (struct xheader *xhdr, char const *keyword, - char const *value, size_t vsize) -{ - size_t len = strlen (keyword) + vsize + 3; /* ' ' + '=' + '\n' */ - size_t p; - size_t n = 0; - char nbuf[UINTMAX_STRSIZE_BOUND]; - char const *np; - - do - { - p = n; - np = umaxtostr (len + p, nbuf); - n = nbuf + sizeof nbuf - 1 - np; - } - while (n != p); - - x_obstack_grow (xhdr, np, n); - x_obstack_1grow (xhdr, ' '); - x_obstack_grow (xhdr, keyword, strlen (keyword)); - x_obstack_1grow (xhdr, '='); - x_obstack_grow (xhdr, value, vsize); - x_obstack_1grow (xhdr, '\n'); -} - -static void -xheader_print (struct xheader *xhdr, char const *keyword, char const *value) -{ - xheader_print_n (xhdr, keyword, value, strlen (value)); -} - -void -xheader_finish (struct xheader *xhdr) -{ - struct keyword_list *kp; - - for (kp = keyword_override_list; kp; kp = kp->next) - code_string (kp->value, kp->pattern, xhdr); - - xhdr->buffer = obstack_finish (xhdr->stk); -} - -void -xheader_destroy (struct xheader *xhdr) -{ - if (xhdr->stk) - { - obstack_free (xhdr->stk, NULL); - free (xhdr->stk); - xhdr->stk = NULL; - } - else - free (xhdr->buffer); - xhdr->buffer = 0; - xhdr->size = 0; -} - - -/* Buildable strings */ - -void -xheader_string_begin (struct xheader *xhdr) -{ - xhdr->string_length = 0; -} - -void -xheader_string_add (struct xheader *xhdr, char const *s) -{ - if (xhdr->buffer) - return; - xheader_init (xhdr); - xhdr->string_length += strlen (s); - x_obstack_grow (xhdr, s, strlen (s)); -} - -bool -xheader_string_end (struct xheader *xhdr, char const *keyword) -{ - uintmax_t len; - uintmax_t p; - uintmax_t n = 0; - size_t size; - char nbuf[UINTMAX_STRSIZE_BOUND]; - char const *np; - char *cp; - - if (xhdr->buffer) - return false; - xheader_init (xhdr); - - len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */ - - do - { - p = n; - np = umaxtostr (len + p, nbuf); - n = nbuf + sizeof nbuf - 1 - np; - } - while (n != p); - - p = strlen (keyword) + n + 2; - size = p; - if (size != p) - { - ERROR ((0, 0, - _("Generated keyword/value pair is too long (keyword=%s, length=%s)"), - keyword, nbuf)); - obstack_free (xhdr->stk, obstack_finish (xhdr->stk)); - return false; - } - x_obstack_blank (xhdr, p); - x_obstack_1grow (xhdr, '\n'); - cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1; - memmove (cp + p, cp, xhdr->string_length); - cp = stpcpy (cp, np); - *cp++ = ' '; - cp = stpcpy (cp, keyword); - *cp++ = '='; - return true; -} - - -/* Implementations */ - -static void -out_of_range_header (char const *keyword, char const *value, - uintmax_t minus_minval, uintmax_t maxval) -{ - char minval_buf[UINTMAX_STRSIZE_BOUND + 1]; - char maxval_buf[UINTMAX_STRSIZE_BOUND]; - char *minval_string = umaxtostr (minus_minval, minval_buf + 1); - char *maxval_string = umaxtostr (maxval, maxval_buf); - if (minus_minval) - *--minval_string = '-'; - - /* TRANSLATORS: The first %s is the pax extended header keyword - (atime, gid, etc.). */ - ERROR ((0, 0, _("Extended header %s=%s is out of range %s..%s"), - keyword, value, minval_string, maxval_string)); -} - -static void -code_string (char const *string, char const *keyword, struct xheader *xhdr) -{ - char *outstr; - if (!utf8_convert (true, string, &outstr)) - { - /* FIXME: report error */ - outstr = xstrdup (string); - } - xheader_print (xhdr, keyword, outstr); - free (outstr); -} - -static void -decode_string (char **string, char const *arg) -{ - if (*string) - { - free (*string); - *string = NULL; - } - if (!utf8_convert (false, arg, string)) - { - /* FIXME: report error and act accordingly to --pax invalid=UTF-8 */ - assign_string (string, arg); - } -} - -static void -code_time (struct timespec t, char const *keyword, struct xheader *xhdr) -{ - char buf[TIMESPEC_STRSIZE_BOUND]; - xheader_print (xhdr, keyword, code_timespec (t, buf)); -} - -enum decode_time_status - { - decode_time_success, - decode_time_range, - decode_time_bad_header - }; - -static enum decode_time_status -_decode_time (struct timespec *ts, char const *arg, char const *keyword) -{ - time_t s; - unsigned long int ns = 0; - char *p; - char *arg_lim; - bool negative = *arg == '-'; - - errno = 0; - - if (ISDIGIT (arg[negative])) - { - if (negative) - { - intmax_t i = strtoimax (arg, &arg_lim, 10); - if (TYPE_SIGNED (time_t) ? i < TYPE_MINIMUM (time_t) : i < 0) - return decode_time_range; - s = i; - } - else - { - uintmax_t i = strtoumax (arg, &arg_lim, 10); - if (TYPE_MAXIMUM (time_t) < i) - return decode_time_range; - s = i; - } - - p = arg_lim; - - if (errno == ERANGE) - return decode_time_range; - - if (*p == '.') - { - int digits = 0; - bool trailing_nonzero = false; - - while (ISDIGIT (*++p)) - if (digits < LOG10_BILLION) - { - ns = 10 * ns + (*p - '0'); - digits++; - } - else - trailing_nonzero |= *p != '0'; - - while (digits++ < LOG10_BILLION) - ns *= 10; - - if (negative) - { - /* Convert "-1.10000000000001" to s == -2, ns == 89999999. - I.e., truncate time stamps towards minus infinity while - converting them to internal form. */ - ns += trailing_nonzero; - if (ns != 0) - { - if (s == TYPE_MINIMUM (time_t)) - return decode_time_range; - s--; - ns = BILLION - ns; - } - } - } - - if (! *p) - { - ts->tv_sec = s; - ts->tv_nsec = ns; - return decode_time_success; - } - } - - return decode_time_bad_header; -} - -static bool -decode_time (struct timespec *ts, char const *arg, char const *keyword) -{ - switch (_decode_time (ts, arg, keyword)) - { - case decode_time_success: - return true; - case decode_time_bad_header: - ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"), - keyword, arg)); - return false; - case decode_time_range: - out_of_range_header (keyword, arg, - (uintmax_t) TYPE_MINIMUM (time_t), - TYPE_MAXIMUM (time_t)); - return false; - } - return true; -} - - - -static void -code_num (uintmax_t value, char const *keyword, struct xheader *xhdr) -{ - char sbuf[UINTMAX_STRSIZE_BOUND]; - xheader_print (xhdr, keyword, umaxtostr (value, sbuf)); -} - -static bool -decode_num (uintmax_t *num, char const *arg, uintmax_t maxval, - char const *keyword) -{ - uintmax_t u; - char *arg_lim; - - if (! (ISDIGIT (*arg) - && (errno = 0, u = strtoumax (arg, &arg_lim, 10), !*arg_lim))) - { - ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"), - keyword, arg)); - return false; - } - - if (! (u <= maxval && errno != ERANGE)) - { - out_of_range_header (keyword, arg, 0, maxval); - return false; - } - - *num = u; - return true; -} - -static void -dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)), - char const *keyword __attribute__ ((unused)), - struct xheader *xhdr __attribute__ ((unused)), - void const *data __attribute__ ((unused))) -{ -} - -static void -dummy_decoder (struct tar_stat_info *st __attribute__ ((unused)), - char const *keyword __attribute__ ((unused)), - char const *arg __attribute__ ((unused)), - size_t size __attribute__((unused))) -{ -} - -static void -atime_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_time (st->atime, keyword, xhdr); -} - -static void -atime_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - struct timespec ts; - if (decode_time (&ts, arg, keyword)) - st->atime = ts; -} - -static void -gid_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_num (st->stat.st_gid, keyword, xhdr); -} - -static void -gid_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (gid_t), keyword)) - st->stat.st_gid = u; -} - -static void -gname_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_string (st->gname, keyword, xhdr); -} - -static void -gname_decoder (struct tar_stat_info *st, - char const *keyword __attribute__((unused)), - char const *arg, - size_t size __attribute__((unused))) -{ - decode_string (&st->gname, arg); -} - -static void -linkpath_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_string (st->link_name, keyword, xhdr); -} - -static void -linkpath_decoder (struct tar_stat_info *st, - char const *keyword __attribute__((unused)), - char const *arg, - size_t size __attribute__((unused))) -{ - decode_string (&st->link_name, arg); -} - -static void -ctime_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_time (st->ctime, keyword, xhdr); -} - -static void -ctime_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - struct timespec ts; - if (decode_time (&ts, arg, keyword)) - st->ctime = ts; -} - -static void -mtime_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - struct timespec const *mtime = data; - code_time (mtime ? *mtime : st->mtime, keyword, xhdr); -} - -static void -mtime_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - struct timespec ts; - if (decode_time (&ts, arg, keyword)) - st->mtime = ts; -} - -static void -path_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_string (st->file_name, keyword, xhdr); -} - -static void -path_decoder (struct tar_stat_info *st, - char const *keyword __attribute__((unused)), - char const *arg, - size_t size __attribute__((unused))) -{ - decode_string (&st->orig_file_name, arg); - decode_string (&st->file_name, arg); - st->had_trailing_slash = strip_trailing_slashes (st->file_name); -} - -static void -size_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_num (st->stat.st_size, keyword, xhdr); -} - -static void -size_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword)) - st->stat.st_size = u; -} - -static void -uid_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_num (st->stat.st_uid, keyword, xhdr); -} - -static void -uid_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (uid_t), keyword)) - st->stat.st_uid = u; -} - -static void -uname_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data __attribute__ ((unused))) -{ - code_string (st->uname, keyword, xhdr); -} - -static void -uname_decoder (struct tar_stat_info *st, - char const *keyword __attribute__((unused)), - char const *arg, - size_t size __attribute__((unused))) -{ - decode_string (&st->uname, arg); -} - -static void -sparse_size_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - size_coder (st, keyword, xhdr, data); -} - -static void -sparse_size_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword)) - st->stat.st_size = u; -} - -static void -sparse_numblocks_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, - void const *data __attribute__ ((unused))) -{ - code_num (st->sparse_map_avail, keyword, xhdr); -} - -static void -sparse_numblocks_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - uintmax_t u; - if (decode_num (&u, arg, SIZE_MAX, keyword)) - { - st->sparse_map_size = u; - st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]); - st->sparse_map_avail = 0; - } -} - -static void -sparse_offset_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - size_t const *pi = data; - code_num (st->sparse_map[*pi].offset, keyword, xhdr); -} - -static void -sparse_offset_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword)) - { - if (st->sparse_map_avail < st->sparse_map_size) - st->sparse_map[st->sparse_map_avail].offset = u; - else - ERROR ((0, 0, _("Malformed extended header: excess %s=%s"), - "GNU.sparse.offset", arg)); - } -} - -static void -sparse_numbytes_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - size_t const *pi = data; - code_num (st->sparse_map[*pi].numbytes, keyword, xhdr); -} - -static void -sparse_numbytes_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - uintmax_t u; - if (decode_num (&u, arg, SIZE_MAX, keyword)) - { - if (st->sparse_map_avail < st->sparse_map_size) - st->sparse_map[st->sparse_map_avail++].numbytes = u; - else - ERROR ((0, 0, _("Malformed extended header: excess %s=%s"), - keyword, arg)); - } -} - -static void -sparse_map_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size __attribute__((unused))) -{ - int offset = 1; - - st->sparse_map_avail = 0; - while (1) - { - uintmax_t u; - char *delim; - struct sp_array e; - - if (!ISDIGIT (*arg)) - { - ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"), - keyword, arg)); - return; - } - - errno = 0; - u = strtoumax (arg, &delim, 10); - if (offset) - { - e.offset = u; - if (!(u == e.offset && errno != ERANGE)) - { - out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (off_t)); - return; - } - } - else - { - e.numbytes = u; - if (!(u == e.numbytes && errno != ERANGE)) - { - out_of_range_header (keyword, arg, 0, TYPE_MAXIMUM (size_t)); - return; - } - if (st->sparse_map_avail < st->sparse_map_size) - st->sparse_map[st->sparse_map_avail++] = e; - else - { - ERROR ((0, 0, _("Malformed extended header: excess %s=%s"), - keyword, arg)); - return; - } - } - - offset = !offset; - - if (*delim == 0) - break; - else if (*delim != ',') - { - ERROR ((0, 0, - _("Malformed extended header: invalid %s: unexpected delimiter %c"), - keyword, *delim)); - return; - } - - arg = delim + 1; - } - - if (!offset) - ERROR ((0, 0, - _("Malformed extended header: invalid %s: odd number of values"), - keyword)); -} - -static void -dumpdir_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - xheader_print_n (xhdr, keyword, data, dumpdir_size (data)); -} - -static void -dumpdir_decoder (struct tar_stat_info *st, - char const *keyword __attribute__((unused)), - char const *arg, - size_t size) -{ - st->dumpdir = xmalloc (size); - memcpy (st->dumpdir, arg, size); -} - -static void -volume_label_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - code_string (data, keyword, xhdr); -} - -static void -volume_label_decoder (struct tar_stat_info *st, - char const *keyword __attribute__((unused)), - char const *arg, - size_t size __attribute__((unused))) -{ - decode_string (&volume_label, arg); -} - -static void -volume_size_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - off_t const *v = data; - code_num (*v, keyword, xhdr); -} - -static void -volume_size_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, size_t size) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword)) - continued_file_size = u; -} - -/* FIXME: Merge with volume_size_coder */ -static void -volume_offset_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - off_t const *v = data; - code_num (*v, keyword, xhdr); -} - -static void -volume_offset_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, size_t size) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (uintmax_t), keyword)) - continued_file_offset = u; -} - -static void -volume_filename_decoder (struct tar_stat_info *st, - char const *keyword __attribute__((unused)), - char const *arg, - size_t size __attribute__((unused))) -{ - decode_string (&continued_file_name, arg); -} - -static void -sparse_major_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - code_num (st->sparse_major, keyword, xhdr); -} - -static void -sparse_major_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword)) - st->sparse_major = u; -} - -static void -sparse_minor_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) -{ - code_num (st->sparse_minor, keyword, xhdr); -} - -static void -sparse_minor_decoder (struct tar_stat_info *st, - char const *keyword, - char const *arg, - size_t size) -{ - uintmax_t u; - if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword)) - st->sparse_minor = u; -} - -struct xhdr_tab const xhdr_tab[] = { - { "atime", atime_coder, atime_decoder, false }, - { "comment", dummy_coder, dummy_decoder, false }, - { "charset", dummy_coder, dummy_decoder, false }, - { "ctime", ctime_coder, ctime_decoder, false }, - { "gid", gid_coder, gid_decoder, false }, - { "gname", gname_coder, gname_decoder, false }, - { "linkpath", linkpath_coder, linkpath_decoder, false }, - { "mtime", mtime_coder, mtime_decoder, false }, - { "path", path_coder, path_decoder, false }, - { "size", size_coder, size_decoder, false }, - { "uid", uid_coder, uid_decoder, false }, - { "uname", uname_coder, uname_decoder, false }, - - /* Sparse file handling */ - { "GNU.sparse.name", path_coder, path_decoder, - true }, - { "GNU.sparse.major", sparse_major_coder, sparse_major_decoder, - true }, - { "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder, - true }, - { "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder, - true }, - { "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder, - true }, - - /* tar 1.14 - 1.15.90 keywords. */ - { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, true }, - /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x' - headers, and each of them was meaningful. It confilcted with POSIX specs, - which requires that "when extended header records conflict, the last one - given in the header shall take precedence." */ - { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, - true }, - { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, - true }, - /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ - { "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, - sparse_map_decoder, false }, - - { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, - true }, - - /* Keeps the tape/volume label. May be present only in the global headers. - Equivalent to GNUTYPE_VOLHDR. */ - { "GNU.volume.label", volume_label_coder, volume_label_decoder, true }, - - /* These may be present in a first global header of the archive. - They provide the same functionality as GNUTYPE_MULTIVOL header. - The GNU.volume.size keeps the real_s_sizeleft value, which is - otherwise kept in the size field of a multivolume header. The - GNU.volume.offset keeps the offset of the start of this volume, - otherwise kept in oldgnu_header.offset. */ - { "GNU.volume.filename", volume_label_coder, volume_filename_decoder, - true }, - { "GNU.volume.size", volume_size_coder, volume_size_decoder, true }, - { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, true }, - - { NULL, NULL, NULL, false } -};