diff options
Diffstat (limited to 'contrib/ntp/libopts')
42 files changed, 14934 insertions, 0 deletions
diff --git a/contrib/ntp/libopts/COPYING.lgpl b/contrib/ntp/libopts/COPYING.lgpl new file mode 100644 index 0000000..129c5de --- /dev/null +++ b/contrib/ntp/libopts/COPYING.lgpl @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library 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 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/contrib/ntp/libopts/COPYING.mbsd b/contrib/ntp/libopts/COPYING.mbsd new file mode 100644 index 0000000..8a70427 --- /dev/null +++ b/contrib/ntp/libopts/COPYING.mbsd @@ -0,0 +1,26 @@ +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. + + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. diff --git a/contrib/ntp/libopts/MakeDefs.inc b/contrib/ntp/libopts/MakeDefs.inc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/ntp/libopts/MakeDefs.inc diff --git a/contrib/ntp/libopts/Makefile.am b/contrib/ntp/libopts/Makefile.am new file mode 100644 index 0000000..5f138614 --- /dev/null +++ b/contrib/ntp/libopts/Makefile.am @@ -0,0 +1,24 @@ +## LIBOPTS Makefile +MAINTAINERCLEANFILES = Makefile.in +if INSTALL_LIBOPTS +lib_LTLIBRARIES = libopts.la +else +noinst_LTLIBRARIES = libopts.la +endif +libopts_la_SOURCES = libopts.c +libopts_la_CPPFLAGS = -I$(top_srcdir) +libopts_la_LDFLAGS = -version-info 29:0:4 +EXTRA_DIST = \ + COPYING.lgpl COPYING.mbsd MakeDefs.inc \ + README autoopts/options.h autoopts/usage-txt.h \ + autoopts.c autoopts.h boolean.c \ + compat/windows-config.h compat/compat.h compat/pathfind.c \ + compat/snprintf.c compat/strdup.c compat/strchr.c \ + configfile.c cook.c enumeration.c \ + environment.c genshell.c genshell.h \ + load.c m4/libopts.m4 m4/liboptschk.m4 \ + makeshell.c nested.c numeric.c \ + pgusage.c proto.h putshell.c \ + restore.c save.c sort.c \ + stack.c streqvcmp.c text_mmap.c \ + tokenize.c usage.c version.c diff --git a/contrib/ntp/libopts/Makefile.in b/contrib/ntp/libopts/Makefile.in new file mode 100644 index 0000000..06b52a2 --- /dev/null +++ b/contrib/ntp/libopts/Makefile.in @@ -0,0 +1,528 @@ +# Makefile.in generated by automake 1.9.6 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@ + +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@ +subdir = libopts +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \ + $(top_srcdir)/m4/define_dir.m4 \ + $(top_srcdir)/m4/hs_ulong_const.m4 \ + $(top_srcdir)/m4/os_cflags.m4 $(top_srcdir)/version.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) +libopts_la_LIBADD = +am_libopts_la_OBJECTS = libopts_la-libopts.lo +libopts_la_OBJECTS = $(am_libopts_la_OBJECTS) +@INSTALL_LIBOPTS_FALSE@am_libopts_la_rpath = +@INSTALL_LIBOPTS_TRUE@am_libopts_la_rpath = -rpath $(libdir) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libopts_la_SOURCES) +DIST_SOURCES = $(libopts_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +ARLIB_DIR = @ARLIB_DIR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINSUBDIR = @BINSUBDIR@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHUTEST = @CHUTEST@ +CLKTEST = @CLKTEST@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DCFD = @DCFD@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EF_LIBS = @EF_LIBS@ +EF_PROGS = @EF_PROGS@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_LIBOPTS_FALSE = @INSTALL_LIBOPTS_FALSE@ +INSTALL_LIBOPTS_TRUE = @INSTALL_LIBOPTS_TRUE@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCRYPTO = @LCRYPTO@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@ +LIBOPTS_DIR = @LIBOPTS_DIR@ +LIBOPTS_LDADD = @LIBOPTS_LDADD@ +LIBPARSE = @LIBPARSE@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MAKE_ADJTIMED = @MAKE_ADJTIMED@ +MAKE_CHECK_LAYOUT = @MAKE_CHECK_LAYOUT@ +MAKE_CHECK_Y2K = @MAKE_CHECK_Y2K@ +MAKE_LIBNTPSIM = @MAKE_LIBNTPSIM@ +MAKE_LIBPARSE = @MAKE_LIBPARSE@ +MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@ +MAKE_NTPDSIM = @MAKE_NTPDSIM@ +MAKE_NTPTIME = @MAKE_NTPTIME@ +MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ +MAKE_TICKADJ = @MAKE_TICKADJ@ +MAKE_TIMETRIM = @MAKE_TIMETRIM@ +NEED_LIBOPTS_FALSE = @NEED_LIBOPTS_FALSE@ +NEED_LIBOPTS_TRUE = @NEED_LIBOPTS_TRUE@ +OBJEXT = @OBJEXT@ +OPENSSL = @OPENSSL@ +OPENSSL_INC = @OPENSSL_INC@ +OPENSSL_LIB = @OPENSSL_LIB@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_PERL = @PATH_PERL@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PATH_SH = @PATH_SH@ +PROPDELAY = @PROPDELAY@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TESTDCF = @TESTDCF@ +U = @U@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_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@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +MAINTAINERCLEANFILES = Makefile.in +@INSTALL_LIBOPTS_TRUE@lib_LTLIBRARIES = libopts.la +@INSTALL_LIBOPTS_FALSE@noinst_LTLIBRARIES = libopts.la +libopts_la_SOURCES = libopts.c +libopts_la_CPPFLAGS = -I$(top_srcdir) +libopts_la_LDFLAGS = -version-info 29:0:4 +EXTRA_DIST = \ + COPYING.lgpl COPYING.mbsd MakeDefs.inc \ + README autoopts/options.h autoopts/usage-txt.h \ + autoopts.c autoopts.h boolean.c \ + compat/windows-config.h compat/compat.h compat/pathfind.c \ + compat/snprintf.c compat/strdup.c compat/strchr.c \ + configfile.c cook.c enumeration.c \ + environment.c genshell.c genshell.h \ + load.c m4/libopts.m4 m4/liboptschk.m4 \ + makeshell.c nested.c numeric.c \ + pgusage.c proto.h putshell.c \ + restore.c save.c sort.c \ + stack.c streqvcmp.c text_mmap.c \ + tokenize.c usage.c version.c + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(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) --foreign libopts/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign libopts/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 +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_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 + +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 +libopts.la: $(libopts_la_OBJECTS) $(libopts_la_DEPENDENCIES) + $(LINK) $(am_libopts_la_rpath) $(libopts_la_LDFLAGS) $(libopts_la_OBJECTS) $(libopts_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libopts_la-libopts.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.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 $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.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 `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libopts_la-libopts.lo: libopts.c +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopts_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libopts_la-libopts.lo -MD -MP -MF "$(DEPDIR)/libopts_la-libopts.Tpo" -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libopts_la-libopts.Tpo" "$(DEPDIR)/libopts_la-libopts.Plo"; else rm -f "$(DEPDIR)/libopts_la-libopts.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libopts.c' object='libopts_la-libopts.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopts_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +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)/autoopts $(distdir)/compat $(distdir)/m4 + @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: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: 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: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-libLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool 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-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-info-am uninstall-libLTLIBRARIES + +# 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/contrib/ntp/libopts/README b/contrib/ntp/libopts/README new file mode 100644 index 0000000..7cbe0b0 --- /dev/null +++ b/contrib/ntp/libopts/README @@ -0,0 +1,93 @@ + THIS TARBALL IS NOT A FULL DISTRIBUTION. + +The contents of this tarball is designed to be incorporated into +software packages that utilize the AutoOpts option automation +package and are intended to be installed on systems that may not +have libopts installed. It is redistributable under the terms +of either the LGPL (see COPYING.lgpl) or under the terms of +the advertising clause free BSD license (see COPYING.mbsd). + +Usage Instructions for autoconf/automake/libtoolized projects: + +1. Install the unrolled tarball into your package source tree, + copying ``libopts.m4'' to your autoconf macro directory. + + In your bootstrap (pre-configure) script, you can do this: + + rm -rf libopts libopts-* + gunzip -c `autoopts-config libsrc` | tar -xvf - + mv -f libopts-*.*.* libopts + cp -fp libopts/m4/*.m4 m4/. + + I tend to put my configure auxiliary files in "m4". + Whatever directory you choose, if it is not ".", then + be sure to tell autoconf about it with: + + AC_CONFIG_AUX_DIR(m4) + + This is one macro where you *MUST* remember to *NOT* quote + the argument. If you do, automake will get lost. + +2. Add the following to your ``configure.ac'' file: + + LIBOPTS_CHECK + + or: + + LIBOPTS_CHECK([relative/path/to/libopts]) + + This macro will automatically invoke + + AC_CONFIG_FILES( [relative/path/to/libopts/Makefile] ) + + The default ``relative/path/to/libopts'' is simply + ``libopts''. + +3. Add the following to your top level ``Makefile.am'' file: + + if NEED_LIBOPTS + SUBDIRS += $(LIBOPTS_DIR) + endif + + where ``<...>'' can be whatever other files or directories + you may need. The SUBDIRS must be properly ordered. + *PLEASE NOTE* it is crucial that the SUBDIRS be set under the + control of an automake conditional. To work correctly, + automake has to know the range of possible values of SUBDIRS. + It's a magical name with magical properties. ``NEED_LIBOPTS'' + will be correctly set by the ``LIBOPTS_CHECK'' macro, above. + +4. Add ``$(LIBOPTS_CFLAGS)'' to relevant compiler flags and + ``$(LIBOPTS_LDADD)'' to relevant link options whereever + you need them in your build tree. + +5. Make sure your object files explicitly depend upon the + generated options header file. e.g.: + + $(prog_OBJECTS) : prog-opts.h + prog-opts.h : prog-opts.c + prog-opts.c : prog-opts.def + autogen prog-opts.def + +6. *OPTIONAL* -- + If you are creating man pages and texi documentation from + the program options, you will need these rules somewhere, too: + + man_MANS = prog.1 + prog.1 : prog-opts.def + autogen -Tagman1.tpl -bprog prog-opts.def + + prog-invoke.texi : prog-opts.def + autogen -Taginfo.tpl -bprog-invoke prog-opts.def + +If your package does not utilize the auto* tools, then you +will need to hand craft the rules for building the library. + +LICENSING: + +This material is copyright 1993-2007 by Bruce Korb. +You are licensed to use this under the terms of either +the GNU Lesser General Public License (see: COPYING.lgpl), or, +at your option, the modified Berkeley Software Distribution +License (see: COPYING.mbsd). Both of these files should be +included with this tarball. diff --git a/contrib/ntp/libopts/autoopts.c b/contrib/ntp/libopts/autoopts.c new file mode 100644 index 0000000..139841b --- /dev/null +++ b/contrib/ntp/libopts/autoopts.c @@ -0,0 +1,1120 @@ + +/* + * $Id: autoopts.c,v 4.25 2007/04/15 19:01:18 bkorb Exp $ + * Time-stamp: "2007-04-15 11:10:40 bkorb" + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +static char const zNil[] = ""; + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static tSuccess +findOptDesc( tOptions* pOpts, tOptState* pOptState ); + +static tSuccess +nextOption( tOptions* pOpts, tOptState* pOptState ); + +static tSuccess +doPresets( tOptions* pOpts ); + +static int +checkConsistency( tOptions* pOpts ); +/* = = = END-STATIC-FORWARD = = = */ + +LOCAL void * +ao_malloc( size_t sz ) +{ + void * res = malloc(sz); + if (res == NULL) { + fprintf( stderr, "malloc of %d bytes failed\n", (int)sz ); + exit( EXIT_FAILURE ); + } + return res; +} +#undef malloc +#define malloc(_s) ao_malloc(_s) + +LOCAL void * +ao_realloc( void *p, size_t sz ) +{ + void * res = realloc(p, sz); + if (res == NULL) { + fprintf( stderr, "realloc of %d bytes at 0x%p failed\n", (int)sz, p ); + exit( EXIT_FAILURE ); + } + return res; +} +#undef realloc +#define realloc(_p,_s) ao_realloc(_p,_s) + + +LOCAL void +ao_free( void *p ) +{ + if (p != NULL) + free(p); +} +#undef free +#define free(_p) ao_free(_p) + + +LOCAL char * +ao_strdup( char const *str ) +{ + char * res = strdup(str); + if (res == NULL) { + fprintf( stderr, "strdup of %d byte string failed\n", (int)strlen(str) ); + exit( EXIT_FAILURE ); + } + return res; +} +#undef strdup +#define strdup(_p) ao_strdup(_p) + +#ifndef HAVE_PATHFIND +# include "compat/pathfind.c" +#endif + +#ifndef HAVE_SNPRINTF +# include "compat/snprintf.c" +#endif + +#ifndef HAVE_STRDUP +# include "compat/strdup.c" +#endif + +#ifndef HAVE_STRCHR +# include "compat/strchr.c" +#endif + +/* + * handleOption + * + * This routine handles equivalencing, sets the option state flags and + * invokes the handler procedure, if any. + */ +LOCAL tSuccess +handleOption( tOptions* pOpts, tOptState* pOptState ) +{ + /* + * Save a copy of the option procedure pointer. + * If this is an equivalence class option, we still want this proc. + */ + tOptDesc* pOD = pOptState->pOD; + tOptProc* pOP = pOD->pOptProc; + if (pOD->fOptState & OPTST_ALLOC_ARG) + AGFREE(pOD->optArg.argString); + + pOD->optArg.argString = pOptState->pzOptArg; + + /* + * IF we are presetting options, then we will ignore any un-presettable + * options. They are the ones either marked as such. + */ + if ( ((pOpts->fOptSet & OPTPROC_PRESETTING) != 0) + && ((pOD->fOptState & OPTST_NO_INIT) != 0) + ) + return PROBLEM; + + /* + * IF this is an equivalence class option, + * THEN + * Save the option value that got us to this option + * entry. (It may not be pOD->optChar[0], if this is an + * equivalence entry.) + * set the pointer to the equivalence class base + */ + if (pOD->optEquivIndex != NO_EQUIVALENT) { + tOptDesc* p = pOpts->pOptDesc + pOD->optEquivIndex; + + /* + * IF the current option state has not been defined (set on the + * command line), THEN we will allow continued resetting of + * the value. Once "defined", then it must not change. + */ + if ((pOD->fOptState & OPTST_DEFINED) != 0) { + /* + * The equivalenced-to option has been found on the command + * line before. Make sure new occurrences are the same type. + * + * IF this option has been previously equivalenced and + * it was not the same equivalenced-to option, + * THEN we have a usage problem. + */ + if (p->optActualIndex != pOD->optIndex) { + fprintf( stderr, (char*)zMultiEquiv, p->pz_Name, pOD->pz_Name, + (pOpts->pOptDesc + p->optActualIndex)->pz_Name); + return FAILURE; + } + } else { + /* + * Set the equivalenced-to actual option index to no-equivalent + * so that we set all the entries below. This option may either + * never have been selected before, or else it was selected by + * some sort of "presetting" mechanism. + */ + p->optActualIndex = NO_EQUIVALENT; + } + + if (p->optActualIndex != pOD->optIndex) { + /* + * First time through, copy over the state + * and add in the equivalence flag + */ + p->optActualValue = pOD->optValue; + p->optActualIndex = pOD->optIndex; + pOptState->flags |= OPTST_EQUIVALENCE; + } + + /* + * Copy the most recent option argument. set membership state + * is kept in ``p->optCookie''. Do not overwrite. + */ + p->optArg.argString = pOD->optArg.argString; + pOD = p; + + } else { + pOD->optActualValue = pOD->optValue; + pOD->optActualIndex = pOD->optIndex; + } + + pOD->fOptState &= OPTST_PERSISTENT_MASK; + pOD->fOptState |= (pOptState->flags & ~OPTST_PERSISTENT_MASK); + + /* + * Keep track of count only for DEFINED (command line) options. + * IF we have too many, build up an error message and bail. + */ + if ( (pOD->fOptState & OPTST_DEFINED) + && (++pOD->optOccCt > pOD->optMaxCt) ) { + + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + char const * pzEqv = + (pOD->optEquivIndex != NO_EQUIVALENT) ? zEquiv : zNil; + + fputs( zErrOnly, stderr ); + + if (pOD->optMaxCt > 1) + fprintf(stderr, zAtMost, pOD->optMaxCt, pOD->pz_Name, pzEqv); + else + fprintf(stderr, zOnlyOne, pOD->pz_Name, pzEqv); + } + + return FAILURE; + } + + /* + * If provided a procedure to call, call it + */ + if (pOP != (tpOptProc)NULL) + (*pOP)( pOpts, pOD ); + + return SUCCESS; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * HUNT FOR OPTIONS IN THE ARGUMENT LIST + * + * The next four procedures are "private" to nextOption(). + * nextOption() uses findOptDesc() to find the next descriptor and it, in + * turn, uses longOptionFind() and shortOptionFind() to actually do the hunt. + * + * longOptionFind + * + * Find the long option descriptor for the current option + */ +LOCAL tSuccess +longOptionFind( tOptions* pOpts, char* pzOptName, tOptState* pOptState ) +{ + ag_bool disable = AG_FALSE; + char* pzEq = strchr( pzOptName, '=' ); + tOptDesc* pOD = pOpts->pOptDesc; + int idx = 0; + int idxLim = pOpts->optCt; + int matchCt = 0; + int matchIdx = 0; + int nameLen; + + /* + * IF the value is attached to the name, + * THEN clip it off. + * Either way, figure out how long our name is + */ + if (pzEq != NULL) { + nameLen = (int)(pzEq - pzOptName); + *pzEq = NUL; + } else nameLen = strlen( pzOptName ); + + do { + if (SKIP_OPT(pOD)) + continue; + + if (strneqvcmp( pzOptName, pOD->pz_Name, nameLen ) == 0) { + /* + * IF we have a complete match + * THEN it takes priority over any already located partial + */ + if (pOD->pz_Name[ nameLen ] == NUL) { + matchCt = 1; + matchIdx = idx; + break; + } + } + + /* + * IF there is a disable name + * *AND* no argument value has been supplied + * (disabled options may have no argument) + * *AND* the option name matches the disable name + * THEN ... + */ + else if ( (pOD->pz_DisableName != NULL) + && (strneqvcmp(pzOptName, pOD->pz_DisableName, nameLen) == 0) + ) { + disable = AG_TRUE; + + /* + * IF we have a complete match + * THEN it takes priority over any already located partial + */ + if (pOD->pz_DisableName[ nameLen ] == NUL) { + matchCt = 1; + matchIdx = idx; + break; + } + } + + else + continue; + + /* + * We found a partial match, either regular or disabling. + * Remember the index for later. + */ + matchIdx = idx; + + if (++matchCt > 1) + break; + + } while (pOD++, (++idx < idxLim)); + + if (pzEq != NULL) + *(pzEq++) = '='; + + /* + * Make sure we either found an exact match or found only one partial + */ + if (matchCt == 1) { + /* + * IF we found a disablement name, + * THEN set the bit in the callers' flag word + */ + if (disable) + pOptState->flags |= OPTST_DISABLED; + + pOptState->pOD = pOpts->pOptDesc + matchIdx; + pOptState->pzOptArg = pzEq; + pOptState->optType = TOPT_LONG; + return SUCCESS; + } + + /* + * IF there is no equal sign + * *AND* we are using named arguments + * *AND* there is a default named option, + * THEN return that option. + */ + if ( (pzEq == NULL) + && NAMED_OPTS(pOpts) + && (pOpts->specOptIdx.default_opt != NO_EQUIVALENT)) { + pOptState->pOD = pOpts->pOptDesc + pOpts->specOptIdx.default_opt; + + pOptState->pzOptArg = pzOptName; + pOptState->optType = TOPT_DEFAULT; + return SUCCESS; + } + + /* + * IF we are to stop on errors (the default, actually) + * THEN call the usage procedure. + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf( stderr, zIllOptStr, pOpts->pzProgPath, + (matchCt == 0) ? zIllegal : zAmbiguous, pzOptName ); + (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE ); + } + + return FAILURE; +} + + +/* + * shortOptionFind + * + * Find the short option descriptor for the current option + */ +LOCAL tSuccess +shortOptionFind( tOptions* pOpts, uint_t optValue, tOptState* pOptState ) +{ + tOptDesc* pRes = pOpts->pOptDesc; + int ct = pOpts->optCt; + + /* + * Search the option list + */ + for (;;) { + /* + * IF the values match, + * THEN we stop here + */ + if ((! SKIP_OPT(pRes)) && (optValue == pRes->optValue)) { + pOptState->pOD = pRes; + pOptState->optType = TOPT_SHORT; + return SUCCESS; + } + + /* + * Advance to next option description + */ + pRes++; + + /* + * IF we have searched everything, ... + */ + if (--ct <= 0) + break; + } + + /* + * IF the character value is a digit + * AND there is a special number option ("-n") + * THEN the result is the "option" itself and the + * option is the specially marked "number" option. + */ + if ( isdigit( optValue ) + && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) { + pOptState->pOD = \ + pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option; + (pOpts->pzCurOpt)--; + pOptState->optType = TOPT_SHORT; + return SUCCESS; + } + + /* + * IF we are to stop on errors (the default, actually) + * THEN call the usage procedure. + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf( stderr, zIllOptChr, pOpts->pzProgPath, optValue ); + (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE ); + } + + return FAILURE; +} + + +/* + * findOptDesc + * + * Find the option descriptor for the current option + */ +static tSuccess +findOptDesc( tOptions* pOpts, tOptState* pOptState ) +{ + /* + * IF we are continuing a short option list (e.g. -xyz...) + * THEN continue a single flag option. + * OTHERWISE see if there is room to advance and then do so. + */ + if ((pOpts->pzCurOpt != NULL) && (*pOpts->pzCurOpt != NUL)) + return shortOptionFind( pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState ); + + if (pOpts->curOptIdx >= pOpts->origArgCt) + return PROBLEM; /* NORMAL COMPLETION */ + + pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx ]; + + /* + * IF all arguments must be named options, ... + */ + if (NAMED_OPTS(pOpts)) { + char* pz = pOpts->pzCurOpt; + pOpts->curOptIdx++; + + /* + * Skip over any flag/option markers. + * In this mode, they are not required. + */ + while (*pz == '-') pz++; + + return longOptionFind( pOpts, pz, pOptState ); + } + + /* + * Note the kind of flag/option marker + */ + if (*((pOpts->pzCurOpt)++) != '-') + return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ + + /* + * Special hack for a hyphen by itself + */ + if (*(pOpts->pzCurOpt) == NUL) + return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ + + /* + * The current argument is to be processed as an option argument + */ + pOpts->curOptIdx++; + + /* + * We have an option marker. + * Test the next character for long option indication + */ + if (pOpts->pzCurOpt[0] == '-') { + if (*++(pOpts->pzCurOpt) == NUL) + /* + * NORMAL COMPLETION - NOT this arg, but rest are operands + */ + return PROBLEM; + + /* + * We do not allow the hyphen to be used as a flag value. + * Therefore, if long options are not to be accepted, we punt. + */ + if ((pOpts->fOptSet & OPTPROC_LONGOPT) == 0) { + fprintf( stderr, zIllOptStr, pOpts->pzProgPath, + zIllegal, pOpts->pzCurOpt-2 ); + return FAILURE; + } + + return longOptionFind( pOpts, pOpts->pzCurOpt, pOptState ); + } + + /* + * If short options are not allowed, then do long + * option processing. Otherwise the character must be a + * short (i.e. single character) option. + */ + if ((pOpts->fOptSet & OPTPROC_SHORTOPT) != 0) + return shortOptionFind( pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState ); + + return longOptionFind( pOpts, pOpts->pzCurOpt, pOptState ); +} + + +/* + * nextOption + * + * Find the option descriptor and option argument (if any) for the + * next command line argument. DO NOT modify the descriptor. Put + * all the state in the state argument so that the option can be skipped + * without consequence (side effect). + */ +static tSuccess +nextOption( tOptions* pOpts, tOptState* pOptState ) +{ + tSuccess res; + enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE; + teOptArgType at; + + res = findOptDesc( pOpts, pOptState ); + if (! SUCCESSFUL( res )) + return res; + pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK); + at = OPTST_GET_ARGTYPE(pOptState->flags); + + /* + * Figure out what to do about option arguments. An argument may be + * required, not associated with the option, or be optional. We detect the + * latter by examining for an option marker on the next possible argument. + * Disabled mode option selection also disables option arguments. + */ + if ((pOptState->flags & OPTST_DISABLED) != 0) + arg_type = ARG_NONE; + else if (at == OPARG_TYPE_NONE) + arg_type = ARG_NONE; + else if (pOptState->flags & OPTST_ARG_OPTIONAL) + arg_type = ARG_MAY; + else + arg_type = ARG_MUST; + + switch (arg_type) { + case ARG_MUST: + /* + * An option argument is required. Long options can either have + * a separate command line argument, or an argument attached by + * the '=' character. Figure out which. + */ + switch (pOptState->optType) { + case TOPT_SHORT: + /* + * See if an arg string follows the flag character + */ + if (*++(pOpts->pzCurOpt) == NUL) + pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx++ ]; + pOptState->pzOptArg = pOpts->pzCurOpt; + break; + + case TOPT_LONG: + /* + * See if an arg string has already been assigned (glued on + * with an `=' character) + */ + if (pOptState->pzOptArg == NULL) + pOptState->pzOptArg = pOpts->origArgVect[ pOpts->curOptIdx++ ]; + break; + + default: +#ifdef DEBUG + fputs( "AutoOpts lib error: option type not selected\n", + stderr ); + exit( EXIT_FAILURE ); +#endif + + case TOPT_DEFAULT: + /* + * The option was selected by default. The current token is + * the option argument. + */ + break; + } + + /* + * Make sure we did not overflow the argument list. + */ + if (pOpts->curOptIdx > pOpts->origArgCt) { + fprintf( stderr, zMisArg, pOpts->pzProgPath, + pOptState->pOD->pz_Name ); + return FAILURE; + } + + pOpts->pzCurOpt = NULL; /* next time advance to next arg */ + break; + + case ARG_MAY: + /* + * An option argument is optional. + */ + switch (pOptState->optType) { + case TOPT_SHORT: + if (*++pOpts->pzCurOpt != NUL) + pOptState->pzOptArg = pOpts->pzCurOpt; + else { + char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; + + /* + * BECAUSE it is optional, we must make sure + * we did not find another flag and that there + * is such an argument. + */ + if ((pzLA == NULL) || (*pzLA == '-')) + pOptState->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + pOptState->pzOptArg = pzLA; + } + } + break; + + case TOPT_LONG: + /* + * Look for an argument if we don't already have one (glued on + * with a `=' character) *AND* we are not in named argument mode + */ + if ( (pOptState->pzOptArg == NULL) + && (! NAMED_OPTS(pOpts))) { + char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; + + /* + * BECAUSE it is optional, we must make sure + * we did not find another flag and that there + * is such an argument. + */ + if ((pzLA == NULL) || (*pzLA == '-')) + pOptState->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + pOptState->pzOptArg = pzLA; + } + } + break; + + default: + case TOPT_DEFAULT: + fputs( "AutoOpts lib error: defaulted to option with optional arg\n", + stderr ); + exit( EX_SOFTWARE ); + } + + /* + * After an option with an optional argument, we will + * *always* start with the next option because if there + * were any characters following the option name/flag, + * they would be interpreted as the argument. + */ + pOpts->pzCurOpt = NULL; + break; + + default: /* CANNOT */ + /* + * No option argument. Make sure next time around we find + * the correct option flag character for short options + */ + if (pOptState->optType == TOPT_SHORT) + (pOpts->pzCurOpt)++; + + /* + * It is a long option. Make sure there was no ``=xxx'' argument + */ + else if (pOptState->pzOptArg != NULL) { + fprintf( stderr, zNoArg, pOpts->pzProgPath, + pOptState->pOD->pz_Name ); + return FAILURE; + } + + /* + * It is a long option. Advance to next command line argument. + */ + else + pOpts->pzCurOpt = NULL; + } + + return SUCCESS; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * DO PRESETS + * + * The next several routines do the immediate action pass on the command + * line options, then the environment variables, then the config files in + * reverse order. Once done with that, the order is reversed and all + * the config files and environment variables are processed again, this + * time only processing the non-immediate action options. doPresets() + * will then return for optionProcess() to do the final pass on the command + * line arguments. + */ + +/* + * doImmediateOpts - scan the command line for immediate action options + */ +LOCAL tSuccess +doImmediateOpts( tOptions* pOpts ) +{ + pOpts->curOptIdx = 1; /* start by skipping program name */ + pOpts->pzCurOpt = NULL; + + /* + * Examine all the options from the start. We process any options that + * are marked for immediate processing. + */ + for (;;) { + tOptState optState = OPTSTATE_INITIALIZER(PRESET); + + switch (nextOption( pOpts, &optState )) { + case FAILURE: goto optionsDone; + case PROBLEM: return SUCCESS; /* no more args */ + case SUCCESS: break; + } + + /* + * IF this *is* an immediate-attribute option, then do it. + */ + if (! DO_IMMEDIATELY(optState.flags)) + continue; + + if (! SUCCESSFUL( handleOption( pOpts, &optState ))) + break; + } optionsDone:; + + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE ); + return FAILURE; +} + + +LOCAL tSuccess +doRegularOpts( tOptions* pOpts ) +{ + /* + * Now, process all the options from our current position onward. + * (This allows interspersed options and arguments for the few + * non-standard programs that require it.) + */ + for (;;) { + tOptState optState = OPTSTATE_INITIALIZER(DEFINED); + + switch (nextOption( pOpts, &optState )) { + case FAILURE: goto optionsDone; + case PROBLEM: return SUCCESS; /* no more args */ + case SUCCESS: break; + } + + /* + * IF this is not being processed normally (i.e. is immediate action) + * THEN skip it (unless we are supposed to do it a second time). + */ + if (! DO_NORMALLY(optState.flags)) { + if (! DO_SECOND_TIME(optState.flags)) + continue; + optState.pOD->optOccCt--; /* don't count last time */ + } + + if (! SUCCESSFUL( handleOption( pOpts, &optState ))) + break; + } optionsDone:; + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE ); + return FAILURE; +} + + +/* + * doPresets - check for preset values from a config file or the envrionment + */ +static tSuccess +doPresets( tOptions* pOpts ) +{ + tOptDesc * pOD = NULL; + + if (! SUCCESSFUL( doImmediateOpts( pOpts ))) + return FAILURE; + + /* + * IF this option set has a --save-opts option, then it also + * has a --load-opts option. See if a command line option has disabled + * option presetting. + */ + if (pOpts->specOptIdx.save_opts != 0) { + pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1; + if (DISABLED_OPT(pOD)) + return SUCCESS; + } + + /* + * Until we return from this procedure, disable non-presettable opts + */ + pOpts->fOptSet |= OPTPROC_PRESETTING; + /* + * IF there are no config files, + * THEN do any environment presets and leave. + */ + if (pOpts->papzHomeList == NULL) { + doEnvPresets( pOpts, ENV_ALL ); + } + else { + doEnvPresets( pOpts, ENV_IMM ); + + /* + * Check to see if environment variables have disabled presetting. + */ + if ((pOD != NULL) && ! DISABLED_OPT(pOD)) + internalFileLoad( pOpts ); + + /* + * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment + * variable options. Only the loading of .rc files. + */ + doEnvPresets( pOpts, ENV_NON_IMM ); + } + pOpts->fOptSet &= ~OPTPROC_PRESETTING; + + return SUCCESS; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * VERIFY OPTION CONSISTENCY + * + * Make sure that the argument list passes our consistency tests. + */ +static int +checkConsistency( tOptions* pOpts ) +{ + int errCt = 0; + tOptDesc* pOD = pOpts->pOptDesc; + int oCt = pOpts->presetOptCt; + + /* + * FOR each of "oCt" options, ... + */ + for (;;) { + const int* pMust = pOD->pOptMust; + const int* pCant = pOD->pOptCant; + + /* + * IF the current option was provided on the command line + * THEN ensure that any "MUST" requirements are not + * "DEFAULT" (unspecified) *AND* ensure that any + * "CANT" options have not been SET or DEFINED. + */ + if (SELECTED_OPT(pOD)) { + if (pMust != NULL) for (;;) { + tOptDesc* p = pOpts->pOptDesc + *(pMust++); + if (UNUSED_OPT(p)) { + const tOptDesc* pN = pOpts->pOptDesc + pMust[-1]; + errCt++; + fprintf( stderr, zReqFmt, pOD->pz_Name, pN->pz_Name ); + } + + if (*pMust == NO_EQUIVALENT) + break; + } + + if (pCant != NULL) for (;;) { + tOptDesc* p = pOpts->pOptDesc + *(pCant++); + if (SELECTED_OPT(p)) { + const tOptDesc* pN = pOpts->pOptDesc + pCant[-1]; + errCt++; + fprintf( stderr, zCantFmt, pOD->pz_Name, pN->pz_Name ); + } + + if (*pCant == NO_EQUIVALENT) + break; + } + } + + /* + * IF this option is not equivalenced to another, + * OR it is equivalenced to itself (is the equiv. root) + * THEN we need to make sure it occurs often enough. + */ + if ( (pOD->optEquivIndex == NO_EQUIVALENT) + || (pOD->optEquivIndex == pOD->optIndex) ) do { + /* + * IF the occurrence counts have been satisfied, + * THEN there is no problem. + */ + if (pOD->optOccCt >= pOD->optMinCt) + break; + + /* + * IF MUST_SET means SET and PRESET are okay, + * so min occurrence count doesn't count + */ + if ( (pOD->fOptState & OPTST_MUST_SET) + && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) ) + break; + + errCt++; + if (pOD->optMinCt > 1) + fprintf( stderr, zNotEnough, pOD->pz_Name, pOD->optMinCt ); + else fprintf( stderr, zNeedOne, pOD->pz_Name ); + } while (0); + + if (--oCt <= 0) + break; + pOD++; + } + + /* + * IF we are stopping on errors, check to see if any remaining + * arguments are required to be there or prohibited from being there. + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + + /* + * Check for prohibition + */ + if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) { + if (pOpts->origArgCt > pOpts->curOptIdx) { + fprintf( stderr, zNoArgs, pOpts->pzProgName ); + ++errCt; + } + } + + /* + * ELSE not prohibited, check for being required + */ + else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) { + if (pOpts->origArgCt <= pOpts->curOptIdx) { + fprintf( stderr, zArgsMust, pOpts->pzProgName ); + ++errCt; + } + } + } + + return errCt; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE + */ +/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ +/*=* + * library: opts + * header: your-opts.h + * + * lib_description: + * + * These are the routines that libopts users may call directly from their + * code. There are several other routines that can be called by code + * generated by the libopts option templates, but they are not to be + * called from any other user code. The @file{options.h} header is + * fairly clear about this, too. +=*/ + +/*=export_func optionProcess + * + * what: this is the main option processing routine + * + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + argc + program arg count + + * arg: + char** + argv + program arg vector + + * + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: + * + * This is the main entry point for processing options. It is intended + * that this procedure be called once at the beginning of the execution of + * a program. Depending on options selected earlier, it is sometimes + * necessary to stop and restart option processing, or to select completely + * different sets of options. This can be done easily, but you generally + * do not want to do this. + * + * The number of arguments processed always includes the program name. + * If one of the arguments is "--", then it is counted and the processing + * stops. If an error was encountered and errors are to be tolerated, then + * the returned value is the index of the argument causing the error. + * A hyphen by itself ("-") will also cause processing to stop and will + * @emph{not} be counted among the processed arguments. A hyphen by itself + * is treated as an operand. Encountering an operand stops option + * processing. + * + * err: Errors will cause diagnostics to be printed. @code{exit(3)} may + * or may not be called. It depends upon whether or not the options + * were generated with the "allow-errors" attribute, or if the + * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. +=*/ +int +optionProcess( + tOptions* pOpts, + int argCt, + char** argVect ) +{ + if (! SUCCESSFUL( validateOptionsStruct( pOpts, argVect[0] ))) + exit( EX_SOFTWARE ); + + /* + * Establish the real program name, the program full path, + * and do all the presetting the first time thru only. + */ + if ((pOpts->fOptSet & OPTPROC_INITDONE) == 0) { + pOpts->origArgCt = argCt; + pOpts->origArgVect = argVect; + pOpts->fOptSet |= OPTPROC_INITDONE; + + if (! SUCCESSFUL( doPresets( pOpts ))) + return 0; + + if ((pOpts->fOptSet & OPTPROC_REORDER) != 0) + optionSort( pOpts ); + + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + } + + /* + * IF we are (re)starting, + * THEN reset option location + */ + else if (pOpts->curOptIdx <= 0) { + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + } + + if (! SUCCESSFUL( doRegularOpts( pOpts ))) + return pOpts->origArgCt; + + /* + * IF there were no errors + * AND we have RC/INI files + * AND there is a request to save the files + * THEN do that now before testing for conflicts. + * (conflicts are ignored in preset options) + */ + if (pOpts->specOptIdx.save_opts != 0) { + tOptDesc* pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts; + + if (SELECTED_OPT( pOD )) { + optionSaveFile( pOpts ); + exit( EXIT_SUCCESS ); + } + } + + /* + * IF we are checking for errors, + * THEN look for too few occurrences of required options + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + if (checkConsistency( pOpts ) != 0) + (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE ); + } + + return pOpts->curOptIdx; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/autoopts.c */ diff --git a/contrib/ntp/libopts/autoopts.h b/contrib/ntp/libopts/autoopts.h new file mode 100644 index 0000000..2645757 --- /dev/null +++ b/contrib/ntp/libopts/autoopts.h @@ -0,0 +1,387 @@ + +/* + * Time-stamp: "2007-04-15 09:59:39 bkorb" + * + * autoopts.h $Id: autoopts.h,v 4.23 2007/04/15 19:01:18 bkorb Exp $ + * Time-stamp: "2005-02-14 05:59:50 bkorb" + * + * This file defines all the global structures and special values + * used in the automated option processing library. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +#ifndef AUTOGEN_AUTOOPTS_H +#define AUTOGEN_AUTOOPTS_H + +#include "compat/compat.h" + +#define AO_NAME_LIMIT 127 +#define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1)) + +#ifndef AG_PATH_MAX +# ifdef PATH_MAX +# define AG_PATH_MAX ((size_t)PATH_MAX) +# else +# define AG_PATH_MAX ((size_t)4096) +# endif +#else +# if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN) +# undef AG_PATH_MAX +# define AG_PATH_MAX ((size_t)PATH_MAX) +# endif +#endif + +#undef EXPORT +#define EXPORT + +#if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +#else +# define DIRCH '/' +#endif + +#ifndef EX_NOINPUT +# define EX_NOINPUT 66 +#endif +#ifndef EX_SOFTWARE +# define EX_SOFTWARE 70 +#endif +#ifndef EX_CONFIG +# define EX_CONFIG 78 +#endif + +/* + * Convert the number to a list usable in a printf call + */ +#define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F + +#define NAMED_OPTS(po) \ + (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0) + +#define SKIP_OPT(p) (((p)->fOptState & (OPTST_DOCUMENT|OPTST_OMITTED)) != 0) + +typedef int tDirection; +#define DIRECTION_PRESET -1 +#define DIRECTION_PROCESS 1 +#define DIRECTION_CALLED 0 + +#define PROCESSING(d) ((d)>0) +#define PRESETTING(d) ((d)<0) + +#define ISNAMECHAR( c ) (isalnum(c) || ((c) == '_') || ((c) == '-')) + +/* + * Procedure success codes + * + * USAGE: define procedures to return "tSuccess". Test their results + * with the SUCCEEDED, FAILED and HADGLITCH macros. + * + * Microsoft sticks its nose into user space here, so for Windows' sake, + * make sure all of these are undefined. + */ +#undef SUCCESS +#undef FAILURE +#undef PROBLEM +#undef SUCCEEDED +#undef SUCCESSFUL +#undef FAILED +#undef HADGLITCH + +#define SUCCESS ((tSuccess) 0) +#define FAILURE ((tSuccess)-1) +#define PROBLEM ((tSuccess) 1) + +typedef int tSuccess; + +#define SUCCEEDED( p ) ((p) == SUCCESS) +#define SUCCESSFUL( p ) SUCCEEDED( p ) +#define FAILED( p ) ((p) < SUCCESS) +#define HADGLITCH( p ) ((p) > SUCCESS) + +/* + * When loading a line (or block) of text as an option, the value can + * be processed in any of several modes: + * + * @table @samp + * @item keep + * Every part of the value between the delimiters is saved. + * + * @item uncooked + * Even if the value begins with quote characters, do not do quote processing. + * + * @item cooked + * If the value looks like a quoted string, then process it. + * Double quoted strings are processed the way strings are in "C" programs, + * except they are treated as regular characters if the following character + * is not a well-established escape sequence. + * Single quoted strings (quoted with apostrophies) are handled the way + * strings are handled in shell scripts, *except* that backslash escapes + * are honored before backslash escapes and apostrophies. + * @end table + */ +typedef enum { + OPTION_LOAD_COOKED, + OPTION_LOAD_UNCOOKED, + OPTION_LOAD_KEEP +} tOptionLoadMode; + +extern tOptionLoadMode option_load_mode; + +/* + * The pager state is used by optionPagedUsage() procedure. + * When it runs, it sets itself up to be called again on exit. + * If, however, a routine needs a child process to do some work + * before it is done, then 'pagerState' must be set to + * 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try + * to run the pager program before its time. + */ +typedef enum { + PAGER_STATE_INITIAL, + PAGER_STATE_READY, + PAGER_STATE_CHILD +} tePagerState; + +extern tePagerState pagerState; + +typedef enum { + ENV_ALL, + ENV_IMM, + ENV_NON_IMM +} teEnvPresetType; + +typedef enum { + TOPT_UNDEFINED = 0, + TOPT_SHORT, + TOPT_LONG, + TOPT_DEFAULT +} teOptType; + +typedef struct { + tOptDesc* pOD; + tCC* pzOptArg; + tAoUL flags; + teOptType optType; +} tOptState; +#define OPTSTATE_INITIALIZER(st) \ + { NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED } + +#define TEXTTO_TABLE \ + _TT_( LONGUSAGE ) \ + _TT_( USAGE ) \ + _TT_( VERSION ) +#define _TT_(n) \ + TT_ ## n , + +typedef enum { TEXTTO_TABLE COUNT_TT } teTextTo; + +#undef _TT_ + +typedef struct { + tCC* pzStr; + tCC* pzReq; + tCC* pzNum; + tCC* pzKey; + tCC* pzKeyL; + tCC* pzBool; + tCC* pzNest; + tCC* pzOpt; + tCC* pzNo; + tCC* pzBrk; + tCC* pzNoF; + tCC* pzSpc; + tCC* pzOptFmt; +} arg_types_t; + +#define AGALOC( c, w ) ao_malloc((size_t)c) +#define AGREALOC( p, c, w ) ao_realloc((void*)p, (size_t)c) +#define AGFREE( p ) ao_free((void*)p) +#define AGDUPSTR( p, s, w ) (p = ao_strdup(s)) + +static void * +ao_malloc( size_t sz ); + +static void * +ao_realloc( void *p, size_t sz ); + +static void +ao_free( void *p ); + +static char * +ao_strdup( char const *str ); + +#define TAGMEM( m, t ) + +/* + * DO option handling? + * + * Options are examined at two times: at immediate handling time and at + * normal handling time. If an option is disabled, the timing may be + * different from the handling of the undisabled option. The OPTST_DIABLED + * bit indicates the state of the currently discovered option. + * So, here's how it works: + * + * A) handling at "immediate" time, either 1 or 2: + * + * 1. OPTST_DISABLED is not set: + * IMM must be set + * DISABLE_IMM don't care + * TWICE don't care + * DISABLE_TWICE don't care + * 0 -and- 1 x x x + * + * 2. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM must be set + * TWICE don't care + * DISABLE_TWICE don't care + * 1 -and- x 1 x x + */ +#define DO_IMMEDIATELY(_flg) \ + ( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \ + || ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \ + == (OPTST_DISABLED|OPTST_DISABLE_IMM) )) + +/* B) handling at "regular" time because it was not immediate + * + * 1. OPTST_DISABLED is not set: + * IMM must *NOT* be set + * DISABLE_IMM don't care + * TWICE don't care + * DISABLE_TWICE don't care + * 0 -and- 0 x x x + * + * 2. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM don't care + * TWICE must be set + * DISABLE_TWICE don't care + * 1 -and- x x 1 x + */ +#define DO_NORMALLY(_flg) ( \ + (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \ + || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \ + OPTST_DISABLED) ) + +/* C) handling at "regular" time because it is to be handled twice. + * The immediate bit was already tested and found to be set: + * + * 3. OPTST_DISABLED is not set: + * IMM is set (but don't care) + * DISABLE_IMM don't care + * TWICE must be set + * DISABLE_TWICE don't care + * 0 -and- ? x 1 x + * + * 4. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM is set (but don't care) + * TWICE don't care + * DISABLE_TWICE must be set + * 1 -and- x ? x 1 + */ +#define DO_SECOND_TIME(_flg) ( \ + (((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \ + OPTST_TWICE) \ + || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \ + (OPTST_DISABLED|OPTST_DISABLE_TWICE) )) + +/* + * text_mmap structure. Only active on platforms with mmap(2). + */ +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#else +# ifndef PROT_READ +# define PROT_READ 0x01 +# endif +# ifndef PROT_WRITE +# define PROT_WRITE 0x02 +# endif +# ifndef MAP_SHARED +# define MAP_SHARED 0x01 +# endif +# ifndef MAP_PRIVATE +# define MAP_PRIVATE 0x02 +# endif +#endif + +#ifndef MAP_FAILED +# define MAP_FAILED ((void*)-1) +#endif + +#ifndef _SC_PAGESIZE +# ifdef _SC_PAGE_SIZE +# define _SC_PAGESIZE _SC_PAGE_SIZE +# endif +#endif + +#ifndef HAVE_STRCHR +extern char* strchr( char const *s, int c); +extern char* strrchr( char const *s, int c); +#endif + +/* + * Define and initialize all the user visible strings. + * We do not do translations. If translations are to be done, then + * the client will provide a callback for that purpose. + */ +#undef DO_TRANSLATIONS +#include "autoopts/usage-txt.h" + +/* + * File pointer for usage output + */ +extern FILE* option_usage_fp; + +extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt; + +#endif /* AUTOGEN_AUTOOPTS_H */ +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/autoopts.h */ diff --git a/contrib/ntp/libopts/autoopts/options.h b/contrib/ntp/libopts/autoopts/options.h new file mode 100644 index 0000000..c2ceeb3 --- /dev/null +++ b/contrib/ntp/libopts/autoopts/options.h @@ -0,0 +1,977 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (options.h) + * + * It has been AutoGen-ed Saturday May 5, 2007 at 12:02:34 PM PDT + * From the definitions funcs.def + * and the template file options_h + * + * This file defines all the global structures and special values + * used in the automated option processing library. + * + * Automated Options copyright 1992-Y Bruce Korb + * + * AutoOpts 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 of the License, or (at your option) any later version. + * + * AutoOpts is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with AutoOpts. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ +#ifndef AUTOOPTS_OPTIONS_H_GUARD +#define AUTOOPTS_OPTIONS_H_GUARD +#include <sys/types.h> + +#if defined(HAVE_STDINT_H) +# include <stdint.h> +#elif defined(HAVE_INTTYPES_H) +# include <inttypes.h> +#endif /* HAVE_STDINT/INTTYPES_H */ + +#if defined(HAVE_LIMITS_H) +# include <limits.h> +#elif defined(HAVE_SYS_LIMITS_H) +# include <sys/limits.h> +#endif /* HAVE_LIMITS/SYS_LIMITS_H */ + +#if defined(HAVE_SYSEXITS_H) +# include <sysexits.h> +#endif /* HAVE_SYSEXITS_H */ + +#ifndef EX_USAGE +# define EX_USAGE 64 +#endif + +/* + * PUBLIC DEFINES + * + * The following defines may be used in applications that need to test the + * state of an option. To test against these masks and values, a pointer + * to an option descriptor must be obtained. There are two ways: + * + * 1. inside an option processing procedure, it is the second argument, + * conventionally "tOptDesc* pOD". + * + * 2. Outside of an option procedure (or to reference a different option + * descriptor), use either "&DESC( opt_name )" or "&pfx_DESC( opt_name )". + * + * See the relevant generated header file to determine which and what + * values for "opt_name" are available. + */ + +#define OPTIONS_STRUCT_VERSION 118784 +#define OPTIONS_VERSION_STRING "29:0:4" +#define OPTIONS_MINIMUM_VERSION 102400 +#define OPTIONS_MIN_VER_STRING "25:0:0" + +typedef enum { + OPARG_TYPE_NONE = 0, + OPARG_TYPE_STRING = 1, /* default type/ vanilla string */ + OPARG_TYPE_ENUMERATION = 2, /* opt arg is an enum (keyword list) */ + OPARG_TYPE_BOOLEAN = 3, /* opt arg is boolean-valued */ + OPARG_TYPE_MEMBERSHIP = 4, /* opt arg sets set membership bits */ + OPARG_TYPE_NUMERIC = 5, /* opt arg has numeric value */ + OPARG_TYPE_HIERARCHY = 6 /* option arg is hierarchical value */ +} teOptArgType; + +typedef struct optionValue { + teOptArgType valType; + char* pzName; + union { + char strVal[1]; /* OPARG_TYPE_STRING */ + unsigned int enumVal; /* OPARG_TYPE_ENUMERATION */ + unsigned int boolVal; /* OPARG_TYPE_BOOLEAN */ + unsigned long setVal; /* OPARG_TYPE_MEMBERSHIP */ + long longVal; /* OPARG_TYPE_NUMERIC */ + void* nestVal; /* OPARG_TYPE_HIERARCHY */ + } v; +} tOptionValue; + +/* + * Bits in the fOptState option descriptor field. + */ +typedef enum { + OPTST_SET_ID = 0, /* Set via the "SET_OPT()" macro */ + OPTST_PRESET_ID = 1, /* Set via an RC/INI file */ + OPTST_DEFINED_ID = 2, /* Set via a command line option */ + OPTST_EQUIVALENCE_ID = 4, /* selected by equiv'ed option */ + OPTST_DISABLED_ID = 5, /* option is in disabled state */ + OPTST_ALLOC_ARG_ID = 6, /* pzOptArg was allocated */ + OPTST_NO_INIT_ID = 8, /* option cannot be preset */ + OPTST_NUMBER_OPT_ID = 9, /* opt value (flag) is any digit */ + OPTST_STACKED_ID = 10, /* opt uses optionStackArg proc */ + OPTST_INITENABLED_ID = 11, /* option defaults to enabled */ + OPTST_ARG_TYPE_1_ID = 12, /* bit 1 of arg type enum */ + OPTST_ARG_TYPE_2_ID = 13, /* bit 2 of arg type enum */ + OPTST_ARG_TYPE_3_ID = 14, /* bit 3 of arg type enum */ + OPTST_ARG_TYPE_4_ID = 15, /* bit 4 of arg type enum */ + OPTST_ARG_OPTIONAL_ID = 16, /* the option arg not required */ + OPTST_IMM_ID = 17, /* process opt on first pass */ + OPTST_DISABLE_IMM_ID = 18, /* process disablement immed. */ + OPTST_OMITTED_ID = 19, /* compiled out of program */ + OPTST_MUST_SET_ID = 20, /* must be set or pre-set */ + OPTST_DOCUMENT_ID = 21, /* opt is for doc only */ + OPTST_TWICE_ID = 22, /* process opt twice - imm + reg */ + OPTST_DISABLE_TWICE_ID = 23 /* process disabled option twice */ +} opt_state_enum_t; + +#define OPTST_INIT 0U +#define OPTST_SET (1U << OPTST_SET_ID) +#define OPTST_PRESET (1U << OPTST_PRESET_ID) +#define OPTST_DEFINED (1U << OPTST_DEFINED_ID) +#define OPTST_EQUIVALENCE (1U << OPTST_EQUIVALENCE_ID) +#define OPTST_DISABLED (1U << OPTST_DISABLED_ID) +#define OPTST_ALLOC_ARG (1U << OPTST_ALLOC_ARG_ID) +#define OPTST_NO_INIT (1U << OPTST_NO_INIT_ID) +#define OPTST_NUMBER_OPT (1U << OPTST_NUMBER_OPT_ID) +#define OPTST_STACKED (1U << OPTST_STACKED_ID) +#define OPTST_INITENABLED (1U << OPTST_INITENABLED_ID) +#define OPTST_ARG_TYPE_1 (1U << OPTST_ARG_TYPE_1_ID) +#define OPTST_ARG_TYPE_2 (1U << OPTST_ARG_TYPE_2_ID) +#define OPTST_ARG_TYPE_3 (1U << OPTST_ARG_TYPE_3_ID) +#define OPTST_ARG_TYPE_4 (1U << OPTST_ARG_TYPE_4_ID) +#define OPTST_ARG_OPTIONAL (1U << OPTST_ARG_OPTIONAL_ID) +#define OPTST_IMM (1U << OPTST_IMM_ID) +#define OPTST_DISABLE_IMM (1U << OPTST_DISABLE_IMM_ID) +#define OPTST_OMITTED (1U << OPTST_OMITTED_ID) +#define OPTST_MUST_SET (1U << OPTST_MUST_SET_ID) +#define OPTST_DOCUMENT (1U << OPTST_DOCUMENT_ID) +#define OPTST_TWICE (1U << OPTST_TWICE_ID) +#define OPTST_DISABLE_TWICE (1U << OPTST_DISABLE_TWICE_ID) +#define OPT_STATE_MASK 0x00FFFF77U + +#define OPTST_SET_MASK ( \ + OPTST_SET | \ + OPTST_PRESET | \ + OPTST_DEFINED ) + +#define OPTST_MUTABLE_MASK ( \ + OPTST_SET | \ + OPTST_PRESET | \ + OPTST_DEFINED | \ + OPTST_EQUIVALENCE | \ + OPTST_DISABLED | \ + OPTST_ALLOC_ARG ) + +#define OPTST_SELECTED_MASK ( \ + OPTST_SET | \ + OPTST_DEFINED ) + +#define OPTST_ARG_TYPE_MASK ( \ + OPTST_ARG_TYPE_1 | \ + OPTST_ARG_TYPE_2 | \ + OPTST_ARG_TYPE_3 | \ + OPTST_ARG_TYPE_4 ) + +#ifdef NO_OPTIONAL_OPT_ARGS +# undef OPTST_ARG_OPTIONAL +# define OPTST_ARG_OPTIONAL 0 +#endif + +#define OPTST_PERSISTENT_MASK (~OPTST_MUTABLE_MASK) + +#define SELECTED_OPT( pod ) ((pod)->fOptState & OPTST_SELECTED_MASK) +#define UNUSED_OPT( pod ) (((pod)->fOptState & OPTST_SET_MASK) == 0) +#define DISABLED_OPT( pod ) ((pod)->fOptState & OPTST_DISABLED) +#define OPTION_STATE( pod ) ((pod)->fOptState) + +#define OPTST_SET_ARGTYPE(n) ((n) << OPTST_ARG_TYPE_1_ID) +#define OPTST_GET_ARGTYPE(f) (((f) & OPTST_ARG_TYPE_MASK)>>OPTST_ARG_TYPE_1_ID) + +/* + * PRIVATE INTERFACES + * + * The following values are used in the generated code to communicate + * with the option library procedures. They are not for public use + * and may be subject to change. + */ + +/* + * Define the processing state flags + */ +typedef enum { + OPTPROC_LONGOPT_ID = 0, /* Process long style options */ + OPTPROC_SHORTOPT_ID = 1, /* Process short style "flags" */ + OPTPROC_ERRSTOP_ID = 2, /* Stop on argument errors */ + OPTPROC_DISABLEDOPT_ID = 3, /* Current option is disabled */ + OPTPROC_NO_REQ_OPT_ID = 4, /* no options are required */ + OPTPROC_NUM_OPT_ID = 5, /* there is a number option */ + OPTPROC_INITDONE_ID = 6, /* have initializations been done? */ + OPTPROC_NEGATIONS_ID = 7, /* any negation options? */ + OPTPROC_ENVIRON_ID = 8, /* check environment? */ + OPTPROC_NO_ARGS_ID = 9, /* Disallow remaining arguments */ + OPTPROC_ARGS_REQ_ID = 10, /* Require arguments after options */ + OPTPROC_REORDER_ID = 11, /* reorder operands after options */ + OPTPROC_GNUUSAGE_ID = 12, /* emit usage in GNU style */ + OPTPROC_TRANSLATE_ID = 13, /* Translate strings in tOptions */ + OPTPROC_HAS_IMMED_ID = 14, /* program defines immed options */ + OPTPROC_PRESETTING_ID = 19 /* opt processing in preset state */ +} optproc_state_enum_t; + +#define OPTPROC_NONE 0U +#define OPTPROC_LONGOPT (1U << OPTPROC_LONGOPT_ID) +#define OPTPROC_SHORTOPT (1U << OPTPROC_SHORTOPT_ID) +#define OPTPROC_ERRSTOP (1U << OPTPROC_ERRSTOP_ID) +#define OPTPROC_DISABLEDOPT (1U << OPTPROC_DISABLEDOPT_ID) +#define OPTPROC_NO_REQ_OPT (1U << OPTPROC_NO_REQ_OPT_ID) +#define OPTPROC_NUM_OPT (1U << OPTPROC_NUM_OPT_ID) +#define OPTPROC_INITDONE (1U << OPTPROC_INITDONE_ID) +#define OPTPROC_NEGATIONS (1U << OPTPROC_NEGATIONS_ID) +#define OPTPROC_ENVIRON (1U << OPTPROC_ENVIRON_ID) +#define OPTPROC_NO_ARGS (1U << OPTPROC_NO_ARGS_ID) +#define OPTPROC_ARGS_REQ (1U << OPTPROC_ARGS_REQ_ID) +#define OPTPROC_REORDER (1U << OPTPROC_REORDER_ID) +#define OPTPROC_GNUUSAGE (1U << OPTPROC_GNUUSAGE_ID) +#define OPTPROC_TRANSLATE (1U << OPTPROC_TRANSLATE_ID) +#define OPTPROC_HAS_IMMED (1U << OPTPROC_HAS_IMMED_ID) +#define OPTPROC_PRESETTING (1U << OPTPROC_PRESETTING_ID) +#define OPTPROC_STATE_MASK 0x00087FFFU + +#define STMTS(s) do { s; } while (0) + +/* + * The following must be #defined instead of typedef-ed + * because "static const" cannot both be applied to a type, + * tho each individually can...so they all are + */ +#define tSCC static char const +#define tCC char const +#define tAoSC static char +#define tAoUC unsigned char +#define tAoUI unsigned int +#define tAoUL unsigned long +#define tAoUS unsigned short + +/* + * It is so disgusting that there must be so many ways + * of specifying TRUE and FALSE. + */ +typedef enum { AG_FALSE = 0, AG_TRUE } ag_bool; + +/* + * Define a structure that describes each option and + * a pointer to the procedure that handles it. + * The argument is the count of this flag previously seen. + */ +typedef struct options tOptions; +typedef struct optDesc tOptDesc; +typedef struct optNames tOptNames; + +/* + * The option procedures do the special processing for each + * option flag that needs it. + */ +typedef void (tOptProc)( tOptions* pOpts, tOptDesc* pOptDesc ); +typedef tOptProc* tpOptProc; + +/* + * The usage procedure will never return. It calls "exit(2)" + * with the "exitCode" argument passed to it. + */ +typedef void (tUsageProc)( tOptions* pOpts, int exitCode ); +typedef tUsageProc* tpUsageProc; + +/* + * Special definitions. "NOLIMIT" is the 'max' value to use when + * a flag may appear multiple times without limit. "NO_EQUIVALENT" + * is an illegal value for 'optIndex' (option description index). + */ +#define NOLIMIT USHRT_MAX +#define OPTION_LIMIT SHRT_MAX +#define NO_EQUIVALENT (OPTION_LIMIT+1) + +/* + * Special values for optValue. It must not be generatable from the + * computation "optIndex +96". Since "optIndex" is limited to 100, ... + */ +#define NUMBER_OPTION '#' + +typedef struct argList tArgList; +#define MIN_ARG_ALLOC_CT 6 +#define INCR_ARG_ALLOC_CT 8 +struct argList { + int useCt; + int allocCt; + tCC* apzArgs[ MIN_ARG_ALLOC_CT ]; +}; + +typedef union { + char const * argString; + uintptr_t argEnum; + uintptr_t argIntptr; + long argInt; + unsigned long argUint; + unsigned int argBool; +} optArgBucket_t; + +/* + * Descriptor structure for each option. + * Only the fields marked "PUBLIC" are for public use. + */ +struct optDesc { + tAoUS const optIndex; /* PUBLIC */ + tAoUS const optValue; /* PUBLIC */ + tAoUS optActualIndex; /* PUBLIC */ + tAoUS optActualValue; /* PUBLIC */ + + tAoUS const optEquivIndex; /* PUBLIC */ + tAoUS const optMinCt; + tAoUS const optMaxCt; + tAoUS optOccCt; /* PUBLIC */ + + tAoUI fOptState; /* PUBLIC */ + tAoUI reserved; + optArgBucket_t optArg; /* PUBLIC */ +# define pzLastArg optArg.argString + void* optCookie; /* PUBLIC */ + + const int * pOptMust; + const int * pOptCant; + tpOptProc pOptProc; + char const* pzText; + + char const* pz_NAME; + char const* pz_Name; + char const* pz_DisableName; + char const* pz_DisablePfx; +}; + +/* + * Some options need special processing, so we store their + * indexes in a known place: + */ +typedef struct optSpecIndex tOptSpecIndex; +struct optSpecIndex { + const tAoUS more_help; + const tAoUS save_opts; + const tAoUS number_option; + const tAoUS default_opt; +}; + +/* + * The procedure generated for translating option text + */ +typedef void (tOptionXlateProc)(void); + +struct options { + int const structVersion; + int origArgCt; + char** origArgVect; + unsigned int fOptSet; + unsigned int curOptIdx; + char* pzCurOpt; + + char const* pzProgPath; + char const* pzProgName; + char const* const pzPROGNAME; + char const* const pzRcName; + char const* const pzCopyright; + char const* const pzCopyNotice; + char const* const pzFullVersion; + char const* const* const papzHomeList; + char const* const pzUsageTitle; + char const* const pzExplain; + char const* const pzDetail; + tOptDesc* const pOptDesc; + char const* const pzBugAddr; + + void* pExtensions; + void* pSavedState; + + tpUsageProc pUsageProc; + tOptionXlateProc* pTransProc; + + tOptSpecIndex specOptIdx; + int const optCt; + int const presetOptCt; +}; + +/* + * "token list" structure returned by "string_tokenize()" + */ +typedef struct { + unsigned long tkn_ct; + unsigned char* tkn_list[1]; +} token_list_t; + +/* + * Hide the interface - it pollutes a POSIX claim, but leave it for + * anyone #include-ing this header + */ +#define strneqvcmp option_strneqvcmp +#define streqvcmp option_streqvcmp +#define streqvmap option_streqvmap +#define strequate option_strequate +#define strtransform option_strtransform + +/* + * This is an output only structure used by text_mmap and text_munmap. + * Clients must not alter the contents and must provide it to both + * the text_mmap and text_munmap procedures. BE ADVISED: if you are + * mapping the file with PROT_WRITE the NUL byte at the end MIGHT NOT + * BE WRITABLE. In any event, that byte is not be written back + * to the source file. ALSO: if "txt_data" is valid and "txt_errno" + * is not zero, then there *may* not be a terminating NUL. + */ +typedef struct { + void* txt_data; /* text file data */ + size_t txt_size; /* actual file size */ + size_t txt_full_size; /* mmaped mem size */ + int txt_fd; /* file descriptor */ + int txt_zero_fd; /* fd for /dev/zero */ + int txt_errno; /* warning code */ + int txt_prot; /* "prot" flags */ + int txt_flags; /* mapping type */ + int txt_alloc; /* if we malloced memory */ +} tmap_info_t; + +#define TEXT_MMAP_FAILED_ADDR(a) ((void*)(a) == (void*)MAP_FAILED) + +#ifdef __cplusplus +extern "C" { +#define CPLUSPLUS_CLOSER } +#else +#define CPLUSPLUS_CLOSER +#endif + +/* + * The following routines may be coded into AutoOpts client code: + */ + +/* From: tokenize.c line 115 + * + * ao_string_tokenize - tokenize an input string + * + * Arguments: + * string string to be tokenized + * + * Returns: token_list_t* - pointer to a structure that lists each token + * + * This function will convert one input string into a list of strings. + * The list of strings is derived by separating the input based on + * white space separation. However, if the input contains either single + * or double quote characters, then the text after that character up to + * a matching quote will become the string in the list. + * + * The returned pointer should be deallocated with @code{free(3C)} when + * are done using the data. The data are placed in a single block of + * allocated memory. Do not deallocate individual token/strings. + * + * The structure pointed to will contain at least these two fields: + * @table @samp + * @item tkn_ct + * The number of tokens found in the input string. + * @item tok_list + * An array of @code{tkn_ct + 1} pointers to substring tokens, with + * the last pointer set to NULL. + * @end table + * + * There are two types of quoted strings: single quoted (@code{'}) and + * double quoted (@code{"}). Singly quoted strings are fairly raw in that + * escape characters (@code{\\}) are simply another character, except when + * preceding the following characters: + * @example + * @code{\\} double backslashes reduce to one + * @code{'} incorporates the single quote into the string + * @code{\n} suppresses both the backslash and newline character + * @end example + * + * Double quote strings are formed according to the rules of string + * constants in ANSI-C programs. + */ +extern token_list_t* ao_string_tokenize( char const* ); + + +/* From: configfile.c line 113 + * + * configFileLoad - parse a configuration file + * + * Arguments: + * pzFile the file to load + * + * Returns: const tOptionValue* - An allocated, compound value structure + * + * This routine will load a named configuration file and parse the + * text as a hierarchically valued option. The option descriptor + * created from an option definition file is not used via this interface. + * The returned value is "named" with the input file name and is of + * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to + * @code{optionGetValue()}, @code{optionNextValue()} and + * @code{optionUnloadNested()}. + */ +extern const tOptionValue* configFileLoad( char const* ); + + +/* From: configfile.c line 883 + * + * optionFileLoad - Load the locatable config files, in order + * + * Arguments: + * pOpts program options descriptor + * pzProg program name + * + * Returns: int - 0 -> SUCCESS, -1 -> FAILURE + * + * This function looks in all the specified directories for a configuration + * file ("rc" file or "ini" file) and processes any found twice. The first + * time through, they are processed in reverse order (last file first). At + * that time, only "immediate action" configurables are processed. For + * example, if the last named file specifies not processing any more + * configuration files, then no more configuration files will be processed. + * Such an option in the @strong{first} named directory will have no effect. + * + * Once the immediate action configurables have been handled, then the + * directories are handled in normal, forward order. In that way, later + * config files can override the settings of earlier config files. + * + * See the AutoOpts documentation for a thorough discussion of the + * config file format. + * + * Configuration files not found or not decipherable are simply ignored. + */ +extern int optionFileLoad( tOptions*, char const* ); + + +/* From: configfile.c line 245 + * + * optionFindNextValue - find a hierarcicaly valued option instance + * + * Arguments: + * pOptDesc an option with a nested arg type + * pPrevVal the last entry + * name name of value to find + * value the matching value + * + * Returns: const tOptionValue* - a compound value structure + * + * This routine will find the next entry in a nested value option or + * configurable. It will search through the list and return the next entry + * that matches the criteria. + */ +extern const tOptionValue* optionFindNextValue( const tOptDesc*, const tOptionValue*, char const*, char const* ); + + +/* From: configfile.c line 171 + * + * optionFindValue - find a hierarcicaly valued option instance + * + * Arguments: + * pOptDesc an option with a nested arg type + * name name of value to find + * value the matching value + * + * Returns: const tOptionValue* - a compound value structure + * + * This routine will find an entry in a nested value option or configurable. + * It will search through the list and return a matching entry. + */ +extern const tOptionValue* optionFindValue( const tOptDesc*, char const*, char const* ); + + +/* From: restore.c line 188 + * + * optionFree - free allocated option processing memory + * + * Arguments: + * pOpts program options descriptor + * + * AutoOpts sometimes allocates memory and puts pointers to it in the + * option state structures. This routine deallocates all such memory. + */ +extern void optionFree( tOptions* ); + + +/* From: configfile.c line 314 + * + * optionGetValue - get a specific value from a hierarcical list + * + * Arguments: + * pOptValue a hierarchcal value + * valueName name of value to get + * + * Returns: const tOptionValue* - a compound value structure + * + * This routine will find an entry in a nested value option or configurable. + * If "valueName" is NULL, then the first entry is returned. Otherwise, + * the first entry with a name that exactly matches the argument will be + * returned. + */ +extern const tOptionValue* optionGetValue( const tOptionValue*, char const* ); + + +/* From: load.c line 521 + * + * optionLoadLine - process a string for an option name and value + * + * Arguments: + * pOpts program options descriptor + * pzLine NUL-terminated text + * + * This is a client program callable routine for setting options from, for + * example, the contents of a file that they read in. Only one option may + * appear in the text. It will be treated as a normal (non-preset) option. + * + * When passed a pointer to the option struct and a string, it will find + * the option named by the first token on the string and set the option + * argument to the remainder of the string. The caller must NUL terminate + * the string. Any embedded new lines will be included in the option + * argument. If the input looks like one or more quoted strings, then the + * input will be "cooked". The "cooking" is identical to the string + * formation used in AutoGen definition files (@pxref{basic expression}), + * except that you may not use backquotes. + */ +extern void optionLoadLine( tOptions*, char const* ); + + +/* From: configfile.c line 373 + * + * optionNextValue - get the next value from a hierarchical list + * + * Arguments: + * pOptValue a hierarchcal list value + * pOldValue a value from this list + * + * Returns: const tOptionValue* - a compound value structure + * + * This routine will return the next entry after the entry passed in. At the + * end of the list, NULL will be returned. If the entry is not found on the + * list, NULL will be returned and "@var{errno}" will be set to EINVAL. + * The "@var{pOldValue}" must have been gotten from a prior call to this + * routine or to "@code{opitonGetValue()}". + */ +extern const tOptionValue* optionNextValue( const tOptionValue*, const tOptionValue* ); + + +/* From: usage.c line 128 + * + * optionOnlyUsage - Print usage text for just the options + * + * Arguments: + * pOpts program options descriptor + * ex_code exit code for calling exit(3) + * + * This routine will print only the usage for each option. + * This function may be used when the emitted usage must incorporate + * information not available to AutoOpts. + */ +extern void optionOnlyUsage( tOptions*, int ); + + +/* From: autoopts.c line 1012 + * + * optionProcess - this is the main option processing routine + * + * Arguments: + * pOpts program options descriptor + * argc program arg count + * argv program arg vector + * + * Returns: int - the count of the arguments processed + * + * This is the main entry point for processing options. It is intended + * that this procedure be called once at the beginning of the execution of + * a program. Depending on options selected earlier, it is sometimes + * necessary to stop and restart option processing, or to select completely + * different sets of options. This can be done easily, but you generally + * do not want to do this. + * + * The number of arguments processed always includes the program name. + * If one of the arguments is "--", then it is counted and the processing + * stops. If an error was encountered and errors are to be tolerated, then + * the returned value is the index of the argument causing the error. + * A hyphen by itself ("-") will also cause processing to stop and will + * @emph{not} be counted among the processed arguments. A hyphen by itself + * is treated as an operand. Encountering an operand stops option + * processing. + */ +extern int optionProcess( tOptions*, int, char** ); + + +/* From: restore.c line 145 + * + * optionRestore - restore option state from memory copy + * + * Arguments: + * pOpts program options descriptor + * + * Copy back the option state from saved memory. + * The allocated memory is left intact, so this routine can be + * called repeatedly without having to call optionSaveState again. + * If you are restoring a state that was saved before the first call + * to optionProcess(3AO), then you may change the contents of the + * argc/argv parameters to optionProcess. + */ +extern void optionRestore( tOptions* ); + + +/* From: save.c line 334 + * + * optionSaveFile - saves the option state to a file + * + * Arguments: + * pOpts program options descriptor + * + * This routine will save the state of option processing to a file. The name + * of that file can be specified with the argument to the @code{--save-opts} + * option, or by appending the @code{rcfile} attribute to the last + * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it + * will default to @code{.@i{programname}rc}. If you wish to specify another + * file, you should invoke the @code{SET_OPT_SAVE_OPTS( @i{filename} )} macro. + */ +extern void optionSaveFile( tOptions* ); + + +/* From: restore.c line 93 + * + * optionSaveState - saves the option state to memory + * + * Arguments: + * pOpts program options descriptor + * + * This routine will allocate enough memory to save the current option + * processing state. If this routine has been called before, that memory + * will be reused. You may only save one copy of the option state. This + * routine may be called before optionProcess(3AO). If you do call it + * before the first call to optionProcess, then you may also change the + * contents of argc/argv after you call optionRestore(3AO) + * + * In fact, more strongly put: it is safest to only use this function + * before having processed any options. In particular, the saving and + * restoring of stacked string arguments and hierarchical values is + * disabled. The values are not saved. + */ +extern void optionSaveState( tOptions* ); + + +/* From: nested.c line 559 + * + * optionUnloadNested - Deallocate the memory for a nested value + * + * Arguments: + * pOptVal the hierarchical value + * + * A nested value needs to be deallocated. The pointer passed in should + * have been gotten from a call to @code{configFileLoad()} (See + * @pxref{libopts-configFileLoad}). + */ +extern void optionUnloadNested( tOptionValue const * ); + + +/* From: version.c line 58 + * + * optionVersion - return the compiled AutoOpts version number + * + * Returns: char const* - the version string in constant memory + * + * Returns the full version string compiled into the library. + * The returned string cannot be modified. + */ +extern char const* optionVersion( void ); + + +/* From: ../compat/pathfind.c line 34 + * + * pathfind - fild a file in a list of directories + * + * Arguments: + * path colon separated list of search directories + * file the name of the file to look for + * mode the mode bits that must be set to match + * + * Returns: char* - the path to the located file + * + * the pathfind function is available only if HAVE_PATHFIND is not defined + * + * pathfind looks for a a file with name "FILE" and "MODE" access + * along colon delimited "PATH", and returns the full pathname as a + * string, or NULL if not found. If "FILE" contains a slash, then + * it is treated as a relative or absolute path and "PATH" is ignored. + * + * @strong{NOTE}: this function is compiled into @file{libopts} only if + * it is not natively supplied. + * + * The "MODE" argument is a string of option letters chosen from the + * list below: + * @example + * Letter Meaning + * r readable + * w writable + * x executable + * f normal file (NOT IMPLEMENTED) + * b block special (NOT IMPLEMENTED) + * c character special (NOT IMPLEMENTED) + * d directory (NOT IMPLEMENTED) + * p FIFO (pipe) (NOT IMPLEMENTED) + * u set user ID bit (NOT IMPLEMENTED) + * g set group ID bit (NOT IMPLEMENTED) + * k sticky bit (NOT IMPLEMENTED) + * s size nonzero (NOT IMPLEMENTED) + * @end example + */ +#ifndef HAVE_PATHFIND +extern char* pathfind( char const*, char const*, char const* ); +#endif /* HAVE_PATHFIND */ + + +/* From: streqvcmp.c line 233 + * + * strequate - map a list of characters to the same value + * + * Arguments: + * ch_list characters to equivalence + * + * Each character in the input string get mapped to the first character + * in the string. + * This function name is mapped to option_strequate so as to not conflict + * with the POSIX name space. + */ +extern void strequate( char const* ); + + +/* From: streqvcmp.c line 143 + * + * streqvcmp - compare two strings with an equivalence mapping + * + * Arguments: + * str1 first string + * str2 second string + * + * Returns: int - the difference between two differing characters + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * This function name is mapped to option_streqvcmp so as to not conflict + * with the POSIX name space. + */ +extern int streqvcmp( char const*, char const* ); + + +/* From: streqvcmp.c line 180 + * + * streqvmap - Set the character mappings for the streqv functions + * + * Arguments: + * From Input character + * To Mapped-to character + * ct compare length + * + * Set the character mapping. If the count (@code{ct}) is set to zero, then + * the map is cleared by setting all entries in the map to their index + * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" + * character. If @code{ct} is greater than 1, then @code{From} and @code{To} + * are incremented and the process repeated until @code{ct} entries have been + * set. For example, + * @example + * streqvmap( 'a', 'A', 26 ); + * @end example + * @noindent + * will alter the mapping so that all English lower case letters + * will map to upper case. + * + * This function name is mapped to option_streqvmap so as to not conflict + * with the POSIX name space. + */ +extern void streqvmap( char, char, int ); + + +/* From: streqvcmp.c line 102 + * + * strneqvcmp - compare two strings with an equivalence mapping + * + * Arguments: + * str1 first string + * str2 second string + * ct compare length + * + * Returns: int - the difference between two differing characters + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * The comparison is limited to @code{ct} bytes. + * This function name is mapped to option_strneqvcmp so as to not conflict + * with the POSIX name space. + */ +extern int strneqvcmp( char const*, char const*, int ); + + +/* From: streqvcmp.c line 259 + * + * strtransform - convert a string into its mapped-to value + * + * Arguments: + * dest output string + * src input string + * + * Each character in the input string is mapped and the mapped-to + * character is put into the output. + * This function name is mapped to option_strtransform so as to not conflict + * with the POSIX name space. + */ +extern void strtransform( char*, char const* ); + +/* AutoOpts PRIVATE FUNCTIONS: */ +tOptProc optionStackArg, optionUnstackArg, optionBooleanVal, optionNumericVal; + +extern char* ao_string_cook( char*, int* ); + +extern unsigned int ao_string_cook_escape_char( char const*, char*, unsigned int ); + +extern void export_options_to_guile( tOptions* ); + +extern void genshelloptUsage( tOptions*, int ); + +extern void optionBooleanVal( tOptions*, tOptDesc* ); + +extern uintptr_t optionEnumerationVal( tOptions*, tOptDesc*, char const * const *, unsigned int ); + +extern char const* optionKeywordName( tOptDesc*, unsigned int ); + +extern void optionLoadOpt( tOptions*, tOptDesc* ); + +extern ag_bool optionMakePath( char*, int, char const*, char const* ); + +extern void optionNestedVal( tOptions*, tOptDesc* ); + +extern void optionNumericVal( tOptions*, tOptDesc* ); + +extern void optionPagedUsage( tOptions*, tOptDesc* ); + +extern void optionParseShell( tOptions* ); + +extern void optionPrintVersion( tOptions*, tOptDesc* ); + +extern void optionPutShell( tOptions* ); + +extern void optionSetMembers( tOptions*, tOptDesc*, char const * const *, unsigned int ); + +extern void optionStackArg( tOptions*, tOptDesc* ); + +extern void optionUnstackArg( tOptions*, tOptDesc* ); + +extern void optionUsage( tOptions*, int ); + +extern void optionVersionStderr( tOptions*, tOptDesc* ); + +extern void* text_mmap( char const*, int, int, tmap_info_t* ); + +extern int text_munmap( tmap_info_t* ); + +CPLUSPLUS_CLOSER +#endif /* AUTOOPTS_OPTIONS_H_GUARD */ +/* + * Local Variables: + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * options.h ends here */ diff --git a/contrib/ntp/libopts/autoopts/usage-txt.h b/contrib/ntp/libopts/autoopts/usage-txt.h new file mode 100644 index 0000000..5aaaa01 --- /dev/null +++ b/contrib/ntp/libopts/autoopts/usage-txt.h @@ -0,0 +1,355 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (usage-txt.h) + * + * It has been AutoGen-ed Saturday May 5, 2007 at 12:02:33 PM PDT + * From the definitions usage-txt.def + * and the template file usage-txt.tpl + * + * This file handles all the bookkeeping required for tracking all the little + * tiny strings used by the AutoOpts library. There are 113 + * of them. This is not versioned because it is entirely internal to the + * library and accessed by client code only in a very well-controlled way: + * they may substitute translated strings using a procedure that steps through + * all the string pointers. + * + * AutoOpts 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 of the License, or (at your option) any later version. + * + * AutoOpts is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with AutoOpts. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ +#ifndef AUTOOPTS_USAGE_TXT_H_GUARD +#define AUTOOPTS_USAGE_TXT_H_GUARD + +#undef cch_t +#define cch_t char const + +/* + * One structure to hold all the pointers to all the stringlets. + */ +typedef struct { + int field_ct; + char* utpz_GnuBoolArg; + char* utpz_GnuKeyArg; + char* utpz_GnuKeyLArg; + char* utpz_GnuNumArg; + char* utpz_GnuStrArg; + cch_t* apz_str[ 108 ]; +} usage_text_t; + +/* + * Declare the global structure with all the pointers to translated + * strings. This is then used by the usage generation procedure. + */ +extern usage_text_t option_usage_text; + +#if defined(AUTOOPTS_INTERNAL) /* DEFINE ALL THE STRINGS = = = = = */ +/* + * Provide a mapping from a short name to fields in this structure. + */ +#define zAO_Bad (option_usage_text.apz_str[ 0]) +#define zAO_Big (option_usage_text.apz_str[ 1]) +#define zAO_Err (option_usage_text.apz_str[ 2]) +#define zAO_Sml (option_usage_text.apz_str[ 3]) +#define zAll (option_usage_text.apz_str[ 4]) +#define zAlt (option_usage_text.apz_str[ 5]) +#define zAmbigKey (option_usage_text.apz_str[ 6]) +#define zAmbiguous (option_usage_text.apz_str[ 7]) +#define zArgsMust (option_usage_text.apz_str[ 8]) +#define zAtMost (option_usage_text.apz_str[ 9]) +#define zAuto (option_usage_text.apz_str[ 10]) +#define zBadPipe (option_usage_text.apz_str[ 11]) +#define zBadVerArg (option_usage_text.apz_str[ 12]) +#define zCantFmt (option_usage_text.apz_str[ 13]) +#define zCantSave (option_usage_text.apz_str[ 14]) +#define zDefaultOpt (option_usage_text.apz_str[ 15]) +#define zDis (option_usage_text.apz_str[ 16]) +#define zEnab (option_usage_text.apz_str[ 17]) +#define zEquiv (option_usage_text.apz_str[ 18]) +#define zErrOnly (option_usage_text.apz_str[ 19]) +#define zExamineFmt (option_usage_text.apz_str[ 20]) +#define zFiveSpaces (option_usage_text.apz_str[ 21]) +#define zFlagOkay (option_usage_text.apz_str[ 22]) +#define zFmtFmt (option_usage_text.apz_str[ 23]) +#define zForkFail (option_usage_text.apz_str[ 24]) +#define zFSErrOptLoad (option_usage_text.apz_str[ 25]) +#define zFSErrReadFile (option_usage_text.apz_str[ 26]) +#define zGenshell (option_usage_text.apz_str[ 27]) +#define zGnuBoolArg (option_usage_text.utpz_GnuBoolArg) +#define zGnuBreak (option_usage_text.apz_str[ 28]) +#define zGnuKeyArg (option_usage_text.utpz_GnuKeyArg) +#define zGnuKeyLArg (option_usage_text.utpz_GnuKeyLArg) +#define zGnuNestArg (option_usage_text.apz_str[ 29]) +#define zGnuNumArg (option_usage_text.utpz_GnuNumArg) +#define zGnuOptArg (option_usage_text.apz_str[ 30]) +#define zGnuOptFmt (option_usage_text.apz_str[ 31]) +#define zGnuStrArg (option_usage_text.utpz_GnuStrArg) +#define zIllOptChr (option_usage_text.apz_str[ 32]) +#define zIllOptStr (option_usage_text.apz_str[ 33]) +#define zIllegal (option_usage_text.apz_str[ 34]) +#define zInvalOptDesc (option_usage_text.apz_str[ 35]) +#define zKeyWords (option_usage_text.apz_str[ 36]) +#define zLoadCooked (option_usage_text.apz_str[ 37]) +#define zLoadKeep (option_usage_text.apz_str[ 38]) +#define zLoadType (option_usage_text.apz_str[ 39]) +#define zLoadUncooked (option_usage_text.apz_str[ 40]) +#define zLtypeInteger (option_usage_text.apz_str[ 41]) +#define zLtypeNest (option_usage_text.apz_str[ 42]) +#define zLtypeString (option_usage_text.apz_str[ 43]) +#define zLtypeBool (option_usage_text.apz_str[ 44]) +#define zLtypeKeyword (option_usage_text.apz_str[ 45]) +#define zLtypeSetMembership (option_usage_text.apz_str[ 46]) +#define zMembers (option_usage_text.apz_str[ 47]) +#define zMisArg (option_usage_text.apz_str[ 48]) +#define zMultiEquiv (option_usage_text.apz_str[ 49]) +#define zMust (option_usage_text.apz_str[ 50]) +#define zNeedOne (option_usage_text.apz_str[ 51]) +#define zNoArg (option_usage_text.apz_str[ 52]) +#define zNoArgs (option_usage_text.apz_str[ 53]) +#define zNoCreat (option_usage_text.apz_str[ 54]) +#define zNoFlags (option_usage_text.apz_str[ 55]) +#define zNoKey (option_usage_text.apz_str[ 56]) +#define zNoLim (option_usage_text.apz_str[ 57]) +#define zNoPreset (option_usage_text.apz_str[ 58]) +#define zNoRq_NoShrtTtl (option_usage_text.apz_str[ 59]) +#define zNoRq_ShrtTtl (option_usage_text.apz_str[ 60]) +#define zNoStat (option_usage_text.apz_str[ 61]) +#define zNoState (option_usage_text.apz_str[ 62]) +#define zNone (option_usage_text.apz_str[ 63]) +#define zNotDef (option_usage_text.apz_str[ 64]) +#define zNotEnough (option_usage_text.apz_str[ 65]) +#define zNotFile (option_usage_text.apz_str[ 66]) +#define zNotNumber (option_usage_text.apz_str[ 67]) +#define zNrmOptFmt (option_usage_text.apz_str[ 68]) +#define zNumberOpt (option_usage_text.apz_str[ 69]) +#define zOneSpace (option_usage_text.apz_str[ 70]) +#define zOnlyOne (option_usage_text.apz_str[ 71]) +#define zOptsOnly (option_usage_text.apz_str[ 72]) +#define zPathFmt (option_usage_text.apz_str[ 73]) +#define zPlsSendBugs (option_usage_text.apz_str[ 74]) +#define zPreset (option_usage_text.apz_str[ 75]) +#define zPresetFile (option_usage_text.apz_str[ 76]) +#define zPresetIntro (option_usage_text.apz_str[ 77]) +#define zProg (option_usage_text.apz_str[ 78]) +#define zProhib (option_usage_text.apz_str[ 79]) +#define zReorder (option_usage_text.apz_str[ 80]) +#define zReqFmt (option_usage_text.apz_str[ 81]) +#define zReqOptFmt (option_usage_text.apz_str[ 82]) +#define zReqThese (option_usage_text.apz_str[ 83]) +#define zReq_NoShrtTtl (option_usage_text.apz_str[ 84]) +#define zReq_ShrtTtl (option_usage_text.apz_str[ 85]) +#define zSepChars (option_usage_text.apz_str[ 86]) +#define zSetMembers (option_usage_text.apz_str[ 87]) +#define zSetMemberSettings (option_usage_text.apz_str[ 88]) +#define zShrtGnuOptFmt (option_usage_text.apz_str[ 89]) +#define zSixSpaces (option_usage_text.apz_str[ 90]) +#define zStdBoolArg (option_usage_text.apz_str[ 91]) +#define zStdBreak (option_usage_text.apz_str[ 92]) +#define zStdKeyArg (option_usage_text.apz_str[ 93]) +#define zStdKeyLArg (option_usage_text.apz_str[ 94]) +#define zStdNestArg (option_usage_text.apz_str[ 95]) +#define zStdNoArg (option_usage_text.apz_str[ 96]) +#define zStdNumArg (option_usage_text.apz_str[ 97]) +#define zStdOptArg (option_usage_text.apz_str[ 98]) +#define zStdReqArg (option_usage_text.apz_str[ 99]) +#define zStdStrArg (option_usage_text.apz_str[100]) +#define zTabHyp (option_usage_text.apz_str[101]) +#define zTabHypAnd (option_usage_text.apz_str[102]) +#define zTabout (option_usage_text.apz_str[103]) +#define zThreeSpaces (option_usage_text.apz_str[104]) +#define zTwoSpaces (option_usage_text.apz_str[105]) +#define zUpTo (option_usage_text.apz_str[106]) +#define zValidKeys (option_usage_text.apz_str[107]) + + /* + * First, set up the strings. Some of these are writable. These are all in + * English. This gets compiled into libopts and is distributed here so that + * xgettext (or equivalents) can extract these strings for translation. + */ + + static char eng_zGnuBoolArg[] = "=T/F"; + static char eng_zGnuKeyArg[] = "=KWd"; + static char eng_zGnuKeyLArg[] = "=Mbr"; + static char eng_zGnuNumArg[] = "=num"; + static char eng_zGnuStrArg[] = "=str"; +static char const usage_txt[3208] = + "AutoOpts function called without option descriptor\n\0" + "\tThis exceeds the compiled library version: \0" + "Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n\0" + "\tThis is less than the minimum library version: \0" + "all\0" + "\t\t\t\t- an alternate for %s\n\0" + "%s error: the keyword `%s' is ambiguous for %s\n\0" + "ambiguous\0" + "%s: Command line arguments required\n\0" + "%d %s%s options allowed\n\0" + "version and help options:\0" + "Error %d (%s) from the pipe(2) syscall\n\0" + "ERROR: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and copyright notice\n\0" + "ERROR: %s option conflicts with the %s option\n\0" + "%s(optionSaveState): error: cannot allocate %d bytes\n\0" + "\t\t\t\t- default option for unnamed options\n\0" + "\t\t\t\t- disabled as --%s\n\0" + "\t\t\t\t- enabled by default\n\0" + "-equivalence\0" + "ERROR: only \0" + " - examining environment variables named %s_*\n\0" + " \0" + "Options are specified by doubled hyphens and their name\n" + "or by a single hyphen and the flag character.\n\0" + "%%-%ds %%s\n\0" + "fs error %d (%s) on fork - cannot obtain %s usage\n\0" + "File error %d (%s) opening %s for loading options\n\0" + "fs error %d (%s) reading file %s\n\0" + "\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n\0" + "\n" + "%s\n\n\0" + "=Cplx\0" + "[=arg]\0" + "--%2$s%1$s\0" + "%s: illegal option -- %c\n\0" + "%s: %s option -- %s\n\0" + "illegal\0" + "AutoOpts ERROR: invalid option descriptor for %s\n\0" + "words=\0" + "cooked\0" + "keep\0" + "type=\0" + "uncooked\0" + "integer\0" + "nested\0" + "string\0" + "bool\0" + "keyword\0" + "set\0" + "\t\t\t\t- is a set membership option\n\0" + "%s: option `%s' requires an argument\n\0" + "Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'\0" + "\t\t\t\t- must appear between %d and %d times\n\0" + "ERROR: The %s option is required\n\0" + "%s: option `%s' cannot have an argument\n\0" + "%s: Command line arguments not allowed\n\0" + "error %d (%s) creating %s\n\0" + "Options are specified by single or double hyphens and their name.\n\0" + "%s error: `%s' does not match any %s keywords\n\0" + "\t\t\t\t- may appear multiple times\n\0" + "\t\t\t\t- may not be preset\n\0" + " Arg Option-Name Description\n\0" + " Flg Arg Option-Name Description\n\0" + "error %d (%s) stat-ing %s\n\0" + "%s(optionRestore): error: no saved option state\n\0" + "none\0" + "'%s' not defined\n\0" + "ERROR: The %s option must appear %d times\n\0" + "error: cannot load options from non-regular file %s\n\0" + "%s error: `%s' is not a recognizable number\n\0" + " %3s %s\0" + "The '-#<number>' option may omit the hash char\n\0" + " \0" + "one %s%s option allowed\n\0" + "All arguments are named options.\n\0" + " - reading file %s\0" + "\n" + "please send bug reports to: %s\n\0" + "\t\t\t\t- may NOT appear - preset only\n\0" + "# preset/initialization file\n" + "# %s#\n\0" + "\n" + "The following option preset mechanisms are supported:\n\0" + "program\0" + "prohibits these options:\n\0" + "Operands and options may be intermixed. They will be reordered.\n\0" + "ERROR: %s option requires the %s option\n\0" + " %3s %-14s %s\0" + "requires these options:\n\0" + " Arg Option-Name Req? Description\n\0" + " Flg Arg Option-Name Req? Description\n\0" + "-_^\0" + "members=\0" + "or you may use a numeric representation. Preceding these with a '!' will\n" + "clear the bits, specifying 'none' will clear all bits, and 'all' will set them\n" + "all. Multiple entries may be passed as an option argument list.\n\0" + "%s\0" + " \0" + "T/F\0" + "\n" + "%s\n\n" + "%s\0" + "KWd\0" + "Mbr\0" + "Cpx\0" + "no \0" + "Num\0" + "opt\0" + "YES\0" + "Str\0" + "\t\t\t\t- \0" + "\t\t\t\t-- and \0" + "\t\t\t\t%s\n\0" + " \0" + " \0" + "\t\t\t\t- may appear up to %d times\n\0" + "The valid \"%s\" option keywords are:\n\0"; + + + /* + * Now, define (and initialize) the structure that contains + * the pointers to all these strings. + * Aren't you glad you don't maintain this by hand? + */ + usage_text_t option_usage_text = { + 113, + eng_zGnuBoolArg, eng_zGnuKeyArg, eng_zGnuKeyLArg, eng_zGnuNumArg, + eng_zGnuStrArg, + { + usage_txt + 0, usage_txt + 52, usage_txt + 98, usage_txt + 197, + usage_txt + 247, usage_txt + 251, usage_txt + 278, usage_txt + 327, + usage_txt + 337, usage_txt + 374, usage_txt + 399, usage_txt + 425, + usage_txt + 465, usage_txt + 602, usage_txt + 650, usage_txt + 704, + usage_txt + 746, usage_txt + 770, usage_txt + 796, usage_txt + 809, + usage_txt + 823, usage_txt + 870, usage_txt + 876, usage_txt + 979, + usage_txt + 991, usage_txt +1042, usage_txt +1093, usage_txt +1127, + usage_txt +1233, usage_txt +1239, usage_txt +1245, usage_txt +1252, + usage_txt +1263, usage_txt +1289, usage_txt +1310, usage_txt +1318, + usage_txt +1369, usage_txt +1376, usage_txt +1383, usage_txt +1388, + usage_txt +1394, usage_txt +1403, usage_txt +1411, usage_txt +1418, + usage_txt +1425, usage_txt +1430, usage_txt +1438, usage_txt +1442, + usage_txt +1476, usage_txt +1514, usage_txt +1579, usage_txt +1622, + usage_txt +1657, usage_txt +1698, usage_txt +1738, usage_txt +1765, + usage_txt +1832, usage_txt +1880, usage_txt +1913, usage_txt +1938, + usage_txt +1973, usage_txt +2011, usage_txt +2038, usage_txt +2087, + usage_txt +2092, usage_txt +2110, usage_txt +2154, usage_txt +2208, + usage_txt +2254, usage_txt +2262, usage_txt +2310, usage_txt +2312, + usage_txt +2337, usage_txt +2371, usage_txt +2390, usage_txt +2424, + usage_txt +2460, usage_txt +2498, usage_txt +2554, usage_txt +2562, + usage_txt +2588, usage_txt +2654, usage_txt +2696, usage_txt +2710, + usage_txt +2735, usage_txt +2775, usage_txt +2818, usage_txt +2822, + usage_txt +2831, usage_txt +3050, usage_txt +3053, usage_txt +3060, + usage_txt +3064, usage_txt +3072, usage_txt +3076, usage_txt +3080, + usage_txt +3084, usage_txt +3088, usage_txt +3092, usage_txt +3096, + usage_txt +3100, usage_txt +3104, usage_txt +3111, usage_txt +3123, + usage_txt +3131, usage_txt +3135, usage_txt +3138, usage_txt +3171 + } + }; + +#endif /* DO_TRANSLATIONS */ +#endif /* AUTOOPTS_USAGE_TXT_H_GUARD */ diff --git a/contrib/ntp/libopts/boolean.c b/contrib/ntp/libopts/boolean.c new file mode 100644 index 0000000..37148a9 --- /dev/null +++ b/contrib/ntp/libopts/boolean.c @@ -0,0 +1,106 @@ + +/* + * $Id: boolean.c,v 4.10 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-13 10:10:39 bkorb" + * + * Automated Options Paged Usage module. + * + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/*=export_func optionBooleanVal + * private: + * + * what: Decipher a boolean value + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * Decipher a true or false value for a boolean valued option argument. + * The value is true, unless it starts with 'n' or 'f' or "#f" or + * it is an empty string or it is a number that evaluates to zero. +=*/ +void +optionBooleanVal( tOptions* pOpts, tOptDesc* pOD ) +{ + char* pz; + ag_bool res = AG_TRUE; + + switch (*(pOD->optArg.argString)) { + case '0': + { + long val = strtol( pOD->optArg.argString, &pz, 0 ); + if ((val != 0) || (*pz != NUL)) + break; + /* FALLTHROUGH */ + } + case 'N': + case 'n': + case 'F': + case 'f': + case NUL: + res = AG_FALSE; + break; + case '#': + if (pOD->optArg.argString[1] != 'f') + break; + res = AG_FALSE; + } + + if (pOD->fOptState & OPTST_ALLOC_ARG) { + AGFREE(pOD->optArg.argString); + pOD->fOptState &= ~OPTST_ALLOC_ARG; + } + pOD->optArg.argBool = res; +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/boolean.c */ diff --git a/contrib/ntp/libopts/compat/compat.h b/contrib/ntp/libopts/compat/compat.h new file mode 100644 index 0000000..b3bd58f --- /dev/null +++ b/contrib/ntp/libopts/compat/compat.h @@ -0,0 +1,319 @@ +/* -*- Mode: C -*- */ + +/* --- fake the preprocessor into handlng portability */ +/* + * Time-stamp: "2007-02-03 17:41:06 bkorb" + * + * Author: Gary V Vaughan <gvaughan@oranda.demon.co.uk> + * Created: Mon Jun 30 15:54:46 1997 + * + * $Id: compat.h,v 4.16 2007/04/27 01:10:47 bkorb Exp $ + */ +#ifndef COMPAT_H_GUARD +#define COMPAT_H_GUARD 1 + +#if defined(HAVE_CONFIG_H) +# include <config.h> + +#elif defined(_WIN32) && !defined(__CYGWIN__) +# include "windows-config.h" + +#else +# error "compat.h" requires "config.h" + choke me. +#endif + + +#ifndef HAVE_STRSIGNAL + char * strsignal( int signo ); +#endif + +#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */ +#define __USE_GNU 1 /* exact same thing as above */ +#define __EXTENSIONS__ 1 /* and another way to call for it */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * SYSTEM HEADERS: + */ +#include <sys/types.h> +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif +#include <sys/param.h> +#if HAVE_SYS_PROCSET_H +# include <sys/procset.h> +#endif +#include <sys/stat.h> +#include <sys/wait.h> + +#if defined( HAVE_SOLARIS_SYSINFO ) +# include <sys/systeminfo.h> +#elif defined( HAVE_UNAME_SYSCALL ) +# include <sys/utsname.h> +#endif + +#ifdef DAEMON_ENABLED +# if HAVE_SYS_STROPTS_H +# include <sys/stropts.h> +# endif + +# if HAVE_SYS_SOCKET_H +# include <sys/socket.h> +# endif + +# if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H) +# error This system cannot support daemon processing + Choke Me. +# endif + +# if HAVE_SYS_POLL_H +# include <sys/poll.h> +# endif + +# if HAVE_SYS_SELECT_H +# include <sys/select.h> +# endif + +# if HAVE_NETINET_IN_H +# include <netinet/in.h> +# endif + +# if HAVE_SYS_UN_H +# include <sys/un.h> +# endif +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * USER HEADERS: + */ +#include <stdio.h> +#include <assert.h> +#include <ctype.h> + +/* + * Directory opening stuff: + */ +# if defined (_POSIX_SOURCE) +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +# define REAL_DIR_ENTRY(dp) 1 +# else /* !_POSIX_SOURCE */ +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +# endif /* !_POSIX_SOURCE */ + +# if defined (HAVE_DIRENT_H) +# include <dirent.h> +# define D_NAMLEN(dirent) strlen((dirent)->d_name) +# else /* !HAVE_DIRENT_H */ +# define dirent direct +# define D_NAMLEN(dirent) (dirent)->d_namlen +# if defined (HAVE_SYS_NDIR_H) +# include <sys/ndir.h> +# endif /* HAVE_SYS_NDIR_H */ +# if defined (HAVE_SYS_DIR_H) +# include <sys/dir.h> +# endif /* HAVE_SYS_DIR_H */ +# if defined (HAVE_NDIR_H) +# include <ndir.h> +# endif /* HAVE_NDIR_H */ +# endif /* !HAVE_DIRENT_H */ + +#include <errno.h> +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#endif +#ifndef O_NONBLOCK +# define O_NONBLOCK FNDELAY +#endif + +#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H) +# include <libgen.h> +#endif + +#if defined(HAVE_LIMITS_H) /* this is also in options.h */ +# include <limits.h> +#elif defined(HAVE_SYS_LIMITS_H) +# include <sys/limits.h> +#endif /* HAVE_LIMITS/SYS_LIMITS_H */ + +#include <memory.h> +#include <setjmp.h> +#include <signal.h> + +#if defined( HAVE_STDINT_H ) +# include <stdint.h> +#elif defined( HAVE_INTTYPES_H ) +# include <inttypes.h> +#endif + +#include <stdlib.h> +#include <string.h> + +#include <time.h> + +#ifdef HAVE_UTIME_H +# include <utime.h> +#endif + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * FIXUPS and CONVIENCE STUFF: + */ +#ifdef __cplusplus +# define EXTERN extern "C" +#else +# define EXTERN extern +#endif + +/* some systems #def errno! and others do not declare it!! */ +#ifndef errno + extern int errno; +#endif + +/* Some machines forget this! */ + +# ifndef EXIT_FAILURE +# define EXIT_SUCCESS 0 +# define EXIT_FAILURE 1 +# endif + +#ifndef NUL +# define NUL '\0' +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H) +# include <sys/param.h> +#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */ + +#if !defined (MAXPATHLEN) && defined (PATH_MAX) +# define MAXPATHLEN PATH_MAX +#endif /* !MAXPATHLEN && PATH_MAX */ + +#if !defined (MAXPATHLEN) && defined(_MAX_PATH) +# define PATH_MAX _MAX_PATH +# define MAXPATHLEN _MAX_PATH +#endif + +#if !defined (MAXPATHLEN) +# define MAXPATHLEN ((size_t)4096) +#endif /* MAXPATHLEN */ + +#define AG_PATH_MAX ((size_t)MAXPATHLEN) + +#ifndef LONG_MAX +# define LONG_MAX ~(1L << (8*sizeof(long) -1)) +# define INT_MAX ~(1 << (8*sizeof(int) -1)) +#endif + +#ifndef ULONG_MAX +# define ULONG_MAX ~(OUL) +# define UINT_MAX ~(OU) +#endif + +#ifndef SHORT_MAX +# define SHORT_MAX ~(1 << (8*sizeof(short) -1)) +#else +# define USHORT_MAX ~(OUS) +#endif + +#ifndef HAVE_INT8_T + typedef signed char int8_t; +#endif +#ifndef HAVE_UINT8_T + typedef unsigned char uint8_t; +#endif +#ifndef HAVE_INT16_T + typedef signed short int16_t; +#endif +#ifndef HAVE_UINT16_T + typedef unsigned short uint16_t; +#endif +#ifndef HAVE_UINT_T + typedef unsigned int uint_t; +#endif + +#ifndef HAVE_INT32_T +# if SIZEOF_INT == 4 + typedef signed int int32_t; +# elif SIZEOF_LONG == 4 + typedef signed long int32_t; +# endif +#endif + +#ifndef HAVE_UINT32_T +# if SIZEOF_INT == 4 + typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 + typedef unsigned long uint32_t; +# else +# error Cannot create a uint32_t type. + Choke Me. +# endif +#endif + +#ifndef HAVE_INTPTR_T + typedef signed long intptr_t; +#endif +#ifndef HAVE_UINTPTR_T + typedef unsigned long uintptr_t; +#endif + +/* redefine these for BSD style string libraries */ +#ifndef HAVE_STRCHR +# define strchr index +# define strrchr rindex +#endif + +#ifdef USE_FOPEN_BINARY +# ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG "b" +# endif +# ifndef FOPEN_TEXT_FLAG +# define FOPEN_TEXT_FLAG "t" +# endif +#else +# ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG +# endif +# ifndef FOPEN_TEXT_FLAG +# define FOPEN_TEXT_FLAG +# endif +#endif + +#ifndef STR +# define _STR(s) #s +# define STR(s) _STR(s) +#endif + +/* ##### Pointer sized word ##### */ + +/* FIXME: the MAX stuff in here is broken! */ +#if SIZEOF_CHARP > SIZEOF_INT + typedef long t_word; + #define WORD_MAX LONG_MAX + #define WORD_MIN LONG_MIN +#else /* SIZEOF_CHARP <= SIZEOF_INT */ + typedef int t_word; + #define WORD_MAX INT_MAX + #define WORD_MIN INT_MIN +#endif + +#endif /* COMPAT_H_GUARD */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/compat.h */ diff --git a/contrib/ntp/libopts/compat/pathfind.c b/contrib/ntp/libopts/compat/pathfind.c new file mode 100644 index 0000000..96eb771 --- /dev/null +++ b/contrib/ntp/libopts/compat/pathfind.c @@ -0,0 +1,339 @@ +/* -*- Mode: C -*- */ + +/* pathfind.c --- find a FILE MODE along PATH */ + +/* + * Author: Gary V Vaughan <gvaughan@oranda.demon.co.uk> + * Time-stamp: "2006-09-23 19:46:16 bkorb" + * Created: Tue Jun 24 15:07:31 1997 + * Last Modified: $Date: 2006/11/27 01:52:23 $ + * by: bkorb + * + * $Id: pathfind.c,v 4.10 2006/11/27 01:52:23 bkorb Exp $ + */ + +/* Code: */ + +#include "compat.h" +#ifndef HAVE_PATHFIND +#if defined(__windows__) && !defined(__CYGWIN__) +char* +pathfind( char const* path, + char const* fileName, + char const* mode ) +{ + return NULL; +} +#else + +static char* make_absolute( char const *string, char const *dot_path ); +static char* canonicalize_pathname( char *path ); +static char* extract_colon_unit( char* dir, char const *string, int *p_index ); + + +/*=export_func pathfind + * + * what: fild a file in a list of directories + * + * ifndef: HAVE_PATHFIND + * + * arg: + char const* + path + colon separated list of search directories + + * arg: + char const* + file + the name of the file to look for + + * arg: + char const* + mode + the mode bits that must be set to match + + * + * ret_type: char* + * ret_desc: the path to the located file + * + * doc: + * + * pathfind looks for a a file with name "FILE" and "MODE" access + * along colon delimited "PATH", and returns the full pathname as a + * string, or NULL if not found. If "FILE" contains a slash, then + * it is treated as a relative or absolute path and "PATH" is ignored. + * + * @strong{NOTE}: this function is compiled into @file{libopts} only if + * it is not natively supplied. + * + * The "MODE" argument is a string of option letters chosen from the + * list below: + * @example + * Letter Meaning + * r readable + * w writable + * x executable + * f normal file (NOT IMPLEMENTED) + * b block special (NOT IMPLEMENTED) + * c character special (NOT IMPLEMENTED) + * d directory (NOT IMPLEMENTED) + * p FIFO (pipe) (NOT IMPLEMENTED) + * u set user ID bit (NOT IMPLEMENTED) + * g set group ID bit (NOT IMPLEMENTED) + * k sticky bit (NOT IMPLEMENTED) + * s size nonzero (NOT IMPLEMENTED) + * @end example + * + * example: + * To find the "ls" command using the "PATH" environment variable: + * @example + * #include <stdlib.h> + * char* pz_ls = pathfind( getenv("PATH"), "ls", "rx" ); + * <<do whatever with pz_ls>> + * free( pz_ls ); + * @end example + * The path is allocated with @code{malloc(3C)}, so you must @code{free(3C)} + * the result. Also, do not use unimplemented file modes. :-) + * + * err: returns NULL if the file is not found. +=*/ +char* +pathfind( char const* path, + char const* fileName, + char const* mode ) +{ + int p_index = 0; + int mode_bits = 0; + char* pathName = NULL; + char zPath[ AG_PATH_MAX + 1 ]; + + if (strchr( mode, 'r' )) mode_bits |= R_OK; + if (strchr( mode, 'w' )) mode_bits |= W_OK; + if (strchr( mode, 'x' )) mode_bits |= X_OK; + + /* + * FOR each non-null entry in the colon-separated path, DO ... + */ + for (;;) { + DIR* dirP; + char* colon_unit = extract_colon_unit( zPath, path, &p_index ); + + /* + * IF no more entries, THEN quit + */ + if (colon_unit == NULL) + break; + + dirP = opendir( colon_unit ); + + /* + * IF the directory is inaccessable, THEN next directory + */ + if (dirP == NULL) + continue; + + /* + * FOR every entry in the given directory, ... + */ + for (;;) { + struct dirent *entP = readdir( dirP ); + + if (entP == (struct dirent*)NULL) + break; + + /* + * IF the file name matches the one we are looking for, ... + */ + if (strcmp( entP->d_name, fileName ) == 0) { + char* pzFullName = make_absolute( fileName, colon_unit); + + /* + * Make sure we can access it in the way we want + */ + if (access( pzFullName, mode_bits ) >= 0) { + /* + * We can, so normalize the name and return it below + */ + pathName = canonicalize_pathname( pzFullName ); + } + + free( (void*)pzFullName ); + break; + } + } + + closedir( dirP ); + + if (pathName != NULL) + break; + } + + return pathName; +} + +/* + * Turn STRING (a pathname) into an absolute pathname, assuming that + * DOT_PATH contains the symbolic location of `.'. This always returns + * a new string, even if STRING was an absolute pathname to begin with. + */ +static char* +make_absolute( char const *string, char const *dot_path ) +{ + char *result; + int result_len; + + if (!dot_path || *string == '/') { + result = strdup( string ); + } else { + if (dot_path && dot_path[0]) { + result = malloc( 2 + strlen( dot_path ) + strlen( string ) ); + strcpy( result, dot_path ); + result_len = strlen( result ); + if (result[result_len - 1] != '/') { + result[result_len++] = '/'; + result[result_len] = '\0'; + } + } else { + result = malloc( 3 + strlen( string ) ); + result[0] = '.'; result[1] = '/'; result[2] = '\0'; + result_len = 2; + } + + strcpy( result + result_len, string ); + } + + return result; +} + +/* + * Canonicalize PATH, and return a new path. The new path differs from + * PATH in that: + * + * Multiple `/'s are collapsed to a single `/'. + * Leading `./'s are removed. + * Trailing `/.'s are removed. + * Trailing `/'s are removed. + * Non-leading `../'s and trailing `..'s are handled by removing + * portions of the path. + */ +static char* +canonicalize_pathname( char *path ) +{ + int i, start; + char stub_char, *result; + + /* The result cannot be larger than the input PATH. */ + result = strdup( path ); + + stub_char = (*path == '/') ? '/' : '.'; + + /* Walk along RESULT looking for things to compact. */ + i = 0; + while (result[i]) { + while (result[i] != '\0' && result[i] != '/') + i++; + + start = i++; + + /* If we didn't find any slashes, then there is nothing left to + * do. + */ + if (!result[start]) + break; + + /* Handle multiple `/'s in a row. */ + while (result[i] == '/') + i++; + +#if !defined (apollo) + if ((start + 1) != i) +#else + if ((start + 1) != i && (start != 0 || i != 2)) +#endif /* apollo */ + { + strcpy( result + start + 1, result + i ); + i = start + 1; + } + + /* Handle backquoted `/'. */ + if (start > 0 && result[start - 1] == '\\') + continue; + + /* Check for trailing `/', and `.' by itself. */ + if ((start && !result[i]) + || (result[i] == '.' && !result[i+1])) { + result[--i] = '\0'; + break; + } + + /* Check for `../', `./' or trailing `.' by itself. */ + if (result[i] == '.') { + /* Handle `./'. */ + if (result[i + 1] == '/') { + strcpy( result + i, result + i + 1 ); + i = (start < 0) ? 0 : start; + continue; + } + + /* Handle `../' or trailing `..' by itself. */ + if (result[i + 1] == '.' && + (result[i + 2] == '/' || !result[i + 2])) { + while (--start > -1 && result[start] != '/') + ; + strcpy( result + start + 1, result + i + 2 ); + i = (start < 0) ? 0 : start; + continue; + } + } + } + + if (!*result) { + *result = stub_char; + result[1] = '\0'; + } + + return result; +} + +/* + * Given a string containing units of information separated by colons, + * return the next one pointed to by (P_INDEX), or NULL if there are no + * more. Advance (P_INDEX) to the character after the colon. + */ +static char* +extract_colon_unit( char* pzDir, char const *string, int *p_index ) +{ + char* pzDest = pzDir; + int ix = *p_index; + + if (string == NULL) + return NULL; + + if ((unsigned)ix >= strlen( string )) + return NULL; + + { + char const* pzSrc = string + ix; + + while (*pzSrc == ':') pzSrc++; + + for (;;) { + char ch = (*(pzDest++) = *(pzSrc++)); + switch (ch) { + case ':': + pzDest[-1] = NUL; + case NUL: + goto copy_done; + } + + if ((pzDest - pzDir) >= AG_PATH_MAX) + break; + } copy_done:; + + ix = pzSrc - string; + } + + if (*pzDir == NUL) + return NULL; + + *p_index = ix; + return pzDir; +} +#endif /* __windows__ / __CYGWIN__ */ +#endif /* HAVE_PATHFIND */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/pathfind.c */ diff --git a/contrib/ntp/libopts/compat/snprintf.c b/contrib/ntp/libopts/compat/snprintf.c new file mode 100644 index 0000000..fc91d63 --- /dev/null +++ b/contrib/ntp/libopts/compat/snprintf.c @@ -0,0 +1,60 @@ + +#ifndef HAVE_VPRINTF +#include "choke-me: no vprintf and no snprintf" +#endif + +#if defined(HAVE_STDARG_H) +# include <stdarg.h> +# ifndef VA_START +# define VA_START(a, f) va_start(a, f) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# define SNV_USING_STDARG_H + +#elif defined(HAVE_VARARGS_H) +# include <varargs.h> +# ifndef VA_START +# define VA_START(a, f) va_start(a) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# undef SNV_USING_STDARG_H + +#else +# include "must-have-stdarg-or-varargs" +#endif + +static int +snprintf(char *str, size_t n, char const *fmt, ...) +{ + va_list ap; + int rval; + +#ifdef VSPRINTF_CHARSTAR + char *rp; + VA_START(ap, fmt); + rp = vsprintf(str, fmt, ap); + VA_END(ap); + rval = strlen(rp); + +#else + VA_START(ap, fmt); + rval = vsprintf(str, fmt, ap); + VA_END(ap); +#endif + + if (rval > n) { + fprintf(stderr, "snprintf buffer overrun %d > %d\n", rval, (int)n); + abort(); + } + return rval; +} + +static int +vsnprintf( char *str, size_t n, char const *fmt, va_list ap ) +{ +#ifdef VSPRINTF_CHARSTAR + return (strlen(vsprintf(str, fmt, ap))); +#else + return (vsprintf(str, fmt, ap)); +#endif +} diff --git a/contrib/ntp/libopts/compat/strchr.c b/contrib/ntp/libopts/compat/strchr.c new file mode 100644 index 0000000..413f999 --- /dev/null +++ b/contrib/ntp/libopts/compat/strchr.c @@ -0,0 +1,60 @@ +/* + SYNOPSIS + #include <string.h> + + char *strchr(char const *s, int c); + + char *strrchr(char const *s, int c); + + DESCRIPTION + The strchr() function returns a pointer to the first occurrence of the + character c in the string s. + + The strrchr() function returns a pointer to the last occurrence of the + character c in the string s. + + Here "character" means "byte" - these functions do not work with wide + or multi-byte characters. + + RETURN VALUE + The strchr() and strrchr() functions return a pointer to the matched + character or NULL if the character is not found. + + CONFORMING TO + SVID 3, POSIX, BSD 4.3, ISO 9899 +*/ + +char* +strchr( char const *s, int c) +{ + do { + if ((unsigned)*s == (unsigned)c) + return s; + + } while (*(++s) != NUL); + + return NULL; +} + +char* +strrchr( char const *s, int c) +{ + char const *e = s + strlen(s); + + for (;;) { + if (--e < s) + break; + + if ((unsigned)*e == (unsigned)c) + return e; + } + return NULL; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/strsignal.c */ diff --git a/contrib/ntp/libopts/compat/strdup.c b/contrib/ntp/libopts/compat/strdup.c new file mode 100644 index 0000000..e2933a8 --- /dev/null +++ b/contrib/ntp/libopts/compat/strdup.c @@ -0,0 +1,19 @@ +/* + * Platforms without strdup ?!?!?! + */ + +static char * +strdup( char const *s ) +{ + char *cp; + + if (s == NULL) + return NULL; + + cp = (char *) AGALOC((unsigned) (strlen(s)+1), "strdup"); + + if (cp != NULL) + (void) strcpy(cp, s); + + return cp; +} diff --git a/contrib/ntp/libopts/compat/windows-config.h b/contrib/ntp/libopts/compat/windows-config.h new file mode 100644 index 0000000..2612980 --- /dev/null +++ b/contrib/ntp/libopts/compat/windows-config.h @@ -0,0 +1,130 @@ + +/* + * Time-stamp: "2006-10-14 14:55:09 bkorb" + * by: bkorb + * Last Committed: $Date: 2007/04/28 22:19:23 $ + */ +#ifndef WINDOWS_CONFIG_HACKERY +#define WINDOWS_CONFIG_HACKERY 1 + +/* + * The definitions below have been stolen from NTP's config.h for Windows. + * However, they may be kept here in order to keep libopts independent from + * the NTP project. + */ +#ifndef __windows__ +# define __windows__ 4 +#endif + +/* + * Miscellaneous functions that Microsoft maps + * to other names + * + * #define inline __inline + * #define vsnprintf _vsnprintf + */ +#define snprintf _snprintf +/* + * #define stricmp _stricmp + * #define strcasecmp _stricmp + * #define isascii __isascii + * #define finite _finite + * #define random rand + * #define srandom srand + */ + +#define SIZEOF_INT 4 +#define SIZEOF_CHARP 4 +#define SIZEOF_LONG 4 +#define SIZEOF_SHORT 2 + +typedef unsigned long uintptr_t; + +/* + * # define HAVE_NET_IF_H + * # define QSORT_USES_VOID_P + * # define HAVE_SETVBUF + * # define HAVE_VSPRINTF + * # define HAVE_SNPRINTF + * # define HAVE_VSNPRINTF + * # define HAVE_PROTOTYPES /* from ntpq.mak * / + * # define HAVE_MEMMOVE + * # define HAVE_TERMIOS_H + * # define HAVE_ERRNO_H + * # define HAVE_STDARG_H + * # define HAVE_NO_NICE + * # define HAVE_MKTIME + * # define TIME_WITH_SYS_TIME + * # define HAVE_IO_COMPLETION_PORT + * # define ISC_PLATFORM_NEEDNTOP + * # define ISC_PLATFORM_NEEDPTON + * # define NEED_S_CHAR_TYPEDEF + * # define USE_PROTOTYPES /* for ntp_types.h * / + * + * #define ULONG_CONST(a) a ## UL + */ + +#define HAVE_LIMITS_H 1 +#define HAVE_STRDUP 1 +#define HAVE_STRCHR 1 +#define HAVE_FCNTL_H 1 + +/* + * VS.NET's version of wspiapi.h has a bug in it + * where it assigns a value to a variable inside + * an if statement. It should be comparing them. + * We prevent inclusion since we are not using this + * code so we don't have to see the warning messages + */ +#ifndef _WSPIAPI_H_ +#define _WSPIAPI_H_ +#endif + +/* Prevent inclusion of winsock.h in windows.h */ +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif + +#ifndef __RPCASYNC_H__ +#define __RPCASYNC_H__ +#endif + +/* Include Windows headers */ +#include <windows.h> +#include <winsock2.h> +#include <limits.h> + +/* + * Compatibility declarations for Windows, assuming SYS_WINNT + * has been defined. + */ +#define strdup _strdup +#define stat _stat /* struct stat from <sys/stat.h> */ +#define unlink _unlink +#define fchmod( _x, _y ); +#define ssize_t SSIZE_T + +#include <io.h> +#define open _open +#define close _close +#define read _read +#define write _write +#define lseek _lseek +#define pipe _pipe +#define dup2 _dup2 + +#define O_RDWR _O_RDWR +#define O_RDONLY _O_RDONLY +#define O_EXCL _O_EXCL + +#ifndef S_ISREG +# define S_IFREG _S_IFREG +# define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG) +#endif + +#ifndef S_ISDIR +# define S_IFDIR _S_IFDIR +# define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) +#endif + +#endif /* WINDOWS_CONFIG_HACKERY */ diff --git a/contrib/ntp/libopts/configfile.c b/contrib/ntp/libopts/configfile.c new file mode 100644 index 0000000..e0b8a74 --- /dev/null +++ b/contrib/ntp/libopts/configfile.c @@ -0,0 +1,1290 @@ +/* + * $Id: configfile.c,v 1.21 2007/04/15 19:01:18 bkorb Exp $ + * Time-stamp: "2007-04-15 11:22:46 bkorb" + * + * configuration/rc/ini file handling. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +filePreset( + tOptions* pOpts, + char const* pzFileName, + int direction ); + +static char* +handleComment( char* pzText ); + +static char* +handleConfig( + tOptions* pOpts, + tOptState* pOS, + char* pzText, + int direction ); + +static char* +handleDirective( + tOptions* pOpts, + char* pzText ); + +static char* +handleProgramSection( + tOptions* pOpts, + char* pzText ); + +static char* +handleStructure( + tOptions* pOpts, + tOptState* pOS, + char* pzText, + int direction ); + +static char* +parseKeyWordType( + tOptions* pOpts, + char* pzText, + tOptionValue* pType ); + +static char* +parseLoadMode( + char* pzText, + tOptionLoadMode* pMode ); + +static char* +parseSetMemType( + tOptions* pOpts, + char* pzText, + tOptionValue* pType ); + +static char* +parseValueType( + char* pzText, + tOptionValue* pType ); + +static char* +skipUnknown( char* pzText ); +/* = = = END-STATIC-FORWARD = = = */ + + +/*=export_func configFileLoad + * + * what: parse a configuration file + * arg: + char const* + pzFile + the file to load + + * + * ret_type: const tOptionValue* + * ret_desc: An allocated, compound value structure + * + * doc: + * This routine will load a named configuration file and parse the + * text as a hierarchically valued option. The option descriptor + * created from an option definition file is not used via this interface. + * The returned value is "named" with the input file name and is of + * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to + * @code{optionGetValue()}, @code{optionNextValue()} and + * @code{optionUnloadNested()}. + * + * err: + * If the file cannot be loaded or processed, @code{NULL} is returned and + * @var{errno} is set. It may be set by a call to either @code{open(2)} + * @code{mmap(2)} or other file system calls, or it may be: + * @itemize @bullet + * @item + * @code{ENOENT} - the file was empty. + * @item + * @code{EINVAL} - the file contents are invalid -- not properly formed. + * @item + * @code{ENOMEM} - not enough memory to allocate the needed structures. + * @end itemize +=*/ +const tOptionValue* +configFileLoad( char const* pzFile ) +{ + tmap_info_t cfgfile; + tOptionValue* pRes = NULL; + tOptionLoadMode save_mode = option_load_mode; + + char* pzText = + text_mmap( pzFile, PROT_READ, MAP_PRIVATE, &cfgfile ); + + if (TEXT_MMAP_FAILED_ADDR(pzText)) + return NULL; /* errno is set */ + + option_load_mode = OPTION_LOAD_COOKED; + pRes = optionLoadNested(pzText, pzFile, strlen(pzFile)); + + if (pRes == NULL) { + int err = errno; + text_munmap( &cfgfile ); + errno = err; + } else + text_munmap( &cfgfile ); + + option_load_mode = save_mode; + return pRes; +} + + +/*=export_func optionFindValue + * + * what: find a hierarcicaly valued option instance + * arg: + const tOptDesc* + pOptDesc + an option with a nested arg type + + * arg: + char const* + name + name of value to find + + * arg: + char const* + value + the matching value + + * + * ret_type: const tOptionValue* + * ret_desc: a compound value structure + * + * doc: + * This routine will find an entry in a nested value option or configurable. + * It will search through the list and return a matching entry. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +const tOptionValue* +optionFindValue( const tOptDesc* pOptDesc, + char const* pzName, char const* pzVal ) +{ + const tOptionValue* pRes = NULL; + + if ( (pOptDesc == NULL) + || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + } + + else if (pOptDesc->optCookie == NULL) { + errno = ENOENT; + } + + else do { + tArgList* pAL = pOptDesc->optCookie; + int ct = pAL->useCt; + void** ppOV = (void**)(pAL->apzArgs); + + if (ct == 0) { + errno = ENOENT; + break; + } + + if (pzName == NULL) { + pRes = (tOptionValue*)*ppOV; + break; + } + + while (--ct >= 0) { + const tOptionValue* pOV = *(ppOV++); + const tOptionValue* pRV = optionGetValue( pOV, pzName ); + + if (pRV == NULL) + continue; + + if (pzVal == NULL) { + pRes = pOV; + break; + } + } + if (pRes == NULL) + errno = ENOENT; + } while (0); + + return pRes; +} + + +/*=export_func optionFindNextValue + * + * what: find a hierarcicaly valued option instance + * arg: + const tOptDesc* + pOptDesc + an option with a nested arg type + + * arg: + const tOptionValue* + pPrevVal + the last entry + + * arg: + char const* + name + name of value to find + + * arg: + char const* + value + the matching value + + * + * ret_type: const tOptionValue* + * ret_desc: a compound value structure + * + * doc: + * This routine will find the next entry in a nested value option or + * configurable. It will search through the list and return the next entry + * that matches the criteria. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +const tOptionValue* +optionFindNextValue( const tOptDesc* pOptDesc, const tOptionValue* pPrevVal, + char const* pzName, char const* pzVal ) +{ + int foundOldVal = 0; + tOptionValue* pRes = NULL; + + if ( (pOptDesc == NULL) + || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + } + + else if (pOptDesc->optCookie == NULL) { + errno = ENOENT; + } + + else do { + tArgList* pAL = pOptDesc->optCookie; + int ct = pAL->useCt; + void** ppOV = (void**)pAL->apzArgs; + + if (ct == 0) { + errno = ENOENT; + break; + } + + while (--ct >= 0) { + tOptionValue* pOV = *(ppOV++); + if (foundOldVal) { + pRes = pOV; + break; + } + if (pOV == pPrevVal) + foundOldVal = 1; + } + if (pRes == NULL) + errno = ENOENT; + } while (0); + + return pRes; +} + + +/*=export_func optionGetValue + * + * what: get a specific value from a hierarcical list + * arg: + const tOptionValue* + pOptValue + a hierarchcal value + + * arg: + char const* + valueName + name of value to get + + * + * ret_type: const tOptionValue* + * ret_desc: a compound value structure + * + * doc: + * This routine will find an entry in a nested value option or configurable. + * If "valueName" is NULL, then the first entry is returned. Otherwise, + * the first entry with a name that exactly matches the argument will be + * returned. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +const tOptionValue* +optionGetValue( const tOptionValue* pOld, char const* pzValName ) +{ + tArgList* pAL; + tOptionValue* pRes = NULL; + + if ((pOld == NULL) || (pOld->valType != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + return NULL; + } + pAL = pOld->v.nestVal; + + if (pAL->useCt > 0) { + int ct = pAL->useCt; + void** papOV = (void**)(pAL->apzArgs); + + if (pzValName == NULL) { + pRes = (tOptionValue*)*papOV; + } + + else do { + tOptionValue* pOV = *(papOV++); + if (strcmp( pOV->pzName, pzValName ) == 0) { + pRes = pOV; + break; + } + } while (--ct > 0); + } + if (pRes == NULL) + errno = ENOENT; + return pRes; +} + + +/*=export_func optionNextValue + * + * what: get the next value from a hierarchical list + * arg: + const tOptionValue* + pOptValue + a hierarchcal list value + + * arg: + const tOptionValue* + pOldValue + a value from this list + + * + * ret_type: const tOptionValue* + * ret_desc: a compound value structure + * + * doc: + * This routine will return the next entry after the entry passed in. At the + * end of the list, NULL will be returned. If the entry is not found on the + * list, NULL will be returned and "@var{errno}" will be set to EINVAL. + * The "@var{pOldValue}" must have been gotten from a prior call to this + * routine or to "@code{opitonGetValue()}". + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value or @code{pOldValue} does not point to a + * member of that option value. + * @item + * @code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. + * @end itemize +=*/ +tOptionValue const * +optionNextValue(tOptionValue const * pOVList,tOptionValue const * pOldOV ) +{ + tArgList* pAL; + tOptionValue* pRes = NULL; + int err = EINVAL; + + if ((pOVList == NULL) || (pOVList->valType != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + return NULL; + } + pAL = pOVList->v.nestVal; + { + int ct = pAL->useCt; + void** papNV = (void**)(pAL->apzArgs); + + while (ct-- > 0) { + tOptionValue* pNV = *(papNV++); + if (pNV == pOldOV) { + if (ct == 0) { + err = ENOENT; + + } else { + err = 0; + pRes = (tOptionValue*)*papNV; + } + break; + } + } + } + if (err != 0) + errno = err; + return pRes; +} + + +/* filePreset + * + * Load a file containing presetting information (a configuration file). + */ +static void +filePreset( + tOptions* pOpts, + char const* pzFileName, + int direction ) +{ + tmap_info_t cfgfile; + tOptState st = OPTSTATE_INITIALIZER(PRESET); + char* pzFileText = + text_mmap( pzFileName, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile ); + + if (TEXT_MMAP_FAILED_ADDR(pzFileText)) + return; + + if (direction == DIRECTION_CALLED) { + st.flags = OPTST_DEFINED; + direction = DIRECTION_PROCESS; + } + + /* + * IF this is called via "optionProcess", then we are presetting. + * This is the default and the PRESETTING bit will be set. + * If this is called via "optionFileLoad", then the bit is not set + * and we consider stuff set herein to be "set" by the client program. + */ + if ((pOpts->fOptSet & OPTPROC_PRESETTING) == 0) + st.flags = OPTST_SET; + + do { + while (isspace( (int)*pzFileText )) pzFileText++; + + if (isalpha( (int)*pzFileText )) { + pzFileText = handleConfig( pOpts, &st, pzFileText, direction ); + + } else switch (*pzFileText) { + case '<': + if (isalpha( (int)pzFileText[1] )) + pzFileText = handleStructure(pOpts, &st, pzFileText, direction); + + else switch (pzFileText[1]) { + case '?': + pzFileText = handleDirective( pOpts, pzFileText ); + break; + + case '!': + pzFileText = handleComment( pzFileText ); + break; + + case '/': + pzFileText = strchr( pzFileText+2, '>' ); + if (pzFileText++ != NULL) + break; + + default: + goto all_done; + } + break; + + case '[': + pzFileText = handleProgramSection( pOpts, pzFileText ); + break; + + case '#': + pzFileText = strchr( pzFileText+1, '\n' ); + break; + + default: + goto all_done; /* invalid format */ + } + } while (pzFileText != NULL); + + all_done: + text_munmap( &cfgfile ); +} + + +/* handleComment + * + * "pzText" points to a "<!" sequence. + * Theoretically, we should ensure that it begins with "<!--", + * but actually I don't care that much. It ends with "-->". + */ +static char* +handleComment( char* pzText ) +{ + char* pz = strstr( pzText, "-->" ); + if (pz != NULL) + pz += 3; + return pz; +} + + +/* handleConfig + * + * "pzText" points to the start of some value name. + * The end of the entry is the end of the line that is not preceded by + * a backslash escape character. The string value is always processed + * in "cooked" mode. + */ +static char* +handleConfig( + tOptions* pOpts, + tOptState* pOS, + char* pzText, + int direction ) +{ + char* pzName = pzText++; + char* pzEnd = strchr( pzText, '\n' ); + + if (pzEnd == NULL) + return pzText + strlen(pzText); + + while (ISNAMECHAR( (int)*pzText )) pzText++; + while (isspace( (int)*pzText )) pzText++; + if (pzText > pzEnd) { + name_only: + *pzEnd++ = NUL; + loadOptionLine( pOpts, pOS, pzName, direction, OPTION_LOAD_UNCOOKED ); + return pzEnd; + } + + /* + * Either the first character after the name is a ':' or '=', + * or else we must have skipped over white space. Anything else + * is an invalid format and we give up parsing the text. + */ + if ((*pzText == '=') || (*pzText == ':')) { + while (isspace( (int)*++pzText )) ; + if (pzText > pzEnd) + goto name_only; + } else if (! isspace((int)pzText[-1])) + return NULL; + + /* + * IF the value is continued, remove the backslash escape and push "pzEnd" + * on to a newline *not* preceded by a backslash. + */ + if (pzEnd[-1] == '\\') { + char* pcD = pzEnd-1; + char* pcS = pzEnd; + + for (;;) { + char ch = *(pcS++); + switch (ch) { + case NUL: + pcS = NULL; + + case '\n': + *pcD = NUL; + pzEnd = pcS; + goto copy_done; + + case '\\': + if (*pcS == '\n') { + ch = *(pcS++); + } + /* FALLTHROUGH */ + default: + *(pcD++) = ch; + } + } copy_done:; + + } else { + /* + * The newline was not preceded by a backslash. NUL it out + */ + *(pzEnd++) = NUL; + } + + /* + * "pzName" points to what looks like text for one option/configurable. + * It is NUL terminated. Process it. + */ + loadOptionLine( pOpts, pOS, pzName, direction, OPTION_LOAD_UNCOOKED ); + + return pzEnd; +} + + +/* handleDirective + * + * "pzText" points to a "<?" sequence. + * For the moment, we only handle "<?program" directives. + */ +static char* +handleDirective( + tOptions* pOpts, + char* pzText ) +{ + char ztitle[32] = "<?"; + size_t title_len = strlen( zProg ); + size_t name_len; + + if ( (strncmp( pzText+2, zProg, title_len ) != 0) + || (! isspace( (int)pzText[title_len+2] )) ) { + pzText = strchr( pzText+2, '>' ); + if (pzText != NULL) + pzText++; + return pzText; + } + + name_len = strlen( pOpts->pzProgName ); + strcpy( ztitle+2, zProg ); + title_len += 2; + + do { + pzText += title_len; + + if (isspace((int)*pzText)) { + while (isspace((int)*pzText)) pzText++; + if ( (strneqvcmp( pzText, pOpts->pzProgName, (int)name_len) == 0) + && (pzText[name_len] == '>')) { + pzText += name_len + 1; + break; + } + } + + pzText = strstr( pzText, ztitle ); + } while (pzText != NULL); + + return pzText; +} + + +/* handleProgramSection + * + * "pzText" points to a '[' character. + * The "traditional" [PROG_NAME] segmentation of the config file. + * Do not ever mix with the "<?program prog-name>" variation. + */ +static char* +handleProgramSection( + tOptions* pOpts, + char* pzText ) +{ + size_t len = strlen( pOpts->pzPROGNAME ); + if ( (strncmp( pzText+1, pOpts->pzPROGNAME, len ) == 0) + && (pzText[len+1] == ']')) + return strchr( pzText + len + 2, '\n' ); + + if (len > 16) + return NULL; + + { + char z[24]; + sprintf( z, "[%s]", pOpts->pzPROGNAME ); + pzText = strstr( pzText, z ); + } + + if (pzText != NULL) + pzText = strchr( pzText, '\n' ); + return pzText; +} + + +/* handleStructure + * + * "pzText" points to a '<' character, followed by an alpha. + * The end of the entry is either the "/>" following the name, or else a + * "</name>" string. + */ +static char* +handleStructure( + tOptions* pOpts, + tOptState* pOS, + char* pzText, + int direction ) +{ + tOptionLoadMode mode = option_load_mode; + tOptionValue valu; + + char* pzName = ++pzText; + char* pzData; + char* pcNulPoint; + + while (ISNAMECHAR( *pzText )) pzText++; + pcNulPoint = pzText; + valu.valType = OPARG_TYPE_STRING; + + switch (*pzText) { + case ' ': + case '\t': + pzText = parseAttributes( pOpts, pzText, &mode, &valu ); + if (*pzText == '>') + break; + if (*pzText != '/') + return NULL; + /* FALLTHROUGH */ + + case '/': + if (pzText[1] != '>') + return NULL; + *pzText = NUL; + pzText += 2; + loadOptionLine( pOpts, pOS, pzName, direction, mode ); + return pzText; + + case '>': + break; + + default: + pzText = strchr( pzText, '>'); + if (pzText != NULL) + pzText++; + return pzText; + } + + /* + * If we are here, we have a value. "pzText" points to a closing angle + * bracket. Separate the name from the value for a moment. + */ + *pcNulPoint = NUL; + pzData = ++pzText; + + /* + * Find the end of the option text and NUL terminate it + */ + { + char z[64], *pz = z; + size_t len = strlen(pzName) + 4; + if (len > sizeof(z)) + pz = AGALOC(len, "scan name"); + + sprintf( pz, "</%s>", pzName ); + *pzText = ' '; + pzText = strstr( pzText, pz ); + if (pz != z) AGFREE(pz); + + if (pzText == NULL) + return pzText; + + *pzText = NUL; + + pzText += len-1; + } + + /* + * Rejoin the name and value for parsing by "loadOptionLine()". + * Erase any attributes parsed by "parseAttributes()". + */ + memset(pcNulPoint, ' ', pzData - pcNulPoint); + + /* + * "pzName" points to what looks like text for one option/configurable. + * It is NUL terminated. Process it. + */ + loadOptionLine( pOpts, pOS, pzName, direction, mode ); + + return pzText; +} + + +/* internalFileLoad + * + * Load a configuration file. This may be invoked either from + * scanning the "homerc" list, or from a specific file request. + * (see "optionFileLoad()", the implementation for --load-opts) + */ +LOCAL void +internalFileLoad( tOptions* pOpts ) +{ + int idx; + int inc = DIRECTION_PRESET; + char zFileName[ AG_PATH_MAX+1 ]; + + if (pOpts->papzHomeList == NULL) + return; + + /* + * Find the last RC entry (highest priority entry) + */ + for (idx = 0; pOpts->papzHomeList[ idx+1 ] != NULL; ++idx) ; + + /* + * For every path in the home list, ... *TWICE* We start at the last + * (highest priority) entry, work our way down to the lowest priority, + * handling the immediate options. + * Then we go back up, doing the normal options. + */ + for (;;) { + struct stat StatBuf; + cch_t* pzPath; + + /* + * IF we've reached the bottom end, change direction + */ + if (idx < 0) { + inc = DIRECTION_PROCESS; + idx = 0; + } + + pzPath = pOpts->papzHomeList[ idx ]; + + /* + * IF we've reached the top end, bail out + */ + if (pzPath == NULL) + break; + + idx += inc; + + if (! optionMakePath( zFileName, (int)sizeof(zFileName), + pzPath, pOpts->pzProgPath )) + continue; + + /* + * IF the file name we constructed is a directory, + * THEN append the Resource Configuration file name + * ELSE we must have the complete file name + */ + if (stat( zFileName, &StatBuf ) != 0) + continue; /* bogus name - skip the home list entry */ + + if (S_ISDIR( StatBuf.st_mode )) { + size_t len = strlen( zFileName ); + char* pz; + + if (len + 1 + strlen( pOpts->pzRcName ) >= sizeof( zFileName )) + continue; + + pz = zFileName + len; + if (pz[-1] != DIRCH) + *(pz++) = DIRCH; + strcpy( pz, pOpts->pzRcName ); + } + + filePreset( pOpts, zFileName, inc ); + + /* + * IF we are now to skip config files AND we are presetting, + * THEN change direction. We must go the other way. + */ + { + tOptDesc * pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts+1; + if (DISABLED_OPT(pOD) && PRESETTING(inc)) { + idx -= inc; /* go back and reprocess current file */ + inc = DIRECTION_PROCESS; + } + } + } /* twice for every path in the home list, ... */ +} + + +/*=export_func optionFileLoad + * + * what: Load the locatable config files, in order + * + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + char const* + pzProg + program name + + * + * ret_type: int + * ret_desc: 0 -> SUCCESS, -1 -> FAILURE + * + * doc: + * + * This function looks in all the specified directories for a configuration + * file ("rc" file or "ini" file) and processes any found twice. The first + * time through, they are processed in reverse order (last file first). At + * that time, only "immediate action" configurables are processed. For + * example, if the last named file specifies not processing any more + * configuration files, then no more configuration files will be processed. + * Such an option in the @strong{first} named directory will have no effect. + * + * Once the immediate action configurables have been handled, then the + * directories are handled in normal, forward order. In that way, later + * config files can override the settings of earlier config files. + * + * See the AutoOpts documentation for a thorough discussion of the + * config file format. + * + * Configuration files not found or not decipherable are simply ignored. + * + * err: Returns the value, "-1" if the program options descriptor + * is out of date or indecipherable. Otherwise, the value "0" will + * always be returned. +=*/ +int +optionFileLoad( tOptions* pOpts, char const* pzProgram ) +{ + if (! SUCCESSFUL( validateOptionsStruct( pOpts, pzProgram ))) + return -1; + + pOpts->pzProgName = pzProgram; + internalFileLoad( pOpts ); + return 0; +} + + +/*=export_func optionLoadOpt + * private: + * + * what: Load an option rc/ini file + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * Processes the options found in the file named with + * pOptDesc->optArg.argString. +=*/ +void +optionLoadOpt( tOptions* pOpts, tOptDesc* pOptDesc ) +{ + /* + * IF the option is not being disabled, THEN load the file. There must + * be a file. (If it is being disabled, then the disablement processing + * already took place. It must be done to suppress preloading of ini/rc + * files.) + */ + if (! DISABLED_OPT( pOptDesc )) { + struct stat sb; + if (stat( pOptDesc->optArg.argString, &sb ) != 0) { + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) + return; + + fprintf( stderr, zFSErrOptLoad, errno, strerror( errno ), + pOptDesc->optArg.argString ); + exit(EX_NOINPUT); + /* NOT REACHED */ + } + + if (! S_ISREG( sb.st_mode )) { + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) + return; + + fprintf( stderr, zNotFile, pOptDesc->optArg.argString ); + exit(EX_NOINPUT); + /* NOT REACHED */ + } + + filePreset(pOpts, pOptDesc->optArg.argString, DIRECTION_CALLED); + } +} + + +/* parseAttributes + * + * Parse the various attributes of an XML-styled config file entry + */ +LOCAL char* +parseAttributes( + tOptions* pOpts, + char* pzText, + tOptionLoadMode* pMode, + tOptionValue* pType ) +{ + size_t lenLoadType = strlen( zLoadType ); + size_t lenKeyWords = strlen( zKeyWords ); + size_t lenSetMem = strlen( zSetMembers ); + + do { + switch (*pzText) { + case '/': pType->valType = OPARG_TYPE_NONE; + case '>': return pzText; + + default: + case NUL: return NULL; + + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + case '\v': + break; + } + + while (isspace( (int)*++pzText )) ; + + if (strncmp( pzText, zLoadType, lenLoadType ) == 0) { + pzText = parseValueType( pzText+lenLoadType, pType ); + continue; + } + + if (strncmp( pzText, zKeyWords, lenKeyWords ) == 0) { + pzText = parseKeyWordType( pOpts, pzText+lenKeyWords, pType ); + continue; + } + + if (strncmp( pzText, zSetMembers, lenSetMem ) == 0) { + pzText = parseSetMemType( pOpts, pzText+lenSetMem, pType ); + continue; + } + + pzText = parseLoadMode( pzText, pMode ); + } while (pzText != NULL); + + return pzText; +} + + +/* parseKeyWordType + * + * "pzText" points to the character after "words=". + * What should follow is a name of a keyword (enumeration) list. + */ +static char* +parseKeyWordType( + tOptions* pOpts, + char* pzText, + tOptionValue* pType ) +{ + return skipUnknown( pzText ); +} + + +/* parseLoadMode + * + * "pzText" points to some name character. We check for "cooked" or + * "uncooked" or "keep". This function should handle any attribute + * that does not have an associated value. + */ +static char* +parseLoadMode( + char* pzText, + tOptionLoadMode* pMode ) +{ + { + size_t len = strlen(zLoadCooked); + if (strncmp( pzText, zLoadCooked, len ) == 0) { + if ( (pzText[len] == '>') + || (pzText[len] == '/') + || isspace((int)pzText[len])) { + *pMode = OPTION_LOAD_COOKED; + return pzText + len; + } + goto unknown; + } + } + + { + size_t len = strlen(zLoadUncooked); + if (strncmp( pzText, zLoadUncooked, len ) == 0) { + if ( (pzText[len] == '>') + || (pzText[len] == '/') + || isspace((int)pzText[len])) { + *pMode = OPTION_LOAD_UNCOOKED; + return pzText + len; + } + goto unknown; + } + } + + { + size_t len = strlen(zLoadKeep); + if (strncmp( pzText, zLoadKeep, len ) == 0) { + if ( (pzText[len] == '>') + || (pzText[len] == '/') + || isspace((int)pzText[len])) { + *pMode = OPTION_LOAD_KEEP; + return pzText + len; + } + goto unknown; + } + } + + unknown: + return skipUnknown( pzText ); +} + + +/* parseSetMemType + * + * "pzText" points to the character after "members=" + * What should follow is a name of a "set membership". + * A collection of bit flags. + */ +static char* +parseSetMemType( + tOptions* pOpts, + char* pzText, + tOptionValue* pType ) +{ + return skipUnknown( pzText ); +} + + +/* parseValueType + * + * "pzText" points to the character after "type=" + */ +static char* +parseValueType( + char* pzText, + tOptionValue* pType ) +{ + { + size_t len = strlen(zLtypeString); + if (strncmp( pzText, zLtypeString, len ) == 0) { + if ((pzText[len] == '>') || isspace((int)pzText[len])) { + pType->valType = OPARG_TYPE_STRING; + return pzText + len; + } + goto unknown; + } + } + + { + size_t len = strlen(zLtypeInteger); + if (strncmp( pzText, zLtypeInteger, len ) == 0) { + if ((pzText[len] == '>') || isspace((int)pzText[len])) { + pType->valType = OPARG_TYPE_NUMERIC; + return pzText + len; + } + goto unknown; + } + } + + { + size_t len = strlen(zLtypeBool); + if (strncmp( pzText, zLtypeBool, len ) == 0) { + if ((pzText[len] == '>') || isspace(pzText[len])) { + pType->valType = OPARG_TYPE_BOOLEAN; + return pzText + len; + } + goto unknown; + } + } + + { + size_t len = strlen(zLtypeKeyword); + if (strncmp( pzText, zLtypeKeyword, len ) == 0) { + if ((pzText[len] == '>') || isspace((int)pzText[len])) { + pType->valType = OPARG_TYPE_ENUMERATION; + return pzText + len; + } + goto unknown; + } + } + + { + size_t len = strlen(zLtypeSetMembership); + if (strncmp( pzText, zLtypeSetMembership, len ) == 0) { + if ((pzText[len] == '>') || isspace((int)pzText[len])) { + pType->valType = OPARG_TYPE_MEMBERSHIP; + return pzText + len; + } + goto unknown; + } + } + + { + size_t len = strlen(zLtypeNest); + if (strncmp( pzText, zLtypeNest, len ) == 0) { + if ((pzText[len] == '>') || isspace((int)pzText[len])) { + pType->valType = OPARG_TYPE_HIERARCHY; + return pzText + len; + } + goto unknown; + } + } + + unknown: + pType->valType = OPARG_TYPE_NONE; + return skipUnknown( pzText ); +} + + +/* skipUnknown + * + * Skip over some unknown attribute + */ +static char* +skipUnknown( char* pzText ) +{ + for (;; pzText++) { + if (isspace( (int)*pzText )) return pzText; + switch (*pzText) { + case NUL: return NULL; + case '/': + case '>': return pzText; + } + } +} + + +/* validateOptionsStruct + * + * Make sure the option descriptor is there and that we understand it. + * This should be called from any user entry point where one needs to + * worry about validity. (Some entry points are free to assume that + * the call is not the first to the library and, thus, that this has + * already been called.) + */ +LOCAL tSuccess +validateOptionsStruct( tOptions* pOpts, char const* pzProgram ) +{ + if (pOpts == NULL) { + fputs( zAO_Bad, stderr ); + exit( EX_CONFIG ); + } + + /* + * IF the client has enabled translation and the translation procedure + * is available, then go do it. + */ + if ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0) + && (pOpts->pTransProc != 0) ) { + (*pOpts->pTransProc)(); + pOpts->fOptSet &= ~OPTPROC_TRANSLATE; + } + + /* + * IF the struct version is not the current, and also + * either too large (?!) or too small, + * THEN emit error message and fail-exit + */ + if ( ( pOpts->structVersion != OPTIONS_STRUCT_VERSION ) + && ( (pOpts->structVersion > OPTIONS_STRUCT_VERSION ) + || (pOpts->structVersion < OPTIONS_MINIMUM_VERSION ) + ) ) { + + fprintf( stderr, zAO_Err, pOpts->origArgVect[0], + NUM_TO_VER( pOpts->structVersion )); + if (pOpts->structVersion > OPTIONS_STRUCT_VERSION ) + fputs( zAO_Big, stderr ); + else + fputs( zAO_Sml, stderr ); + + return FAILURE; + } + + /* + * If the program name hasn't been set, then set the name and the path + * and the set of equivalent characters. + */ + if (pOpts->pzProgName == NULL) { + char const* pz = strrchr( pzProgram, DIRCH ); + + if (pz == NULL) + pOpts->pzProgName = pzProgram; + else pOpts->pzProgName = pz+1; + + pOpts->pzProgPath = pzProgram; + + /* + * when comparing long names, these are equivalent + */ + strequate( zSepChars ); + } + + return SUCCESS; +} + + +/** + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/configfile.c */ diff --git a/contrib/ntp/libopts/cook.c b/contrib/ntp/libopts/cook.c new file mode 100644 index 0000000..bebd123 --- /dev/null +++ b/contrib/ntp/libopts/cook.c @@ -0,0 +1,354 @@ + +/* + * $Id: cook.c,v 4.10 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2006-09-24 15:21:02 bkorb" + * + * This file contains the routines that deal with processing quoted strings + * into an internal format. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +/* = = = END-STATIC-FORWARD = = = */ + +/*=export_func ao_string_cook_escape_char + * private: + * + * what: escape-process a string fragment + * arg: + char const* + pzScan + points to character after the escape + + * arg: + char* + pRes + Where to put the result byte + + * arg: + unsigned int + nl_ch + replacement char if scanned char is \n + + * + * ret-type: unsigned int + * ret-desc: The number of bytes consumed processing the escaped character. + * + * doc: + * + * This function converts "t" into "\t" and all your other favorite + * escapes, including numeric ones: hex and ocatal, too. + * The returned result tells the caller how far to advance the + * scan pointer (passed in). The default is to just pass through the + * escaped character and advance the scan by one. + * + * Some applications need to keep an escaped newline, others need to + * suppress it. This is accomplished by supplying a '\n' replacement + * character that is different from \n, if need be. For example, use + * 0x7F and never emit a 0x7F. + * + * err: @code{NULL} is returned if the string is mal-formed. +=*/ +unsigned int +ao_string_cook_escape_char( char const* pzIn, char* pRes, u_int nl ) +{ + unsigned int res = 1; + + switch (*pRes = *pzIn++) { + case NUL: /* NUL - end of input string */ + return 0; + case '\r': + if (*pzIn != '\n') + return 1; + res++; + /* FALLTHROUGH */ + case '\n': /* NL - emit newline */ + *pRes = (char)nl; + return res; + + case 'a': *pRes = '\a'; break; + case 'b': *pRes = '\b'; break; + case 'f': *pRes = '\f'; break; + case 'n': *pRes = '\n'; break; + case 'r': *pRes = '\r'; break; + case 't': *pRes = '\t'; break; + case 'v': *pRes = '\v'; break; + + case 'x': /* HEX Escape */ + if (isxdigit( (int)*pzIn )) { + unsigned int val; + unsigned char ch = *pzIn++; + + if ((ch >= 'A') && (ch <= 'F')) + val = 10 + (ch - 'A'); + else if ((ch >= 'a') && (ch <= 'f')) + val = 10 + (ch - 'a'); + else val = ch - '0'; + + ch = *pzIn; + + if (! isxdigit( ch )) { + *pRes = val; + res = 2; + break; + } + val <<= 4; + if ((ch >= 'A') && (ch <= 'F')) + val += 10 + (ch - 'A'); + else if ((ch >= 'a') && (ch <= 'f')) + val += 10 + (ch - 'a'); + else val += ch - '0'; + + res = 3; + *pRes = val; + } + break; + + default: + /* + * IF the character copied was an octal digit, + * THEN set the output character to an octal value + */ + if (isdigit( (int)*pRes ) && (*pRes < '8')) { + unsigned int val = *pRes - '0'; + unsigned char ch = *pzIn++; + + /* + * IF the second character is *not* an octal digit, + * THEN save the value and bail + */ + if ((ch < '0') || (ch > '7')) { + *pRes = val; + break; + } + + val = (val<<3) + (ch - '0'); + ch = *pzIn; + res = 2; + + /* + * IF the THIRD character is *not* an octal digit, + * THEN save the value and bail + */ + if ((ch < '0') || (ch > '7')) { + *pRes = val; + break; + } + + /* + * IF the new value would not be too large, + * THEN add on the third and last character value + */ + if ((val<<3) < 0xFF) { + val = (val<<3) + (ch - '0'); + res = 3; + } + + *pRes = val; + break; + } + } + + return res; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * A quoted string has been found. + * Find the end of it and compress any escape sequences. + */ +/*=export_func ao_string_cook + * private: + * + * what: concatenate and escape-process strings + * arg: + char* + pzScan + The *MODIFIABLE* input buffer + + * arg: + int* + pLineCt + The (possibly NULL) pointer to a line count + + * + * ret-type: char* + * ret-desc: The address of the text following the processed strings. + * The return value is NULL if the strings are ill-formed. + * + * doc: + * + * A series of one or more quoted strings are concatenated together. + * If they are quoted with double quotes (@code{"}), then backslash + * escapes are processed per the C programming language. If they are + * single quote strings, then the backslashes are honored only when they + * precede another backslash or a single quote character. + * + * err: @code{NULL} is returned if the string(s) is/are mal-formed. +=*/ +char* +ao_string_cook( char* pzScan, int* pLineCt ) +{ + int l = 0; + char q = *pzScan; + + /* + * It is a quoted string. Process the escape sequence characters + * (in the set "abfnrtv") and make sure we find a closing quote. + */ + char* pzD = pzScan++; + char* pzS = pzScan; + + if (pLineCt == NULL) + pLineCt = &l; + + for (;;) { + /* + * IF the next character is the quote character, THEN we may end the + * string. We end it unless the next non-blank character *after* the + * string happens to also be a quote. If it is, then we will change + * our quote character to the new quote character and continue + * condensing text. + */ + while (*pzS == q) { + *pzD = NUL; /* This is probably the end of the line */ + pzS++; + + scan_for_quote: + while (isspace((int)*pzS)) + if (*(pzS++) == '\n') + (*pLineCt)++; + + /* + * IF the next character is a quote character, + * THEN we will concatenate the strings. + */ + switch (*pzS) { + case '"': + case '\'': + break; + + case '/': + /* + * Allow for a comment embedded in the concatenated string. + */ + switch (pzS[1]) { + default: return NULL; + case '/': + /* + * Skip to end of line + */ + pzS = strchr( pzS, '\n' ); + if (pzS == NULL) + return NULL; + (*pLineCt)++; + break; + + case '*': + { + char* p = strstr( pzS+2, "*/" ); + /* + * Skip to terminating star slash + */ + if (p == NULL) + return NULL; + while (pzS < p) { + if (*(pzS++) == '\n') + (*pLineCt)++; + } + + pzS = p + 2; + } + } + goto scan_for_quote; + + default: + /* + * The next non-whitespace character is not a quote. + * The series of quoted strings has come to an end. + */ + return pzS; + } + + q = *(pzS++); /* assign new quote character and advance scan */ + } + + /* + * We are inside a quoted string. Copy text. + */ + switch (*(pzD++) = *(pzS++)) { + case NUL: + return NULL; + + case '\n': + (*pLineCt)++; + break; + + case '\\': + /* + * IF we are escaping a new line, + * THEN drop both the escape and the newline from + * the result string. + */ + if (*pzS == '\n') { + pzS++; + pzD--; + (*pLineCt)++; + } + + /* + * ELSE IF the quote character is '"' or '`', + * THEN we do the full escape character processing + */ + else if (q != '\'') { + int ct = ao_string_cook_escape_char( pzS, pzD-1, (u_int)'\n' ); + if (ct == 0) + return NULL; + + pzS += ct; + } /* if (q != '\'') */ + + /* + * OTHERWISE, we only process "\\", "\'" and "\#" sequences. + * The latter only to easily hide preprocessing directives. + */ + else switch (*pzS) { + case '\\': + case '\'': + case '#': + pzD[-1] = *pzS++; + } + } /* switch (*(pzD++) = *(pzS++)) */ + } /* for (;;) */ +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/cook.c */ diff --git a/contrib/ntp/libopts/enumeration.c b/contrib/ntp/libopts/enumeration.c new file mode 100644 index 0000000..67dd4f4 --- /dev/null +++ b/contrib/ntp/libopts/enumeration.c @@ -0,0 +1,498 @@ + +/* + * $Id: enumeration.c,v 4.17 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-13 10:22:35 bkorb" + * + * Automated Options Paged Usage module. + * + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +tSCC* pz_enum_err_fmt; + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +enumError( + tOptions* pOpts, + tOptDesc* pOD, + tCC* const * paz_names, + int name_ct ); + +static uintptr_t +findName( + tCC* pzName, + tOptions* pOpts, + tOptDesc* pOD, + tCC* const * paz_names, + unsigned int name_ct ); +/* = = = END-STATIC-FORWARD = = = */ + +static void +enumError( + tOptions* pOpts, + tOptDesc* pOD, + tCC* const * paz_names, + int name_ct ) +{ + size_t max_len = 0; + size_t ttl_len = 0; + + if (pOpts != NULL) + fprintf( option_usage_fp, pz_enum_err_fmt, pOpts->pzProgName, + pOD->optArg.argString, pOD->pz_Name ); + + fprintf( option_usage_fp, zValidKeys, pOD->pz_Name ); + + if (**paz_names == 0x7F) { + paz_names++; + name_ct--; + } + + /* + * Figure out the maximum length of any name, plus the total length + * of all the names. + */ + { + tCC * const * paz = paz_names; + int ct = name_ct; + + do { + size_t len = strlen( *(paz++) ) + 1; + if (len > max_len) + max_len = len; + ttl_len += len; + } while (--ct > 0); + } + + /* + * IF any one entry is about 1/2 line or longer, print one per line + */ + if (max_len > 35) { + do { + fprintf( option_usage_fp, " %s\n", *(paz_names++) ); + } while (--name_ct > 0); + } + + /* + * ELSE IF they all fit on one line, then do so. + */ + else if (ttl_len < 76) { + fputc( ' ', option_usage_fp ); + do { + fputc( ' ', option_usage_fp ); + fputs( *(paz_names++), option_usage_fp ); + } while (--name_ct > 0); + fputc( '\n', option_usage_fp ); + } + + /* + * Otherwise, columnize the output + */ + else { + int ent_no = 0; + char zFmt[16]; /* format for all-but-last entries on a line */ + + sprintf( zFmt, "%%-%ds", (int)max_len ); + max_len = 78 / max_len; /* max_len is now max entries on a line */ + fputs( " ", option_usage_fp ); + + /* + * Loop through all but the last entry + */ + while (--name_ct > 0) { + if (++ent_no == max_len) { + /* + * Last entry on a line. Start next line, too. + */ + fprintf( option_usage_fp, "%s\n ", *(paz_names++) ); + ent_no = 0; + } + + else + fprintf( option_usage_fp, zFmt, *(paz_names++) ); + } + fprintf( option_usage_fp, "%s\n", *paz_names ); + } + + /* + * IF we do not have a pOpts pointer, then this output is being requested + * by the usage procedure. Let's not re-invoke it recursively. + */ + if (pOpts != NULL) + (*(pOpts->pUsageProc))( pOpts, EXIT_FAILURE ); + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) + fputs( zSetMemberSettings, option_usage_fp ); +} + + +static uintptr_t +findName( + tCC* pzName, + tOptions* pOpts, + tOptDesc* pOD, + tCC* const * paz_names, + unsigned int name_ct ) +{ + uintptr_t res = name_ct; + size_t len = strlen( (char*)pzName ); + uintptr_t idx; + /* + * Look for an exact match, but remember any partial matches. + * Multiple partial matches means we have an ambiguous match. + */ + for (idx = 0; idx < name_ct; idx++) { + if (strncmp( (char*)paz_names[idx], (char*)pzName, len) == 0) { + if (paz_names[idx][len] == NUL) + return idx; /* full match */ + + if (res != name_ct) { + pz_enum_err_fmt = zAmbigKey; + option_usage_fp = stderr; + enumError( pOpts, pOD, paz_names, (int)name_ct ); + } + res = idx; /* save partial match */ + } + } + + /* + * no partial match -> error + */ + if (res == name_ct) { + pz_enum_err_fmt = zNoKey; + option_usage_fp = stderr; + enumError( pOpts, pOD, paz_names, (int)name_ct ); + } + + /* + * Return the matching index as a char* pointer. + * The result gets stashed in a char* pointer, so it will have to fit. + */ + return res; +} + + +/*=export_func optionKeywordName + * what: Convert between enumeration values and strings + * private: + * + * arg: tOptDesc*, pOD, enumeration option description + * arg: unsigned int, enum_val, the enumeration value to map + * + * ret_type: char const* + * ret_desc: the enumeration name from const memory + * + * doc: This converts an enumeration value into the matching string. +=*/ +char const* +optionKeywordName( + tOptDesc* pOD, + unsigned int enum_val ) +{ + tOptDesc od; + + od.optArg.argEnum = enum_val; + (*(pOD->pOptProc))( (void*)(2UL), &od ); + return od.optArg.argString; +} + + +/*=export_func optionEnumerationVal + * what: Convert from a string to an enumeration value + * private: + * + * arg: tOptions*, pOpts, the program options descriptor + * arg: tOptDesc*, pOD, enumeration option description + * arg: char const * const *, paz_names, list of enumeration names + * arg: unsigned int, name_ct, number of names in list + * + * ret_type: uintptr_t + * ret_desc: the enumeration value + * + * doc: This converts the optArg.argString string from the option description + * into the index corresponding to an entry in the name list. + * This will match the generated enumeration value. + * Full matches are always accepted. Partial matches are accepted + * if there is only one partial match. +=*/ +uintptr_t +optionEnumerationVal( + tOptions* pOpts, + tOptDesc* pOD, + tCC * const * paz_names, + unsigned int name_ct ) +{ + uintptr_t res = 0UL; + + /* + * IF the program option descriptor pointer is invalid, + * then it is some sort of special request. + */ + switch ((uintptr_t)pOpts) { + case 0UL: + /* + * print the list of enumeration names. + */ + enumError( pOpts, pOD, paz_names, (int)name_ct ); + break; + + case 1UL: + { + unsigned int ix = pOD->optArg.argEnum; + /* + * print the name string. + */ + if (ix >= name_ct) + printf( "INVALID-%d", ix ); + else + fputs( paz_names[ ix ], stdout ); + + break; + } + + case 2UL: + { + tSCC zInval[] = "*INVALID*"; + unsigned int ix = pOD->optArg.argEnum; + /* + * Replace the enumeration value with the name string. + */ + if (ix >= name_ct) + return (uintptr_t)zInval; + + res = (uintptr_t)paz_names[ ix ]; + break; + } + + default: + res = findName( pOD->optArg.argString, pOpts, pOD, paz_names, name_ct ); + + if (pOD->fOptState & OPTST_ALLOC_ARG) { + AGFREE(pOD->optArg.argString); + pOD->fOptState &= ~OPTST_ALLOC_ARG; + pOD->optArg.argString = NULL; + } + } + + return res; +} + + +/*=export_func optionSetMembers + * what: Convert between bit flag values and strings + * private: + * + * arg: tOptions*, pOpts, the program options descriptor + * arg: tOptDesc*, pOD, enumeration option description + * arg: char const * const *, + * paz_names, list of enumeration names + * arg: unsigned int, name_ct, number of names in list + * + * doc: This converts the optArg.argString string from the option description + * into the index corresponding to an entry in the name list. + * This will match the generated enumeration value. + * Full matches are always accepted. Partial matches are accepted + * if there is only one partial match. +=*/ +void +optionSetMembers( + tOptions* pOpts, + tOptDesc* pOD, + tCC* const * paz_names, + unsigned int name_ct ) +{ + /* + * IF the program option descriptor pointer is invalid, + * then it is some sort of special request. + */ + switch ((uintptr_t)pOpts) { + case 0UL: + /* + * print the list of enumeration names. + */ + enumError( pOpts, pOD, paz_names, (int)name_ct ); + return; + + case 1UL: + { + /* + * print the name string. + */ + uintptr_t bits = (uintptr_t)pOD->optCookie; + uintptr_t res = 0; + size_t len = 0; + + while (bits != 0) { + if (bits & 1) { + if (len++ > 0) fputs( " | ", stdout ); + fputs( paz_names[ res ], stdout ); + } + if (++res >= name_ct) break; + bits >>= 1; + } + return; + } + + case 2UL: + { + char* pz; + uintptr_t bits = (uintptr_t)pOD->optCookie; + uintptr_t res = 0; + size_t len = 0; + + /* + * Replace the enumeration value with the name string. + * First, determine the needed length, then allocate and fill in. + */ + while (bits != 0) { + if (bits & 1) + len += strlen( paz_names[ res ]) + 8; + if (++res >= name_ct) break; + bits >>= 1; + } + + pOD->optArg.argString = pz = AGALOC( len, "enum name" ); + + /* + * Start by clearing all the bits. We want to turn off any defaults + * because we will be restoring to current state, not adding to + * the default set of bits. + */ + strcpy( pz, "none" ); + pz += 4; + bits = (uintptr_t)pOD->optCookie; + res = 0; + while (bits != 0) { + if (bits & 1) { + strcpy( pz, " + " ); + strcpy( pz+3, paz_names[ res ]); + pz += strlen( paz_names[ res ]) + 3; + } + if (++res >= name_ct) break; + bits >>= 1; + } + return; + } + + default: + break; + } + + { + tCC* pzArg = pOD->optArg.argString; + uintptr_t res; + if ((pzArg == NULL) || (*pzArg == NUL)) { + pOD->optCookie = (void*)0; + return; + } + + res = (uintptr_t)pOD->optCookie; + for (;;) { + tSCC zSpn[] = " ,|+\t\r\f\n"; + int iv, len; + + pzArg += strspn( pzArg, zSpn ); + iv = (*pzArg == '!'); + if (iv) + pzArg += strspn( pzArg+1, zSpn ) + 1; + + len = strcspn( pzArg, zSpn ); + if (len == 0) + break; + + if ((len == 3) && (strncmp(pzArg, zAll, (size_t)3) == 0)) { + if (iv) + res = 0; + else res = ~0UL; + } + else if ((len == 4) && (strncmp(pzArg, zNone, (size_t)4) == 0)) { + if (! iv) + res = 0; + } + else do { + char* pz; + uintptr_t bit = strtoul( pzArg, &pz, 0 ); + + if (pz != pzArg + len) { + char z[ AO_NAME_SIZE ]; + tCC* p; + if (*pz != NUL) { + if (len >= AO_NAME_LIMIT) + break; + strncpy( z, pzArg, (size_t)len ); + z[len] = NUL; + p = z; + } else { + p = pzArg; + } + + bit = 1UL << findName(p, pOpts, pOD, paz_names, name_ct); + } + if (iv) + res &= ~bit; + else res |= bit; + } while (0); + + if (pzArg[len] == NUL) + break; + pzArg += len + 1; + } + if (name_ct < (8 * sizeof( uintptr_t ))) { + res &= (1UL << name_ct) - 1UL; + } + + pOD->optCookie = (void*)res; + } +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/enumeration.c */ diff --git a/contrib/ntp/libopts/environment.c b/contrib/ntp/libopts/environment.c new file mode 100644 index 0000000..9fb1550 --- /dev/null +++ b/contrib/ntp/libopts/environment.c @@ -0,0 +1,279 @@ + +/* + * $Id: environment.c,v 4.13 2007/04/15 19:01:18 bkorb Exp $ + * Time-stamp: "2007-04-15 11:50:35 bkorb" + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +checkEnvOpt(tOptState * os, char * env_name, + tOptions* pOpts, teEnvPresetType type); +/* = = = END-STATIC-FORWARD = = = */ + +/* + * doPrognameEnv - check for preset values from the ${PROGNAME} + * environment variable. This is accomplished by parsing the text into + * tokens, temporarily replacing the arg vector and calling + * doImmediateOpts and/or doRegularOpts. + */ +LOCAL void +doPrognameEnv( tOptions* pOpts, teEnvPresetType type ) +{ + char const* pczOptStr = getenv( pOpts->pzPROGNAME ); + token_list_t* pTL; + int sv_argc; + tAoUI sv_flag; + char** sv_argv; + + /* + * IF there is no such environment variable + * *or* there is, but we are doing immediate opts and there are + * no immediate opts to do (--help inside $PROGNAME is silly, + * but --no-load-defs is not, so that is marked) + * THEN bail out now. ( + */ + if ( (pczOptStr == NULL) + || ( (type == ENV_IMM) + && ((pOpts->fOptSet & OPTPROC_HAS_IMMED) == 0) ) ) + return; + + /* + * Tokenize the string. If there's nothing of interest, we'll bail + * here immediately. + */ + pTL = ao_string_tokenize( pczOptStr ); + if (pTL == NULL) + return; + + /* + * Substitute our $PROGNAME argument list for the real one + */ + sv_argc = pOpts->origArgCt; + sv_argv = pOpts->origArgVect; + sv_flag = pOpts->fOptSet; + + /* + * We add a bogus pointer to the start of the list. The program name + * has already been pulled from "argv", so it won't get dereferenced. + * The option scanning code will skip the "program name" at the start + * of this list of tokens, so we accommodate this way .... + */ + pOpts->origArgVect = (char**)(pTL->tkn_list - 1); + pOpts->origArgCt = pTL->tkn_ct + 1; + pOpts->fOptSet &= ~OPTPROC_ERRSTOP; + + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + + switch (type) { + case ENV_IMM: + /* + * We know the OPTPROC_HAS_IMMED bit is set. + */ + (void)doImmediateOpts( pOpts ); + break; + + case ENV_NON_IMM: + (void)doRegularOpts( pOpts ); + break; + + default: + /* + * Only to immediate opts if the OPTPROC_HAS_IMMED bit is set. + */ + if (pOpts->fOptSet & OPTPROC_HAS_IMMED) { + (void)doImmediateOpts( pOpts ); + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + } + (void)doRegularOpts( pOpts ); + break; + } + + /* + * Free up the temporary arg vector and restore the original program args. + */ + free( pTL ); + pOpts->origArgVect = sv_argv; + pOpts->origArgCt = sv_argc; + pOpts->fOptSet = sv_flag; +} + +static void +checkEnvOpt(tOptState * os, char * env_name, + tOptions* pOpts, teEnvPresetType type) +{ + os->pzOptArg = getenv( env_name ); + if (os->pzOptArg == NULL) + return; + + os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState; + os->optType = TOPT_UNDEFINED; + + if ( (os->pOD->pz_DisablePfx != NULL) + && (streqvcmp( os->pzOptArg, os->pOD->pz_DisablePfx ) == 0)) { + os->flags |= OPTST_DISABLED; + os->pzOptArg = NULL; + } + + switch (type) { + case ENV_IMM: + /* + * Process only immediate actions + */ + if (DO_IMMEDIATELY(os->flags)) + break; + return; + + case ENV_NON_IMM: + /* + * Process only NON immediate actions + */ + if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags)) + break; + return; + + default: /* process everything */ + break; + } + + /* + * Make sure the option value string is persistent and consistent. + * + * The interpretation of the option value depends + * on the type of value argument the option takes + */ + if (os->pzOptArg != NULL) { + if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) { + os->pzOptArg = NULL; + } else if ( (os->pOD->fOptState & OPTST_ARG_OPTIONAL) + && (*os->pzOptArg == NUL)) { + os->pzOptArg = NULL; + } else if (*os->pzOptArg == NUL) { + os->pzOptArg = zNil; + } else { + AGDUPSTR( os->pzOptArg, os->pzOptArg, "option argument" ); + os->flags |= OPTST_ALLOC_ARG; + } + } + + handleOption( pOpts, os ); +} + +/* + * doEnvPresets - check for preset values from the envrionment + * This routine should process in all, immediate or normal modes.... + */ +LOCAL void +doEnvPresets( tOptions* pOpts, teEnvPresetType type ) +{ + int ct; + tOptState st; + char* pzFlagName; + size_t spaceLeft; + char zEnvName[ AO_NAME_SIZE ]; + + /* + * Finally, see if we are to look at the environment + * variables for initial values. + */ + if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0) + return; + + doPrognameEnv( pOpts, type ); + + ct = pOpts->presetOptCt; + st.pOD = pOpts->pOptDesc; + + pzFlagName = zEnvName + + snprintf( zEnvName, sizeof( zEnvName ), "%s_", pOpts->pzPROGNAME ); + spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1; + + for (;ct-- > 0; st.pOD++) { + /* + * If presetting is disallowed, then skip this entry + */ + if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0) + || (st.pOD->optEquivIndex != NO_EQUIVALENT) ) + continue; + + /* + * IF there is no such environment variable, + * THEN skip this entry, too. + */ + if (strlen( st.pOD->pz_NAME ) >= spaceLeft) + continue; + + /* + * Set up the option state + */ + strcpy( pzFlagName, st.pOD->pz_NAME ); + checkEnvOpt(&st, zEnvName, pOpts, type); + } + + /* + * Special handling for ${PROGNAME_LOAD_OPTS} + */ + if (pOpts->specOptIdx.save_opts != 0) { + st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1; + strcpy( pzFlagName, st.pOD->pz_NAME ); + checkEnvOpt(&st, zEnvName, pOpts, type); + } +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/environment.c */ diff --git a/contrib/ntp/libopts/genshell.c b/contrib/ntp/libopts/genshell.c new file mode 100644 index 0000000..de098a5 --- /dev/null +++ b/contrib/ntp/libopts/genshell.c @@ -0,0 +1,354 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (genshell.c) + * + * It has been AutoGen-ed Saturday May 5, 2007 at 12:02:35 PM PDT + * From the definitions genshell.def + * and the template file options + * + * Generated from AutoOpts 29:0:4 templates. + */ + +/* + * This file was produced by an AutoOpts template. AutoOpts is a + * copyrighted work. This source file is not encumbered by AutoOpts + * licensing, but is provided under the licensing terms chosen by the + * genshellopt author or copyright holder. AutoOpts is licensed under + * the terms of the LGPL. The redistributable library (``libopts'') is + * licensed under the terms of either the LGPL or, at the users discretion, + * the BSD license. See the AutoOpts and/or libopts sources for details. + * + * This source file is copyrighted and licensed under the following terms: + * + * genshellopt copyright 1999-2007 Bruce Korb - all rights reserved + * + * genshellopt 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 of the License, or (at your option) any later version. + * + * genshellopt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with genshellopt. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ + + +#include <limits.h> + +#define OPTION_CODE_COMPILE 1 +#include "genshell.h" + +#ifdef __cplusplus +extern "C" { +#endif +tSCC zCopyright[] = + "genshellopt copyright (c) 1999-2007 Bruce Korb, all rights reserved"; +tSCC zCopyrightNotice[] = + "genshellopt is free software; you can redistribute it and/or\n\ +modify it under the terms of the GNU Lesser General Public\n\ +License as published by the Free Software Foundation; either\n\ +version 2.1 of the License, or (at your option) any later version.\n\n\ +genshellopt is distributed in the hope that it will be useful,\n\ +but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n\ +Lesser General Public License for more details.\n\n\ +You should have received a copy of the GNU Lesser General Public\n\ +License along with genshellopt. If not, write to:\n\ +\tThe Free Software Foundation, Inc.,\n\ +\t51 Franklin Street, Fifth Floor\n\ +\tBoston, MA 02110-1301, USA."; +extern tUsageProc genshelloptUsage; + +#ifndef NULL +# define NULL 0 +#endif +#ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +# define EXIT_FAILURE 1 +#endif +/* + * Script option description: + */ +tSCC zScriptText[] = + "Output Script File"; +tSCC zScript_NAME[] = "SCRIPT"; +tSCC zScript_Name[] = "script"; +#define SCRIPT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Shell option description: + */ +tSCC zShellText[] = + "Shell name (follows \"#!\" magic)"; +tSCC zShell_NAME[] = "SHELL"; +tSCC zNotShell_Name[] = "no-shell"; +tSCC zNotShell_Pfx[] = "no"; +#define zShell_Name (zNotShell_Name + 3) +#define SHELL_FLAGS (OPTST_INITENABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Help/More_Help/Version option descriptions: + */ +tSCC zHelpText[] = "Display usage information and exit"; +tSCC zHelp_Name[] = "help"; + +tSCC zMore_HelpText[] = "Extended usage information passed thru pager"; +tSCC zMore_Help_Name[] = "more-help"; + +tSCC zVersionText[] = "Output version information and exit"; +tSCC zVersion_Name[] = "version"; +/* + * Declare option callback procedures + */ +extern tOptProc + optionPagedUsage, optionPrintVersion; +static tOptProc + doUsageOpt; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Define the Genshellopt Option Descriptions. + */ +static tOptDesc optDesc[ OPTION_CT ] = { + { /* entry idx, value */ 0, VALUE_OPT_SCRIPT, + /* equiv idx, value */ 0, VALUE_OPT_SCRIPT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SCRIPT_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ zScriptText, zScript_NAME, zScript_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_OPT_SHELL, + /* equiv idx, value */ 1, VALUE_OPT_SHELL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SHELL_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ zShellText, zShell_NAME, zShell_Name, + /* disablement strs */ zNotShell_Name, zNotShell_Pfx }, + +#ifdef NO_OPTIONAL_OPT_ARGS +# define VERSION_OPT_FLAGS OPTST_IMM | OPTST_NO_INIT +#else +# define VERSION_OPT_FLAGS OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT +#endif + + { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VERSION_OPT_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPrintVersion, + /* desc, NAME, name */ zVersionText, NULL, zVersion_Name, + /* disablement strs */ NULL, NULL }, + +#undef VERSION_OPT_FLAGS + + + { /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ zHelpText, NULL, zHelp_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ zMore_HelpText, NULL, zMore_Help_Name, + /* disablement strs */ NULL, NULL } +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Define the Genshellopt Option Environment + */ +tSCC zPROGNAME[] = "GENSHELLOPT"; +tSCC zUsageTitle[] = +"genshellopt - Generate Shell Option Processing Script - Ver. 1\n\ +USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n"; +#define zRcName NULL +#define apzHomeList NULL + +tSCC zBugsAddr[] = "autogen-users@lists.sourceforge.net"; +tSCC zExplain[] = "\n\ +Note that `shell' is only useful if the output file does not already\n\ +exist. If it does, then the shell name and optional first argument\n\ +will be extracted from the script file.\n"; +tSCC zDetail[] = "\n\ +If the script file already exists and contains Automated Option Processing\n\ +text, the second line of the file through the ending tag will be replaced\n\ +by the newly generated text. The first `#!' line will be regenerated.\n"; +tSCC zFullVersion[] = GENSHELLOPT_FULL_VERSION; +/* extracted from optcode.tpl near line 408 */ + +#if defined(ENABLE_NLS) +# define OPTPROC_BASE OPTPROC_TRANSLATE + static tOptionXlateProc translate_option_strings; +#else +# define OPTPROC_BASE OPTPROC_NONE +# define translate_option_strings NULL +#endif /* ENABLE_NLS */ + +tOptions genshelloptOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_NEGATIONS + + OPTPROC_NO_ARGS ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zCopyrightNotice, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + genshelloptUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_OPT_MORE_HELP, + 0 /* no option state saving */, + NO_EQUIVALENT /* index of '-#' option */, + NO_EQUIVALENT /* index of default opt */ + }, + 5 /* full option count */, 2 /* user option count */ +}; + +/* + * Create the static procedure(s) declared above. + */ +static void +doUsageOpt( + tOptions* pOptions, + tOptDesc* pOptDesc ) +{ + USAGE( EXIT_SUCCESS ); +} +/* extracted from optcode.tpl near line 514 */ + +#if ENABLE_NLS +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <autoopts/usage-txt.h> + +static char* AO_gettext( char const* pz ); +static void coerce_it(void** s); + +static char* +AO_gettext( char const* pz ) +{ + char* pzRes; + if (pz == NULL) + return NULL; + pzRes = _(pz); + if (pzRes == pz) + return pzRes; + pzRes = strdup( pzRes ); + if (pzRes == NULL) { + fputs( _("No memory for duping translated strings\n"), stderr ); + exit( EXIT_FAILURE ); + } + return pzRes; +} + +static void coerce_it(void** s) { *s = AO_gettext(*s); } +#define COERSION(_f) \ + coerce_it((void*)&(genshelloptOptions._f)) + +/* + * This invokes the translation code (e.g. gettext(3)). + */ +static void +translate_option_strings( void ) +{ + /* + * Guard against re-translation. It won't work. The strings will have + * been changed by the first pass through this code. One shot only. + */ + if (option_usage_text.field_ct == 0) + return; + /* + * Do the translations. The first pointer follows the field count field. + * The field count field is the size of a pointer. + */ + { + char** ppz = (char**)(void*)&(option_usage_text); + int ix = option_usage_text.field_ct; + + do { + ppz++; + *ppz = AO_gettext(*ppz); + } while (--ix > 0); + } + option_usage_text.field_ct = 0; + + { + tOptDesc* pOD = genshelloptOptions.pOptDesc; + int ix = genshelloptOptions.optCt; + + for (;;) { + pOD->pzText = AO_gettext(pOD->pzText); + pOD->pz_NAME = AO_gettext(pOD->pz_NAME); + pOD->pz_Name = AO_gettext(pOD->pz_Name); + pOD->pz_DisableName = AO_gettext(pOD->pz_DisableName); + pOD->pz_DisablePfx = AO_gettext(pOD->pz_DisablePfx); + if (--ix <= 0) + break; + pOD++; + } + } + COERSION(pzCopyright); + COERSION(pzCopyNotice); + COERSION(pzFullVersion); + COERSION(pzUsageTitle); + COERSION(pzExplain); + COERSION(pzDetail); +} + +#endif /* ENABLE_NLS */ + +#ifdef __cplusplus +} +#endif +/* genshell.c ends here */ diff --git a/contrib/ntp/libopts/genshell.h b/contrib/ntp/libopts/genshell.h new file mode 100644 index 0000000..b57677d --- /dev/null +++ b/contrib/ntp/libopts/genshell.h @@ -0,0 +1,149 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (genshell.h) + * + * It has been AutoGen-ed Saturday May 5, 2007 at 12:02:35 PM PDT + * From the definitions genshell.def + * and the template file options + * + * Generated from AutoOpts 29:0:4 templates. + */ + +/* + * This file was produced by an AutoOpts template. AutoOpts is a + * copyrighted work. This header file is not encumbered by AutoOpts + * licensing, but is provided under the licensing terms chosen by the + * genshellopt author or copyright holder. AutoOpts is licensed under + * the terms of the LGPL. The redistributable library (``libopts'') is + * licensed under the terms of either the LGPL or, at the users discretion, + * the BSD license. See the AutoOpts and/or libopts sources for details. + * + * This source file is copyrighted and licensed under the following terms: + * + * genshellopt copyright 1999-2007 Bruce Korb - all rights reserved + * + * genshellopt 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 of the License, or (at your option) any later version. + * + * genshellopt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with genshellopt. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. + */ +/* + * This file contains the programmatic interface to the Automated + * Options generated for the genshellopt program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +#ifndef AUTOOPTS_GENSHELL_H_GUARD +#define AUTOOPTS_GENSHELL_H_GUARD +#include <autoopts/options.h> + +/* + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION 118784 +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif + +/* + * Enumeration of each option: + */ +typedef enum { + INDEX_OPT_SCRIPT = 0, + INDEX_OPT_SHELL = 1, + INDEX_OPT_VERSION = 2, + INDEX_OPT_HELP = 3, + INDEX_OPT_MORE_HELP = 4 +} teOptIndex; + +#define OPTION_CT 5 +#define GENSHELLOPT_VERSION "1" +#define GENSHELLOPT_FULL_VERSION "genshellopt - Generate Shell Option Processing Script - Ver. 1" + +/* + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the teOptIndex enumeration above). + * e.g. HAVE_OPT( SCRIPT ) + */ +#define DESC(n) (genshelloptOptions.pOptDesc[INDEX_OPT_## n]) +#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n))) +#define OPT_ARG(n) (DESC(n).optArg.argString) +#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK) +#define COUNT_OPT(n) (DESC(n).optOccCt) +#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n))) +#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n))) +#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n))) +#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt) +#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs) +#define CLEAR_OPT(n) STMTS( \ + DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ( (DESC(n).fOptState & OPTST_INITENABLED) == 0) \ + DESC(n).fOptState |= OPTST_DISABLED; \ + DESC(n).optCookie = NULL ) + +/* + * Interface defines for specific options. + */ +#define VALUE_OPT_SCRIPT 'o' +#define VALUE_OPT_SHELL 's' + +#define VALUE_OPT_VERSION 'v' +#define VALUE_OPT_HELP '?' +#define VALUE_OPT_MORE_HELP '!' +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_OPTERR STMTS( genshelloptOptions.fOptSet &= ~OPTPROC_ERRSTOP ) +#define ERRSTOP_OPTERR STMTS( genshelloptOptions.fOptSet |= OPTPROC_ERRSTOP ) +#define RESTART_OPT(n) STMTS( \ + genshelloptOptions.curOptIdx = (n); \ + genshelloptOptions.pzCurOpt = NULL ) +#define START_OPT RESTART_OPT(1) +#define USAGE(c) (*genshelloptOptions.pUsageProc)( &genshelloptOptions, c ) +/* extracted from opthead.tpl near line 360 */ + +/* * * * * * + * + * Declare the genshellopt option descriptor. + */ +#ifdef __cplusplus +extern "C" { +#endif + +extern tOptions genshelloptOptions; + +#ifndef _ +# if ENABLE_NLS +# include <stdio.h> + static inline char* aoGetsText( char const* pz ) { + if (pz == NULL) return NULL; + return (char*)gettext( pz ); + } +# define _(s) aoGetsText(s) +# else /* ENABLE_NLS */ +# define _(s) s +# endif /* ENABLE_NLS */ +#endif + +#ifdef __cplusplus +} +#endif +#endif /* AUTOOPTS_GENSHELL_H_GUARD */ +/* genshell.h ends here */ diff --git a/contrib/ntp/libopts/libopts.c b/contrib/ntp/libopts/libopts.c new file mode 100644 index 0000000..feb7557 --- /dev/null +++ b/contrib/ntp/libopts/libopts.c @@ -0,0 +1,30 @@ +#define AUTOOPTS_INTERNAL +#include "compat/compat.h" +#define LOCAL static +#include "autoopts/options.h" +#include "autoopts/usage-txt.h" +#include "genshell.h" +#include "autoopts.h" +#include "proto.h" +#include "autoopts.c" +#include "boolean.c" +#include "configfile.c" +#include "cook.c" +#include "enumeration.c" +#include "environment.c" +#include "genshell.c" +#include "load.c" +#include "makeshell.c" +#include "nested.c" +#include "numeric.c" +#include "pgusage.c" +#include "putshell.c" +#include "restore.c" +#include "save.c" +#include "sort.c" +#include "stack.c" +#include "streqvcmp.c" +#include "text_mmap.c" +#include "tokenize.c" +#include "usage.c" +#include "version.c" diff --git a/contrib/ntp/libopts/load.c b/contrib/ntp/libopts/load.c new file mode 100644 index 0000000..eeeb125 --- /dev/null +++ b/contrib/ntp/libopts/load.c @@ -0,0 +1,563 @@ + +/* + * $Id: load.c,v 4.20 2007/02/04 22:17:39 bkorb Exp $ + * Time-stamp: "2007-02-04 11:54:57 bkorb" + * + * This file contains the routines that deal with processing text strings + * for options, either from a NUL-terminated string passed in or from an + * rc/ini file. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED; + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static ag_bool +insertProgramPath( + char* pzBuf, + int bufSize, + tCC* pzName, + tCC* pzProgPath ); + +static ag_bool +insertEnvVal( + char* pzBuf, + int bufSize, + tCC* pzName, + tCC* pzProgPath ); + +static char* +assembleArgValue( char* pzTxt, tOptionLoadMode mode ); +/* = = = END-STATIC-FORWARD = = = */ + +/*=export_func optionMakePath + * private: + * + * what: translate and construct a path + * arg: + char* + pzBuf + The result buffer + + * arg: + int + bufSize + The size of this buffer + + * arg: + char const* + pzName + The input name + + * arg: + char const* + pzProgPath + The full path of the current program + + * + * ret-type: ag_bool + * ret-desc: AG_TRUE if the name was handled, otherwise AG_FALSE. + * If the name does not start with ``$'', then it is handled + * simply by copying the input name to the output buffer and + * resolving the name with either @code{canonicalize_file_name(3GLIBC)} + * or @code{realpath(3C)}. + * + * doc: + * + * This routine will copy the @code{pzName} input name into the @code{pzBuf} + * output buffer, carefully not exceeding @code{bufSize} bytes. If the + * first character of the input name is a @code{'$'} character, then there + * is special handling: + * @* + * @code{$$} is replaced with the directory name of the @code{pzProgPath}, + * searching @code{$PATH} if necessary. + * @* + * @code{$@} is replaced with the AutoGen package data installation directory + * (aka @code{pkgdatadir}). + * @* + * @code{$NAME} is replaced by the contents of the @code{NAME} environment + * variable. If not found, the search fails. + * + * Please note: both @code{$$} and @code{$NAME} must be at the start of the + * @code{pzName} string and must either be the entire string or be followed + * by the @code{'/'} (backslash on windows) character. + * + * err: @code{AG_FALSE} is returned if: + * @* + * @bullet{} The input name exceeds @code{bufSize} bytes. + * @* + * @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string + * and the next character is not '/'. + * @* + * @bullet{} libopts was built without PKGDATADIR defined and @code{$@@} + * was specified. + * @* + * @bullet{} @code{NAME} is not a known environment variable + * @* + * @bullet{} @code{canonicalize_file_name} or @code{realpath} return + * errors (cannot resolve the resulting path). +=*/ +ag_bool +optionMakePath( + char* pzBuf, + int bufSize, + tCC* pzName, + tCC* pzProgPath ) +{ + size_t name_len = strlen( pzName ); + +# ifndef PKGDATADIR +# define PKGDATADIR "" +# endif + + tSCC pkgdatadir[] = PKGDATADIR; + + ag_bool res = AG_TRUE; + + if (bufSize <= name_len) + return AG_FALSE; + + /* + * IF not an environment variable, just copy the data + */ + if (*pzName != '$') { + tCC* pzS = pzName; + char* pzD = pzBuf; + int ct = bufSize; + + for (;;) { + if ( (*(pzD++) = *(pzS++)) == NUL) + break; + if (--ct <= 0) + return AG_FALSE; + } + } + + /* + * IF the name starts with "$$", then it must be "$$" or + * it must start with "$$/". In either event, replace the "$$" + * with the path to the executable and append a "/" character. + */ + else switch (pzName[1]) { + case NUL: + return AG_FALSE; + + case '$': + res = insertProgramPath( pzBuf, bufSize, pzName, pzProgPath ); + break; + + case '@': + if (pkgdatadir[0] == NUL) + return AG_FALSE; + + if (name_len + sizeof (pkgdatadir) > bufSize) + return AG_FALSE; + + strcpy(pzBuf, pkgdatadir); + strcpy(pzBuf + sizeof(pkgdatadir) - 1, pzName + 2); + break; + + default: + res = insertEnvVal( pzBuf, bufSize, pzName, pzProgPath ); + } + + if (! res) + return AG_FALSE; + +#if defined(HAVE_CANONICALIZE_FILE_NAME) + { + char* pz = canonicalize_file_name(pzBuf); + if (pz == NULL) + return AG_FALSE; + if (strlen(pz) < bufSize) + strcpy(pzBuf, pz); + free(pz); + } + +#elif defined(HAVE_REALPATH) + { + char z[ PATH_MAX+1 ]; + + if (realpath( pzBuf, z ) == NULL) + return AG_FALSE; + + if (strlen(z) < bufSize) + strcpy( pzBuf, z ); + } +#endif + + return AG_TRUE; +} + + +static ag_bool +insertProgramPath( + char* pzBuf, + int bufSize, + tCC* pzName, + tCC* pzProgPath ) +{ + tCC* pzPath; + tCC* pz; + int skip = 2; + + switch (pzName[2]) { + case DIRCH: + skip = 3; + case NUL: + break; + default: + return AG_FALSE; + } + + /* + * See if the path is included in the program name. + * If it is, we're done. Otherwise, we have to hunt + * for the program using "pathfind". + */ + if (strchr( pzProgPath, DIRCH ) != NULL) + pzPath = pzProgPath; + else { + pzPath = pathfind( getenv( "PATH" ), (char*)pzProgPath, "rx" ); + + if (pzPath == NULL) + return AG_FALSE; + } + + pz = strrchr( pzPath, DIRCH ); + + /* + * IF we cannot find a directory name separator, + * THEN we do not have a path name to our executable file. + */ + if (pz == NULL) + return AG_FALSE; + + pzName += skip; + + /* + * Concatenate the file name to the end of the executable path. + * The result may be either a file or a directory. + */ + if ((pz - pzPath)+1 + strlen(pzName) >= bufSize) + return AG_FALSE; + + memcpy( pzBuf, pzPath, (size_t)((pz - pzPath)+1) ); + strcpy( pzBuf + (pz - pzPath) + 1, pzName ); + + /* + * If the "pzPath" path was gotten from "pathfind()", then it was + * allocated and we need to deallocate it. + */ + if (pzPath != pzProgPath) + free( (void*)pzPath ); + return AG_TRUE; +} + + +static ag_bool +insertEnvVal( + char* pzBuf, + int bufSize, + tCC* pzName, + tCC* pzProgPath ) +{ + char* pzDir = pzBuf; + + for (;;) { + int ch = (int)*++pzName; + if (! ISNAMECHAR( ch )) + break; + *(pzDir++) = (char)ch; + } + + if (pzDir == pzBuf) + return AG_FALSE; + + *pzDir = NUL; + + pzDir = getenv( pzBuf ); + + /* + * Environment value not found -- skip the home list entry + */ + if (pzDir == NULL) + return AG_FALSE; + + if (strlen( pzDir ) + 1 + strlen( pzName ) >= bufSize) + return AG_FALSE; + + sprintf( pzBuf, "%s%s", pzDir, pzName ); + return AG_TRUE; +} + + +LOCAL void +mungeString( char* pzTxt, tOptionLoadMode mode ) +{ + char* pzE; + + if (mode == OPTION_LOAD_KEEP) + return; + + if (isspace( (int)*pzTxt )) { + char* pzS = pzTxt; + char* pzD = pzTxt; + while (isspace( (int)*++pzS )) ; + while ((*(pzD++) = *(pzS++)) != NUL) ; + pzE = pzD-1; + } else + pzE = pzTxt + strlen( pzTxt ); + + while ((pzE > pzTxt) && isspace( (int)pzE[-1] )) pzE--; + *pzE = NUL; + + if (mode == OPTION_LOAD_UNCOOKED) + return; + + switch (*pzTxt) { + default: return; + case '"': + case '\'': break; + } + + switch (pzE[-1]) { + default: return; + case '"': + case '\'': break; + } + + (void)ao_string_cook( pzTxt, NULL ); +} + + +static char* +assembleArgValue( char* pzTxt, tOptionLoadMode mode ) +{ + tSCC zBrk[] = " \t:="; + char* pzEnd = strpbrk( pzTxt, zBrk ); + int space_break; + + /* + * Not having an argument to a configurable name is okay. + */ + if (pzEnd == NULL) + return pzTxt + strlen(pzTxt); + + /* + * If we are keeping all whitespace, then the modevalue starts with the + * character that follows the end of the configurable name, regardless + * of which character caused it. + */ + if (mode == OPTION_LOAD_KEEP) { + *(pzEnd++) = NUL; + return pzEnd; + } + + /* + * If the name ended on a white space character, remember that + * because we'll have to skip over an immediately following ':' or '=' + * (and the white space following *that*). + */ + space_break = isspace((int)*pzEnd); + *(pzEnd++) = NUL; + while (isspace((int)*pzEnd)) pzEnd++; + if (space_break && ((*pzEnd == ':') || (*pzEnd == '='))) + while (isspace((int)*++pzEnd)) ; + + return pzEnd; +} + + +/* + * Load an option from a block of text. The text must start with the + * configurable/option name and be followed by its associated value. + * That value may be processed in any of several ways. See "tOptionLoadMode" + * in autoopts.h. + */ +LOCAL void +loadOptionLine( + tOptions* pOpts, + tOptState* pOS, + char* pzLine, + tDirection direction, + tOptionLoadMode load_mode ) +{ + while (isspace( (int)*pzLine )) pzLine++; + + { + char* pzArg = assembleArgValue( pzLine, load_mode ); + + if (! SUCCESSFUL( longOptionFind( pOpts, pzLine, pOS ))) + return; + if (pOS->flags & OPTST_NO_INIT) + return; + pOS->pzOptArg = pzArg; + } + + switch (pOS->flags & (OPTST_IMM|OPTST_DISABLE_IMM)) { + case 0: + /* + * The selected option has no immediate action. + * THEREFORE, if the direction is PRESETTING + * THEN we skip this option. + */ + if (PRESETTING(direction)) + return; + break; + + case OPTST_IMM: + if (PRESETTING(direction)) { + /* + * We are in the presetting direction with an option we handle + * immediately for enablement, but normally for disablement. + * Therefore, skip if disabled. + */ + if ((pOS->flags & OPTST_DISABLED) == 0) + return; + } else { + /* + * We are in the processing direction with an option we handle + * immediately for enablement, but normally for disablement. + * Therefore, skip if NOT disabled. + */ + if ((pOS->flags & OPTST_DISABLED) != 0) + return; + } + break; + + case OPTST_DISABLE_IMM: + if (PRESETTING(direction)) { + /* + * We are in the presetting direction with an option we handle + * immediately for disablement, but normally for disablement. + * Therefore, skip if NOT disabled. + */ + if ((pOS->flags & OPTST_DISABLED) != 0) + return; + } else { + /* + * We are in the processing direction with an option we handle + * immediately for disablement, but normally for disablement. + * Therefore, skip if disabled. + */ + if ((pOS->flags & OPTST_DISABLED) == 0) + return; + } + break; + + case OPTST_IMM|OPTST_DISABLE_IMM: + /* + * The selected option is always for immediate action. + * THEREFORE, if the direction is PROCESSING + * THEN we skip this option. + */ + if (PROCESSING(direction)) + return; + break; + } + + /* + * Fix up the args. + */ + if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) { + if (*pOS->pzOptArg != NUL) + return; + pOS->pzOptArg = NULL; + + } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) { + if (*pOS->pzOptArg == NUL) + pOS->pzOptArg = NULL; + else { + AGDUPSTR( pOS->pzOptArg, pOS->pzOptArg, "option argument" ); + pOS->flags |= OPTST_ALLOC_ARG; + } + + } else { + if (*pOS->pzOptArg == NUL) + pOS->pzOptArg = zNil; + else { + AGDUPSTR( pOS->pzOptArg, pOS->pzOptArg, "option argument" ); + pOS->flags |= OPTST_ALLOC_ARG; + } + } + + { + tOptionLoadMode sv = option_load_mode; + option_load_mode = load_mode; + handleOption( pOpts, pOS ); + option_load_mode = sv; + } +} + + +/*=export_func optionLoadLine + * + * what: process a string for an option name and value + * + * arg: tOptions*, pOpts, program options descriptor + * arg: char const*, pzLine, NUL-terminated text + * + * doc: + * + * This is a client program callable routine for setting options from, for + * example, the contents of a file that they read in. Only one option may + * appear in the text. It will be treated as a normal (non-preset) option. + * + * When passed a pointer to the option struct and a string, it will find + * the option named by the first token on the string and set the option + * argument to the remainder of the string. The caller must NUL terminate + * the string. Any embedded new lines will be included in the option + * argument. If the input looks like one or more quoted strings, then the + * input will be "cooked". The "cooking" is identical to the string + * formation used in AutoGen definition files (@pxref{basic expression}), + * except that you may not use backquotes. + * + * err: Invalid options are silently ignored. Invalid option arguments + * will cause a warning to print, but the function should return. +=*/ +void +optionLoadLine( + tOptions* pOpts, + tCC* pzLine ) +{ + tOptState st = OPTSTATE_INITIALIZER(SET); + char* pz; + AGDUPSTR( pz, pzLine, "user option line" ); + loadOptionLine( pOpts, &st, pz, DIRECTION_PROCESS, OPTION_LOAD_COOKED ); + AGFREE( pz ); +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/load.c */ diff --git a/contrib/ntp/libopts/m4/libopts.m4 b/contrib/ntp/libopts/m4/libopts.m4 new file mode 100644 index 0000000..adc3235 --- /dev/null +++ b/contrib/ntp/libopts/m4/libopts.m4 @@ -0,0 +1,509 @@ +dnl -*- buffer-read-only: t -*- vi: set ro: +dnl +dnl DO NOT EDIT THIS FILE (libopts.m4) +dnl +dnl It has been AutoGen-ed Saturday May 5, 2007 at 12:02:37 PM PDT +dnl From the definitions libopts.def +dnl and the template file conftest.tpl +dnl +dnl do always before generated macros: +dnl +AC_DEFUN([INVOKE_LIBOPTS_MACROS_FIRST],[ +[if test X${INVOKE_LIBOPTS_MACROS_FIRST_done} != Xyes ; then] + # ================= + # AC_HEADER_STDC + # ================= + AC_HEADER_STDC + # ================= + # AC_HEADER_DIRENT + # ================= + AC_HEADER_DIRENT + + # ================= + # AC_CHECK_HEADERS + # ================= + AC_CHECK_HEADERS(dlfcn.h errno.h fcntl.h libgen.h memory.h netinet/in.h \ + setjmp.h sys/mman.h sys/param.h sys/poll.h sys/procset.h sys/select.h \ + sys/socket.h sys/stropts.h sys/time.h sys/un.h sys/wait.h unistd.h \ + utime.h sysexits.h) + + # -------------------------------------------- + # Verify certain entries from AC_CHECK_HEADERS + # -------------------------------------------- + [for f in sys_types sys_mman sys_param sys_stat sys_wait \ + string errno stdlib memory setjmp + do eval as_ac_var=\${ac_cv_header_${f}_h+set} + test "${as_ac_var}" = set] || \ + AC_MSG_ERROR([You must have ${f}.h on your system]) + done + + # ================================================ + # AC_CHECK_HEADERS: stdarg.h is present define HAVE_STDARG_H, otherwise + # if varargs.h is present define HAVE_VARARGS_H. + # ================================================ + AC_CHECK_HEADERS(stdarg.h varargs.h, break) + [if test `eval echo '${'$as_ac_Header'}'` != yes; then] + AC_MSG_ERROR([You must have stdarg.h or varargs.h on your system]) + fi + + # ================================================ + # Similarly for the string.h and strings.h headers + # ================================================ + AC_CHECK_HEADERS(string.h strings.h, break) + [if test `eval echo '${'$as_ac_Header'}'` != yes; then] + AC_MSG_ERROR([You must have string.h or strings.h on your system]) + fi + + # ===================== + # ...and limits headers + # ===================== + AC_CHECK_HEADERS(limits.h sys/limits.h values.h, break) + [if test `eval echo '${'$as_ac_Header'}'` != yes; then] + AC_MSG_ERROR([You must have one of limits.h, sys/limits.h or values.h]) + fi + + # ======================== + # ...and int types headers + # ======================== + AC_CHECK_HEADERS(stdint.h inttypes.h, break) + AC_CHECK_TYPES([int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, + intptr_t, uint_t]) + + # ==================== + # uintptr type & sizes + # ==================== + AC_CHECK_TYPES([uintptr_t], , + [AC_DEFINE([uintptr_t], unsigned long, + [Alternate uintptr_t for systems without it.])]) + AC_CHECK_SIZEOF(char*, 4) + AC_CHECK_SIZEOF(int, 4) + AC_CHECK_SIZEOF(long, 4) + AC_CHECK_SIZEOF(short, 2) + + # ---------------------------------------------------------------------- + # AC_CHECK_LIB for SVR4 libgen, and use it if it defines pathfind. + # ---------------------------------------------------------------------- + AC_CHECK_LIB(gen, pathfind) + AC_FUNC_VPRINTF + AC_CHECK_FUNCS([mmap canonicalize_file_name snprintf strdup strchr strrchr]) +[ INVOKE_LIBOPTS_MACROS_FIRST_done=yes +fi]]) + +dnl +dnl @synopsis INVOKE_LIBOPTS_MACROS +dnl +dnl This macro will invoke the AutoConf macros specified in libopts.def +dnl that have not been disabled with "omit-invocation". +dnl +AC_DEFUN([LIBOPTS_WITH_REGEX_HEADER],[ + AC_ARG_WITH([regex-header], + AC_HELP_STRING([--with-regex-header], [a reg expr header is specified]), + [libopts_cv_with_regex_header=${with_regex_header}], + AC_CACHE_CHECK([whether a reg expr header is specified], libopts_cv_with_regex_header, + libopts_cv_with_regex_header=no) + ) # end of AC_ARG_WITH + + if test "X${libopts_cv_with_regex_header}" != Xno + then + AC_DEFINE_UNQUOTED([REGEX_HEADER],[<${libopts_cv_with_regex_header}>]) + else + AC_DEFINE([REGEX_HEADER],[<regex.h>],[name of regex header file]) + fi + +]) # end of AC_DEFUN of LIBOPTS_WITH_REGEX_HEADER + + +AC_DEFUN([LIBOPTS_WITHLIB_REGEX],[ + AC_ARG_WITH([libregex], + AC_HELP_STRING([--with-libregex], [libregex installation prefix]), + [libopts_cv_with_libregex_root=${with_libregex}], + AC_CACHE_CHECK([whether with-libregex was specified], libopts_cv_with_libregex_root, + libopts_cv_with_libregex_root=no) + ) # end of AC_ARG_WITH libregex + + if test "${with_libguile+set}" = set && \ + test "${withval}" = no + then ## disabled by request + libopts_cv_with_libregex_root=no + libopts_cv_with_libregex_cflags=no + libopts_cv_with_libregex_libs=no + else + + AC_ARG_WITH([libregex-cflags], + AC_HELP_STRING([--with-libregex-cflags], [libregex compile flags]), + [libopts_cv_with_libregex_cflags=${with_regex_cflags}], + AC_CACHE_CHECK([whether with-libregex-cflags was specified], libopts_cv_with_libregex_cflags, + libopts_cv_with_libregex_cflags=no) + ) # end of AC_ARG_WITH libregex-cflags + + AC_ARG_WITH([libregex-libs], + AC_HELP_STRING([--with-libregex-libs], [libregex link command arguments]), + [libopts_cv_with_libregex_libs=${with_regex_libs}], + AC_CACHE_CHECK([whether with-libregex-libs was specified], libopts_cv_with_libregex_libs, + libopts_cv_with_libregex_libs=no) + ) # end of AC_ARG_WITH libregex-libs + + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_cflags=no ;; + * ) libopts_cv_with_libregex_cflags=-I${libopts_cv_with_libregex_root}/include ;; + esac + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_libs=no ;; + * ) libopts_cv_with_libregex_libs="-L${libopts_cv_with_libregex_root}/lib -lregex";; + esac + esac + libopts_save_CPPFLAGS="${CPPFLAGS}" + libopts_save_LIBS="${LIBS}" + fi ## disabled by request + + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${libopts_cv_with_libregex_cflags}" ;; + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_libs="" ;; + * ) + LIBS="${LIBS} ${libopts_cv_with_libregex_libs}" ;; + esac + LIBREGEX_CFLAGS="" + LIBREGEX_LIBS="" + AC_MSG_CHECKING([whether libregex functions properly]) + AC_CACHE_VAL([libopts_cv_with_libregex],[ + AC_TRY_RUN([@%:@include <stdio.h> +@%:@include <stdlib.h> +@%:@include <sys/types.h> +@%:@include REGEX_HEADER +static regex_t re; +void comp_re( char const* pzPat ) { + int res = regcomp( &re, pzPat, REG_EXTENDED|REG_ICASE|REG_NEWLINE ); + if (res == 0) return; + exit( res ); } +int main() { + regmatch_t m@<:@2@:>@; + comp_re( "^.*\@S|@" ); + comp_re( "()|no.*" ); + comp_re( "." ); + if (regexec( &re, "X", 2, m, 0 ) != 0) return 1; + if ((m@<:@0@:>@.rm_so != 0) || (m@<:@0@:>@.rm_eo != 1)) { + fputs( "error: regex -->.<-- did not match\n", stderr ); + return 1; + } + return 0; }], + [libopts_cv_with_libregex=yes], [libopts_cv_with_libregex=no], + [libopts_cv_with_libregex=no]) # end of AC_TRY_RUN + ]) # end of AC_CACHE_VAL for libopts_cv_with_libregex + AC_MSG_RESULT([${libopts_cv_with_libregex}]) + + if test "X${libopts_cv_with_libregex}" != Xno + then + AC_DEFINE([WITH_LIBREGEX],[1], + [Define this if a working libregex can be found]) + else + CPPFLAGS="${libopts_save_CPPFLAGS}" + LIBS="${libopts_save_LIBS}" + fi + +]) # end of AC_DEFUN of LIBOPTS_WITHLIB_REGEX + + +AC_DEFUN([LIBOPTS_RUN_PATHFIND],[ + AC_MSG_CHECKING([whether pathfind(3) works]) + AC_CACHE_VAL([libopts_cv_run_pathfind],[ + AC_TRY_RUN([@%:@include <string.h> +@%:@include <stdlib.h> +int main (int argc, char** argv) { + char* pz = pathfind( getenv( "PATH" ), "sh", "x" ); + return (pz == 0) ? 1 : 0; +}], + [libopts_cv_run_pathfind=yes],[libopts_cv_run_pathfind=no],[libopts_cv_run_pathfind=no] + ) # end of TRY_RUN + ]) # end of AC_CACHE_VAL for libopts_cv_run_pathfind + AC_MSG_RESULT([${libopts_cv_run_pathfind}]) + + if test "X${libopts_cv_run_pathfind}" != Xno + then + AC_DEFINE([HAVE_PATHFIND],[1], + [Define this if pathfind(3) works]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_PATHFIND + + +AC_DEFUN([LIBOPTS_TEST_DEV_ZERO],[ + AC_MSG_CHECKING([whether /dev/zero is readable device]) + AC_CACHE_VAL([libopts_cv_test_dev_zero],[ + libopts_cv_test_dev_zero=`exec 2> /dev/null +dzero=\`ls -lL /dev/zero | egrep ^c......r\` +test -z "${dzero}" && exit 1 +echo ${dzero}` + if test $? -ne 0 + then libopts_cv_test_dev_zero=no + elif test -z "$libopts_cv_test_dev_zero" + then libopts_cv_test_dev_zero=no + fi + ]) # end of CACHE_VAL of libopts_cv_test_dev_zero + AC_MSG_RESULT([${libopts_cv_test_dev_zero}]) + + if test "X${libopts_cv_test_dev_zero}" != Xno + then + AC_DEFINE([HAVE_DEV_ZERO],[1], + [Define this if /dev/zero is readable device]) + fi + +]) # end of AC_DEFUN of LIBOPTS_TEST_DEV_ZERO + + +AC_DEFUN([LIBOPTS_RUN_REALPATH],[ + AC_MSG_CHECKING([whether we have a functional realpath(3C)]) + AC_CACHE_VAL([libopts_cv_run_realpath],[ + AC_TRY_RUN([@%:@include <limits.h> +@%:@include <stdlib.h> +int main (int argc, char** argv) { +@%:@ifndef PATH_MAX +choke me!! +@%:@else + char zPath@<:@PATH_MAX+1@:>@; +@%:@endif + char *pz = realpath(argv@<:@0@:>@, zPath); + return (pz == zPath) ? 0 : 1; +}], + [libopts_cv_run_realpath=yes],[libopts_cv_run_realpath=no],[libopts_cv_run_realpath=no] + ) # end of TRY_RUN + ]) # end of AC_CACHE_VAL for libopts_cv_run_realpath + AC_MSG_RESULT([${libopts_cv_run_realpath}]) + + if test "X${libopts_cv_run_realpath}" != Xno + then + AC_DEFINE([HAVE_REALPATH],[1], + [Define this if we have a functional realpath(3C)]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_REALPATH + + +AC_DEFUN([LIBOPTS_RUN_STRFTIME],[ + AC_MSG_CHECKING([whether strftime() works]) + AC_CACHE_VAL([libopts_cv_run_strftime],[ + AC_TRY_RUN([@%:@include <time.h> +@%:@include <string.h> +char t_buf@<:@ 64 @:>@; +int main() { + static char const z@<:@@:>@ = "Thursday Aug 28 240"; + struct tm tm; + tm.tm_sec = 36; /* seconds after the minute @<:@0, 61@:>@ */ + tm.tm_min = 44; /* minutes after the hour @<:@0, 59@:>@ */ + tm.tm_hour = 12; /* hour since midnight @<:@0, 23@:>@ */ + tm.tm_mday = 28; /* day of the month @<:@1, 31@:>@ */ + tm.tm_mon = 7; /* months since January @<:@0, 11@:>@ */ + tm.tm_year = 86; /* years since 1900 */ + tm.tm_wday = 4; /* days since Sunday @<:@0, 6@:>@ */ + tm.tm_yday = 239; /* days since January 1 @<:@0, 365@:>@ */ + tm.tm_isdst = 1; /* flag for daylight savings time */ + strftime( t_buf, sizeof( t_buf ), "%A %b %d %j", &tm ); + return (strcmp( t_buf, z ) != 0); }], + [libopts_cv_run_strftime=yes],[libopts_cv_run_strftime=no],[libopts_cv_run_strftime=no] + ) # end of TRY_RUN + ]) # end of AC_CACHE_VAL for libopts_cv_run_strftime + AC_MSG_RESULT([${libopts_cv_run_strftime}]) + + if test "X${libopts_cv_run_strftime}" != Xno + then + AC_DEFINE([HAVE_STRFTIME],[1], + [Define this if strftime() works]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_STRFTIME + + +AC_DEFUN([LIBOPTS_RUN_FOPEN_BINARY],[ + AC_MSG_CHECKING([whether fopen accepts "b" mode]) + AC_CACHE_VAL([libopts_cv_run_fopen_binary],[ + AC_TRY_RUN([@%:@include <stdio.h> +int main (int argc, char** argv) { +FILE* fp = fopen("conftest.@S|@ac_ext", "rb"); +return (fp == NULL) ? 1 : fclose(fp); }], + [libopts_cv_run_fopen_binary=yes],[libopts_cv_run_fopen_binary=no],[libopts_cv_run_fopen_binary=no] + ) # end of TRY_RUN + ]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_binary + AC_MSG_RESULT([${libopts_cv_run_fopen_binary}]) + + if test "X${libopts_cv_run_fopen_binary}" != Xno + then + AC_DEFINE([FOPEN_BINARY_FLAG],"b", + [fopen(3) accepts a 'b' in the mode flag]) + else + AC_DEFINE([FOPEN_BINARY_FLAG],"", + [fopen(3) accepts a 'b' in the mode flag]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_BINARY + + +AC_DEFUN([LIBOPTS_RUN_FOPEN_TEXT],[ + AC_MSG_CHECKING([whether fopen accepts "t" mode]) + AC_CACHE_VAL([libopts_cv_run_fopen_text],[ + AC_TRY_RUN([@%:@include <stdio.h> +int main (int argc, char** argv) { +FILE* fp = fopen("conftest.@S|@ac_ext", "rt"); +return (fp == NULL) ? 1 : fclose(fp); }], + [libopts_cv_run_fopen_text=yes],[libopts_cv_run_fopen_text=no],[libopts_cv_run_fopen_text=no] + ) # end of TRY_RUN + ]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_text + AC_MSG_RESULT([${libopts_cv_run_fopen_text}]) + + if test "X${libopts_cv_run_fopen_text}" != Xno + then + AC_DEFINE([FOPEN_TEXT_FLAG],"t", + [fopen(3) accepts a 't' in the mode flag]) + else + AC_DEFINE([FOPEN_TEXT_FLAG],"", + [fopen(3) accepts a 't' in the mode flag]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_TEXT + + +AC_DEFUN([LIBOPTS_DISABLE_OPTIONAL_ARGS],[ + AC_ARG_ENABLE([optional-args], + AC_HELP_STRING([--disable-optional-args], [not wanting optional option args]), + [libopts_cv_enable_optional_args=${enable_optional_args}], + AC_CACHE_CHECK([whether not wanting optional option args], libopts_cv_enable_optional_args, + libopts_cv_enable_optional_args=yes) + ) # end of AC_ARG_ENABLE + + if test "X${libopts_cv_enable_optional_args}" = Xno + then + AC_DEFINE([NO_OPTIONAL_OPT_ARGS], [1], + [Define this if optional arguments are disallowed]) + fi + +]) # end of AC_DEFUN of LIBOPTS_DISABLE_OPTIONAL_ARGS + + +AC_DEFUN([INVOKE_LIBOPTS_MACROS],[ + INVOKE_LIBOPTS_MACROS_FIRST + # Check to see if a reg expr header is specified. + LIBOPTS_WITH_REGEX_HEADER + + # Check to see if a working libregex can be found. + LIBOPTS_WITHLIB_REGEX + + # Check to see if pathfind(3) works. + LIBOPTS_RUN_PATHFIND + + # Check to see if /dev/zero is readable device. + LIBOPTS_TEST_DEV_ZERO + + # Check to see if we have a functional realpath(3C). + LIBOPTS_RUN_REALPATH + + # Check to see if strftime() works. + LIBOPTS_RUN_STRFTIME + + # Check to see if fopen accepts "b" mode. + LIBOPTS_RUN_FOPEN_BINARY + + # Check to see if fopen accepts "t" mode. + LIBOPTS_RUN_FOPEN_TEXT + + # Check to see if not wanting optional option args. + LIBOPTS_DISABLE_OPTIONAL_ARGS + +]) # end AC_DEFUN of INVOKE_LIBOPTS_MACROS + +dnl @synopsis LIBOPTS_CHECK +dnl +dnl Time-stamp: "2006-09-23 19:36:24 bkorb" +dnl Last Committed: $Date: 2006/09/24 02:59:00 $ +dnl +dnl If autoopts-config works, add the linking information to LIBS. +dnl Otherwise, add ``libopts-${ao_rev}'' to SUBDIRS and run all +dnl the config tests that the library needs. Invoke the +dnl "INVOKE_LIBOPTS_MACROS" macro iff we are building libopts. +dnl +dnl Default to system libopts +dnl +AC_DEFUN([LIBOPTS_CHECK],[ + [NEED_LIBOPTS_DIR=''] + m4_pushdef([AO_Libopts_Dir], + [ifelse($1, , [libopts], [$1])]) + AC_SUBST(LIBOPTS_DIR, AO_Libopts_Dir) + AC_ARG_ENABLE([local-libopts], + AC_HELP_STRING([--enable-local-libopts], + [Force using the supplied libopts tearoff code]),[ + if test x$enableval = xyes ; then + AC_MSG_NOTICE([Using supplied libopts tearoff]) + LIBOPTS_LDADD='$(top_builddir)/AO_Libopts_Dir/libopts.la' + LIBOPTS_CFLAGS='-I$(top_srcdir)/AO_Libopts_Dir' + NEED_LIBOPTS_DIR=true + fi]) + + AC_ARG_ENABLE([libopts-install], + AC_HELP_STRING([--disable-libopts-install], + [Do not install libopts with client installation])) + AM_CONDITIONAL([INSTALL_LIBOPTS],[test "X${enable_libopts_install}" != Xno]) + + [if test -z "${NEED_LIBOPTS_DIR}" ; then] + AC_MSG_CHECKING([whether autoopts-config can be found]) + AC_ARG_WITH([autoopts-config], + AC_HELP_STRING([--with-autoopts-config], + [specify the config-info script]), + [lo_cv_with_autoopts_config=${with_autoopts_config}], + AC_CACHE_CHECK([whether autoopts-config is specified], + [lo_cv_with_autoopts_config], + [if autoopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=autoopts-config + elif libopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=libopts-config + else lo_cv_with_autoopts_config=no ; fi]) + ) # end of AC_ARG_WITH + + AC_CACHE_VAL([lo_cv_test_autoopts],[ + if test -z "${lo_cv_with_autoopts_config}" \ + -o X"${lo_cv_with_autoopts_config}" = Xno + then + if autoopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=autoopts-config + elif libopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=libopts-config + else lo_cv_with_autoopts_config=false ; fi + fi + lo_cv_test_autoopts=` + ${lo_cv_with_autoopts_config} --libs` 2> /dev/null + if test $? -ne 0 -o -z "${lo_cv_test_autoopts}" + then lo_cv_test_autoopts=no ; fi + ]) # end of CACHE_VAL + AC_MSG_RESULT([${lo_cv_test_autoopts}]) + + [if test "X${lo_cv_test_autoopts}" != Xno + then + LIBOPTS_LDADD="${lo_cv_test_autoopts}" + LIBOPTS_CFLAGS="`${lo_cv_with_autoopts_config} --cflags`" + else + LIBOPTS_LDADD='$(top_builddir)/]AO_Libopts_Dir[/libopts.la' + LIBOPTS_CFLAGS='-I$(top_srcdir)/]AO_Libopts_Dir[' + NEED_LIBOPTS_DIR=true + fi + fi # end of if test -z "${NEED_LIBOPTS_DIR}"] + + AM_CONDITIONAL([NEED_LIBOPTS], [test -n "${NEED_LIBOPTS_DIR}"]) + AC_SUBST(LIBOPTS_LDADD) + AC_SUBST(LIBOPTS_CFLAGS) + AC_SUBST(LIBOPTS_DIR, AO_Libopts_Dir) + AC_CONFIG_FILES(AO_Libopts_Dir/Makefile) + m4_popdef([AO_Libopts_Dir]) + + [if test -n "${NEED_LIBOPTS_DIR}" ; then] + INVOKE_LIBOPTS_MACROS + else + INVOKE_LIBOPTS_MACROS_FIRST + [fi +# end of AC_DEFUN of LIBOPTS_CHECK] +]) diff --git a/contrib/ntp/libopts/m4/liboptschk.m4 b/contrib/ntp/libopts/m4/liboptschk.m4 new file mode 100644 index 0000000..14e7f27 --- /dev/null +++ b/contrib/ntp/libopts/m4/liboptschk.m4 @@ -0,0 +1,42 @@ +# liboptschk.m4 serial 1 (autogen - 5.7.3) +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Time-stamp: "2006-09-23 19:42:31 bkorb" +dnl Last Committed: $Date: 2006/09/24 02:59:00 $ + +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +AC_PREREQ(2.50) + +AC_DEFUN([ag_FIND_LIBOPTS], + [if test "X${ac_cv_header_autoopts_options_h}" == Xno + then + : + else + f=`autoopts-config cflags` 2>/dev/null + test X"${f}" = X && f=`libopts-config cflags` 2>/dev/null + if test X"${f}" = X + then + : + else + AC_DEFINE([HAVE_LIBOPTS],[1],[define if we can find libopts]) + CFLAGS="${CFLAGS} ${f}" + f=`autoopts-config ldflags` 2>/dev/null + test X"${f}" = X && f=`libopts-config ldflags` 2>/dev/null + LIBS="${LIBS} ${f}" + fi + fi]) diff --git a/contrib/ntp/libopts/makeshell.c b/contrib/ntp/libopts/makeshell.c new file mode 100644 index 0000000..8447d45 --- /dev/null +++ b/contrib/ntp/libopts/makeshell.c @@ -0,0 +1,1122 @@ + +/* + * $Id: makeshell.c,v 4.20 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-27 06:05:45 bkorb" + * + * This module will interpret the options set in the tOptions + * structure and create a Bourne shell script capable of parsing them. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +tOptions* pShellParseOptions = NULL; + +/* * * * * * * * * * * * * * * * * * * * * + * + * Setup Format Strings + */ +tSCC zStartMarker[] = +"# # # # # # # # # # -- do not modify this marker --\n#\n" +"# DO NOT EDIT THIS SECTION"; + +tSCC zPreamble[] = +"%s OF %s\n#\n" +"# From here to the next `-- do not modify this marker --',\n" +"# the text has been generated %s\n"; + +tSCC zEndPreamble[] = +"# From the %s option definitions\n#\n"; + +tSCC zMultiDef[] = "\n" +"if test -z \"${%1$s_%2$s}\"\n" +"then\n" +" %1$s_%2$s_CT=0\n" +"else\n" +" %1$s_%2$s_CT=1\n" +" %1$s_%2$s_1=\"${%1$s_%2$s}\"\n" +"fi\n" +"export %1$s_%2$s_CT"; + +tSCC zSingleDef[] = "\n" +"%1$s_%2$s=\"${%1$s_%2$s-'%3$s'}\"\n" +"%1$s_%2$s_set=false\n" +"export %1$s_%2$s\n"; + +tSCC zSingleNoDef[] = "\n" +"%1$s_%2$s=\"${%1$s_%2$s}\"\n" +"%1$s_%2$s_set=false\n" +"export %1$s_%2$s\n"; + +/* * * * * * * * * * * * * * * * * * * * * + * + * LOOP START + * + * The loop may run in either of two modes: + * all options are named options (loop only) + * regular, marked option processing. + */ +tSCC zLoopCase[] = "\n" +"OPT_PROCESS=true\n" +"OPT_ARG=\"$1\"\n\n" +"while ${OPT_PROCESS} && [ $# -gt 0 ]\ndo\n" +" OPT_ELEMENT=''\n" +" OPT_ARG_VAL=''\n\n" + /* + * 'OPT_ARG' may or may not match the current $1 + */ +" case \"${OPT_ARG}\" in\n" +" -- )\n" +" OPT_PROCESS=false\n" +" shift\n" +" ;;\n\n"; + +tSCC zLoopOnly[] = "\n" +"OPT_ARG=\"$1\"\n\n" +"while [ $# -gt 0 ]\ndo\n" +" OPT_ELEMENT=''\n" +" OPT_ARG_VAL=''\n\n" +" OPT_ARG=\"${1}\"\n"; + +/* * * * * * * * * * * * * * * * + * + * CASE SELECTORS + * + * If the loop runs as a regular option loop, + * then we must have selectors for each acceptable option + * type (long option, flag character and non-option) + */ +tSCC zLongSelection[] = +" --* )\n"; + +tSCC zFlagSelection[] = +" -* )\n"; + +tSCC zEndSelection[] = +" ;;\n\n"; + +tSCC zNoSelection[] = +" * )\n" +" OPT_PROCESS=false\n" +" ;;\n" +" esac\n\n"; + +/* * * * * * * * * * * * * * * * + * + * LOOP END + */ +tSCC zLoopEnd[] = +" if [ -n \"${OPT_ARG_VAL}\" ]\n" +" then\n" +" eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n" +" export %1$s_${OPT_NAME}${OPT_ELEMENT}\n" +" fi\n" +"done\n\n" +"unset OPT_PROCESS || :\n" +"unset OPT_ELEMENT || :\n" +"unset OPT_ARG || :\n" +"unset OPT_ARG_NEEDED || :\n" +"unset OPT_NAME || :\n" +"unset OPT_CODE || :\n" +"unset OPT_ARG_VAL || :\n%2$s"; + +tSCC zTrailerMarker[] = "\n" +"# # # # # # # # # #\n#\n" +"# END OF AUTOMATED OPTION PROCESSING\n" +"#\n# # # # # # # # # # -- do not modify this marker --\n"; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * OPTION SELECTION + */ +tSCC zOptionCase[] = +" case \"${OPT_CODE}\" in\n"; + +tSCC zOptionPartName[] = +" '%s' | \\\n"; + +tSCC zOptionFullName[] = +" '%s' )\n"; + +tSCC zOptionFlag[] = +" '%c' )\n"; + +tSCC zOptionEndSelect[] = +" ;;\n\n"; + +tSCC zOptionUnknown[] = +" * )\n" +" echo Unknown %s: \"${OPT_CODE}\" >&2\n" +" echo \"$%s_USAGE_TEXT\"\n" +" exit 1\n" +" ;;\n" +" esac\n\n"; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * OPTION PROCESSING + * + * Formats for emitting the text for handling particular options + */ +tSCC zTextExit[] = +" echo \"$%s_%s_TEXT\"\n" +" exit 0\n"; + +tSCC zPagedUsageExit[] = +" echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n" +" exit 0\n"; + +tSCC zCmdFmt[] = +" %s\n"; + +tSCC zCountTest[] = +" if [ $%1$s_%2$s_CT -ge %3$d ] ; then\n" +" echo Error: more than %3$d %2$s options >&2\n" +" echo \"$%1$s_USAGE_TEXT\"\n" +" exit 1 ; fi\n"; + +tSCC zMultiArg[] = +" %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n" +" OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n" +" OPT_NAME='%2$s'\n"; + +tSCC zSingleArg[] = +" if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" +" echo Error: duplicate %2$s option >&2\n" +" echo \"$%1$s_USAGE_TEXT\"\n" +" exit 1 ; fi\n" +" %1$s_%2$s_set=true\n" +" OPT_NAME='%2$s'\n"; + +tSCC zNoMultiArg[] = +" %1$s_%2$s_CT=0\n" +" OPT_ELEMENT=''\n" +" %1$s_%2$s='%3$s'\n" +" export %1$s_%2$s\n" +" OPT_NAME='%2$s'\n"; + +tSCC zNoSingleArg[] = +" if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" +" echo Error: duplicate %2$s option >&2\n" +" echo \"$%1$s_USAGE_TEXT\"\n" +" exit 1 ; fi\n" +" %1$s_%2$s_set=true\n" +" %1$s_%2$s='%3$s'\n" +" export %1$s_%2$s\n" +" OPT_NAME='%2$s'\n"; + +tSCC zMayArg[] = +" eval %1$s_%2$s${OPT_ELEMENT}=true\n" +" export %1$s_%2$s${OPT_ELEMENT}\n" +" OPT_ARG_NEEDED=OK\n"; + +tSCC zMustArg[] = +" OPT_ARG_NEEDED=YES\n"; + +tSCC zCantArg[] = +" eval %1$s_%2$s${OPT_ELEMENT}=true\n" +" export %1$s_%2$s${OPT_ELEMENT}\n" +" OPT_ARG_NEEDED=NO\n"; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * LONG OPTION PROCESSING + * + * Formats for emitting the text for handling long option types + */ +tSCC zLongOptInit[] = +" OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n" +" shift\n" +" OPT_ARG=\"$1\"\n\n" +" case \"${OPT_CODE}\" in *=* )\n" +" OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n" +" OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\n"; + +tSCC zLongOptArg[] = +" case \"${OPT_ARG_NEEDED}\" in\n" +" NO )\n" +" OPT_ARG_VAL=''\n" +" ;;\n\n" +" YES )\n" +" if [ -z \"${OPT_ARG_VAL}\" ]\n" +" then\n" +" if [ $# -eq 0 ]\n" +" then\n" +" echo No argument provided for ${OPT_NAME} option >&2\n" +" echo \"$%s_USAGE_TEXT\"\n" +" exit 1\n" +" fi\n\n" +" OPT_ARG_VAL=\"${OPT_ARG}\"\n" +" shift\n" +" OPT_ARG=\"$1\"\n" +" fi\n" +" ;;\n\n" +" OK )\n" +" if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n" +" then\n" +" case \"${OPT_ARG}\" in -* ) ;; * )\n" +" OPT_ARG_VAL=\"${OPT_ARG}\"\n" +" shift\n" +" OPT_ARG=\"$1\" ;; esac\n" +" fi\n" +" ;;\n" +" esac\n"; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * FLAG OPTION PROCESSING + * + * Formats for emitting the text for handling flag option types + */ +tSCC zFlagOptInit[] = +" OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n" +" OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\n"; + +tSCC zFlagOptArg[] = +" case \"${OPT_ARG_NEEDED}\" in\n" +" NO )\n" +" if [ -n \"${OPT_ARG}\" ]\n" +" then\n" +" OPT_ARG=-\"${OPT_ARG}\"\n" +" else\n" +" shift\n" +" OPT_ARG=\"$1\"\n" +" fi\n" +" ;;\n\n" +" YES )\n" +" if [ -n \"${OPT_ARG}\" ]\n" +" then\n" +" OPT_ARG_VAL=\"${OPT_ARG}\"\n\n" +" else\n" +" if [ $# -eq 0 ]\n" +" then\n" +" echo No argument provided for ${OPT_NAME} option >&2\n" +" echo \"$%s_USAGE_TEXT\"\n" +" exit 1\n" +" fi\n" +" shift\n" +" OPT_ARG_VAL=\"$1\"\n" +" fi\n\n" +" shift\n" +" OPT_ARG=\"$1\"\n" +" ;;\n\n" +" OK )\n" +" if [ -n \"${OPT_ARG}\" ]\n" +" then\n" +" OPT_ARG_VAL=\"${OPT_ARG}\"\n" +" shift\n" +" OPT_ARG=\"$1\"\n\n" +" else\n" +" shift\n" +" if [ $# -gt 0 ]\n" +" then\n" +" case \"$1\" in -* ) ;; * )\n" +" OPT_ARG_VAL=\"$1\"\n" +" shift ;; esac\n" +" OPT_ARG=\"$1\"\n" +" fi\n" +" fi\n" +" ;;\n" +" esac\n"; + +tSCC* pzShell = NULL; +static char* pzLeader = NULL; +static char* pzTrailer = NULL; + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD ); + +static void +emitUsage( tOptions* pOpts ); + +static void +emitSetup( tOptions* pOpts ); + +static void +printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc ); + +static void +printOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc ); + +static void +emitFlag( tOptions* pOpts ); + +static void +emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ); + +static void +emitLong( tOptions* pOpts ); + +static void +openOutput( char const* pzFile ); +/* = = = END-STATIC-FORWARD = = = */ + +/*=export_func optionParseShell + * private: + * + * what: Decipher a boolean value + * arg: + tOptions* + pOpts + program options descriptor + + * + * doc: + * Emit a shell script that will parse the command line options. +=*/ +void +optionParseShell( tOptions* pOpts ) +{ + /* + * Check for our SHELL option now. + * IF the output file contains the "#!" magic marker, + * it will override anything we do here. + */ + if (HAVE_OPT( SHELL )) + pzShell = OPT_ARG( SHELL ); + + else if (! ENABLED_OPT( SHELL )) + pzShell = NULL; + + else if ((pzShell = getenv( "SHELL" )), + pzShell == NULL) + + pzShell = "/bin/sh"; + + /* + * Check for a specified output file + */ + if (HAVE_OPT( SCRIPT )) + openOutput( OPT_ARG( SCRIPT )); + + emitUsage( pOpts ); + emitSetup( pOpts ); + + /* + * There are four modes of option processing. + */ + switch (pOpts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) { + case OPTPROC_LONGOPT: + fputs( zLoopCase, stdout ); + + fputs( zLongSelection, stdout ); + fputs( zLongOptInit, stdout ); + emitLong( pOpts ); + printf( zLongOptArg, pOpts->pzPROGNAME ); + fputs( zEndSelection, stdout ); + + fputs( zNoSelection, stdout ); + break; + + case 0: + fputs( zLoopOnly, stdout ); + fputs( zLongOptInit, stdout ); + emitLong( pOpts ); + printf( zLongOptArg, pOpts->pzPROGNAME ); + break; + + case OPTPROC_SHORTOPT: + fputs( zLoopCase, stdout ); + + fputs( zFlagSelection, stdout ); + fputs( zFlagOptInit, stdout ); + emitFlag( pOpts ); + printf( zFlagOptArg, pOpts->pzPROGNAME ); + fputs( zEndSelection, stdout ); + + fputs( zNoSelection, stdout ); + break; + + case OPTPROC_LONGOPT|OPTPROC_SHORTOPT: + fputs( zLoopCase, stdout ); + + fputs( zLongSelection, stdout ); + fputs( zLongOptInit, stdout ); + emitLong( pOpts ); + printf( zLongOptArg, pOpts->pzPROGNAME ); + fputs( zEndSelection, stdout ); + + fputs( zFlagSelection, stdout ); + fputs( zFlagOptInit, stdout ); + emitFlag( pOpts ); + printf( zFlagOptArg, pOpts->pzPROGNAME ); + fputs( zEndSelection, stdout ); + + fputs( zNoSelection, stdout ); + break; + } + + printf( zLoopEnd, pOpts->pzPROGNAME, zTrailerMarker ); + if ((pzTrailer != NULL) && (*pzTrailer != '\0')) + fputs( pzTrailer, stdout ); + else if (ENABLED_OPT( SHELL )) + printf( "\nenv | grep '^%s_'\n", pOpts->pzPROGNAME ); + + fflush( stdout ); + fchmod( STDOUT_FILENO, 0755 ); + fclose( stdout ); +} + + +static void +textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD ) +{ +# define _TT_(n) tSCC z ## n [] = #n; + TEXTTO_TABLE +# undef _TT_ +# define _TT_(n) z ## n , + static char const* apzTTNames[] = { TEXTTO_TABLE }; +# undef _TT_ + +#if defined(__windows__) && !defined(__CYGWIN__) + printf( "%1$s_%2$s_TEXT='no %2$s text'\n", + pOpts->pzPROGNAME, apzTTNames[ whichVar ]); +#else + int nlHoldCt = 0; + int pipeFd[2]; + FILE* fp; + + printf( "%s_%s_TEXT='", pOpts->pzPROGNAME, apzTTNames[ whichVar ]); + fflush( stdout ); + + if (pipe( pipeFd ) != 0) { + fprintf( stderr, zBadPipe, errno, strerror( errno )); + exit( EXIT_FAILURE ); + } + + switch (fork()) { + case -1: + fprintf( stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName); + exit( EXIT_FAILURE ); + break; + + case 0: + dup2( pipeFd[1], STDERR_FILENO ); + dup2( pipeFd[1], STDOUT_FILENO ); + close( pipeFd[0] ); + + switch (whichVar) { + case TT_LONGUSAGE: + (*(pOpts->pUsageProc))( pOpts, EXIT_SUCCESS ); + /* NOTREACHED */ + exit( EXIT_FAILURE ); + + case TT_USAGE: + (*(pOpts->pUsageProc))( pOpts, EXIT_FAILURE ); + /* NOTREACHED */ + exit( EXIT_FAILURE ); + + case TT_VERSION: + if (pOD->fOptState & OPTST_ALLOC_ARG) { + AGFREE(pOD->optArg.argString); + pOD->fOptState &= ~OPTST_ALLOC_ARG; + } + pOD->optArg.argString = "c"; + optionPrintVersion( pOpts, pOD ); + /* NOTREACHED */ + + default: + exit( EXIT_FAILURE ); + } + + default: + close( pipeFd[1] ); + fp = fdopen( pipeFd[0], "r" FOPEN_BINARY_FLAG ); + } + + for (;;) { + int ch = fgetc( fp ); + switch (ch) { + + case '\n': + nlHoldCt++; + break; + + case '\'': + while (nlHoldCt > 0) { + fputc( '\n', stdout ); + nlHoldCt--; + } + fputs( "'\\''", stdout ); + break; + + case EOF: + goto endCharLoop; + + default: + while (nlHoldCt > 0) { + fputc( '\n', stdout ); + nlHoldCt--; + } + fputc( ch, stdout ); + break; + } + } endCharLoop:; + + fputs( "'\n\n", stdout ); + close( pipeFd[0] ); +#endif +} + + +static void +emitUsage( tOptions* pOpts ) +{ + char zTimeBuf[ AO_NAME_SIZE ]; + + /* + * First, switch stdout to the output file name. + * Then, change the program name to the one defined + * by the definitions (rather than the current + * executable name). Down case the upper cased name. + */ + if (pzLeader != NULL) + fputs( pzLeader, stdout ); + + { + tSCC zStdout[] = "stdout"; + tCC* pzOutName; + + { + time_t curTime = time( NULL ); + struct tm* pTime = localtime( &curTime ); + strftime(zTimeBuf, AO_NAME_SIZE, "%A %B %e, %Y at %r %Z", pTime ); + } + + if (HAVE_OPT( SCRIPT )) + pzOutName = OPT_ARG( SCRIPT ); + else pzOutName = zStdout; + + if ((pzLeader == NULL) && (pzShell != NULL)) + printf( "#! %s\n", pzShell ); + + printf( zPreamble, zStartMarker, pzOutName, zTimeBuf ); + } + + /* + * Get a copy of the original program name in lower case + */ + { + char* pzPN = zTimeBuf; + tCC* pz = pOpts->pzPROGNAME; + for (;;) { + if ((*pzPN++ = tolower( *pz++ )) == '\0') + break; + } + } + + printf( zEndPreamble, pOpts->pzPROGNAME ); + + pOpts->pzProgPath = pOpts->pzProgName = zTimeBuf; + textToVariable( pOpts, TT_LONGUSAGE, NULL ); + textToVariable( pOpts, TT_USAGE, NULL ); + + { + tOptDesc* pOptDesc = pOpts->pOptDesc; + int optionCt = pOpts->optCt; + + for (;;) { + if (pOptDesc->pOptProc == optionPrintVersion) { + textToVariable( pOpts, TT_VERSION, pOptDesc ); + break; + } + + if (--optionCt <= 0) + break; + pOptDesc++; + } + } +} + + +static void +emitSetup( tOptions* pOpts ) +{ + tOptDesc* pOptDesc = pOpts->pOptDesc; + int optionCt = pOpts->presetOptCt; + char const* pzFmt; + char const* pzDefault; + + for (;optionCt > 0; pOptDesc++, --optionCt) { + char zVal[16]; + + /* + * Options that are either usage documentation or are compiled out + * are not to be processed. + */ + if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL)) + continue; + + if (pOptDesc->optMaxCt > 1) + pzFmt = zMultiDef; + else pzFmt = zSingleDef; + + /* + * IF this is an enumeration/bitmask option, then convert the value + * to a string before printing the default value. + */ + switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) { + case OPARG_TYPE_ENUMERATION: + (*(pOptDesc->pOptProc))( (tOptions*)2UL, pOptDesc ); + pzDefault = pOptDesc->optArg.argString; + break; + + /* + * Numeric and membership bit options are just printed as a number. + */ + case OPARG_TYPE_NUMERIC: + snprintf( zVal, sizeof( zVal ), "%d", + (int)pOptDesc->optArg.argInt ); + pzDefault = zVal; + break; + + case OPARG_TYPE_MEMBERSHIP: + snprintf( zVal, sizeof( zVal ), "%lu", + (unsigned long)pOptDesc->optArg.argIntptr ); + pzDefault = zVal; + break; + + case OPARG_TYPE_BOOLEAN: + pzDefault = (pOptDesc->optArg.argBool) ? "true" : "false"; + break; + + default: + if (pOptDesc->optArg.argString == NULL) { + if (pzFmt == zSingleDef) + pzFmt = zSingleNoDef; + pzDefault = NULL; + } + else + pzDefault = pOptDesc->optArg.argString; + } + + printf( pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault ); + } +} + + +static void +printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc ) +{ + if (pOptDesc->pOptProc == optionPrintVersion) + printf( zTextExit, pOpts->pzPROGNAME, "VERSION" ); + + else if (pOptDesc->pOptProc == optionPagedUsage) + printf( zPagedUsageExit, pOpts->pzPROGNAME ); + + else if (pOptDesc->pOptProc == optionLoadOpt) { + printf( zCmdFmt, "echo 'Warning: Cannot load options files' >&2" ); + printf( zCmdFmt, "OPT_ARG_NEEDED=YES" ); + + } else if (pOptDesc->pz_NAME == NULL) { + + if (pOptDesc->pOptProc == NULL) { + printf( zCmdFmt, "echo 'Warning: Cannot save options files' " + ">&2" ); + printf( zCmdFmt, "OPT_ARG_NEEDED=OK" ); + } else + printf( zTextExit, pOpts->pzPROGNAME, "LONGUSAGE" ); + + } else { + if (pOptDesc->optMaxCt == 1) + printf( zSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); + else { + if ((unsigned)pOptDesc->optMaxCt < NOLIMIT) + printf( zCountTest, pOpts->pzPROGNAME, + pOptDesc->pz_NAME, pOptDesc->optMaxCt ); + + printf( zMultiArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); + } + + /* + * Fix up the args. + */ + if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) { + printf( zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); + + } else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) { + printf( zMayArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); + + } else { + fputs( zMustArg, stdout ); + } + } + fputs( zOptionEndSelect, stdout ); +} + + +static void +printOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc ) +{ + if (pOptDesc->pOptProc == optionLoadOpt) { + printf( zCmdFmt, "echo 'Warning: Cannot suppress the loading of " + "options files' >&2" ); + + } else if (pOptDesc->optMaxCt == 1) + printf( zNoSingleArg, pOpts->pzPROGNAME, + pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx ); + else + printf( zNoMultiArg, pOpts->pzPROGNAME, + pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx ); + + printf( zCmdFmt, "OPT_ARG_NEEDED=NO" ); + fputs( zOptionEndSelect, stdout ); +} + + +static void +emitFlag( tOptions* pOpts ) +{ + tOptDesc* pOptDesc = pOpts->pOptDesc; + int optionCt = pOpts->optCt; + + fputs( zOptionCase, stdout ); + + for (;optionCt > 0; pOptDesc++, --optionCt) { + + if (SKIP_OPT(pOptDesc)) + continue; + + if (isprint( pOptDesc->optValue )) { + printf( zOptionFlag, pOptDesc->optValue ); + printOptionAction( pOpts, pOptDesc ); + } + } + printf( zOptionUnknown, "flag", pOpts->pzPROGNAME ); +} + + +/* + * Emit the match text for a long option + */ +static void +emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ) +{ + tOptDesc* pOD = pOpts->pOptDesc; + int oCt = pOpts->optCt; + int min = 1; + char zName[ 256 ]; + char* pz = zName; + + for (;;) { + int matchCt = 0; + + /* + * Omit the current option, Documentation opts and compiled out opts. + */ + if ((pOD == pCurOpt) || SKIP_OPT(pOD)){ + if (--oCt <= 0) + break; + pOD++; + continue; + } + + /* + * Check each character of the name case insensitively. + * They must not be the same. They cannot be, because it would + * not compile correctly if they were. + */ + while ( toupper( pOD->pz_Name[matchCt] ) + == toupper( pzMatchName[matchCt] )) + matchCt++; + + if (matchCt > min) + min = matchCt; + + /* + * Check the disablement name, too. + */ + if (pOD->pz_DisableName != NULL) { + matchCt = 0; + while ( toupper( pOD->pz_DisableName[matchCt] ) + == toupper( pzMatchName[matchCt] )) + matchCt++; + if (matchCt > min) + min = matchCt; + } + if (--oCt <= 0) + break; + pOD++; + } + + /* + * IF the 'min' is all or one short of the name length, + * THEN the entire string must be matched. + */ + if ( (pzMatchName[min ] == NUL) + || (pzMatchName[min+1] == NUL) ) + printf( zOptionFullName, pzMatchName ); + + else { + int matchCt = 0; + for (; matchCt <= min; matchCt++) + *pz++ = pzMatchName[matchCt]; + + for (;;) { + *pz = NUL; + printf( zOptionPartName, zName ); + *pz++ = pzMatchName[matchCt++]; + if (pzMatchName[matchCt] == NUL) { + *pz = NUL; + printf( zOptionFullName, zName ); + break; + } + } + } +} + + +/* + * Emit GNU-standard long option handling code + */ +static void +emitLong( tOptions* pOpts ) +{ + tOptDesc* pOD = pOpts->pOptDesc; + int ct = pOpts->optCt; + + fputs( zOptionCase, stdout ); + + /* + * do each option, ... + */ + do { + /* + * Documentation & compiled-out options + */ + if (SKIP_OPT(pOD)) + continue; + + emitMatchExpr( pOD->pz_Name, pOD, pOpts ); + printOptionAction( pOpts, pOD ); + + /* + * Now, do the same thing for the disablement version of the option. + */ + if (pOD->pz_DisableName != NULL) { + emitMatchExpr( pOD->pz_DisableName, pOD, pOpts ); + printOptionInaction( pOpts, pOD ); + } + } while (pOD++, --ct > 0); + + printf( zOptionUnknown, "option", pOpts->pzPROGNAME ); +} + + +static void +openOutput( char const* pzFile ) +{ + FILE* fp; + char* pzData = NULL; + struct stat stbf; + + do { + char* pzScan; + size_t sizeLeft; + + /* + * IF we cannot stat the file, + * THEN assume we are creating a new file. + * Skip the loading of the old data. + */ + if (stat( pzFile, &stbf ) != 0) + break; + + /* + * The file must be a regular file + */ + if (! S_ISREG( stbf.st_mode )) { + fprintf( stderr, zNotFile, pzFile ); + exit( EXIT_FAILURE ); + } + + pzData = AGALOC(stbf.st_size + 1, "file data"); + fp = fopen( pzFile, "r" FOPEN_BINARY_FLAG ); + + sizeLeft = (unsigned)stbf.st_size; + pzScan = pzData; + + /* + * Read in all the data as fast as our OS will let us. + */ + for (;;) { + int inct = fread( (void*)pzScan, (size_t)1, sizeLeft, fp); + if (inct == 0) + break; + + pzScan += inct; + sizeLeft -= inct; + + if (sizeLeft == 0) + break; + } + + /* + * NUL-terminate the leader and look for the trailer + */ + *pzScan = '\0'; + fclose( fp ); + pzScan = strstr( pzData, zStartMarker ); + if (pzScan == NULL) { + pzTrailer = pzData; + break; + } + + *(pzScan++) = NUL; + pzScan = strstr( pzScan, zTrailerMarker ); + if (pzScan == NULL) { + pzTrailer = pzData; + break; + } + + /* + * Check to see if the data contains + * our marker. If it does, then we will skip over it + */ + pzTrailer = pzScan + sizeof( zTrailerMarker ) - 1; + pzLeader = pzData; + } while (AG_FALSE); + + freopen( pzFile, "w" FOPEN_BINARY_FLAG, stdout ); +} + + +/*=export_func genshelloptUsage + * private: + * what: The usage function for the genshellopt generated program + * + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + exitCode + usage text type to produce + + * + * doc: + * This function is used to create the usage strings for the option + * processing shell script code. Two child processes are spawned + * each emitting the usage text in either the short (error exit) + * style or the long style. The generated program will capture this + * and create shell script variables containing the two types of text. +=*/ +void +genshelloptUsage( tOptions* pOpts, int exitCode ) +{ +#if defined(__windows__) && !defined(__CYGWIN__) + optionUsage( pOpts, exitCode ); +#else + /* + * IF not EXIT_SUCCESS, + * THEN emit the short form of usage. + */ + if (exitCode != EXIT_SUCCESS) + optionUsage( pOpts, exitCode ); + fflush( stderr ); + fflush( stdout ); + + option_usage_fp = stdout; + + /* + * First, print our usage + */ + switch (fork()) { + case -1: + optionUsage( pOpts, EXIT_FAILURE ); + /*NOTREACHED*/ + _exit( EXIT_FAILURE ); + + case 0: + pagerState = PAGER_STATE_CHILD; + optionUsage( pOpts, EXIT_SUCCESS ); + /*NOTREACHED*/ + _exit( EXIT_FAILURE ); + + default: + { + int sts; + wait( &sts ); + } + } + + /* + * Generate the pzProgName, since optionProcess() normally + * gets it from the command line + */ + { + char* pz; + AGDUPSTR( pz, pShellParseOptions->pzPROGNAME, "program name" ); + pShellParseOptions->pzProgName = pz; + while (*pz != NUL) { + *pz = tolower( *pz ); + pz++; + } + } + + /* + * Separate the makeshell usage from the client usage + */ + fprintf( option_usage_fp, zGenshell, pShellParseOptions->pzProgName ); + fflush( option_usage_fp ); + + /* + * Now, print the client usage. + */ + switch (fork()) { + case 0: + pagerState = PAGER_STATE_CHILD; + /*FALLTHROUGH*/ + case -1: + optionUsage( pShellParseOptions, EXIT_FAILURE ); + + default: + { + int sts; + wait( &sts ); + } + } + + exit( EXIT_SUCCESS ); +#endif +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/makeshell.c */ diff --git a/contrib/ntp/libopts/nested.c b/contrib/ntp/libopts/nested.c new file mode 100644 index 0000000..b39f8d1 --- /dev/null +++ b/contrib/ntp/libopts/nested.c @@ -0,0 +1,733 @@ + +/* + * $Id: nested.c,v 4.14 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-26 11:04:35 bkorb" + * + * Automated Options Nested Values module. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +removeBackslashes( char* pzSrc ); + +static char const* +scanQuotedString( char const* pzTxt ); + +static tOptionValue* +addStringValue( void** pp, char const* pzName, size_t nameLen, + char const* pzValue, size_t dataLen ); + +static tOptionValue* +addBoolValue( void** pp, char const* pzName, size_t nameLen, + char const* pzValue, size_t dataLen ); + +static tOptionValue* +addNumberValue( void** pp, char const* pzName, size_t nameLen, + char const* pzValue, size_t dataLen ); + +static tOptionValue* +addNestedValue( void** pp, char const* pzName, size_t nameLen, + char* pzValue, size_t dataLen ); + +static char const* +scanNameEntry(char const* pzName, tOptionValue* pRes); + +static char const* +scanXmlEntry( char const* pzName, tOptionValue* pRes ); + +static void +unloadNestedArglist( tArgList* pAL ); + +static void +sortNestedList( tArgList* pAL ); +/* = = = END-STATIC-FORWARD = = = */ + +/* removeBackslashes + * + * This function assumes that all newline characters were preceeded by + * backslashes that need removal. + */ +static void +removeBackslashes( char* pzSrc ) +{ + char* pzD = strchr(pzSrc, '\n'); + + if (pzD == NULL) + return; + *--pzD = '\n'; + + for (;;) { + char ch = ((*pzD++) = *(pzSrc++)); + switch (ch) { + case '\n': *--pzD = ch; break; + case NUL: return; + default: + ; + } + } +} + + +/* scanQuotedString + * + * Find the end of a quoted string, skipping escaped quote characters. + */ +static char const* +scanQuotedString( char const* pzTxt ) +{ + char q = *(pzTxt++); /* remember the type of quote */ + + for (;;) { + char ch = *(pzTxt++); + if (ch == NUL) + return pzTxt-1; + + if (ch == q) + return pzTxt; + + if (ch == '\\') { + ch = *(pzTxt++); + /* + * IF the next character is NUL, drop the backslash, too. + */ + if (ch == NUL) + return pzTxt - 2; + + /* + * IF the quote character or the escape character were escaped, + * then skip both, as long as the string does not end. + */ + if ((ch == q) || (ch == '\\')) { + if (*(pzTxt++) == NUL) + return pzTxt-1; + } + } + } +} + + +/* addStringValue + * + * Associate a name with either a string or no value. + */ +static tOptionValue* +addStringValue( void** pp, char const* pzName, size_t nameLen, + char const* pzValue, size_t dataLen ) +{ + tOptionValue* pNV; + size_t sz = nameLen + dataLen + sizeof(*pNV); + + pNV = AGALOC( sz, "option name/str value pair" ); + if (pNV == NULL) + return NULL; + + if (pzValue == NULL) { + pNV->valType = OPARG_TYPE_NONE; + pNV->pzName = pNV->v.strVal; + + } else { + pNV->valType = OPARG_TYPE_STRING; + if (dataLen > 0) + memcpy( pNV->v.strVal, pzValue, dataLen ); + pNV->v.strVal[dataLen] = NUL; + pNV->pzName = pNV->v.strVal + dataLen + 1; + } + + memcpy( pNV->pzName, pzName, nameLen ); + pNV->pzName[ nameLen ] = NUL; + addArgListEntry( pp, pNV ); + return pNV; +} + + +/* addBoolValue + * + * Associate a name with either a string or no value. + */ +static tOptionValue* +addBoolValue( void** pp, char const* pzName, size_t nameLen, + char const* pzValue, size_t dataLen ) +{ + tOptionValue* pNV; + size_t sz = nameLen + sizeof(*pNV) + 1; + + pNV = AGALOC( sz, "option name/bool value pair" ); + if (pNV == NULL) + return NULL; + while (isspace( (int)*pzValue ) && (dataLen > 0)) { + dataLen--; pzValue++; + } + if (dataLen == 0) + pNV->v.boolVal = 0; + else if (isdigit( (int)*pzValue )) + pNV->v.boolVal = atoi( pzValue ); + else switch (*pzValue) { + case 'f': + case 'F': + case 'n': + case 'N': + pNV->v.boolVal = 0; break; + default: + pNV->v.boolVal = 1; + } + + pNV->valType = OPARG_TYPE_BOOLEAN; + pNV->pzName = (char*)(pNV + 1); + memcpy( pNV->pzName, pzName, nameLen ); + pNV->pzName[ nameLen ] = NUL; + addArgListEntry( pp, pNV ); + return pNV; +} + + +/* addNumberValue + * + * Associate a name with either a string or no value. + */ +static tOptionValue* +addNumberValue( void** pp, char const* pzName, size_t nameLen, + char const* pzValue, size_t dataLen ) +{ + tOptionValue* pNV; + size_t sz = nameLen + sizeof(*pNV) + 1; + + pNV = AGALOC( sz, "option name/bool value pair" ); + if (pNV == NULL) + return NULL; + while (isspace( (int)*pzValue ) && (dataLen > 0)) { + dataLen--; pzValue++; + } + if (dataLen == 0) + pNV->v.boolVal = 0; + else + pNV->v.boolVal = atoi( pzValue ); + + pNV->valType = OPARG_TYPE_NUMERIC; + pNV->pzName = (char*)(pNV + 1); + memcpy( pNV->pzName, pzName, nameLen ); + pNV->pzName[ nameLen ] = NUL; + addArgListEntry( pp, pNV ); + return pNV; +} + + +/* addNestedValue + * + * Associate a name with either a string or no value. + */ +static tOptionValue* +addNestedValue( void** pp, char const* pzName, size_t nameLen, + char* pzValue, size_t dataLen ) +{ + tOptionValue* pNV; + + if (dataLen == 0) { + size_t sz = nameLen + sizeof(*pNV) + 1; + pNV = AGALOC( sz, "empty nested value pair" ); + if (pNV == NULL) + return NULL; + pNV->v.nestVal = NULL; + pNV->valType = OPARG_TYPE_HIERARCHY; + pNV->pzName = (char*)(pNV + 1); + memcpy( pNV->pzName, pzName, nameLen ); + pNV->pzName[ nameLen ] = NUL; + + } else { + pNV = optionLoadNested( pzValue, pzName, nameLen ); + } + + if (pNV != NULL) + addArgListEntry( pp, pNV ); + + return pNV; +} + + +/* scanNameEntry + * + * We have an entry that starts with a name. Find the end of it, cook it + * (if called for) and create the name/value association. + */ +static char const* +scanNameEntry(char const* pzName, tOptionValue* pRes) +{ + tOptionValue* pNV; + char const * pzScan = pzName+1; + char const * pzVal; + size_t nameLen = 1; + size_t dataLen = 0; + + while (ISNAMECHAR( (int)*pzScan )) { pzScan++; nameLen++; } + + while (isspace( (int)*pzScan )) { + char ch = *(pzScan++); + if ((ch == '\n') || (ch == ',')) { + addStringValue(&(pRes->v.nestVal), pzName, nameLen, NULL,(size_t)0); + return pzScan - 1; + } + } + + switch (*pzScan) { + case '=': + case ':': + while (isspace( (int)*++pzScan )) ; + switch (*pzScan) { + case ',': goto comma_char; + case '"': + case '\'': goto quote_char; + case NUL: goto nul_byte; + default: goto default_char; + } + + case ',': + comma_char: + pzScan++; + /* FALLTHROUGH */ + + case NUL: + nul_byte: + addStringValue(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0); + break; + + case '"': + case '\'': + quote_char: + pzVal = pzScan; + pzScan = scanQuotedString( pzScan ); + dataLen = pzScan - pzVal; + pNV = addStringValue( &(pRes->v.nestVal), pzName, nameLen, pzVal, + dataLen ); + if ((pNV != NULL) && (option_load_mode == OPTION_LOAD_COOKED)) + ao_string_cook( pNV->v.strVal, NULL ); + break; + + default: + default_char: + /* + * We have found some strange text value. It ends with a newline + * or a comma. + */ + pzVal = pzScan; + for (;;) { + char ch = *(pzScan++); + switch (ch) { + case NUL: + pzScan--; + dataLen = pzScan - pzVal; + goto string_done; + /* FALLTHROUGH */ + + case '\n': + if ( (pzScan > pzVal + 2) + && (pzScan[-2] == '\\') + && (pzScan[ 0] != NUL)) + continue; + /* FALLTHROUGH */ + + case ',': + dataLen = (pzScan - pzVal) - 1; + string_done: + pNV = addStringValue( &(pRes->v.nestVal), pzName, nameLen, + pzVal, dataLen ); + if (pNV != NULL) + removeBackslashes( pNV->v.strVal ); + goto leave_scan_name; + } + } + break; + } leave_scan_name:; + + return pzScan; +} + + +/* scanXmlEntry + * + * We've found a '<' character. We ignore this if it is a comment or a + * directive. If it is something else, then whatever it is we are looking + * at is bogus. Returning NULL stops processing. + */ +static char const* +scanXmlEntry( char const* pzName, tOptionValue* pRes ) +{ + size_t nameLen = 1, valLen = 0; + char const* pzScan = ++pzName; + char const* pzVal; + tOptionValue valu; + tOptionValue* pNewVal; + tOptionLoadMode save_mode = option_load_mode; + + if (! isalpha((int)*pzName)) { + switch (*pzName) { + default: + pzName = NULL; + break; + + case '!': + pzName = strstr( pzName, "-->" ); + if (pzName != NULL) + pzName += 3; + break; + + case '?': + pzName = strchr( pzName, '>' ); + if (pzName != NULL) + pzName++; + break; + } + return pzName; + } + + while (isalpha( (int)*++pzScan )) nameLen++; + if (nameLen > 64) + return NULL; + valu.valType = OPARG_TYPE_STRING; + + switch (*pzScan) { + case ' ': + case '\t': + pzScan = parseAttributes( + NULL, (char*)pzScan, &option_load_mode, &valu ); + if (*pzScan == '>') { + pzScan++; + break; + } + + if (*pzScan != '/') { + option_load_mode = save_mode; + return NULL; + } + /* FALLTHROUGH */ + + case '/': + if (*++pzScan != '>') { + option_load_mode = save_mode; + return NULL; + } + addStringValue(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0); + option_load_mode = save_mode; + return pzScan+2; + + default: + option_load_mode = save_mode; + return NULL; + + case '>': + pzScan++; + break; + } + + pzVal = pzScan; + + { + char z[68]; + char* pzD = z; + int ct = nameLen; + char const* pzS = pzName; + + *(pzD++) = '<'; + *(pzD++) = '/'; + + do { + *(pzD++) = *(pzS++); + } while (--ct > 0); + *(pzD++) = '>'; + *pzD = NUL; + + pzScan = strstr( pzScan, z ); + if (pzScan == NULL) { + option_load_mode = save_mode; + return NULL; + } + valLen = (pzScan - pzVal); + pzScan += nameLen + 3; + while (isspace( (int)*pzScan )) pzScan++; + } + + switch (valu.valType) { + case OPARG_TYPE_NONE: + addStringValue( &(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0); + break; + + case OPARG_TYPE_STRING: + pNewVal = addStringValue( + &(pRes->v.nestVal), pzName, nameLen, pzVal, valLen); + + if (option_load_mode == OPTION_LOAD_KEEP) + break; + mungeString( pNewVal->v.strVal, option_load_mode ); + break; + + case OPARG_TYPE_BOOLEAN: + addBoolValue( &(pRes->v.nestVal), pzName, nameLen, pzVal, valLen ); + break; + + case OPARG_TYPE_NUMERIC: + addNumberValue( &(pRes->v.nestVal), pzName, nameLen, pzVal, valLen ); + break; + + case OPARG_TYPE_HIERARCHY: + { + char* pz = AGALOC( valLen+1, "hierarchical scan" ); + if (pz == NULL) + break; + memcpy( pz, pzVal, valLen ); + pz[valLen] = NUL; + addNestedValue( &(pRes->v.nestVal), pzName, nameLen, pz, valLen ); + AGFREE(pz); + break; + } + + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + default: + break; + } + + option_load_mode = save_mode; + return pzScan; +} + + +/* unloadNestedArglist + * + * Deallocate a list of option arguments. This must have been gotten from + * a hierarchical option argument, not a stacked list of strings. It is + * an internal call, so it is not validated. The caller is responsible for + * knowing what they are doing. + */ +static void +unloadNestedArglist( tArgList* pAL ) +{ + int ct = pAL->useCt; + tCC** ppNV = pAL->apzArgs; + + while (ct-- > 0) { + tOptionValue* pNV = (tOptionValue*)(void*)*(ppNV++); + if (pNV->valType == OPARG_TYPE_HIERARCHY) + unloadNestedArglist( pNV->v.nestVal ); + AGFREE( pNV ); + } + + AGFREE( (void*)pAL ); +} + + +/*=export_func optionUnloadNested + * + * what: Deallocate the memory for a nested value + * arg: + tOptionValue const * + pOptVal + the hierarchical value + + * + * doc: + * A nested value needs to be deallocated. The pointer passed in should + * have been gotten from a call to @code{configFileLoad()} (See + * @pxref{libopts-configFileLoad}). +=*/ +void +optionUnloadNested( tOptionValue const * pOV ) +{ + if (pOV == NULL) return; + if (pOV->valType != OPARG_TYPE_HIERARCHY) { + errno = EINVAL; + return; + } + + unloadNestedArglist( pOV->v.nestVal ); + + AGFREE( (void*)pOV ); +} + + +/* sortNestedList + * + * This is a _stable_ sort. The entries are sorted alphabetically, + * but within entries of the same name the ordering is unchanged. + * Typically, we also hope the input is sorted. + */ +static void +sortNestedList( tArgList* pAL ) +{ + int ix; + int lm = pAL->useCt; + + /* + * This loop iterates "useCt" - 1 times. + */ + for (ix = 0; ++ix < lm;) { + int iy = ix-1; + tOptionValue* pNewNV = (tOptionValue*)(void*)(pAL->apzArgs[ix]); + tOptionValue* pOldNV = (tOptionValue*)(void*)(pAL->apzArgs[iy]); + + /* + * For as long as the new entry precedes the "old" entry, + * move the old pointer. Stop before trying to extract the + * "-1" entry. + */ + while (strcmp( pOldNV->pzName, pNewNV->pzName ) > 0) { + pAL->apzArgs[iy+1] = (void*)pOldNV; + pOldNV = (tOptionValue*)(void*)(pAL->apzArgs[--iy]); + if (iy < 0) + break; + } + + /* + * Always store the pointer. Sometimes it is redundant, + * but the redundancy is cheaper than a test and branch sequence. + */ + pAL->apzArgs[iy+1] = (void*)pNewNV; + } +} + + +/* optionLoadNested + * private: + * + * what: parse a hierarchical option argument + * arg: + char const* + pzTxt + the text to scan + + * arg: + char const* + pzName + the name for the text + + * arg: + size_t + nameLen + the length of "name" + + * + * ret_type: tOptionValue* + * ret_desc: An allocated, compound value structure + * + * doc: + * A block of text represents a series of values. It may be an + * entire configuration file, or it may be an argument to an + * option that takes a hierarchical value. + */ +LOCAL tOptionValue* +optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen) +{ + tOptionValue* pRes; + tArgList* pAL; + + /* + * Make sure we have some data and we have space to put what we find. + */ + if (pzTxt == NULL) { + errno = EINVAL; + return NULL; + } + while (isspace( (int)*pzTxt )) pzTxt++; + if (*pzTxt == NUL) { + errno = ENOENT; + return NULL; + } + pRes = AGALOC( sizeof(*pRes) + nameLen + 1, "nested args" ); + if (pRes == NULL) { + errno = ENOMEM; + return NULL; + } + pRes->valType = OPARG_TYPE_HIERARCHY; + pRes->pzName = (char*)(pRes + 1); + memcpy( pRes->pzName, pzName, nameLen ); + pRes->pzName[ nameLen ] = NUL; + + pAL = AGALOC( sizeof(*pAL), "nested arg list" ); + if (pAL == NULL) { + AGFREE( pRes ); + return NULL; + } + pRes->v.nestVal = pAL; + pAL->useCt = 0; + pAL->allocCt = MIN_ARG_ALLOC_CT; + + /* + * Scan until we hit a NUL. + */ + do { + while (isspace( (int)*pzTxt )) pzTxt++; + if (isalpha( (int)*pzTxt )) { + pzTxt = scanNameEntry( pzTxt, pRes ); + } + else switch (*pzTxt) { + case NUL: goto scan_done; + case '<': pzTxt = scanXmlEntry( pzTxt, pRes ); + if (*pzTxt == ',') pzTxt++; break; + case '#': pzTxt = strchr( pzTxt, '\n' ); break; + default: goto woops; + } + } while (pzTxt != NULL); scan_done:; + + pAL = pRes->v.nestVal; + if (pAL->useCt != 0) { + sortNestedList( pAL ); + return pRes; + } + + woops: + AGFREE( pRes->v.nestVal ); + AGFREE( pRes ); + return NULL; +} + + +/*=export_func optionNestedVal + * private: + * + * what: parse a hierarchical option argument + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * Nested value was found on the command line +=*/ +void +optionNestedVal( tOptions* pOpts, tOptDesc* pOD ) +{ + tOptionValue* pOV = optionLoadNested( + pOD->optArg.argString, pOD->pz_Name, strlen(pOD->pz_Name)); + + if (pOV != NULL) + addArgListEntry( &(pOD->optCookie), (void*)pOV ); +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/nested.c */ diff --git a/contrib/ntp/libopts/numeric.c b/contrib/ntp/libopts/numeric.c new file mode 100644 index 0000000..05ee9b5 --- /dev/null +++ b/contrib/ntp/libopts/numeric.c @@ -0,0 +1,93 @@ + +/* + * $Id: numeric.c,v 4.11 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-13 10:28:20 bkorb" + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/*=export_func optionNumericVal + * private: + * + * what: Decipher a boolean value + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * Decipher a numeric value. +=*/ +void +optionNumericVal( tOptions* pOpts, tOptDesc* pOD ) +{ + char* pz; + long val; + + /* + * Numeric options may have a range associated with it. + * If it does, the usage procedure requests that it be + * emitted by passing a NULL pOD pointer. + */ + if ((pOD == NULL) || (pOD->optArg.argString == NULL)) + return; + + val = strtol( pOD->optArg.argString, &pz, 0 ); + if (*pz != NUL) { + fprintf( stderr, zNotNumber, pOpts->pzProgName, pOD->optArg.argString ); + (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE); + } + + if (pOD->fOptState & OPTST_ALLOC_ARG) { + AGFREE(pOD->optArg.argString); + pOD->fOptState &= ~OPTST_ALLOC_ARG; + } + + pOD->optArg.argInt = val; +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/numeric.c */ diff --git a/contrib/ntp/libopts/pgusage.c b/contrib/ntp/libopts/pgusage.c new file mode 100644 index 0000000..c417c63 --- /dev/null +++ b/contrib/ntp/libopts/pgusage.c @@ -0,0 +1,157 @@ + +/* + * $Id: pgusage.c,v 4.12 2007/04/28 22:19:23 bkorb Exp $ + * Time-stamp: "2006-07-16 08:13:26 bkorb" + * + * Automated Options Paged Usage module. + * + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +tePagerState pagerState = PAGER_STATE_INITIAL; + +/*=export_func optionPagedUsage + * private: + * + * what: Decipher a boolean value + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * Run the usage output through a pager. + * This is very handy if it is very long. +=*/ +void +optionPagedUsage( tOptions* pOptions, tOptDesc* pOD ) +{ +#if defined(__windows__) && !defined(__CYGWIN__) + (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS ); +#else + static pid_t my_pid; + char zPageUsage[ 1024 ]; + + /* + * IF we are being called after the usage proc is done + * (and thus has called "exit(2)") + * THEN invoke the pager to page through the usage file we created. + */ + switch (pagerState) { + case PAGER_STATE_INITIAL: + { + my_pid = getpid(); +#ifdef HAVE_SNPRINTF + snprintf(zPageUsage, sizeof(zPageUsage), "/tmp/use.%lu", (tAoUL)my_pid); +#else + sprintf( zPageUsage, "/tmp/use.%lu", (tAoUL)my_pid ); +#endif + unlink( zPageUsage ); + + /* + * Set usage output to this temporary file + */ + option_usage_fp = fopen( zPageUsage, "w" FOPEN_BINARY_FLAG ); + if (option_usage_fp == NULL) + _exit( EXIT_FAILURE ); + + pagerState = PAGER_STATE_READY; + + /* + * Set up so this routine gets called during the exit logic + */ + atexit( (void(*)(void))optionPagedUsage ); + + /* + * The usage procedure will now put the usage information into + * the temporary file we created above. + */ + (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS ); + + /*NOTREACHED*/ + _exit( EXIT_FAILURE ); + } + + case PAGER_STATE_READY: + { + tSCC zPage[] = "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu"; + tCC* pzPager = (tCC*)getenv( "PAGER" ); + + /* + * Use the "more(1)" program if "PAGER" has not been defined + */ + if (pzPager == NULL) + pzPager = "more"; + + /* + * Page the file and remove it when done. + */ +#ifdef HAVE_SNPRINTF + snprintf(zPageUsage, sizeof(zPageUsage), zPage, pzPager, (tAoUL)my_pid); +#else + sprintf( zPageUsage, zPage, pzPager, (tAoUL)my_pid ); +#endif + fclose( stderr ); + dup2( STDOUT_FILENO, STDERR_FILENO ); + + (void)system( zPageUsage ); + } + + case PAGER_STATE_CHILD: + /* + * This is a child process used in creating shell script usage. + */ + break; + } +#endif +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/pgusage.c */ diff --git a/contrib/ntp/libopts/proto.h b/contrib/ntp/libopts/proto.h new file mode 100644 index 0000000..e87ab87 --- /dev/null +++ b/contrib/ntp/libopts/proto.h @@ -0,0 +1,91 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * Prototypes for autoopts + * Generated Sat May 5 12:02:36 PDT 2007 + */ +#ifndef AUTOOPTS_PROTO_H_GUARD +#define AUTOOPTS_PROTO_H_GUARD 1 +#ifndef LOCAL +# define LOCAL extern +# define REDEF_LOCAL 1 +#else +# undef REDEF_LOCAL +#endif +/*\n * Extracted from autoopts.c\n */ +LOCAL void * +ao_malloc( size_t sz ); + +LOCAL void * +ao_realloc( void *p, size_t sz ); + +LOCAL void +ao_free( void *p ); + +LOCAL char * +ao_strdup( char const *str ); + +LOCAL tSuccess +handleOption( tOptions* pOpts, tOptState* pOptState ); + +LOCAL tSuccess +longOptionFind( tOptions* pOpts, char* pzOptName, tOptState* pOptState ); + +LOCAL tSuccess +shortOptionFind( tOptions* pOpts, uint_t optValue, tOptState* pOptState ); + +LOCAL tSuccess +doImmediateOpts( tOptions* pOpts ); + +LOCAL tSuccess +doRegularOpts( tOptions* pOpts ); + +/*\n * Extracted from configfile.c\n */ +LOCAL void +internalFileLoad( tOptions* pOpts ); + +LOCAL char* +parseAttributes( + tOptions* pOpts, + char* pzText, + tOptionLoadMode* pMode, + tOptionValue* pType ); + +LOCAL tSuccess +validateOptionsStruct( tOptions* pOpts, char const* pzProgram ); + +/*\n * Extracted from environment.c\n */ +LOCAL void +doPrognameEnv( tOptions* pOpts, teEnvPresetType type ); + +LOCAL void +doEnvPresets( tOptions* pOpts, teEnvPresetType type ); + +/*\n * Extracted from load.c\n */ +LOCAL void +mungeString( char* pzTxt, tOptionLoadMode mode ); + +LOCAL void +loadOptionLine( + tOptions* pOpts, + tOptState* pOS, + char* pzLine, + tDirection direction, + tOptionLoadMode load_mode ); + +/*\n * Extracted from nested.c\n */ +LOCAL tOptionValue* +optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen); + +/*\n * Extracted from sort.c\n */ +LOCAL void +optionSort( tOptions* pOpts ); + +/*\n * Extracted from stack.c\n */ +LOCAL void +addArgListEntry( void** ppAL, void* entry ); + +#ifdef REDEF_LOCAL +# undef LOCAL +# define LOCAL +#endif +#endif /* AUTOOPTS_PROTO_H_GUARD */ diff --git a/contrib/ntp/libopts/putshell.c b/contrib/ntp/libopts/putshell.c new file mode 100644 index 0000000..93d9ef5 --- /dev/null +++ b/contrib/ntp/libopts/putshell.c @@ -0,0 +1,335 @@ + +/* + * $Id: putshell.c,v 4.18 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-13 10:29:39 bkorb" + * + * This module will interpret the options set in the tOptions + * structure and print them to standard out in a fashion that + * will allow them to be interpreted by the Bourne or Korn shells. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +putQuotedStr( tCC* pzStr ); +/* = = = END-STATIC-FORWARD = = = */ + +/* + * Make sure embedded single quotes come out okay. The initial quote has + * been emitted and the closing quote will be upon return. + */ +static void +putQuotedStr( tCC* pzStr ) +{ + /* + * Handle empty strings to make the rest of the logic simpler. + */ + if ((pzStr == NULL) || (*pzStr == NUL)) { + fputs( "''", stdout ); + return; + } + + /* + * Emit any single quotes/apostrophes at the start of the string and + * bail if that is all we need to do. + */ + while (*pzStr == '\'') { + fputs( "\\'", stdout ); + pzStr++; + } + if (*pzStr == NUL) + return; + + /* + * Start the single quote string + */ + fputc( '\'', stdout ); + for (;;) { + tCC* pz = strchr( pzStr, '\'' ); + if (pz == NULL) + break; + + /* + * Emit the string up to the single quote (apostrophe) we just found. + */ + (void)fwrite( pzStr, (size_t)(pz - pzStr), (size_t)1, stdout ); + fputc( '\'', stdout ); + pzStr = pz; + + /* + * Emit an escaped apostrophe for every one we find. + * If that ends the string, do not re-open the single quotes. + */ + while (*++pzStr == '\'') fputs( "\\'", stdout ); + if (*pzStr == NUL) + return; + + fputc( '\'', stdout ); + } + + /* + * If we broke out of the loop, we must still emit the remaining text + * and then close the single quote string. + */ + fputs( pzStr, stdout ); + fputc( '\'', stdout ); +} + + +/*=export_func optionPutShell + * what: write a portable shell script to parse options + * private: + * arg: tOptions*, pOpts, the program options descriptor + * doc: This routine will emit portable shell script text for parsing + * the options described in the option definitions. +=*/ +void +optionPutShell( tOptions* pOpts ) +{ + int optIx = 0; + tSCC zOptCtFmt[] = "OPTION_CT=%d\nexport OPTION_CT\n"; + tSCC zOptNumFmt[] = "%1$s_%2$s=%3$d # 0x%3$X\nexport %1$s_%2$s\n"; + tSCC zOptDisabl[] = "%1$s_%2$s=%3$s\nexport %1$s_%2$s\n"; + tSCC zOptValFmt[] = "%s_%s="; + tSCC zOptEnd[] = "\nexport %s_%s\n"; + tSCC zFullOptFmt[]= "%1$s_%2$s='%3$s'\nexport %1$s_%2$s\n"; + tSCC zEquivMode[] = "%1$s_%2$s_MODE='%3$s'\nexport %1$s_%2$s_MODE\n"; + + printf( zOptCtFmt, pOpts->curOptIdx-1 ); + + do { + tOptDesc* pOD = pOpts->pOptDesc + optIx; + + if (SKIP_OPT(pOD)) + continue; + + /* + * Equivalence classes are hard to deal with. Where the + * option data wind up kind of squishes around. For the purposes + * of emitting shell state, they are not recommended, but we'll + * do something. I guess we'll emit the equivalenced-to option + * at the point in time when the base option is found. + */ + if (pOD->optEquivIndex != NO_EQUIVALENT) + continue; /* equivalence to a different option */ + + /* + * Equivalenced to a different option. Process the current option + * as the equivalenced-to option. Keep the persistent state bits, + * but copy over the set-state bits. + */ + if (pOD->optActualIndex != optIx) { + tOptDesc* p = pOpts->pOptDesc + pOD->optActualIndex; + p->optArg = pOD->optArg; + p->fOptState &= OPTST_PERSISTENT_MASK; + p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK; + printf( zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME ); + pOD = p; + } + + /* + * If the argument type is a set membership bitmask, then we always + * emit the thing. We do this because it will always have some sort + * of bitmask value and we need to emit the bit values. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) { + char const * pz; + uintptr_t val = 1; + printf( zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (int)(uintptr_t)(pOD->optCookie) ); + pOD->optCookie = (void*)(uintptr_t)~0UL; + (*(pOD->pOptProc))( (tOptions*)2UL, pOD ); + + /* + * We are building the typeset list. The list returned starts with + * 'none + ' for use by option saving stuff. We must ignore that. + */ + pz = pOD->optArg.argString + 7; + while (*pz != NUL) { + printf( "typeset -x -i %s_", pOD->pz_NAME ); + pz += strspn( pz, " +\t\n\f" ); + for (;;) { + int ch = *(pz++); + if (islower( ch )) fputc( toupper( ch ), stdout ); + else if (isalnum( ch )) fputc( ch, stdout ); + else if (isspace( ch ) + || (ch == '+')) goto name_done; + else if (ch == NUL) { pz--; goto name_done; } + else fputc( '_', stdout ); + } name_done:; + printf( "=%1$lu # 0x%1$lX\n", (unsigned long)val ); + val <<= 1; + } + + AGFREE(pOD->optArg.argString); + pOD->optArg.argString = NULL; + pOD->fOptState &= ~OPTST_ALLOC_ARG; + continue; + } + + /* + * IF the option was either specified or it wakes up enabled, + * then we will emit information. Otherwise, skip it. + * The idea is that if someone defines an option to initialize + * enabled, we should tell our shell script that it is enabled. + */ + if (UNUSED_OPT( pOD ) && DISABLED_OPT( pOD )) + continue; + + /* + * Handle stacked arguments + */ + if ( (pOD->fOptState & OPTST_STACKED) + && (pOD->optCookie != NULL) ) { + tSCC zOptCookieCt[] = "%1$s_%2$s_CT=%3$d\nexport %1$s_%2$s_CT\n"; + + tArgList* pAL = (tArgList*)pOD->optCookie; + tCC** ppz = pAL->apzArgs; + int ct = pAL->useCt; + + printf( zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct ); + + while (--ct >= 0) { + tSCC numarg_z[] = "%s_%s_%d="; + tSCC end_z[] = "\nexport %s_%s_%d\n"; + + printf( numarg_z, pOpts->pzPROGNAME, pOD->pz_NAME, + pAL->useCt - ct ); + putQuotedStr( *(ppz++) ); + printf( end_z, pOpts->pzPROGNAME, pOD->pz_NAME, + pAL->useCt - ct ); + } + } + + /* + * If the argument has been disabled, + * Then set its value to the disablement string + */ + else if ((pOD->fOptState & OPTST_DISABLED) != 0) + printf( zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME, + (pOD->pz_DisablePfx != NULL) + ? pOD->pz_DisablePfx : "false" ); + + /* + * If the argument type is numeric, the last arg pointer + * is really the VALUE of the string that was pointed to. + */ + else if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) + printf( zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (int)pOD->optArg.argInt ); + + /* + * If the argument type is an enumeration, then it is much + * like a text value, except we call the callback function + * to emit the value corresponding to the "optArg" number. + */ + else if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) { + printf( zOptValFmt, pOpts->pzPROGNAME, pOD->pz_NAME ); + fputc( '\'', stdout ); + (*(pOD->pOptProc))( (tOptions*)1UL, pOD ); + fputc( '\'', stdout ); + printf( zOptEnd, pOpts->pzPROGNAME, pOD->pz_NAME ); + } + + /* + * If the argument type is numeric, the last arg pointer + * is really the VALUE of the string that was pointed to. + */ + else if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) + printf( zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (pOD->optArg.argBool == 0) ? "false" : "true" ); + + /* + * IF the option has an empty value, + * THEN we set the argument to the occurrence count. + */ + else if ( (pOD->optArg.argString == NULL) + || (pOD->optArg.argString[0] == NUL) ) + + printf( zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + pOD->optOccCt ); + + /* + * This option has a text value + */ + else { + printf( zOptValFmt, pOpts->pzPROGNAME, pOD->pz_NAME ); + putQuotedStr( pOD->optArg.argString ); + printf( zOptEnd, pOpts->pzPROGNAME, pOD->pz_NAME ); + } + } while (++optIx < pOpts->presetOptCt ); + + if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0) + && (pOpts->curOptIdx < pOpts->origArgCt)) { + fputs( "set --", stdout ); + for (optIx = pOpts->curOptIdx; optIx < pOpts->origArgCt; optIx++) { + char* pzArg = pOpts->origArgVect[ optIx ]; + if (strchr( pzArg, '\'' ) == NULL) + printf( " '%s'", pzArg ); + else { + fputs( " '", stdout ); + for (;;) { + char ch = *(pzArg++); + switch (ch) { + case '\'': fputs( "'\\''", stdout ); break; + case NUL: goto arg_done; + default: fputc( ch, stdout ); break; + } + } arg_done:; + fputc( '\'', stdout ); + } + } + fputs( "\nOPTION_CT=0\n", stdout ); + } +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/putshell.c */ diff --git a/contrib/ntp/libopts/restore.c b/contrib/ntp/libopts/restore.c new file mode 100644 index 0000000..91eac08 --- /dev/null +++ b/contrib/ntp/libopts/restore.c @@ -0,0 +1,250 @@ + +/* + * restore.c $Id: restore.c,v 4.10 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-13 14:13:17 bkorb" + * + * This module's routines will save the current option state to memory + * and restore it. If saved prior to the initial optionProcess call, + * then the initial state will be restored. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* + * optionFixupSavedOpts Really, it just wipes out option state for + * options that are troublesome to copy. viz., stacked strings and + * hierarcicaly valued option args. We do duplicate string args that + * have been marked as allocated though. + */ +static void +fixupSavedOptionArgs(tOptions* pOpts) +{ + tOptions* p = pOpts->pSavedState; + tOptDesc* pOD = pOpts->pOptDesc; + int ct = pOpts->optCt; + + /* + * Make sure that allocated stuff is only referenced in the + * archived copy of the data. + */ + for (; ct-- > 0; pOD++) { + switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { + case OPARG_TYPE_STRING: + if (pOD->fOptState & OPTST_STACKED) { + tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc); + q->optCookie = NULL; + } + if (pOD->fOptState & OPTST_ALLOC_ARG) { + tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc); + AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg"); + } + break; + + case OPARG_TYPE_HIERARCHY: + { + tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc); + q->optCookie = NULL; + } + } + } +} + +/*=export_func optionSaveState + * + * what: saves the option state to memory + * arg: tOptions*, pOpts, program options descriptor + * + * doc: + * + * This routine will allocate enough memory to save the current option + * processing state. If this routine has been called before, that memory + * will be reused. You may only save one copy of the option state. This + * routine may be called before optionProcess(3AO). If you do call it + * before the first call to optionProcess, then you may also change the + * contents of argc/argv after you call optionRestore(3AO) + * + * In fact, more strongly put: it is safest to only use this function + * before having processed any options. In particular, the saving and + * restoring of stacked string arguments and hierarchical values is + * disabled. The values are not saved. + * + * err: If it fails to allocate the memory, + * it will print a message to stderr and exit. + * Otherwise, it will always succeed. +=*/ +void +optionSaveState(tOptions* pOpts) +{ + tOptions* p = (tOptions*)pOpts->pSavedState; + + if (p == NULL) { + size_t sz = sizeof( *pOpts ) + (pOpts->optCt * sizeof( tOptDesc )); + p = AGALOC( sz, "saved option state" ); + if (p == NULL) { + tCC* pzName = pOpts->pzProgName; + if (pzName == NULL) { + pzName = pOpts->pzPROGNAME; + if (pzName == NULL) + pzName = zNil; + } + fprintf( stderr, zCantSave, pzName, sz ); + exit( EXIT_FAILURE ); + } + + pOpts->pSavedState = p; + } + + memcpy( p, pOpts, sizeof( *p )); + memcpy( p + 1, pOpts->pOptDesc, p->optCt * sizeof( tOptDesc )); + + fixupSavedOptionArgs(pOpts); +} + + +/*=export_func optionRestore + * + * what: restore option state from memory copy + * arg: tOptions*, pOpts, program options descriptor + * + * doc: Copy back the option state from saved memory. + * The allocated memory is left intact, so this routine can be + * called repeatedly without having to call optionSaveState again. + * If you are restoring a state that was saved before the first call + * to optionProcess(3AO), then you may change the contents of the + * argc/argv parameters to optionProcess. + * + * err: If you have not called @code{optionSaveState} before, a diagnostic is + * printed to @code{stderr} and exit is called. +=*/ +void +optionRestore( tOptions* pOpts ) +{ + tOptions* p = (tOptions*)pOpts->pSavedState; + + if (p == NULL) { + tCC* pzName = pOpts->pzProgName; + if (pzName == NULL) { + pzName = pOpts->pzPROGNAME; + if (pzName == NULL) + pzName = zNil; + } + fprintf( stderr, zNoState, pzName ); + exit( EXIT_FAILURE ); + } + + pOpts->pSavedState = NULL; + optionFree(pOpts); + + memcpy( pOpts, p, sizeof( *p )); + memcpy( pOpts->pOptDesc, p+1, p->optCt * sizeof( tOptDesc )); + pOpts->pSavedState = p; + + fixupSavedOptionArgs(pOpts); +} + +/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ + +/*=export_func optionFree + * + * what: free allocated option processing memory + * arg: tOptions*, pOpts, program options descriptor + * + * doc: AutoOpts sometimes allocates memory and puts pointers to it in the + * option state structures. This routine deallocates all such memory. + * + * err: As long as memory has not been corrupted, + * this routine is always successful. +=*/ +void +optionFree( tOptions* pOpts ) +{ + free_saved_state: + { + tOptDesc* p = pOpts->pOptDesc; + int ct = pOpts->optCt; + do { + if (p->fOptState & OPTST_ALLOC_ARG) { + AGFREE(p->optArg.argString); + p->optArg.argString = NULL; + p->fOptState &= ~OPTST_ALLOC_ARG; + } + + switch (OPTST_GET_ARGTYPE(p->fOptState)) { + case OPARG_TYPE_STRING: +#ifdef WITH_LIBREGEX + if ( (p->fOptState & OPTST_STACKED) + && (p->optCookie != NULL)) { + p->optArg.argString = ".*"; + optionUnstackArg(pOpts, p); + } +#else + /* leak memory */; +#endif + break; + + case OPARG_TYPE_HIERARCHY: + if (p->optCookie != NULL) + unloadNestedArglist(p->optCookie); + break; + } + + p->optCookie = NULL; + } while (p++, --ct > 0); + } + if (pOpts->pSavedState != NULL) { + tOptions * p = (tOptions*)pOpts->pSavedState; + memcpy( pOpts, p, sizeof( *p )); + memcpy( pOpts->pOptDesc, p+1, p->optCt * sizeof( tOptDesc )); + AGFREE( pOpts->pSavedState ); + pOpts->pSavedState = NULL; + goto free_saved_state; + } +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/restore.c */ diff --git a/contrib/ntp/libopts/save.c b/contrib/ntp/libopts/save.c new file mode 100644 index 0000000..c889520 --- /dev/null +++ b/contrib/ntp/libopts/save.c @@ -0,0 +1,521 @@ + +/* + * save.c $Id: save.c,v 4.18 2007/04/15 19:01:18 bkorb Exp $ + * Time-stamp: "2007-04-15 11:11:10 bkorb" + * + * This module's routines will take the currently set options and + * store them into an ".rc" file for re-interpretation the next + * time the invoking program is run. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +tSCC zWarn[] = "%s WARNING: cannot save options - "; + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static tCC* +findDirName( tOptions* pOpts, int* p_free ); + +static tCC* +findFileName( tOptions* pOpts, int* p_free_name ); + +static void +printEntry( + FILE * fp, + tOptDesc * p, + tCC* pzLA ); +/* = = = END-STATIC-FORWARD = = = */ + +static tCC* +findDirName( tOptions* pOpts, int* p_free ) +{ + tCC* pzDir; + + if (pOpts->specOptIdx.save_opts == 0) + return NULL; + + pzDir = pOpts->pOptDesc[ pOpts->specOptIdx.save_opts ].optArg.argString; + if ((pzDir != NULL) && (*pzDir != NUL)) + return pzDir; + + /* + * This function only works if there is a directory where + * we can stash the RC (INI) file. + */ + { + tCC* const* papz = pOpts->papzHomeList; + if (papz == NULL) + return NULL; + + while (papz[1] != NULL) papz++; + pzDir = *papz; + } + + /* + * IF it does not require deciphering an env value, then just copy it + */ + if (*pzDir != '$') + return pzDir; + + { + tCC* pzEndDir = strchr( ++pzDir, DIRCH ); + char* pzFileName; + char* pzEnv; + + if (pzEndDir != NULL) { + char z[ AO_NAME_SIZE ]; + if ((pzEndDir - pzDir) > AO_NAME_LIMIT ) + return NULL; + strncpy( z, pzDir, (size_t)(pzEndDir - pzDir) ); + z[ (pzEndDir - pzDir) ] = NUL; + pzEnv = getenv( z ); + } else { + + /* + * Make sure we can get the env value (after stripping off + * any trailing directory or file names) + */ + pzEnv = getenv( pzDir ); + } + + if (pzEnv == NULL) { + fprintf( stderr, zWarn, pOpts->pzProgName ); + fprintf( stderr, zNotDef, pzDir ); + return NULL; + } + + if (pzEndDir == NULL) + return pzEnv; + + { + size_t sz = strlen( pzEnv ) + strlen( pzEndDir ) + 2; + pzFileName = (char*)AGALOC( sz, "dir name" ); + } + + if (pzFileName == NULL) + return NULL; + + *p_free = 1; + /* + * Glue together the full name into the allocated memory. + * FIXME: We lose track of this memory. + */ + sprintf( pzFileName, "%s/%s", pzEnv, pzEndDir ); + return pzFileName; + } +} + + +static tCC* +findFileName( tOptions* pOpts, int* p_free_name ) +{ + tCC* pzDir; + struct stat stBuf; + int free_dir_name = 0; + + pzDir = findDirName( pOpts, &free_dir_name ); + if (pzDir == NULL) + return NULL; + + /* + * See if we can find the specified directory. We use a once-only loop + * structure so we can bail out early. + */ + if (stat( pzDir, &stBuf ) != 0) do { + + /* + * IF we could not, check to see if we got a full + * path to a file name that has not been created yet. + */ + if (errno == ENOENT) { + char z[AG_PATH_MAX]; + + /* + * Strip off the last component, stat the remaining string and + * that string must name a directory + */ + char* pzDirCh = strrchr( pzDir, DIRCH ); + if (pzDirCh == NULL) { + stBuf.st_mode = S_IFREG; + continue; /* bail out of error condition */ + } + + strncpy( z, pzDir, (size_t)(pzDirCh - pzDir)); + z[ pzDirCh - pzDir ] = NUL; + + if ( (stat( z, &stBuf ) == 0) + && S_ISDIR( stBuf.st_mode )) { + + /* + * We found the directory. Restore the file name and + * mark the full name as a regular file + */ + stBuf.st_mode = S_IFREG; + continue; /* bail out of error condition */ + } + } + + /* + * We got a bogus name. + */ + fprintf( stderr, zWarn, pOpts->pzProgName ); + fprintf( stderr, zNoStat, errno, strerror( errno ), pzDir ); + if (free_dir_name) + AGFREE( (void*)pzDir ); + return NULL; + } while (0); + + /* + * IF what we found was a directory, + * THEN tack on the config file name + */ + if (S_ISDIR( stBuf.st_mode )) { + size_t sz = strlen( pzDir ) + strlen( pOpts->pzRcName ) + 2; + + { + char* pzPath = (char*)AGALOC( sz, "file name" ); +#ifdef HAVE_SNPRINTF + snprintf( pzPath, sz, "%s/%s", pzDir, pOpts->pzRcName ); +#else + sprintf( pzPath, "%s/%s", pzDir, pOpts->pzRcName ); +#endif + if (free_dir_name) + AGFREE( (void*)pzDir ); + pzDir = pzPath; + free_dir_name = 1; + } + + /* + * IF we cannot stat the object for any reason other than + * it does not exist, then we bail out + */ + if (stat( pzDir, &stBuf ) != 0) { + if (errno != ENOENT) { + fprintf( stderr, zWarn, pOpts->pzProgName ); + fprintf( stderr, zNoStat, errno, strerror( errno ), + pzDir ); + AGFREE( (void*)pzDir ); + return NULL; + } + + /* + * It does not exist yet, but it will be a regular file + */ + stBuf.st_mode = S_IFREG; + } + } + + /* + * Make sure that whatever we ultimately found, that it either is + * or will soon be a file. + */ + if (! S_ISREG( stBuf.st_mode )) { + fprintf( stderr, zWarn, pOpts->pzProgName ); + fprintf( stderr, zNotFile, pzDir ); + if (free_dir_name) + AGFREE( (void*)pzDir ); + return NULL; + } + + /* + * Get rid of the old file + */ + unlink( pzDir ); + *p_free_name = free_dir_name; + return pzDir; +} + + +static void +printEntry( + FILE * fp, + tOptDesc * p, + tCC* pzLA ) +{ + /* + * There is an argument. Pad the name so values line up. + * Not disabled *OR* this got equivalenced to another opt, + * then use current option name. + * Otherwise, there must be a disablement name. + */ + { + char const * pz; + if (! DISABLED_OPT(p) || (p->optEquivIndex != NO_EQUIVALENT)) + pz = p->pz_Name; + else + pz = p->pz_DisableName; + + fprintf(fp, "%-18s", pz); + } + /* + * IF the option is numeric only, + * THEN the char pointer is really the number + */ + if (OPTST_GET_ARGTYPE(p->fOptState) == OPARG_TYPE_NUMERIC) + fprintf( fp, " %d\n", (int)(t_word)pzLA ); + + /* + * OTHERWISE, FOR each line of the value text, ... + */ + else if (pzLA == NULL) + fputc( '\n', fp ); + + else { + fputc( ' ', fp ); fputc( ' ', fp ); + for (;;) { + tCC* pzNl = strchr( pzLA, '\n' ); + + /* + * IF this is the last line + * THEN bail and print it + */ + if (pzNl == NULL) + break; + + /* + * Print the continuation and the text from the current line + */ + (void)fwrite( pzLA, (size_t)(pzNl - pzLA), (size_t)1, fp ); + pzLA = pzNl+1; /* advance the Last Arg pointer */ + fputs( "\\\n", fp ); + } + + /* + * Terminate the entry + */ + fputs( pzLA, fp ); + fputc( '\n', fp ); + } +} + + +/*=export_func optionSaveFile + * + * what: saves the option state to a file + * + * arg: tOptions*, pOpts, program options descriptor + * + * doc: + * + * This routine will save the state of option processing to a file. The name + * of that file can be specified with the argument to the @code{--save-opts} + * option, or by appending the @code{rcfile} attribute to the last + * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it + * will default to @code{.@i{programname}rc}. If you wish to specify another + * file, you should invoke the @code{SET_OPT_SAVE_OPTS( @i{filename} )} macro. + * + * err: + * + * If no @code{homerc} file was specified, this routine will silently return + * and do nothing. If the output file cannot be created or updated, a message + * will be printed to @code{stderr} and the routine will return. +=*/ +void +optionSaveFile( tOptions* pOpts ) +{ + tOptDesc* pOD; + int ct; + FILE* fp; + + { + int free_name = 0; + tCC* pzFName = findFileName( pOpts, &free_name ); + if (pzFName == NULL) + return; + + fp = fopen( pzFName, "w" FOPEN_BINARY_FLAG ); + if (fp == NULL) { + fprintf( stderr, zWarn, pOpts->pzProgName ); + fprintf( stderr, zNoCreat, errno, strerror( errno ), pzFName ); + if (free_name) + AGFREE((void*) pzFName ); + return; + } + + if (free_name) + AGFREE( (void*)pzFName ); + } + + { + char const* pz = pOpts->pzUsageTitle; + fputs( "# ", fp ); + do { fputc( *pz, fp ); } while (*(pz++) != '\n'); + } + + { + time_t timeVal = time( NULL ); + char* pzTime = ctime( &timeVal ); + + fprintf( fp, zPresetFile, pzTime ); +#ifdef HAVE_ALLOCATED_CTIME + /* + * The return values for ctime(), localtime(), and gmtime() + * normally point to static data that is overwritten by each call. + * The test to detect allocated ctime, so we leak the memory. + */ + AGFREE( (void*)pzTime ); +#endif + } + + /* + * FOR each of the defined options, ... + */ + ct = pOpts->presetOptCt; + pOD = pOpts->pOptDesc; + do { + int arg_state; + tOptDesc* p; + + /* + * IF the option has not been defined + * OR it does not take an initialization value + * OR it is equivalenced to another option + * THEN continue (ignore it) + */ + if (UNUSED_OPT( pOD )) + continue; + + if ((pOD->fOptState & (OPTST_NO_INIT|OPTST_DOCUMENT|OPTST_OMITTED)) + != 0) + continue; + + if ( (pOD->optEquivIndex != NO_EQUIVALENT) + && (pOD->optEquivIndex != pOD->optIndex)) + continue; + + /* + * Set a temporary pointer to the real option description + * (i.e. account for equivalencing) + */ + p = ((pOD->fOptState & OPTST_EQUIVALENCE) != 0) + ? (pOpts->pOptDesc + pOD->optActualIndex) : pOD; + + /* + * IF no arguments are allowed + * THEN just print the name and continue + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NONE) { + char const * pznm = + (DISABLED_OPT( p )) ? p->pz_DisableName : p->pz_Name; + /* + * If the option was disabled and the disablement name is NULL, + * then the disablement was caused by aliasing. + * Use the name as the string to emit. + */ + if (pznm == NULL) + pznm = p->pz_Name; + + fprintf(fp, "%s\n", pznm); + continue; + } + + arg_state = OPTST_GET_ARGTYPE(p->fOptState); + switch (arg_state) { + case 0: + case OPARG_TYPE_NUMERIC: + printEntry( fp, p, (void*)(p->optArg.argInt)); + break; + + case OPARG_TYPE_STRING: + if (p->fOptState & OPTST_STACKED) { + tArgList* pAL = (tArgList*)p->optCookie; + int uct = pAL->useCt; + tCC** ppz = pAL->apzArgs; + + /* + * Disallow multiple copies of disabled options. + */ + if (uct > 1) + p->fOptState &= ~OPTST_DISABLED; + + while (uct-- > 0) + printEntry( fp, p, *(ppz++) ); + } else { + printEntry( fp, p, p->optArg.argString ); + } + break; + + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + { + uintptr_t val = p->optArg.argEnum; + /* + * This is a magic incantation that will convert the + * bit flag values back into a string suitable for printing. + */ + (*(p->pOptProc))( (tOptions*)2UL, p ); + printEntry( fp, p, (void*)(p->optArg.argString)); + + if ( (p->optArg.argString != NULL) + && (arg_state != OPARG_TYPE_ENUMERATION)) { + /* + * set membership strings get allocated + */ + AGFREE( (void*)p->optArg.argString ); + p->fOptState &= ~OPTST_ALLOC_ARG; + } + + p->optArg.argEnum = val; + break; + } + + case OPARG_TYPE_BOOLEAN: + printEntry( fp, p, p->optArg.argBool ? "true" : "false" ); + break; + + default: + break; /* cannot handle - skip it */ + } + } while ( (pOD++), (--ct > 0)); + + fclose( fp ); +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/save.c */ diff --git a/contrib/ntp/libopts/sort.c b/contrib/ntp/libopts/sort.c new file mode 100644 index 0000000..ead7133 --- /dev/null +++ b/contrib/ntp/libopts/sort.c @@ -0,0 +1,359 @@ + +/* + * sort.c $Id: sort.c,v 4.10 2007/04/28 22:19:23 bkorb Exp $ + * Time-stamp: "2006-10-18 11:29:04 bkorb" + * + * This module implements argument sorting. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static tSuccess +mustHandleArg( tOptions* pOpts, char* pzArg, tOptState* pOS, + char** ppzOpts, int* pOptsIdx ); + +static tSuccess +mayHandleArg( tOptions* pOpts, char* pzArg, tOptState* pOS, + char** ppzOpts, int* pOptsIdx ); + +static tSuccess +checkShortOpts( tOptions* pOpts, char* pzArg, tOptState* pOS, + char** ppzOpts, int* pOptsIdx ); +/* = = = END-STATIC-FORWARD = = = */ + +/* + * "mustHandleArg" and "mayHandleArg" are really similar. The biggest + * difference is that "may" will consume the next argument only if it + * does not start with a hyphen and "must" will consume it, hyphen or not. + */ +static tSuccess +mustHandleArg( tOptions* pOpts, char* pzArg, tOptState* pOS, + char** ppzOpts, int* pOptsIdx ) +{ + /* + * An option argument is required. Long options can either have + * a separate command line argument, or an argument attached by + * the '=' character. Figure out which. + */ + switch (pOS->optType) { + case TOPT_SHORT: + /* + * See if an arg string follows the flag character. If not, + * the next arg must be the option argument. + */ + if (*pzArg != NUL) + return SUCCESS; + break; + + case TOPT_LONG: + /* + * See if an arg string has already been assigned (glued on + * with an `=' character). If not, the next is the opt arg. + */ + if (pOS->pzOptArg != NULL) + return SUCCESS; + break; + + default: + return FAILURE; + } + if (pOpts->curOptIdx >= pOpts->origArgCt) + return FAILURE; + + ppzOpts[ (*pOptsIdx)++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + return SUCCESS; +} + +static tSuccess +mayHandleArg( tOptions* pOpts, char* pzArg, tOptState* pOS, + char** ppzOpts, int* pOptsIdx ) +{ + /* + * An option argument is optional. + */ + switch (pOS->optType) { + case TOPT_SHORT: + /* + * IF nothing is glued on after the current flag character, + * THEN see if there is another argument. If so and if it + * does *NOT* start with a hyphen, then it is the option arg. + */ + if (*pzArg != NUL) + return SUCCESS; + break; + + case TOPT_LONG: + /* + * Look for an argument if we don't already have one (glued on + * with a `=' character) + */ + if (pOS->pzOptArg != NULL) + return SUCCESS; + break; + + default: + return FAILURE; + } + if (pOpts->curOptIdx >= pOpts->origArgCt) + return PROBLEM; + + pzArg = pOpts->origArgVect[ pOpts->curOptIdx ]; + if (*pzArg != '-') + ppzOpts[ (*pOptsIdx)++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + return SUCCESS; +} + +/* + * Process a string of short options glued together. If the last one + * does or may take an argument, the do the argument processing and leave. + */ +static tSuccess +checkShortOpts( tOptions* pOpts, char* pzArg, tOptState* pOS, + char** ppzOpts, int* pOptsIdx ) +{ + while (*pzArg != NUL) { + if (FAILED( shortOptionFind( pOpts, (tAoUC)*pzArg, pOS ))) + return FAILURE; + + /* + * See if we can have an arg. + */ + if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) { + pzArg++; + + } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) { + /* + * Take an argument if it is not attached and it does not + * start with a hyphen. + */ + if (pzArg[1] != NUL) + return SUCCESS; + + pzArg = pOpts->origArgVect[ pOpts->curOptIdx ]; + if (*pzArg != '-') + ppzOpts[ (*pOptsIdx)++ ] = + pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + return SUCCESS; + + } else { + /* + * IF we need another argument, be sure it is there and + * take it. + */ + if (pzArg[1] == NUL) { + if (pOpts->curOptIdx >= pOpts->origArgCt) + return FAILURE; + ppzOpts[ (*pOptsIdx)++ ] = + pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + } + return SUCCESS; + } + } + return SUCCESS; +} + +/* + * If the program wants sorted options (separated operands and options), + * then this routine will to the trick. + */ +LOCAL void +optionSort( tOptions* pOpts ) +{ + char** ppzOpts; + char** ppzOpds; + int optsIdx = 0; + int opdsIdx = 0; + + tOptState os = OPTSTATE_INITIALIZER(DEFINED); + + /* + * Disable for POSIX conformance, or if there are no operands. + */ + if ( (getenv( "POSIXLY_CORRECT" ) != NULL) + || NAMED_OPTS(pOpts)) + return; + + /* + * Make sure we can allocate two full-sized arg vectors. + */ + ppzOpts = malloc( pOpts->origArgCt * sizeof( char* )); + if (ppzOpts == NULL) + goto exit_no_mem; + + ppzOpds = malloc( pOpts->origArgCt * sizeof( char* )); + if (ppzOpds == NULL) { + free( ppzOpts ); + goto exit_no_mem; + } + + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + + /* + * Now, process all the options from our current position onward. + * (This allows interspersed options and arguments for the few + * non-standard programs that require it.) + */ + for (;;) { + char* pzArg; + tSuccess res; + + /* + * If we're out of arguments, we're done. Join the option and + * operand lists into the original argument vector. + */ + if (pOpts->curOptIdx >= pOpts->origArgCt) { + errno = 0; + goto joinLists; + } + + pzArg = pOpts->origArgVect[ pOpts->curOptIdx ]; + if (*pzArg != '-') { + ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + continue; + } + + switch (pzArg[1]) { + case NUL: + /* + * A single hyphen is an operand. + */ + ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + continue; + + case '-': + /* + * Two consecutive hypens. Put them on the options list and then + * _always_ force the remainder of the arguments to be operands. + */ + if (pzArg[2] == NUL) { + ppzOpts[ optsIdx++ ] = + pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + goto restOperands; + } + res = longOptionFind( pOpts, pzArg+2, &os ); + break; + + default: + /* + * If short options are not allowed, then do long + * option processing. Otherwise the character must be a + * short (i.e. single character) option. + */ + if ((pOpts->fOptSet & OPTPROC_SHORTOPT) == 0) { + res = longOptionFind( pOpts, pzArg+1, &os ); + } else { + res = shortOptionFind( pOpts, (tAoUC)pzArg[1], &os ); + } + break; + } + if (FAILED( res )) { + errno = EINVAL; + goto freeTemps; + } + + /* + * We've found an option. Add the argument to the option list. + * Next, we have to see if we need to pull another argument to be + * used as the option argument. + */ + ppzOpts[ optsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + + if (OPTST_GET_ARGTYPE(os.pOD->fOptState) == OPARG_TYPE_NONE) { + /* + * No option argument. If we have a short option here, + * then scan for short options until we get to the end + * of the argument string. + */ + if ( (os.optType == TOPT_SHORT) + && FAILED( checkShortOpts( pOpts, pzArg+2, &os, + ppzOpts, &optsIdx )) ) { + errno = EINVAL; + goto freeTemps; + } + + } else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) { + switch (mayHandleArg( pOpts, pzArg+2, &os, ppzOpts, &optsIdx )) { + case FAILURE: errno = EIO; goto freeTemps; + case PROBLEM: errno = 0; goto joinLists; + } + + } else { + switch (mustHandleArg( pOpts, pzArg+2, &os, ppzOpts, &optsIdx )) { + case PROBLEM: + case FAILURE: errno = EIO; goto freeTemps; + } + } + } /* for (;;) */ + + restOperands: + while (pOpts->curOptIdx < pOpts->origArgCt) + ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ]; + + joinLists: + if (optsIdx > 0) + memcpy( pOpts->origArgVect + 1, ppzOpts, optsIdx * sizeof( char* )); + if (opdsIdx > 0) + memcpy( pOpts->origArgVect + 1 + optsIdx, + ppzOpds, opdsIdx * sizeof( char* )); + + freeTemps: + free( ppzOpts ); + free( ppzOpds ); + return; + + exit_no_mem: + errno = ENOMEM; + return; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/sort.c */ diff --git a/contrib/ntp/libopts/stack.c b/contrib/ntp/libopts/stack.c new file mode 100644 index 0000000..6d77f72 --- /dev/null +++ b/contrib/ntp/libopts/stack.c @@ -0,0 +1,269 @@ + +/* + * stack.c + * $Id: stack.c,v 4.13 2007/02/04 17:44:12 bkorb Exp $ + * Time-stamp: "2007-01-13 10:43:21 bkorb" + * + * This is a special option processing routine that will save the + * argument to an option in a FIFO queue. + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +#ifdef WITH_LIBREGEX +# include REGEX_HEADER +#endif + +/*=export_func optionUnstackArg + * private: + * + * what: Remove option args from a stack + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * Invoked for options that are equivalenced to stacked options. +=*/ +void +optionUnstackArg( + tOptions* pOpts, + tOptDesc* pOptDesc ) +{ + int res; + + tArgList* pAL = (tArgList*)pOptDesc->optCookie; + /* + * IF we don't have any stacked options, + * THEN indicate that we don't have any of these options + */ + if (pAL == NULL) { + pOptDesc->fOptState &= OPTST_PERSISTENT_MASK; + if ( (pOptDesc->fOptState & OPTST_INITENABLED) == 0) + pOptDesc->fOptState |= OPTST_DISABLED; + return; + } + +#ifdef WITH_LIBREGEX + { + regex_t re; + int i, ct, dIdx; + + if (regcomp( &re, pOptDesc->optArg.argString, REG_NOSUB ) != 0) + return; + + /* + * search the list for the entry(s) to remove. Entries that + * are removed are *not* copied into the result. The source + * index is incremented every time. The destination only when + * we are keeping a define. + */ + for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) { + tCC* pzSrc = pAL->apzArgs[ i ]; + char* pzEq = strchr( pzSrc, '=' ); + + if (pzEq != NULL) + *pzEq = NUL; + + res = regexec( &re, pzSrc, (size_t)0, NULL, 0 ); + switch (res) { + case 0: + /* + * Remove this entry by reducing the in-use count + * and *not* putting the string pointer back into + * the list. + */ + AGFREE(pzSrc); + pAL->useCt--; + break; + + default: + case REG_NOMATCH: + if (pzEq != NULL) + *pzEq = '='; + + /* + * IF we have dropped an entry + * THEN we have to move the current one. + */ + if (dIdx != i) + pAL->apzArgs[ dIdx ] = pzSrc; + dIdx++; + } + } + + regfree( &re ); + } +#else /* not WITH_LIBREGEX */ + { + int i, ct, dIdx; + + /* + * search the list for the entry(s) to remove. Entries that + * are removed are *not* copied into the result. The source + * index is incremented every time. The destination only when + * we are keeping a define. + */ + for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) { + tCC* pzSrc = pAL->apzArgs[ i ]; + char* pzEq = strchr( pzSrc, '=' ); + + if (pzEq != NULL) + *pzEq = NUL; + + if (strcmp( pzSrc, pOptDesc->optArg.argString ) == 0) { + /* + * Remove this entry by reducing the in-use count + * and *not* putting the string pointer back into + * the list. + */ + AGFREE(pzSrc); + pAL->useCt--; + } else { + if (pzEq != NULL) + *pzEq = '='; + + /* + * IF we have dropped an entry + * THEN we have to move the current one. + */ + if (dIdx != i) + pAL->apzArgs[ dIdx ] = pzSrc; + dIdx++; + } + } + } +#endif /* WITH_LIBREGEX */ + /* + * IF we have unstacked everything, + * THEN indicate that we don't have any of these options + */ + if (pAL->useCt == 0) { + pOptDesc->fOptState &= OPTST_PERSISTENT_MASK; + if ( (pOptDesc->fOptState & OPTST_INITENABLED) == 0) + pOptDesc->fOptState |= OPTST_DISABLED; + AGFREE( (void*)pAL ); + pOptDesc->optCookie = NULL; + } +} + + +/* + * Put an entry into an argument list. The first argument points to + * a pointer to the argument list structure. It gets passed around + * as an opaque address. + */ +LOCAL void +addArgListEntry( void** ppAL, void* entry ) +{ + tArgList* pAL = *(void**)ppAL; + + /* + * IF we have never allocated one of these, + * THEN allocate one now + */ + if (pAL == NULL) { + pAL = (tArgList*)AGALOC( sizeof( *pAL ), "new option arg stack" ); + if (pAL == NULL) + return; + pAL->useCt = 0; + pAL->allocCt = MIN_ARG_ALLOC_CT; + *ppAL = (void*)pAL; + } + + /* + * ELSE if we are out of room + * THEN make it bigger + */ + else if (pAL->useCt >= pAL->allocCt) { + size_t sz = sizeof( *pAL ); + pAL->allocCt += INCR_ARG_ALLOC_CT; + + /* + * The base structure contains space for MIN_ARG_ALLOC_CT + * pointers. We subtract it off to find our augment size. + */ + sz += sizeof(char*) * (pAL->allocCt - MIN_ARG_ALLOC_CT); + pAL = (tArgList*)AGREALOC( (void*)pAL, sz, "expanded opt arg stack" ); + if (pAL == NULL) + return; + *ppAL = (void*)pAL; + } + + /* + * Insert the new argument into the list + */ + pAL->apzArgs[ (pAL->useCt)++ ] = entry; +} + + +/*=export_func optionStackArg + * private: + * + * what: put option args on a stack + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * Keep an entry-ordered list of option arguments. +=*/ +void +optionStackArg( + tOptions* pOpts, + tOptDesc* pOD ) +{ + char * pz; + + if (pOD->optArg.argString == NULL) + return; + + AGDUPSTR(pz, pOD->optArg.argString, "stack arg"); + addArgListEntry( &(pOD->optCookie), (void*)pz ); +} +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/stack.c */ diff --git a/contrib/ntp/libopts/streqvcmp.c b/contrib/ntp/libopts/streqvcmp.c new file mode 100644 index 0000000..8249794 --- /dev/null +++ b/contrib/ntp/libopts/streqvcmp.c @@ -0,0 +1,289 @@ + +/* + * $Id: streqvcmp.c,v 4.10 2007/04/28 22:19:23 bkorb Exp $ + * Time-stamp: "2006-07-26 18:25:53 bkorb" + * + * String Equivalence Comparison + * + * These routines allow any character to be mapped to any other + * character before comparison. In processing long option names, + * the characters "-", "_" and "^" all need to be equivalent + * (because they are treated so by different development environments). + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static unsigned char charmap[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a', + '\b', '\t', '\n', '\v', '\f', '\r', 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', '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', '{', '|', '}', '~', 0x7f, + + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + + +/*=export_func strneqvcmp + * + * what: compare two strings with an equivalence mapping + * + * arg: + char const* + str1 + first string + + * arg: + char const* + str2 + second string + + * arg: + int + ct + compare length + + * + * ret_type: int + * ret_desc: the difference between two differing characters + * + * doc: + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * The comparison is limited to @code{ct} bytes. + * This function name is mapped to option_strneqvcmp so as to not conflict + * with the POSIX name space. + * + * err: none checked. Caller responsible for seg faults. +=*/ +int +strneqvcmp( tCC* s1, tCC* s2, int ct ) +{ + for (; ct > 0; --ct) { + unsigned char u1 = (unsigned char) *s1++; + unsigned char u2 = (unsigned char) *s2++; + int dif = charmap[ u1 ] - charmap[ u2 ]; + + if (dif != 0) + return dif; + + if (u1 == NUL) + return 0; + } + + return 0; +} + + +/*=export_func streqvcmp + * + * what: compare two strings with an equivalence mapping + * + * arg: + char const* + str1 + first string + + * arg: + char const* + str2 + second string + + * + * ret_type: int + * ret_desc: the difference between two differing characters + * + * doc: + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * This function name is mapped to option_streqvcmp so as to not conflict + * with the POSIX name space. + * + * err: none checked. Caller responsible for seg faults. +=*/ +int +streqvcmp( tCC* s1, tCC* s2 ) +{ + for (;;) { + unsigned char u1 = (unsigned char) *s1++; + unsigned char u2 = (unsigned char) *s2++; + int dif = charmap[ u1 ] - charmap[ u2 ]; + + if (dif != 0) + return dif; + + if (u1 == NUL) + return 0; + } +} + + +/*=export_func streqvmap + * + * what: Set the character mappings for the streqv functions + * + * arg: + char + From + Input character + + * arg: + char + To + Mapped-to character + + * arg: + int + ct + compare length + + * + * doc: + * + * Set the character mapping. If the count (@code{ct}) is set to zero, then + * the map is cleared by setting all entries in the map to their index + * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" + * character. If @code{ct} is greater than 1, then @code{From} and @code{To} + * are incremented and the process repeated until @code{ct} entries have been + * set. For example, + * @example + * streqvmap( 'a', 'A', 26 ); + * @end example + * @noindent + * will alter the mapping so that all English lower case letters + * will map to upper case. + * + * This function name is mapped to option_streqvmap so as to not conflict + * with the POSIX name space. + * + * err: none. +=*/ +void +streqvmap( char From, char To, int ct ) +{ + if (ct == 0) { + ct = sizeof( charmap ) - 1; + do { + charmap[ ct ] = ct; + } while (--ct >= 0); + } + + else { + int chTo = (int)To & 0xFF; + int chFrom = (int)From & 0xFF; + + do { + charmap[ chFrom ] = (unsigned)chTo; + chFrom++; + chTo++; + if ((chFrom >= sizeof( charmap )) || (chTo >= sizeof( charmap ))) + break; + } while (--ct > 0); + } +} + + +/*=export_func strequate + * + * what: map a list of characters to the same value + * + * arg: + char const* + ch_list + characters to equivalence + + * + * doc: + * + * Each character in the input string get mapped to the first character + * in the string. + * This function name is mapped to option_strequate so as to not conflict + * with the POSIX name space. + * + * err: none. +=*/ +void +strequate( char const* s ) +{ + if ((s != NULL) && (*s != NUL)) { + unsigned char equiv = (unsigned)*s; + while (*s != NUL) + charmap[ (unsigned)*(s++) ] = equiv; + } +} + + +/*=export_func strtransform + * + * what: convert a string into its mapped-to value + * + * arg: + char* + dest + output string + + * arg: + char const* + src + input string + + * + * doc: + * + * Each character in the input string is mapped and the mapped-to + * character is put into the output. + * This function name is mapped to option_strtransform so as to not conflict + * with the POSIX name space. + * + * err: none. +=*/ +void +strtransform( char* d, char const* s ) +{ + do { + *(d++) = (char)charmap[ (unsigned)*s ]; + } while (*(s++) != NUL); +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/streqvcmp.c */ diff --git a/contrib/ntp/libopts/text_mmap.c b/contrib/ntp/libopts/text_mmap.c new file mode 100644 index 0000000..ced2977 --- /dev/null +++ b/contrib/ntp/libopts/text_mmap.c @@ -0,0 +1,363 @@ +/* + * $Id: text_mmap.c,v 4.15 2006/11/27 01:52:23 bkorb Exp $ + * + * Time-stamp: "2006-09-10 14:50:04 bkorb" + */ + +#ifndef MAP_ANONYMOUS +# ifdef MAP_ANON +# define MAP_ANONYMOUS MAP_ANON +# endif +#endif + +/* + * Some weird systems require that a specifically invalid FD number + * get passed in as an argument value. Which value is that? Well, + * as everybody knows, if open(2) fails, it returns -1, so that must + * be the value. :) + */ +#define AO_INVALID_FD -1 + +#define FILE_WRITABLE(_prt,_flg) \ + ( (_prt & PROT_WRITE) \ + && ((_flg & (MAP_SHARED|MAP_PRIVATE)) == MAP_SHARED)) +#define MAP_FAILED_PTR ((void*)MAP_FAILED) + +/*=export_func text_mmap + * private: + * + * what: map a text file with terminating NUL + * + * arg: char const*, pzFile, name of the file to map + * arg: int, prot, mmap protections (see mmap(2)) + * arg: int, flags, mmap flags (see mmap(2)) + * arg: tmap_info_t*, mapinfo, returned info about the mapping + * + * ret-type: void* + * ret-desc: The mmaped data address + * + * doc: + * + * This routine will mmap a file into memory ensuring that there is at least + * one @file{NUL} character following the file data. It will return the + * address where the file contents have been mapped into memory. If there is a + * problem, then it will return @code{MAP_FAILED} and set @file{errno} + * appropriately. + * + * The named file does not exist, @code{stat(2)} will set @file{errno} as it + * will. If the file is not a regular file, @file{errno} will be + * @code{EINVAL}. At that point, @code{open(2)} is attempted with the access + * bits set appropriately for the requested @code{mmap(2)} protections and flag + * bits. On failure, @file{errno} will be set according to the documentation + * for @code{open(2)}. If @code{mmap(2)} fails, @file{errno} will be set as + * that routine sets it. If @code{text_mmap} works to this point, a valid + * address will be returned, but there may still be ``issues''. + * + * If the file size is not an even multiple of the system page size, then + * @code{text_map} will return at this point and @file{errno} will be zero. + * Otherwise, an anonymous map is attempted. If not available, then an attempt + * is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the + * address of the file's data is returned, bug @code{no} @file{NUL} characters + * are mapped after the end of the data. + * + * see: mmap(2), open(2), stat(2) + * + * err: Any error code issued by mmap(2), open(2), stat(2) is possible. + * Additionally, if the specified file is not a regular file, then + * errno will be set to @code{EINVAL}. + * + * example: + * #include <mylib.h> + * tmap_info_t mi; + * int no_nul; + * void* data = text_mmap( "file", PROT_WRITE, MAP_PRIVATE, &mi ); + * if (data == MAP_FAILED) return; + * no_nul = (mi.txt_size == mi.txt_full_size); + * << use the data >> + * text_munmap( &mi ); +=*/ +void* +text_mmap( char const* pzFile, int prot, int flags, tmap_info_t* pMI ) +{ + memset( pMI, 0, sizeof(*pMI) ); +#ifdef HAVE_MMAP + pMI->txt_zero_fd = -1; +#endif + pMI->txt_fd = -1; + + /* + * Make sure we can stat the regular file. Save the file size. + */ + { + struct stat sb; + if (stat( pzFile, &sb ) != 0) { + pMI->txt_errno = errno; + return MAP_FAILED_PTR; + } + + if (! S_ISREG( sb.st_mode )) { + pMI->txt_errno = errno = EINVAL; + return MAP_FAILED_PTR; + } + + pMI->txt_size = sb.st_size; + } + + /* + * Map mmap flags and protections into open flags and do the open. + */ + { + int o_flag; + /* + * See if we will be updating the file. If we can alter the memory + * and if we share the data and we are *not* copy-on-writing the data, + * then our updates will show in the file, so we must open with + * write access. + */ + if (FILE_WRITABLE(prot,flags)) + o_flag = O_RDWR; + else + o_flag = O_RDONLY; + + /* + * If you're not sharing the file and you are writing to it, + * then don't let anyone else have access to the file. + */ + if (((flags & MAP_SHARED) == 0) && (prot & PROT_WRITE)) + o_flag |= O_EXCL; + + pMI->txt_fd = open( pzFile, o_flag ); + } + + if (pMI->txt_fd == AO_INVALID_FD) { + pMI->txt_errno = errno; + return MAP_FAILED_PTR; + } + +#ifdef HAVE_MMAP /* * * * * WITH MMAP * * * * * */ + /* + * do the mmap. If we fail, then preserve errno, close the file and + * return the failure. + */ + pMI->txt_data = + mmap(NULL, pMI->txt_size+1, prot, flags, pMI->txt_fd, (size_t)0); + if (pMI->txt_data == MAP_FAILED_PTR) { + pMI->txt_errno = errno; + goto fail_return; + } + + /* + * Most likely, everything will turn out fine now. The only difficult + * part at this point is coping with files with sizes that are a multiple + * of the page size. Handling that is what this whole thing is about. + */ + pMI->txt_zero_fd = -1; + pMI->txt_errno = 0; + + { + void* pNuls; +#ifdef _SC_PAGESIZE + size_t pgsz = sysconf(_SC_PAGESIZE); +#else + size_t pgsz = getpagesize(); +#endif + /* + * Compute the pagesize rounded mapped memory size. + * IF this is not the same as the file size, then there are NUL's + * at the end of the file mapping and all is okay. + */ + pMI->txt_full_size = (pMI->txt_size + (pgsz - 1)) & ~(pgsz - 1); + if (pMI->txt_size != pMI->txt_full_size) + return pMI->txt_data; + + /* + * Still here? We have to remap the trailing inaccessible page + * either anonymously or to /dev/zero. + */ + pMI->txt_full_size += pgsz; +#if defined(MAP_ANONYMOUS) + pNuls = mmap( + (void*)(((char*)pMI->txt_data) + pMI->txt_size), + pgsz, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, AO_INVALID_FD, (size_t)0); + + if (pNuls != MAP_FAILED_PTR) + return pMI->txt_data; + + pMI->txt_errno = errno; + +#elif defined(HAVE_DEV_ZERO) + pMI->txt_zero_fd = open( "/dev/zero", O_RDONLY ); + + if (pMI->txt_zero_fd == AO_INVALID_FD) { + pMI->txt_errno = errno; + + } else { + pNuls = mmap( + (void*)(((char*)pMI->txt_data) + pMI->txt_size), pgsz, + PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, + pMI->txt_zero_fd, 0 ); + + if (pNuls != MAP_FAILED_PTR) + return pMI->txt_data; + + pMI->txt_errno = errno; + close( pMI->txt_zero_fd ); + pMI->txt_zero_fd = -1; + } +#endif + + pMI->txt_full_size = pMI->txt_size; + } + + { + void* p = AGALOC( pMI->txt_size+1, "file text" ); + memcpy( p, pMI->txt_data, pMI->txt_size ); + ((char*)p)[pMI->txt_size] = NUL; + munmap(pMI->txt_data, pMI->txt_size ); + pMI->txt_data = p; + } + pMI->txt_alloc = 1; + return pMI->txt_data; + +#else /* * * * * * no HAVE_MMAP * * * * * */ + + pMI->txt_data = AGALOC( pMI->txt_size+1, "file text" ); + if (pMI->txt_data == NULL) { + pMI->txt_errno = ENOMEM; + goto fail_return; + } + + { + size_t sz = pMI->txt_size; + char* pz = pMI->txt_data; + + while (sz > 0) { + ssize_t rdct = read( pMI->txt_fd, pz, sz ); + if (rdct <= 0) { + pMI->txt_errno = errno; + fprintf( stderr, zFSErrReadFile, + errno, strerror( errno ), pzFile ); + free( pMI->txt_data ); + goto fail_return; + } + + pz += rdct; + sz -= rdct; + } + + *pz = NUL; + } + + /* + * We never need a dummy page mapped in + */ + pMI->txt_zero_fd = -1; + pMI->txt_errno = 0; + + return pMI->txt_data; + +#endif /* * * * * * no HAVE_MMAP * * * * * */ + + fail_return: + if (pMI->txt_fd >= 0) { + close( pMI->txt_fd ); + pMI->txt_fd = -1; + } + errno = pMI->txt_errno; + pMI->txt_data = MAP_FAILED_PTR; + return pMI->txt_data; +} + + +/*=export_func text_munmap + * private: + * + * what: unmap the data mapped in by text_mmap + * + * arg: tmap_info_t*, mapinfo, info about the mapping + * + * ret-type: int + * ret-desc: -1 or 0. @file{errno} will have the error code. + * + * doc: + * + * This routine will unmap the data mapped in with @code{text_mmap} and close + * the associated file descriptors opened by that function. + * + * see: munmap(2), close(2) + * + * err: Any error code issued by munmap(2) or close(2) is possible. +=*/ +int +text_munmap( tmap_info_t* pMI ) +{ +#ifdef HAVE_MMAP + int res = 0; + if (pMI->txt_alloc) { + /* + * IF the user has write permission and the text is not mapped private, + * then write back any changes. Hopefully, nobody else has modified + * the file in the mean time. + */ + if ( ((pMI->txt_prot & PROT_WRITE) != 0) + && ((pMI->txt_flags & MAP_PRIVATE) == 0)) { + + if (lseek(pMI->txt_fd, (size_t)0, SEEK_SET) != 0) + goto error_return; + + res = (write( pMI->txt_fd, pMI->txt_data, pMI->txt_size ) < 0) + ? errno : 0; + } + + AGFREE( pMI->txt_data ); + errno = res; + } else { + res = munmap( pMI->txt_data, pMI->txt_full_size ); + } + if (res != 0) + goto error_return; + + res = close( pMI->txt_fd ); + if (res != 0) + goto error_return; + + pMI->txt_fd = -1; + errno = 0; + if (pMI->txt_zero_fd != -1) { + res = close( pMI->txt_zero_fd ); + pMI->txt_zero_fd = -1; + } + + error_return: + pMI->txt_errno = errno; + return res; +#else /* HAVE_MMAP */ + + errno = 0; + /* + * IF the memory is writable *AND* it is not private (copy-on-write) + * *AND* the memory is "sharable" (seen by other processes) + * THEN rewrite the data. + */ + if ( FILE_WRITABLE(pMI->txt_prot, pMI->txt_flags) + && (lseek( pMI->txt_fd, 0, SEEK_SET ) >= 0) ) { + write( pMI->txt_fd, pMI->txt_data, pMI->txt_size ); + } + + close( pMI->txt_fd ); + pMI->txt_fd = -1; + pMI->txt_errno = errno; + free( pMI->txt_data ); + + return pMI->txt_errno; +#endif /* HAVE_MMAP */ +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/text_mmap.c */ diff --git a/contrib/ntp/libopts/tokenize.c b/contrib/ntp/libopts/tokenize.c new file mode 100644 index 0000000..0e576ce --- /dev/null +++ b/contrib/ntp/libopts/tokenize.c @@ -0,0 +1,321 @@ +/* + * This file defines the string_tokenize interface + * Time-stamp: "2006-06-24 15:27:49 bkorb" + * + * string_tokenize copyright 2005 Bruce Korb + * + * string_tokenize 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 of the License, or (at your option) any later version. + * + * string_tokenize is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with string_tokenize; if not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include <ctype.h> +#include <errno.h> +#include <stdlib.h> + +#define cc_t const unsigned char +#define ch_t unsigned char + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +copy_cooked( ch_t** ppDest, char const ** ppSrc ); + +static void +copy_raw( ch_t** ppDest, char const ** ppSrc ); +/* = = = END-STATIC-FORWARD = = = */ + +static void +copy_cooked( ch_t** ppDest, char const ** ppSrc ) +{ + ch_t* pDest = (ch_t*)*ppDest; + const ch_t* pSrc = (const ch_t*)(*ppSrc + 1); + + for (;;) { + ch_t ch = *(pSrc++); + switch (ch) { + case NUL: *ppSrc = NULL; return; + case '"': goto done; + case '\\': + pSrc += ao_string_cook_escape_char( (char*)pSrc, (char*)&ch, 0x7F ); + if (ch == 0x7F) + break; + /* FALLTHROUGH */ + + default: + *(pDest++) = ch; + } + } + + done: + *ppDest = (ch_t*)pDest; /* next spot for storing character */ + *ppSrc = (char const *)pSrc; /* char following closing quote */ +} + + +static void +copy_raw( ch_t** ppDest, char const ** ppSrc ) +{ + ch_t* pDest = *ppDest; + cc_t* pSrc = (cc_t*) (*ppSrc + 1); + + for (;;) { + ch_t ch = *(pSrc++); + switch (ch) { + case NUL: *ppSrc = NULL; return; + case '\'': goto done; + case '\\': + /* + * *Four* escapes are handled: newline removal, escape char + * quoting and apostrophe quoting + */ + switch (*pSrc) { + case NUL: *ppSrc = NULL; return; + case '\r': + if (*(++pSrc) == '\n') + ++pSrc; + continue; + + case '\n': + ++pSrc; + continue; + + case '\'': + ch = '\''; + /* FALLTHROUGH */ + + case '\\': + ++pSrc; + break; + } + /* FALLTHROUGH */ + + default: + *(pDest++) = ch; + } + } + + done: + *ppDest = pDest; /* next spot for storing character */ + *ppSrc = (char const *) pSrc; /* char following closing quote */ +} + + +/*=export_func ao_string_tokenize + * + * what: tokenize an input string + * + * arg: + char const* + string + string to be tokenized + + * + * ret_type: token_list_t* + * ret_desc: pointer to a structure that lists each token + * + * doc: + * + * This function will convert one input string into a list of strings. + * The list of strings is derived by separating the input based on + * white space separation. However, if the input contains either single + * or double quote characters, then the text after that character up to + * a matching quote will become the string in the list. + * + * The returned pointer should be deallocated with @code{free(3C)} when + * are done using the data. The data are placed in a single block of + * allocated memory. Do not deallocate individual token/strings. + * + * The structure pointed to will contain at least these two fields: + * @table @samp + * @item tkn_ct + * The number of tokens found in the input string. + * @item tok_list + * An array of @code{tkn_ct + 1} pointers to substring tokens, with + * the last pointer set to NULL. + * @end table + * + * There are two types of quoted strings: single quoted (@code{'}) and + * double quoted (@code{"}). Singly quoted strings are fairly raw in that + * escape characters (@code{\\}) are simply another character, except when + * preceding the following characters: + * @example + * @code{\\} double backslashes reduce to one + * @code{'} incorporates the single quote into the string + * @code{\n} suppresses both the backslash and newline character + * @end example + * + * Double quote strings are formed according to the rules of string + * constants in ANSI-C programs. + * + * example: + * @example + * #include <stdlib.h> + * int ix; + * token_list_t* ptl = ao_string_tokenize( some_string ) + * for (ix = 0; ix < ptl->tkn_ct; ix++) + * do_something_with_tkn( ptl->tkn_list[ix] ); + * free( ptl ); + * @end example + * Note that everything is freed with the one call to @code{free(3C)}. + * + * err: + * NULL is returned and @code{errno} will be set to indicate the problem: + * @itemize @bullet + * @item + * @code{EINVAL} - There was an unterminated quoted string. + * @item + * @code{ENOENT} - The input string was empty. + * @item + * @code{ENOMEM} - There is not enough memory. + * @end itemize +=*/ +token_list_t* +ao_string_tokenize( char const* str ) +{ + int max_token_ct = 1; /* allow for trailing NUL on string */ + token_list_t* res; + + if (str == NULL) goto bogus_str; + + /* + * Trim leading white space. Use "ENOENT" and a NULL return to indicate + * an empty string was passed. + */ + while (isspace( (ch_t)*str )) str++; + if (*str == NUL) { + bogus_str: + errno = ENOENT; + return NULL; + } + + /* + * Take an approximate count of tokens. If no quoted strings are used, + * it will be accurate. If quoted strings are used, it will be a little + * high and we'll squander the space for a few extra pointers. + */ + { + cc_t* pz = (cc_t*)str; + + do { + max_token_ct++; + while (! isspace( *++pz )) + if (*pz == NUL) goto found_nul; + while (isspace( *pz )) pz++; + } while (*pz != NUL); + + found_nul: + ; + } + + res = malloc( sizeof(*res) + strlen(str) + (max_token_ct * sizeof(ch_t*)) ); + if (res == NULL) { + errno = ENOMEM; + return res; + } + + /* + * Now copy each token into the output buffer. + */ + { + ch_t* pzDest = (ch_t*)(res->tkn_list + (max_token_ct + 1)); + res->tkn_ct = 0; + + do { + res->tkn_list[ res->tkn_ct++ ] = pzDest; + for (;;) { + int ch = (ch_t)*str; + if (isspace( ch )) { + found_white_space: + while (isspace( (ch_t)*++str )) ; + break; + } + + switch (ch) { + case '"': + copy_cooked( &pzDest, &str ); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; + } + if (isspace( (ch_t)*str )) + goto found_white_space; + break; + + case '\'': + copy_raw( &pzDest, &str ); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; + } + if (isspace( (ch_t)*str )) + goto found_white_space; + break; + + case NUL: + goto copy_done; + + default: + str++; + *(pzDest++) = ch; + } + } copy_done:; + + /* + * NUL terminate the last token and see if we have any more tokens. + */ + *(pzDest++) = NUL; + } while (*str != NUL); + + res->tkn_list[ res->tkn_ct ] = NULL; + } + + return res; +} + +#ifdef TEST +#include <stdio.h> +#include <string.h> + +int +main( int argc, char** argv ) +{ + if (argc == 1) { + printf("USAGE: %s arg [ ... ]\n", *argv); + return 1; + } + while (--argc > 0) { + char* arg = *(++argv); + token_list_t* p = ao_string_tokenize( arg ); + if (p == NULL) { + printf( "Parsing string ``%s'' failed:\n\terrno %d (%s)\n", + arg, errno, strerror( errno )); + } else { + int ix = 0; + printf( "Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct ); + do { + printf( " %3d: ``%s''\n", ix+1, p->tkn_list[ix] ); + } while (++ix < p->tkn_ct); + free(p); + } + } + return 0; +} +#endif + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/tokenize.c */ diff --git a/contrib/ntp/libopts/usage.c b/contrib/ntp/libopts/usage.c new file mode 100644 index 0000000..960339b --- /dev/null +++ b/contrib/ntp/libopts/usage.c @@ -0,0 +1,740 @@ + +/* + * usage.c $Id: usage.c,v 4.15 2007/04/28 22:19:23 bkorb Exp $ + * Time-stamp: "2007-04-15 11:02:46 bkorb" + * + * This module implements the default usage procedure for + * Automated Options. It may be overridden, of course. + * + * Sort options: + --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \ + --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \ + --spac=2 --input=usage.c + */ + +/* + * Automated Options copyright 1992-2007 Bruce Korb + * + * Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT) + +static arg_types_t argTypes; + +FILE* option_usage_fp = NULL; +static char zOptFmtLine[ 16 ]; +static ag_bool displayEnum; + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static ag_bool +checkGNUUsage( tOptions* pOpts ); + +static void +printExtendedUsage( + tOptions* pOptions, + tOptDesc* pOD, + arg_types_t* pAT ); + +static void +printInitList( + tCC* const* papz, + ag_bool* pInitIntro, + tCC* pzRc, + tCC* pzPN ); + +static void +printOneUsage( + tOptions* pOptions, + tOptDesc* pOD, + arg_types_t* pAT ); + +static void +printOptionUsage( + tOptions* pOpts, + int ex_code, + tCC* pOptTitle ); + +static void +printProgramDetails( tOptions* pOptions ); + +static int +setGnuOptFmts( tOptions* pOpts, tCC** ppT ); + +static int +setStdOptFmts( tOptions* pOpts, tCC** ppT ); +/* = = = END-STATIC-FORWARD = = = */ + + +/* + * Figure out if we should try to format usage text sort-of like + * the way many GNU programs do. + */ +static ag_bool +checkGNUUsage( tOptions* pOpts ) +{ + char* pz = getenv( "AUTOOPTS_USAGE" ); + if (pz == NULL) + ; + + else if (streqvcmp( pz, "gnu" ) == 0) + pOpts->fOptSet |= OPTPROC_GNUUSAGE; + + else if (streqvcmp( pz, "autoopts" ) == 0) + pOpts->fOptSet &= ~OPTPROC_GNUUSAGE; + + return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? AG_TRUE : AG_FALSE; +} + + +/*=export_func optionOnlyUsage + * + * what: Print usage text for just the options + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + ex_code + exit code for calling exit(3) + + * + * doc: + * This routine will print only the usage for each option. + * This function may be used when the emitted usage must incorporate + * information not available to AutoOpts. +=*/ +void +optionOnlyUsage( + tOptions* pOpts, + int ex_code ) +{ + tCC* pOptTitle = NULL; + + /* + * Determine which header and which option formatting strings to use + */ + if (checkGNUUsage(pOpts)) { + (void)setGnuOptFmts( pOpts, &pOptTitle ); + } + else { + (void)setStdOptFmts( pOpts, &pOptTitle ); + } + + printOptionUsage( pOpts, ex_code, pOptTitle ); +} + + +/*=export_func optionUsage + * private: + * + * what: Print usage text + * arg: + tOptions* + pOptions + program options descriptor + + * arg: + int + exitCode + exit code for calling exit(3) + + * + * doc: + * This routine will print usage in both GNU-standard and AutoOpts-expanded + * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will + * over-ride this, providing the value of it is set to either "gnu" or + * "autoopts". This routine will @strong{not} return. + * + * If "exitCode" is "EX_USAGE" (normally 64), then output will to to stdout + * and the actual exit code will be "EXIT_SUCCESS". +=*/ +void +optionUsage( + tOptions* pOptions, + int usage_exit_code ) +{ + int actual_exit_code = + (usage_exit_code == EX_USAGE) ? EXIT_SUCCESS : usage_exit_code; + + displayEnum = AG_FALSE; + + /* + * Paged usage will preset option_usage_fp to an output file. + * If it hasn't already been set, then set it to standard output + * on successful exit (help was requested), otherwise error out. + */ + if (option_usage_fp == NULL) + option_usage_fp = (actual_exit_code != EXIT_SUCCESS) ? stderr : stdout; + + fprintf( option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName ); + + { + tCC* pOptTitle = NULL; + + /* + * Determine which header and which option formatting strings to use + */ + if (checkGNUUsage(pOptions)) { + int flen = setGnuOptFmts( pOptions, &pOptTitle ); + sprintf( zOptFmtLine, zFmtFmt, flen ); + fputc( '\n', option_usage_fp ); + } + else { + int flen = setStdOptFmts( pOptions, &pOptTitle ); + sprintf( zOptFmtLine, zFmtFmt, flen ); + + /* + * When we exit with EXIT_SUCCESS and the first option is a doc + * option, we do *NOT* want to emit the column headers. + * Otherwise, we do. + */ + if ( (usage_exit_code != EXIT_SUCCESS) + || ((pOptions->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) ) + + fputs( pOptTitle, option_usage_fp ); + } + + printOptionUsage( pOptions, usage_exit_code, pOptTitle ); + } + + /* + * Describe the mechanics of denoting the options + */ + switch (pOptions->fOptSet & OPTPROC_L_N_S) { + case OPTPROC_L_N_S: fputs( zFlagOkay, option_usage_fp ); break; + case OPTPROC_SHORTOPT: break; + case OPTPROC_LONGOPT: fputs( zNoFlags, option_usage_fp ); break; + case 0: fputs( zOptsOnly, option_usage_fp ); break; + } + + if ((pOptions->fOptSet & OPTPROC_NUM_OPT) != 0) { + fputs( zNumberOpt, option_usage_fp ); + } + + if ((pOptions->fOptSet & OPTPROC_REORDER) != 0) { + fputs( zReorder, option_usage_fp ); + } + + if (pOptions->pzExplain != NULL) + fputs( pOptions->pzExplain, option_usage_fp ); + + /* + * IF the user is asking for help (thus exiting with SUCCESS), + * THEN see what additional information we can provide. + */ + if (usage_exit_code == EXIT_SUCCESS) + printProgramDetails( pOptions ); + + if (pOptions->pzBugAddr != NULL) + fprintf( option_usage_fp, zPlsSendBugs, pOptions->pzBugAddr ); + fflush( option_usage_fp ); + + exit( actual_exit_code ); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * PER OPTION TYPE USAGE INFORMATION + */ +static void +printExtendedUsage( + tOptions* pOptions, + tOptDesc* pOD, + arg_types_t* pAT ) +{ + /* + * IF there are option conflicts or dependencies, + * THEN print them here. + */ + if ( (pOD->pOptMust != NULL) + || (pOD->pOptCant != NULL) ) { + + fputs( zTabHyp, option_usage_fp ); + + /* + * DEPENDENCIES: + */ + if (pOD->pOptMust != NULL) { + const int* pOptNo = pOD->pOptMust; + + fputs( zReqThese, option_usage_fp ); + for (;;) { + fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[ + *pOptNo ].pz_Name ); + if (*++pOptNo == NO_EQUIVALENT) + break; + } + + if (pOD->pOptCant != NULL) + fputs( zTabHypAnd, option_usage_fp ); + } + + /* + * CONFLICTS: + */ + if (pOD->pOptCant != NULL) { + const int* pOptNo = pOD->pOptCant; + + fputs( zProhib, option_usage_fp ); + for (;;) { + fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[ + *pOptNo ].pz_Name ); + if (*++pOptNo == NO_EQUIVALENT) + break; + } + } + } + + /* + * IF there is a disablement string + * THEN print the disablement info + */ + if (pOD->pz_DisableName != NULL ) + fprintf( option_usage_fp, zDis, pOD->pz_DisableName ); + + /* + * IF the numeric option has a special callback, + * THEN call it, requesting the range or other special info + */ + if ( (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) + && (pOD->pOptProc != NULL) + && (pOD->pOptProc != optionNumericVal) ) { + (*(pOD->pOptProc))( pOptions, NULL ); + } + + /* + * IF the option defaults to being enabled, + * THEN print that out + */ + if (pOD->fOptState & OPTST_INITENABLED) + fputs( zEnab, option_usage_fp ); + + /* + * IF the option is in an equivalence class + * AND not the designated lead + * THEN print equivalence and leave it at that. + */ + if ( (pOD->optEquivIndex != NO_EQUIVALENT) + && (pOD->optEquivIndex != pOD->optActualIndex ) ) { + fprintf( option_usage_fp, zAlt, + pOptions->pOptDesc[ pOD->optEquivIndex ].pz_Name ); + return; + } + + /* + * IF this particular option can NOT be preset + * AND some form of presetting IS allowed, + * AND it is not an auto-managed option (e.g. --help, et al.) + * THEN advise that this option may not be preset. + */ + if ( ((pOD->fOptState & OPTST_NO_INIT) != 0) + && ( (pOptions->papzHomeList != NULL) + || (pOptions->pzPROGNAME != NULL) + ) + && (pOD->optIndex < pOptions->presetOptCt) + ) + + fputs( zNoPreset, option_usage_fp ); + + /* + * Print the appearance requirements. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) + fputs( zMembers, option_usage_fp ); + + else switch (pOD->optMinCt) { + case 1: + case 0: + switch (pOD->optMaxCt) { + case 0: fputs( zPreset, option_usage_fp ); break; + case NOLIMIT: fputs( zNoLim, option_usage_fp ); break; + case 1: break; + /* + * IF the max is more than one but limited, print "UP TO" message + */ + default: fprintf( option_usage_fp, zUpTo, pOD->optMaxCt ); break; + } + break; + + default: + /* + * More than one is required. Print the range. + */ + fprintf( option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt ); + } + + if ( NAMED_OPTS( pOptions ) + && (pOptions->specOptIdx.default_opt == pOD->optIndex)) + fputs( zDefaultOpt, option_usage_fp ); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Figure out where all the initialization files might live. + * This requires translating some environment variables and + * testing to see if a name is a directory or a file. It's + * squishy, but important to tell users how to find these files. + */ +static void +printInitList( + tCC* const* papz, + ag_bool* pInitIntro, + tCC* pzRc, + tCC* pzPN ) +{ + char zPath[ AG_PATH_MAX+1 ]; + + if (papz == NULL) + return; + + fputs( zPresetIntro, option_usage_fp ); + *pInitIntro = AG_FALSE; + + for (;;) { + char const* pzPath = *(papz++); + + if (pzPath == NULL) + break; + + if (optionMakePath(zPath, (int)sizeof( zPath ), pzPath, pzPN)) + pzPath = zPath; + + /* + * Print the name of the "homerc" file. If the "rcfile" name is + * not empty, we may or may not print that, too... + */ + fprintf( option_usage_fp, zPathFmt, pzPath ); + if (*pzRc != NUL) { + struct stat sb; + + /* + * IF the "homerc" file is a directory, + * then append the "rcfile" name. + */ + if ( (stat( pzPath, &sb ) == 0) + && S_ISDIR( sb.st_mode ) ) { + fputc( DIRCH, option_usage_fp ); + fputs( pzRc, option_usage_fp ); + } + } + + fputc( '\n', option_usage_fp ); + } +} + + +/* + * Print the usage information for a single option. + */ +static void +printOneUsage( + tOptions* pOptions, + tOptDesc* pOD, + arg_types_t* pAT ) +{ + /* + * Flag prefix: IF no flags at all, then omit it. If not printable + * (not allowed for this option), then blank, else print it. + * Follow it with a comma if we are doing GNU usage and long + * opts are to be printed too. + */ + if ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0) + fputs( pAT->pzSpc, option_usage_fp ); + else if (! isgraph( pOD->optValue)) { + if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + fputc( ' ', option_usage_fp ); + fputs( pAT->pzNoF, option_usage_fp ); + } else { + fprintf( option_usage_fp, " -%c", pOD->optValue ); + if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + fputs( ", ", option_usage_fp ); + } + + { + char z[ 80 ]; + tCC* pzArgType; + /* + * Determine the argument type string first on its usage, then, + * when the option argument is required, base the type string on the + * argument type. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NONE) { + pzArgType = pAT->pzNo; + + } else if (pOD->fOptState & OPTST_ARG_OPTIONAL) { + pzArgType = pAT->pzOpt; + + } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { + case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey; break; + case OPARG_TYPE_MEMBERSHIP: pzArgType = pAT->pzKeyL; break; + case OPARG_TYPE_BOOLEAN: pzArgType = pAT->pzBool; break; + case OPARG_TYPE_NUMERIC: pzArgType = pAT->pzNum; break; + case OPARG_TYPE_HIERARCHY: pzArgType = pAT->pzNest; break; + case OPARG_TYPE_STRING: pzArgType = pAT->pzStr; break; + default: goto bogus_desc; break; + } + + snprintf( z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name, + (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt ); + + fprintf( option_usage_fp, zOptFmtLine, z, pOD->pzText ); + + switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + displayEnum = (pOD->pOptProc != NULL) ? AG_TRUE : displayEnum; + } + } + return; + + bogus_desc: + fprintf( stderr, zInvalOptDesc, pOD->pz_Name ); + exit( EX_SOFTWARE ); +} + + +/* + * Print out the usage information for just the options. + */ +static void +printOptionUsage( + tOptions* pOpts, + int ex_code, + tCC* pOptTitle ) +{ + int ct = pOpts->optCt; + int optNo = 0; + tOptDesc* pOD = pOpts->pOptDesc; + int docCt = 0; + + do { + if ((pOD->fOptState & OPTST_OMITTED) != 0) + continue; + + if ((pOD->fOptState & OPTST_DOCUMENT) != 0) { + if (ex_code == EXIT_SUCCESS) { + fprintf(option_usage_fp, argTypes.pzBrk, pOD->pzText, + pOptTitle); + docCt++; + } + + continue; + } + + /* + * IF this is the first auto-opt maintained option + * *AND* we are doing a full help + * *AND* there are documentation options + * *AND* the last one was not a doc option, + * THEN document that the remaining options are not user opts + */ + if ( (pOpts->presetOptCt == optNo) + && (ex_code == EXIT_SUCCESS) + && (docCt > 0) + && ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) ) + fprintf( option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle ); + + printOneUsage( pOpts, pOD, &argTypes ); + + /* + * IF we were invoked because of the --help option, + * THEN print all the extra info + */ + if (ex_code == EXIT_SUCCESS) + printExtendedUsage( pOpts, pOD, &argTypes ); + + } while (pOD++, optNo++, (--ct > 0)); + + fputc( '\n', option_usage_fp ); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * PROGRAM DETAILS + */ +static void +printProgramDetails( tOptions* pOptions ) +{ + ag_bool initIntro = AG_TRUE; + + /* + * Display all the places we look for config files + */ + printInitList( pOptions->papzHomeList, &initIntro, + pOptions->pzRcName, pOptions->pzProgPath ); + + /* + * Let the user know about environment variable settings + */ + if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) { + if (initIntro) + fputs( zPresetIntro, option_usage_fp ); + + fprintf( option_usage_fp, zExamineFmt, pOptions->pzPROGNAME ); + } + + /* + * IF we found an enumeration, + * THEN hunt for it again. Call the handler proc with a NULL + * option struct pointer. That tells it to display the keywords. + */ + if (displayEnum) { + int ct = pOptions->optCt; + int optNo = 0; + tOptDesc* pOD = pOptions->pOptDesc; + + fputc( '\n', option_usage_fp ); + fflush( option_usage_fp ); + do { + switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + (*(pOD->pOptProc))( NULL, pOD ); + } + } while (pOD++, optNo++, (--ct > 0)); + } + + /* + * If there is a detail string, now is the time for that. + */ + if (pOptions->pzDetail != NULL) + fputs( pOptions->pzDetail, option_usage_fp ); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * OPTION LINE FORMATTING SETUP + * + * The "OptFmt" formats receive three arguments: + * 1. the type of the option's argument + * 2. the long name of the option + * 3. "YES" or "no ", depending on whether or not the option must appear + * on the command line. + * These formats are used immediately after the option flag (if used) has + * been printed. + * + * Set up the formatting for GNU-style output + */ +static int +setGnuOptFmts( tOptions* pOpts, tCC** ppT ) +{ + int flen = 22; + *ppT = zNoRq_ShrtTtl; + + argTypes.pzStr = zGnuStrArg; + argTypes.pzReq = zOneSpace; + argTypes.pzNum = zGnuNumArg; + argTypes.pzKey = zGnuKeyArg; + argTypes.pzKeyL = zGnuKeyLArg; + argTypes.pzBool = zGnuBoolArg; + argTypes.pzNest = zGnuNestArg; + argTypes.pzOpt = zGnuOptArg; + argTypes.pzNo = zOneSpace; + argTypes.pzBrk = zGnuBreak; + argTypes.pzNoF = zSixSpaces; + argTypes.pzSpc = zThreeSpaces; + + switch (pOpts->fOptSet & OPTPROC_L_N_S) { + case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break; + case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break; + case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break; + case OPTPROC_SHORTOPT: + argTypes.pzOptFmt = zShrtGnuOptFmt; + zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' '; + argTypes.pzOpt = " [arg]"; + flen = 8; + break; + } + + return flen; +} + + +/* + * Standard (AutoOpts normal) option line formatting + */ +static int +setStdOptFmts( tOptions* pOpts, tCC** ppT ) +{ + int flen = 0; + + argTypes.pzStr = zStdStrArg; + argTypes.pzReq = zStdReqArg; + argTypes.pzNum = zStdNumArg; + argTypes.pzKey = zStdKeyArg; + argTypes.pzKeyL = zStdKeyLArg; + argTypes.pzBool = zStdBoolArg; + argTypes.pzNest = zStdNestArg; + argTypes.pzOpt = zStdOptArg; + argTypes.pzNo = zStdNoArg; + argTypes.pzBrk = zStdBreak; + argTypes.pzNoF = zFiveSpaces; + argTypes.pzSpc = zTwoSpaces; + + switch (pOpts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) { + case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT): + *ppT = zNoRq_ShrtTtl; + argTypes.pzOptFmt = zNrmOptFmt; + flen = 19; + break; + + case OPTPROC_NO_REQ_OPT: + *ppT = zNoRq_NoShrtTtl; + argTypes.pzOptFmt = zNrmOptFmt; + flen = 19; + break; + + case OPTPROC_SHORTOPT: + *ppT = zReq_ShrtTtl; + argTypes.pzOptFmt = zReqOptFmt; + flen = 24; + break; + + case 0: + *ppT = zReq_NoShrtTtl; + argTypes.pzOptFmt = zReqOptFmt; + flen = 24; + } + + return flen; +} + + +/*: + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/usage.c */ diff --git a/contrib/ntp/libopts/version.c b/contrib/ntp/libopts/version.c new file mode 100644 index 0000000..85949d5 --- /dev/null +++ b/contrib/ntp/libopts/version.c @@ -0,0 +1,178 @@ + +/* $Id: version.c,v 4.10 2007/04/28 22:19:23 bkorb Exp $ + * Time-stamp: "2007-04-28 10:08:34 bkorb" + * + * This module implements the default usage procedure for + * Automated Options. It may be overridden, of course. + */ + +static char const zAOV[] = + "Automated Options version %s, copyright (c) 1999-2007 Bruce Korb\n"; + +/* Automated Options is free software. + * You may redistribute 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. + * + * Automated Options is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Automated Options. See the file "COPYING". If not, + * write to: The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in his release of AutoOpts. + * + * The exception is that, if you link the AutoOpts library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the AutoOpts library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name AutoOpts. If you copy code from other sources under the + * General Public License into a copy of AutoOpts, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for AutoOpts, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +/* = = = START-STATIC-FORWARD = = = */ +/* static forward declarations maintained by :mkfwd */ +static void +printVersion( tOptions* pOpts, tOptDesc* pOD, FILE* fp ); +/* = = = END-STATIC-FORWARD = = = */ + +/*=export_func optionVersion + * + * what: return the compiled AutoOpts version number + * ret_type: char const* + * ret_desc: the version string in constant memory + * doc: + * Returns the full version string compiled into the library. + * The returned string cannot be modified. +=*/ +char const* +optionVersion( void ) +{ + static char const zVersion[] = + STR( AO_CURRENT.AO_REVISION ); + + return zVersion; +} + + +static void +printVersion( tOptions* pOpts, tOptDesc* pOD, FILE* fp ) +{ + char swCh; + + /* + * IF the optional argument flag is off, or the argument is not provided, + * then just print the version. + */ + if ( ((pOD->fOptState & OPTST_ARG_OPTIONAL) == 0) + || (pOD->optArg.argString == NULL)) + swCh = 'v'; + else swCh = tolower(pOD->optArg.argString[0]); + + if (pOpts->pzFullVersion != NULL) { + fputs( pOpts->pzFullVersion, fp ); + fputc( '\n', fp ); + + } else { + char const *pz = pOpts->pzUsageTitle; + do { fputc(*pz, fp); } while (*(pz++) != '\n'); + } + + switch (swCh) { + case NUL: /* arg provided, but empty */ + case 'v': + break; + + case 'c': + if (pOpts->pzCopyright != NULL) { + fputs( pOpts->pzCopyright, fp ); + fputc( '\n', fp ); + } + fprintf( fp, zAOV, optionVersion() ); + if (pOpts->pzBugAddr != NULL) + fprintf( fp, zPlsSendBugs, pOpts->pzBugAddr ); + break; + + case 'n': + if (pOpts->pzCopyright != NULL) { + fputs( pOpts->pzCopyright, fp ); + fputc( '\n', fp ); + fputc( '\n', fp ); + } + + if (pOpts->pzCopyNotice != NULL) { + fputs( pOpts->pzCopyNotice, fp ); + fputc( '\n', fp ); + } + + fprintf( fp, zAOV, optionVersion() ); + if (pOpts->pzBugAddr != NULL) + fprintf( fp, zPlsSendBugs, pOpts->pzBugAddr ); + break; + + default: + fprintf( stderr, zBadVerArg, swCh ); + exit( EXIT_FAILURE ); + } + + exit( EXIT_SUCCESS ); +} + +/*=export_func optionPrintVersion + * private: + * + * what: Print the program version + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * This routine will print the version to stdout. +=*/ +void +optionPrintVersion( tOptions* pOpts, tOptDesc* pOD ) +{ + printVersion( pOpts, pOD, stdout ); +} + +/*=export_func optionVersionStderr + * private: + * + * what: Print the program version to stderr + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * + * doc: + * This routine will print the version to stderr. +=*/ +void +optionVersionStderr( tOptions* pOpts, tOptDesc* pOD ) +{ + printVersion( pOpts, pOD, stderr ); +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/version.c */ |