pax_global_header00006660000000000000000000000064151571003510014510gustar00rootroot0000000000000052 comment=cae3d2d9407f2115a96b227542930a5a7ec52ace quotatool-1.8.0/000077500000000000000000000000001515710035100135455ustar00rootroot00000000000000quotatool-1.8.0/.gitignore000066400000000000000000000006361515710035100155420ustar00rootroot00000000000000*~ *.d *.o /config.cache /config.log /config.status /local.mk /quotatool /src/config.h /*.tar.gz /autom4te.cache /FILESYSTEMS /johan* research/ .claude/session.md test/kernels/*/ !test/kernels/initramfs/ test/kernels/initramfs/initramfs.cpio.gz test/kernels/initramfs/busybox-musl test/kernels/rootfs.img test/kernels/alpine-rootfs.img test/kernels/.alpine-cache/ test/results/ test/tmp_run.sh test/bsd/images/ quotatool-1.8.0/AUTHORS000066400000000000000000000010231515710035100146110ustar00rootroot00000000000000Primary Authors --------------- Johan Ekenberg (maintainer and developer since 2002) Mike Glover (wrote the first versions around 1999/2000) Contributors ------------ Andrew Kerr B. ten Berge cagri coltekin -- AIX port Lu Vo François Micaux Mats Erik Andersson -- first patches for BSD quotatool-1.8.0/CLAUDE.md000066400000000000000000000074031515710035100150300ustar00rootroot00000000000000# CLAUDE.md — quotatool project instructions ## Session Start **First priority: read `MASTERPLAN.org`** to understand the project, which milestone is active, and what the current context is. Then read the active milestone's step-plan in `steps/`. Never start work without knowing where we are. 1. Read `MASTERPLAN.org` → active step-plan in `steps/`. 2. Read `.claude/session.md`. Orient. Report status briefly. 3. Check `/dev/kvm` is accessible (needed for VM-based testing). If not: warn the user, simple edits are fine but test/build needs KVM. ## Project - Language: C (ANSI C, no external dependencies) - Build: `./configure && make` - Platforms: Linux (primary), FreeBSD, OpenBSD - Test suite: `test/run-tests --help` (25 kernels, ext4 + XFS, KVM) ## Rules ### State Tracking All state lives in files. LLM context is ephemeral — files are not. - Update files at every checkpoint. No information exists only in conversation. - No duplication. Each fact has one canonical location. Reference, don't copy. - On cold start, a new session must recover fully from files alone. | File/Dir | Purpose | |--------------------|--------------------------------------------| | MASTERPLAN.org | High-level milestones, goal, current state | | steps/NN-*.org | Detailed step-plan per milestone | | research/*.org | Background research (read-only reference) | | .claude/session.md | Session scratchpad (gitignored) | | CLAUDE.md | This file — project instructions | ### Scratch Scripts **ENFORCED**: Never run multi-step bash commands directly via the Bash tool. Write them to `test/tmp_run.sh` and run that. The user has this file pre-approved — avoids permission prompts. **This applies to agents too.** Any agent that needs to run bash commands must use `test/tmp_run.sh`, not direct Bash calls. `tmp_run.sh` is gitignored. Never commit it. ### Bug Fix Workflow For any bug in `src/`: 1. **Reproduce first.** Write or update a test that catches the bug. Run it — confirm it fails. 2. **Fix the code.** Minimal change. 3. **Verify.** Run the test — confirm it passes. Run `--host-only` for no regressions. 4. **Human review.** Present the diff. User reviews in editor and tests manually with `--interactive`. 5. **Commit.** One logical change per commit. Never fix code without first demonstrating the bug exists in a test. ### No Premature Conclusions - Do not mark issues as "not a bug" or "kernel limitation" without thorough investigation. Demonstrate with evidence, not speculation. - When something fails on one host but not another, bisect systematically. Don't guess. - If stuck, say so honestly. Don't paper over confusion with workarounds. ### Testing - Test on multiple hosts before release. Different distros catch different issues (mkfs versions, kernel behavior, package layout). - Full matrix (`--all`) before any push that changes test framework or `src/` code. - `--host-only` for quick verification during development. ### Conventions - Org-mode for all planning and research documents - TODO states: `TODO`, `DOING`, `WAITING`, `DONE`, `CANCELLED` only - Git commits: descriptive, one logical change per commit - Branches for non-trivial work - Do not push without explicit permission - **Never install system packages** — tell the user what to install - **Never work around missing packages** — if a canonical tool is needed, install it. Don't build stubs, shims, or alternatives. Stop, tell the user, decide together. ### Dependencies Keep the dependency stack minimal. Reuse bash, python3, busybox, coreutils before adding anything new. Think cross-distro — what works on Debian may not exist on Fedora. Degrade gracefully when optional tools are missing. quotatool-1.8.0/COPYING000066400000000000000000000354671515710035100146170ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 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. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. 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. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS quotatool-1.8.0/ChangeLog000066400000000000000000000155721515710035100153310ustar00rootroot0000000000000019 Mar 2026 (1.8.0) - Drop macOS, AIX, Solaris, NetBSD platform support See PLATFORM-CHANGES.md for rationale and references v1.7.x continues to support these platforms - Add BSD test framework (FreeBSD 14.4, OpenBSD 7.8) - Fix: Q_SYNC hangs on OpenBSD vnd-backed FFS (#35) - Fix: BSD expired grace period displays as huge number (#36) - Fix: BSD -t grace period writes to wrong uid (#37) - Fix: 5 bugs in src/bsd/quota.c found by code audit (uninitialized struct, grace fields, memory leaks, pointer arithmetic, incorrect casts) - Fix: memory leak in linux/quota.c quota_new() - Fix: uninitialized _do_set_global_* flags (malloc → calloc) - Use mount point directly for BSD quotactl (simpler, matches edquota) - Remove dead code: dqb_curblocks/curinodes in BSD quota_set() - Clean build system: remove dropped platform detection and headers - Null-terminate strncpy buffers in system.c 18 Mar 2026 (1.7.0) - Fix: +0M clearing quota instead of no-op (#31) - Fix: ambiguous "5m" timespan silently passed to quotactl (#32) - Fix: -d grace field showing garbage for expired grace periods (#33) - Fix: XFS grace period reset on newer kernels (hybrid approach) - Fix: removed unused #include , fixes musl builds (#34) - Added multi-kernel test suite (25 kernels, ext4 + XFS) - Clean compile with -Wall -Wextra on gcc and clang - Dead code removal, updated comments - See ROADMAP.md for planned v1.8.0 platform changes 24 July 2024 (1.6.5) - Fix issue #28: 'fix missing __P definition for musl compile' - Add license info to README 1 May 2024 (1.6.4) - Fix issue #27: 'Failed setting gracetime (generic): Invalid argument' - Update to autoconf 2.71 - Code cleanups 2 Oct 2023 (1.6.3) - Fix compiler warnings - Improve documentation - Other minor bugfixes 14 Jan 2013 (1.6.2) - Support for Mac OS X (Darwin) 2 Jan 2013 (1.6.1) - Support for NetBSD (compatibility mode for UFS/FFS-quota) 1 Jan 2013 (1.6.0) - Exit gracefully on Linux VFSV1 && ! GENERIC - Improve / robustify argument parsing - Rewrite algorithms for grace time reset - Use strlcat/strlcpy if available - BSD support (FreeBSD, OpenBSD) 25 Dec 2012 (1.5.1) - Fix bug in Linux format parsing 24 Dec 2012 (1.5.0) - Support linux quota version vfsv1 - Fix inode count modifiers, use base 10 (-i -q 1.2K = 1200 inodes etc) 23 Dec 2012 (1.4.13) - Ignore linux initramfs mount entry for rootfs - Install in sbindir (default = /usr/local/sbin), not bindir - Accept floating point input for sizes, eg 1.01Tb - Fix parsing of large integers (very large filesystems) - Fix typo in machine format - Fix several compile warnings 20 Feb 2012 (1.4.12) - Add Gb and Tb multipliers for size-units - Allow non-existent uid/gid by adding prefix ":" - Fix 64-bit compile warnings - Fix Debian bug #627733: 'Inconsistent units in -d output on XFS' - Do not reset grace periods if option -n given - Move to Github (https://github.com/ekenberg/quotatool) - Better documentation, more examples, cleaned up AUTHORS/ChangeLog 28 Sep 2009 (1.4.11) - Updated Makefile to honor the DESTDIR variable 24 Sep 2007 (1.4.10) - Fix for building on 64-bit systems - Bugfix off-by-one-error in parsing loop devices (thanks Bas Zoetekouw) - Bugfix commandline parsing with option -t - Updated manpage and usage info 20 Feb 2006 (1.4.9) - Fixed a bug when fetching XFS quota for a user/group with no current usage/quota (thanks Francois Micaux - fmicaux@actilis.net) 2 Sept 2005 (1.4.8) - Timeparsing now defaults to seconds as the man-page states it should 13 Jul 2004 (1.4.6) - Bugfix detecting XFS on Linux under certain conditions 7 Jul 2004 (1.4.5) - Bugfix for solaris 9 and other systems with 2 Feb 2004 (1.4.4) - Support for quota on loop-device (linux) 30 Oct 2003 (1.4.3) - bugfix (reset-code caused unnecessary quota_set()) - Added option "-R" (raise-only) to only raise, never lower quotas for uid/gid - Updated manpage 14 Oct 2003 (1.4.2) - autoconf check for u_int64_t - corrections for solaris quota 7 Oct 2003 (1.4.1) - Added "-d" option to dump quota info in machine readable format 27 Sep 2003 (1.4.0) - Added support for new generic quota format found in later kernels (2.4.22 etc) (Johan) 23 Apr 2003 (1.3.2) - Extended checks for quotaformat to work with linux kernel >= 2.4.20 30 Apr 2002 (1.3.0) - support for XFS on Linux - try to use uint_64_t wherever appropriate - minor bugfixes/adjustments 25 Feb 2002 (1.2.1) - support for old + new linux quota format - linux quota format detection at runtime - fixed setting global grace times with new linux quota format - quit using , shipping our own header file instead - removed all memcpy():ing of quota structs, linux + solaris - several minor bugfixes 01 Nov 2001 (1.1.3) - added support for linux 2.4 - fixed man page installation directory 29 Jun 2001 (1.1.2) - added support for AIX 09 Mar 2001 (1.1.1) - fixed segfault on 'quotatool -u' or 'quotatool -g' - fixed integer overflow in parse_size 03 Mar 2001 (1.1.0) - fixed check against MAXQUOTAS in linux/quota.c 03 Mar 2001 (1.1.0) - fixed check against MAXQUOTAS in linux/quota.c 03 Feb 2001 (1.1.alpha2) - wrote a man page (in man/) - removed usage info from README - moved autoconf tools into tools/ - made some changes to the configuration process - forward-ported the linux 2.4 fix from the 1.0 tree 21 Jan 2001 (1.1.alpha1) [unreleased] - branched from 1.0 code - added support for solaris (UFS) quotas - created src/linux and src/solaris directories - made many small changes to make porting easier - added --with-gnu-getopt option to configure 15 Jan 2001 (1.0.beta1) - reorganized functions amongst files - added the '-n' switch - rewrote output functions - rewrote most of main() - moved to a two-pass parse. - it's now possible to use the -t flag without -[ug] 0 - Switched from reading /etc/fstab to /etc/mtab - removed check for *quota when reading /etc/mtab - added a second level of verbosity (-v -v) - added +/- parsing for timespans and blocks/inodes - Started holy war: replaced spaces with tabs >:-) - lots of other stuff, I'm sure. pretty much rewrote the whole thing from scratch. 7 Feb 2000 - Additions/changes to README - Corrected typo in main.c (incorrect report when setting global block grace period) - A few formatting issues corrected. - Replaced all tabs with spaces (3) 1 Feb 2000 - Split to several sourcefiles + quotatool.h - Added autoconf etc (KDevelop did this for me...) - Changed flags.use_user -> flags.usrquota --::-- flags.use_group -> flags.grpquota - Replaced all global variables with struct argdata_t - Added check for "usrquota" and "groupquota" in fstab - New README quotatool-1.8.0/INSTALL000066400000000000000000000171551515710035100146070ustar00rootroot00000000000000====================================================================== Please note: quotatool is probably available for installation through your distribution's package manager. You shouldn't have to build it from source unless you need a more recent version. See http://quotatool.ekenberg.se/index.php?node=download for installation instructions for common Linux distributions. ====================================================================== However, if you do need to build it yourself, this should work in 99% of all cases: ./configure make (or gmake if on *BSD) (as root) make install (or 'gmake install' if on *BSD) Please see the README for more information. ====================================================================== These are the generic installation instructions from autoconf: Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Type `make install' to install the programs and any data files and documentation. 4. You can remove the program binaries and object files from the source code directory by typing `make clean'. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. quotatool-1.8.0/MASTERPLAN.org000066400000000000000000000315601515710035100157310ustar00rootroot00000000000000#+TITLE: quotatool — Masterplan #+AUTHOR: Johan Ekenberg #+DATE: 2026-03-08 (revised 2026-03-15) * AI coding - to the human reader Yes, the rest of this file is mostly maintained by AI (Claude Code). It's a hard decision how much of development chores to hand over to AI, and how much to keep doing by hand. I have chosen to embrace AI for mostly maintaining project notes, todos, research notes, commit messages and large non-core boilerplate code generation like the new test framework. For actual bugs and features I have stayed in the loop, reviewing/coding manually, testing the important bits by hand. I expect these choices will be challenged continuously as we move forward, AI capabilities increasing seamingly exponentially over time. * Purpose This document is the single source of truth for the quotatool modernization effort. It defines the goal, the major milestones to get there, and tracks which milestone is current. Each milestone has a separate step-plan file (=steps/NN-name.org=) created when that milestone becomes active. The step-plan contains detailed tasks, decisions, and progress for that milestone only. Background research lives in =research/=. This document references but does not duplicate that material. * Goal Transform quotatool from a multi-platform legacy tool into a focused, well-tested Linux (+BSD) utility with modern kernel API support. Establish automated testing that makes ongoing maintenance confident and low-effort. * Current State (2026-03-19) - Working tool, ~4,800 LOC of clean C, no dependencies - Supports Linux, FreeBSD, OpenBSD - *Test suite complete* — Linux 25 kernels (ext4+XFS), FreeBSD 14.4, OpenBSD 7.8 - *M2 DONE*: BSD testing, platform drops, code cleanup - Bugs fixed: Q_SYNC hang, #36/#37 grace, 5 audit bugs, memory leak, uninit fields - Dropped: macOS, AIX, Solaris, NetBSD (see PLATFORM-CHANGES.md) - Missing support for newer kernel APIs (quotactl_fd, project quotas) - Packaged in Debian, Ubuntu, Fedora, EPEL, Gentoo, openSUSE, Homebrew - *v1.7.0 released* (March 2026): bug fixes + test framework - *v1.7.1 released*: macOS install fix (#30) - Ready for v1.8.0 release * Strategy *Revised 2026-03-15*: Original plan was "all scaffolding, then all building." Revised to ship bug fixes earlier — the Linux test framework is ready, users benefit from fixes now. BSD scaffolding and platform drops are a separate, later release. Order of work: 1. *M1 (DONE)*: Linux test framework — the foundation 2. *M3 (DONE)*: Bug fixes + cleanup → *released as v1.7.0* 3. *M2*: BSD testing + platform drops (+possibly M4/M5) → *release v1.8.0* 4. *M4/M5*: New features (if not bundled with M2) The key change: M3 before M2. Rationale: - Bug fixes benefit users immediately (grace -r affects 7 kernels) - The test framework to verify fixes is ready (M1) - BSD testing is unbounded effort for low user base - Platform drops deserve their own release with advance notice - v1.7.0 as a "quality release" (fixes + tests) is a positive message; "we deleted your platform" is not * Milestones ** DONE M1: Linux Test Framework [step-plan: steps/01-testing.org] The critical enabler for everything else. Without this, no change can be made with confidence. *Complete as of 2026-03-15.* Delivered: - Clone repo → =run-tests --setup= → =run-tests --all= → full results across 25 kernels - Validated on multiple hosts - 16 kernel-matrix tests × 2 filesystems × 25 kernels - Host-side test checks (arg validation, unit parsing, timespan, dump format) - =--quick= (no VM, instant), =--host-only= (one VM), full matrix - Alpine rootfs for RHEL kernels (musl-based, no host dependency) - Dependency audit complete (dep stack lean, grep -oP → POSIX sed) - All test assertions reviewed for false positives by 4 audit agents - All failures are known quotatool bugs, not framework issues Branch: =m1-testing= (merged to =master= as part of v1.7.0) Inputs: =research/testing-infrastructure.org=, =research/multi-kernel-testing.org= ----- *→ Release v1.7.0 after M3* ----- ** DONE M3: Bug Fixes & Codebase Cleanup [step-plan: steps/03-cleanup.org] /Status: COMPLETE — released as v1.7.0/ Bug fixes and cleanup, verified by the full test suite. This is the first milestone that touches =src/=. *** Priority fixes - *Grace period restart (-r)*: broken on kernels ≤4.12 — sets grace to 0 instead of restarting. Confirmed quotatool bug, 7 kernels affected. Fix and verify with the multi-kernel matrix. - *+0M clears quota*: =parse_size()= returns 0 when =count==0=, ignoring =orig= and =op=. So =+0M= applied to 100M → 0 instead of being a no-op. Discovered and confirmed during M1 testing. - *XFS grace period display*: =-d= reports =block_grace=0= after setting grace on XFS. Possibly a display bug or =-t= not reaching XFS properly (Q5 in =steps/01-testing.org=). - *-d grace field operator precedence*: Linux code path in =main.c= line 109/123 has wrong C operator precedence on the cast. BSD code path (lines 101-107) is correct. The cast applies only to =block_time=, not to the ternary result. - *"5m" timespan ambiguity*: =parse_timespan()= returns -1 for bare "m" (ambiguous: minutes or months), but =main.c= doesn't check the return value. The -1 reaches =quotactl()= unchecked. *** Cleanup - Remove dead code, commented debug blocks - Static analysis (cppcheck, scan-build) - Fix known issues (e.g. mixed indentation) - Evaluate whether shipping custom kernel quota headers is still needed - Ensure clean compile with =-Wall -Wextra= on gcc and clang - Remove unused =#include = from =src/linux/linux_quota.h= *** UX: run-tests CLI review (DONE) - Renamed =run-tests.sh= → =run-tests= (no extension) - No-args shows help - =--all= required for full matrix ----- *v1.7.0 released. v1.7.1 released (macOS install fix).* ----- ** DONE M2: Platform Testing & Cleanup [step-plans: steps/02a-bsd-testing.org, steps/02b-platform-docs.org, steps/02c-platform-drops.org] /Status: COMPLETE. M2a (BSD testing), M2b (platform docs), M2c (code drops) all done./ *** M2a: BSD Test Coverage (scaffolding) Before dropping any platform, establish test coverage for the platforms we're *keeping*. You don't delete code you can't test. FreeBSD and OpenBSD share =src/bsd/quota.c= (181 LOC) — completely different code path from Linux. Uses =quotactl()= on FreeBSD, UFS filesystem, =quota.user=/=quota.group= files. None of this is currently tested. Note: there is no =src/openbsd/= — FreeBSD, OpenBSD, and NetBSD all use =src/bsd/= via the =ANY_BSD= macro in =quotatool.h=. =configure.ac= maps all three to =PLATFORM=bsd=. Tasks: - Fix BSD expired-grace display bug (#36, found during M3 #33 fix) - Research BSD quota APIs, filesystem setup, VM options - FreeBSD test path: QEMU + FreeBSD image, or Cirrus CI (free) - OpenBSD test path: QEMU + OpenBSD image, or Cirrus CI - Adapt test scripts: UFS quota setup, BSD-compatible commands - Reuse existing test logic where possible (limits, grace, etc.) - Verify: quotatool builds and passes basic tests on FreeBSD + OpenBSD Result: same confidence level for BSD as we have for Linux. *** M2b: Document Platform Decisions Before removing code, document *why* each platform is dropped. quotatool is packaged in Homebrew and MacPorts — dropping macOS needs a clear public explanation, not just a commit message. Write =PLATFORM-CHANGES.md= (or section in README) covering: - *macOS*: APFS replaced HFS+ as default (2017). APFS has no traditional quota support. The quotactl() interface quotatool uses doesn't work on APFS. No path forward — not a temporary gap. - *AIX*: no accessible test environment, no known users, IBM's proprietary JFS2 quota API has diverged. - *Solaris/illumos*: ZFS is the standard filesystem. ZFS has its own quota system (=zfs set quota==) that doesn't use quotactl(). - *NetBSD*: broke their quotactl API (=__quotactl=) in a way that's incompatible with quotatool's approach. Would need a full rewrite of the NetBSD backend. - *FreeBSD, OpenBSD*: kept. Active projects, standard UFS quotas, quotatool works. Note: v1.7.0's ROADMAP.md announces these planned drops. Notify Homebrew/MacPorts stakeholders before v1.8.0 release. *** M2c: Drop Dead Platforms With test coverage on the survivors and rationale documented, safely remove the dead. For each drop: 1. Remove =src//= code 2. Update =configure.ac=, =Makefile.am= 3. Run full test suite (Linux + BSD) — verify no regressions 4. Commit per platform (atomic, revertible) Result: smaller, honest codebase. Updated README, configure, Makefile. Inputs: =research/other-os-relevance.org= *** Possibly: bundle M4/M5 into v1.8.0 Decision deferred until after v1.7.0 release. Options: - *v1.8.0 = M2 + M4 + M5*: one big release with platform changes AND new features. Gives distro maintainers a reason to repackage (quotactl_fd + project quotas are real value-adds). - *v1.8.0 = M2 only, v1.9.0 = M4+M5*: smaller releases in quick succession. Less risk per release but more packaging churn. The distro-maintainer argument favors bundling: they won't rush to package a release that only removes platforms. Adding quotactl_fd (tmpfs/bcachefs quotas) and project quotas gives them actual value. ----- *→ Release v1.8.0 here* ----- ** TODO M4: quotactl_fd() Support [step-plan: steps/04-quotactl-fd.org] /Status: NOT STARTED — possibly bundled with M2 in v1.8.0/ Add support for the quotactl_fd() syscall (kernel 5.14+). This enables quota management on tmpfs (kernel 6.6+) and bcachefs — filesystems that have no block device path and thus can't use the original quotactl(). Inputs: =research/linux-kernel-quota-api.org= ** TODO M5: Project Quota Support [step-plan: steps/05-project-quotas.org] /Status: NOT STARTED — possibly bundled with M2 in v1.8.0/ Add =-p= flag for project quotas (quotas on directory trees). Supported by XFS (always) and ext4 (since kernel 4.4). Useful for container storage, web hosting docroots, CI build directories. Inputs: =research/linux-kernel-quota-api.org= ** M6: Release Mechanics [step-plan: steps/06-release.org] /Status: NOT STARTED — applied at each release point/ Ongoing release process. Applied at each release point, not a one-time milestone. Covers: - Tagging, changelog, version bump - Man page updates - README updates (tested kernel matrix, platform support) - Notify downstream packagers (Debian, Fedora, Homebrew, etc.) * Roadmap ** v1.7.0 — Quality Release (M1 + M3) The "everything works better" release. Bug fixes verified by a comprehensive new test suite. *No platform changes* — all existing platforms continue to be supported. Non-destructive upgrade from 1.6.5. What's in it: - Multi-kernel test framework (25 Linux kernels, ext4 + XFS) - Bug fixes: grace -r, +0M, XFS grace display, operator precedence - Codebase cleanup: dead code removal, clean -Wall -Wextra compile - Tested kernel matrix documented in README - ROADMAP section announcing v1.8.0 platform changes (advance notice) What's NOT in it: - No platform drops (that's v1.8.0) - No new features (quotactl_fd, project quotas — that's v1.8.0+) - No CI (local testing is the workflow for a one-person project) ** v1.7.x — Maintenance =master= IS the v1.7.x line. Bug fixes go directly to master, tag, release. Simple — no separate release branch needed. Purpose: macOS users on older OS versions (pre-APFS) and anyone who can't upgrade to v1.8.0 (which drops platforms) can still receive bug fixes via v1.7.x patches. ** v1.8.0 — Platform Focus (M2, possibly +M4/M5) The "honest codebase" release. Drops unsupported platforms, adds BSD test coverage, possibly adds new features. What's in it: - BSD test coverage (FreeBSD, OpenBSD) - Drop macOS, AIX, Solaris, NetBSD (with documented rationale) - *Possibly*: quotactl_fd() support (M4) — tmpfs/bcachefs quotas - *Possibly*: project quotas =-p= flag (M5) - Updated kernel test matrix Decision on M4/M5 inclusion made during M2 development. Branch strategy: - M2 work on =m2-1.8-development= branch (long-lived, off master) - =master= stays stable (v1.7.x) during M2 development - When v1.8.0 is ready: merge =m2-1.8-development= → =master=, tag - Notify Homebrew/MacPorts maintainers *before* release (they got advance notice in v1.7.0's ROADMAP section) ** v1.9.0 or v2.0.0 — Feature Release (if M4/M5 not in v1.8.0) Only needed if M4/M5 are not bundled with v1.8.0. * Principles - *Tests first*: No code change lands without test coverage. - *Files over memory*: All state lives in tracked files, never in LLM context alone. Update files at every checkpoint. - *No duplication*: One source of truth per topic. Reference, don't copy. - *Milestone focus*: Work on one milestone at a time. Don't mix. - *Masterplan is mutable*: Milestones can be reordered, split, merged, or added as understanding grows. But changes are deliberate, not drift. - *Release early, release often*: Ship improvements to users. Don't block fixes behind unrelated work. Separate positive changes (bug fixes) from disruptive changes (platform drops). quotatool-1.8.0/Makefile000066400000000000000000000047021515710035100152100ustar00rootroot00000000000000# # Mike Glover # mpg4@duluoz.net # # Makefile for quotatool # # # # BEGIN setting variables # # local configuration options -include ./local.mk # keep track of our current location dir := $(srcdir) # these get built by the included dir.mk's dirs := . srcs := libs := inc := auto := $(wildcard $(dir)/*.in) objs = $(srcs:.c=.o) # look for a dir.mk in these subdirectories subdirs := src # # END setting variables # BEGIN including subfiles # # include the fragment from each directory -include $(foreach sdir,$(subdirs),$(dir)/$(sdir)/dir.mk) # # END including subfiles # BEGIN rules # # clear out the suffix list and rewrite .SUFFIXES: .SUFFIXES: .c .o .INTERMEDIATE: .d .PHONY: all clean distclean dist install uninstall # compile the program (and the objects) all: $(prog) $(prog): $(objs) $(CC) $(CFLAGS) $(LDFLAGS) -o $(prog) $(objs) $(libs) men := $(wildcard $(srcdir)/man/*) install: $(prog) $(NORMAL_INSTALL) mkdir -p $(DESTDIR)$(sbindir) $(INSTALL_PROGRAM) $(srcdir)/$(prog) $(DESTDIR)$(sbindir)/$(prog) $(foreach man,$(men),mkdir -p $(DESTDIR)$(mandir)/man$(subst .,,$(suffix $(man))) && $(INSTALL_DATA) $(man) $(DESTDIR)$(mandir)/man$(subst .,,$(suffix $(man)))/$(notdir $(man));) uninstall: $(NORMAL_UNINSTALL) rm -f $(bindir)/$(prog) rm -f $(foreach man,$(notdir $(men)), $(mandir)/$(man)) distdir := $(package)-$(version) dist: distclean mkdir ./.$(distdir) cp -fR $(srcdir)/* ./.$(distdir) || true rm -rf ./.$(distdir)/*johan* rm -rf ./.$(distdir)/FILESYSTEMS mv ./.$(distdir) ./$(distdir) tar -zcvf ./$(distdir).tar.gz $(distdir) rm -rf ./$(distdir) cfixes := ~ .o clean: rm -f $(foreach sfix,$(cfixes),$(addsuffix /*$(sfix),$(dirs))) rm -f $(addsuffix /core,$(dirs)) rm -f $(prog) rm -f $(foreach sfix,$(cfixes),$(addsuffix /*$(sfix),$(DESTDIR)$(srcdir)/man)) rm -f $(foreach sfix,$(cfixes),$(addsuffix /*$(sfix),$(DESTDIR)$(srcdir)/tools)) dcfixes := .d distclean: clean rm -f $(foreach sfix,$(dcfixes),$(addsuffix /*$(sfix),$(dirs))) rm -f $(filter-out %/configure,$(auto:.in=)) rm -f $(srcdir)/config.* rm -rf ./$(distdir) ./*.tar.gz # include object dependencies -include $(objs:.o=.d) # # END rules # BEGIN pattern rules # # create dependencies automatically from .c files %.d: %.c $(srcdir)/tools/depend.sh $(CPPFLAGS) $< > $@ # create shared library from a collection of object %.so: $(CC) -shared -Xlinker -x -o $@ $^ $(libs) quotatool-1.8.0/PLATFORM-CHANGES.md000066400000000000000000000123541515710035100163660ustar00rootroot00000000000000# Platform Changes in v1.8.0 quotatool v1.8.0 drops support for macOS, AIX, Solaris, and NetBSD. Linux, FreeBSD, and OpenBSD continue to be fully supported and tested. Users on dropped platforms can continue using v1.7.x, which will receive bug fixes. ## Platforms Dropped ### macOS Apple's transition from HFS+ to APFS removed the foundation quotatool depends on. APFS became the default filesystem in macOS 10.13 High Sierra (September 2017) and does not implement `quotactl(2)` — the POSIX interface for per-user and per-group filesystem quotas. APFS has a concept of "quota size" on volumes, but it is fundamentally different: it limits total volume size (set at creation time), not per-user usage, and is managed through Disk Utility or `diskutil`, not `quotactl`. Apple's own `quotactl(2)` man page documents support only for "ffs" and "hfs" filesystems — APFS is not mentioned. Users have reported that `quotaon` fails on APFS since High Sierra, and the read-only system volume introduced in macOS Catalina (10.15) further breaks traditional quota workflows. References: - [Apple quotactl(2) man page](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/quotactl.2.html) — supports ffs and hfs only - [Apple Disk Utility: File System Formats](https://support.apple.com/guide/disk-utility/file-system-formats-dsku19ed921c/mac) — APFS is "the default file system for Mac computers using macOS 10.13 or later" - [Apple Discussion: quotaon fails on APFS](https://discussions.apple.com/thread/8191931) — reported since High Sierra - [Apple Discussion: BSD quotas unworkable](https://discussions.apple.com/thread/253385872) — read-only root in Monterey **Homebrew and MacPorts users**: quotatool v1.7.x continues to build on macOS and will receive bug fixes. The [Homebrew formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/q/quotatool.rb) and [MacPorts port](https://ports.macports.org/port/quotatool/) can continue to ship v1.7.x for users with HFS+ filesystems. ### AIX AIX has a significant enterprise installed base, but IBM's quota interface has diverged from the standard `quotactl` API. JFS2 (AIX's primary filesystem) uses proprietary extensions — `Q_J2GETQUOTA`, `Q_J2PUTLIMIT`, and a "limit class" system managed via `j2edlimit` — that are incompatible with quotatool's approach. No test environment is available, no AIX-related bug reports have been filed, and the enterprise users who run AIX typically use IBM's own tooling. References: - [AIX quotactl subroutine](https://www.ibm.com/docs/en/aix/7.2.0?topic=q-quotactl-subroutine) — documents JFS2-specific commands and non-standard headers - [Setting JFS2 filesystem quotas](https://www.ibm.com/support/pages/setting-and-using-jfs2-filesystem-quotas) — uses AIX-specific `chfs` and `j2edlimit` ### Solaris / illumos ZFS is the default root filesystem on Oracle Solaris 11 and all illumos distributions. UFS is documented as "a supported legacy file system" that is "not supported as a bootable root file system." ZFS has its own quota system (`zfs set quota=`, `zfs set userquota@user=`, `zfs set groupquota@group=`) that does not use `quotactl`. quotatool's UFS-based approach is irrelevant on modern Solaris/illumos installations. References: - [Transitioning to Oracle Solaris 11](https://docs.oracle.com/cd/E23824_01/html/E24456/filesystem-10.html) — "ZFS is the default root file system" - [Solaris 11.4: Setting ZFS Quotas](https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/manage-zfs/setting-quotas-zfs-file-systems.html) — all quota management via `zfs set` - [ZFS Quotas and Reservations](https://docs.oracle.com/cd/E23823_01/html/819-5461/gazvb.html) — per-user and per-group quotas via `zfs set` ### NetBSD NetBSD 6.0 (October 2012) replaced `quotactl(2)` with a private `__quotactl(2)` system call and a new `libquota(3)` library. The old `quotactl(2)` interface that quotatool uses no longer exists. The `__quotactl(2)` man page explicitly states it is "an internal interface" and that "all application and utility code should use the libquota(3) interface." Porting quotatool to `libquota(3)` would require a full rewrite of the NetBSD backend. Given NetBSD's small user base, this is currently not justified. References: - [NetBSD __quotactl(2)](https://man.netbsd.org/__quotactl.2) — "an internal interface... appeared in NetBSD 6.0" - [NetBSD libquota(3)](https://man.netbsd.org/libquota.3) — "first appeared in NetBSD 6.0" - [NetBSD 6.0 Changes](https://www.netbsd.org/changes/changes-6.0.html) — "Removed quotactl(2) interface, replaced with new private __quotactl(2)" - [NetBSD 6.0 Release](https://www.netbsd.org/releases/formal-6/NetBSD-6.0.html) — "rewritten disk quota subsystem" ## Platforms Kept ### Linux Primary platform. Tested on 25+ vendor kernels spanning kernel 3.2 through 6.19, on ext4 and XFS. Supports old, vfsv0, vfsv1, and generic quota formats. ### FreeBSD Tested on FreeBSD 14.4. UFS quotas via `quotactl(2)` — stable API, no recent changes. ### OpenBSD Tested on OpenBSD 7.8. FFS quotas via `quotactl(2)` — traditional BSD interface, conservative and stable. ## v1.7.x Maintenance The v1.7.x line continues to support all platforms that v1.6.x did. Bug fixes will be backported as needed. quotatool-1.8.0/README.md000066400000000000000000000177421515710035100150370ustar00rootroot00000000000000quotatool ========= > **[Roadmap](ROADMAP.md)** — upcoming releases and platform changes. > **[Platform Changes](PLATFORM-CHANGES.md)** — v1.8.0 drops support for macOS, AIX, Solaris, and NetBSD. ![Quotatool](http://quotatool.ekenberg.se/diskusage.gif) Commandline utility for filesystem quotas on Linux, FreeBSD and OpenBSD *Set 50Gb soft and hard diskusage limits for user johan on filesystem /home* quotatool -u johan -b -q 50G -l 50G /home *See more examples below* ## Installation ### Linux *quotatool is already in your package manager:* * Ubuntu, Mint, Debian: `sudo apt-get install quotatool` * Fedora, Red Hat, CentOS, AlmaLinux, Rocky Linux: `dnf install quotatool` `yum install quotatool` (on RHEL-derivatives, quotatool is in the [EPEL](https://docs.fedoraproject.org/en-US/epel/) repository) * openSUSE: `zypper install quotatool` * Gentoo Linux: `emerge quotatool` ### Install from source code ./configure make sudo make install (use gmake on *BSD) ## Usage quotatool { -u uid | -g gid } [ options ... ] filesystem quotatool { -u | -g } { -i | -b } -t time filesystem quotatool { -u uid | -g gid } -r filesystem quotatool { -u uid | -g gid } -d filesystem Both -u (user) and -g (group) quotas are supported on all platforms. ### Arguments and Options ``` -u uid username or uid. -g gid groupname or gid. See examples below how to handle non-existent uid/gid -b set block limits -i set inode limits -q n set soft limit to n blocks/inodes -l n set hard limit to n blocks/inodes quotatool accepts the units Kb, Mb, Gb, Tb, bytes and blocks to modify limit arguments. Units are base 2 for blocks (1k = 1024) and base 10 for inodes (1k = 1000). Use +/- to raise/lower quota by the specified amount. n can be integer or floating point See examples below. -R Raise only - avoid accidentally lowering quotas for a user/group -t time set global grace period to time. The time parameter consists of an optional '+' or '-' modifier, a number, and one of: 'sec', 'min', 'hour', 'day', 'week', and 'month'. If a +/- modifier is present, the current quota will be increased/reduced by the amount specified -r restart grace period for uid or gid -h print a usage message -v verbose mode -- print status messages during execution use this twice for even more information -n do everything except set the quota. useful with -v to see what is supposed to happen -V show version filesystem is either device name (eg /dev/sda1) or mountpoint (eg /home) ``` ## Examples Set soft block limit to 800Mb, hard block limit to 1.2 Gb for user mpg4 on /home: quotatool -u mpg4 -b -q 800M -l 1.2G /home Raise soft block limit by 100M for non-existent gid 12345 on /dev/loop3: quotatool -g :12345 -b -q +100M /dev/loop3 Set soft inode limit to 1.8k (1800), hard inode limit to 2000 for user johan on /var: quotatool -u johan -i -q 1.8K -l 2000 /var Set the global block grace period to one week on /home: quotatool -u -b -t "1 week" /home Restart inode grace period for user johan on root filesystem: quotatool -u johan -i -r / ## Notes * Grace periods are set on a "global per quotatype and filesystem" basis only. Each quotatype (usrquota / grpquota) on each filesystem has two grace periods - one for block limits and one for inode limits. It is not possible to set different grace periods for users on the same filesystem. BSD-note: On BSD (FreeBSD, OpenBSD), the grace period is cached by the kernel at `quotaon` time. After setting the grace period with `-t`, a `quotaoff`/`quotaon` cycle is required for the new value to take effect. This is the same behavior as `edquota -t` on BSD — it is a BSD kernel design choice, not a limitation of quotatool. * Using non-existent uids/gids like ":12345" can be useful when configuring quotas on a mounted filesystem which is a separate system in it self, like when preparing an install image or repairing a filesystem from another installation. * Limit arguments can be specified in several ways, these are all equivalent: 1M 1m 1Mb 1 "Mb" * Use +/- to raise/lower quotas relative to current limits * Use -v (or -v -v) to see verbose/debug info when running commands ## Platforms and Filesystems quotatool currently builds and works well on: -- Linux -- Quota formats: old, vfsv0, vfsv1 and "generic" Filesystems: ext2, ext3, ext4, ReiserFS and XFS -- BSD -- FreeBSD, OpenBSD (UFS, FFS) See [PLATFORM-CHANGES.md](PLATFORM-CHANGES.md) for details on platforms dropped in v1.8.0 (macOS, AIX, Solaris, NetBSD). Users on these platforms can use quotatool v1.7.x, which continues to receive bug fixes. Missing a feature or found a bug? Add an issue on https://github.com/ekenberg/quotatool/issues ## Testing quotatool includes a multi-kernel test suite that boots vendor kernels in QEMU/virtme-ng VMs and tests quota operations on both ext4 and XFS. The kernel matrix covers actively supported Linux distros (Ubuntu, Debian, RHEL/Alma/CentOS, Fedora, openSUSE) plus recently EOL and historical versions for regression coverage. Kernels are grouped into three tiers: - **Tier 1**: Actively supported distros — must test before release - **Tier 2**: Recently EOL or significant niche — should test - **Tier 3**: Historical/EOL — nice to have, catches regressions Run `test/run-tests --list` to see the current matrix. ### Prerequisites Linux host with KVM support (`/dev/kvm` must exist and be accessible). If `/dev/kvm` exists but isn't accessible, add yourself to the kvm group: sudo usermod -aG kvm $USER # then log out and back in Check what's needed: test/check-deps.sh This shows required and optional tools with distro-specific install hints. The essentials: A working Python 3 installation with pip is required for virtme-ng. **Debian/Ubuntu:** sudo apt install qemu-system-x86 e2fsprogs xfsprogs quota \ util-linux cpio rpm2cpio curl kmod file zstd dpkg pip install virtme-ng **Fedora/RHEL:** sudo dnf install qemu-system-x86-core e2fsprogs xfsprogs quota \ util-linux cpio rpm2cpio curl kmod file zstd dpkg pip install virtme-ng ### Quick start From a fresh clone: ./configure && make # build quotatool test/run-tests --setup --smoke # download kernels, smoke test `--setup` handles everything: downloads busybox, builds initramfs, downloads vendor kernels, builds rootfs for RHEL kernels. First run takes a while (mostly kernel downloads). `--smoke` runs one kernel per boot path (~30 seconds) to verify the infrastructure works. ### Full test run test/run-tests --all # all kernels test/run-tests --kernel debian-12 # single kernel test/run-tests --tier 1 # tier 1 only test/run-tests --list # show all kernels and status test/run-tests --help # full list of options Results are saved to `test/results/`. ### BSD testing BSD tests run quotatool inside FreeBSD and OpenBSD VMs (QEMU/KVM). Separate from the Linux tests — different entry point, different infrastructure. test/bsd/check-deps.sh # verify host tools test/bsd/run-tests --setup # download images, provision VMs test/bsd/run-tests --all # run on FreeBSD + OpenBSD test/bsd/run-tests --freebsd # FreeBSD only test/bsd/run-tests --openbsd # OpenBSD only test/bsd/run-tests --all -v # verbose (show all subtests) test/bsd/run-tests --interactive freebsd # SSH into VM with quotas First run downloads ~660MB (FreeBSD image) and installs OpenBSD from CD (~300MB). Subsequent runs use provisioned snapshots (~15s boot). ### Troubleshooting If a test fails, run the failing kernel with `--verbose`: test/run-tests --kernel --verbose ## License This software is available under the terms of the GNU General Public License (GPL) 2.0 or any later version. quotatool-1.8.0/ROADMAP.md000066400000000000000000000024161515710035100151550ustar00rootroot00000000000000# Roadmap ## v1.8.0 — Platform Changes Drops platforms that no longer have working quota infrastructure. Adds BSD test coverage for the platforms that remain. Changes: - **Dropped**: macOS (APFS has no quotactl), AIX (proprietary JFS2 extensions), Solaris (ZFS has its own quota system), NetBSD (replaced quotactl with incompatible libquota in 6.0) - **Kept**: Linux, FreeBSD, OpenBSD - BSD test coverage (FreeBSD 14.4, OpenBSD 7.8) See [PLATFORM-CHANGES.md](PLATFORM-CHANGES.md) for detailed rationale and references for each platform decision. **macOS/Homebrew users**: v1.7.x continues to build on macOS and will receive bug fixes. ## Future Planned for future releases: - `quotactl_fd()` support (tmpfs/bcachefs quotas, kernel 5.14+) - Project quotas `-p` flag (XFS, ext4 4.4+) ## v1.7.x — Maintenance Bug fixes backported to the v1.7.x line. For users who can't upgrade to v1.8.0. ## v1.7.0 — Quality Release Bug fixes verified by a comprehensive new test suite. **No platform changes** — all existing platforms continue to be supported. What's in it: - Multi-kernel test framework (25+ Linux kernels, ext4 + XFS) - Bug fixes and code cleanup What's NOT in it: - No platform drops (that's v1.8.0) - No new features (quotactl_fd, project quotas — that's v1.8.0+) quotatool-1.8.0/TODO000066400000000000000000000001461515710035100142360ustar00rootroot00000000000000See ROADMAP.md for planned changes. See https://github.com/ekenberg/quotatool/issues for open issues. quotatool-1.8.0/configure000077500000000000000000004721651515710035100154730ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='' PACKAGE_TARNAME='' PACKAGE_VERSION='' PACKAGE_STRING='' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/main.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_func_c_list= ac_subst_vars='LTLIBOBJS LIBOBJS EGREP GREP CPP INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC PLATFORM host_os host_vendor host_cpu host build_os build_vendor build_cpu build PATCHLEVEL MINOR_VERSION MAJOR_VERSION PROGNAME target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_gnu_getopt ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) \ --with-gnu-getopt getopt() is GNU getopt Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" as_fn_append ac_func_c_list " vprintf HAVE_VPRINTF" # Auxiliary files required by this configure script. ac_aux_files="install-sh config.guess config.sub" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}/tools" # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu MAJOR_VERSION=1 MINOR_VERSION=8 PATCHLEVEL=0 COPYRIGHT_NOTICE="Copyright (c) 1999-2026 Mike Glover / Johan Ekenberg" WWW_URL="https://github.com/ekenberg/quotatool | http://quotatool.ekenberg.se" PROGNAME=quotatool printf "%s\n" "#define PROGNAME \"$PROGNAME\"" >>confdefs.h printf "%s\n" "#define MAJOR_VERSION $MAJOR_VERSION" >>confdefs.h printf "%s\n" "#define MINOR_VERSION $MINOR_VERSION" >>confdefs.h printf "%s\n" "#define PATCHLEVEL \"$PATCHLEVEL\"" >>confdefs.h printf "%s\n" "#define COPYRIGHT_NOTICE \"$COPYRIGHT_NOTICE\"" >>confdefs.h printf "%s\n" "#define WWW_URL \"$WWW_URL\"" >>confdefs.h # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case $host in *linux*) PLATFORM=linux printf "%s\n" "#define PLATFORM_LINUX 1" >>confdefs.h ;; *freebsd*|*openbsd*) PLATFORM=bsd printf "%s\n" "#define PLATFORM_BSD 1" >>confdefs.h ;; *) PLATFORM=unknown printf "%s\n" "#define PLATFORM_UNKNOWN 1" >>confdefs.h ;; esac printf "%s\n" "#define PLATFORM $PLATFORM" >>confdefs.h ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in unistd.h fcntl.h limits.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else $as_nop \ as_fn_error $? "Missing required headers" "$LINENO" 5 fi done for ac_header in mntent.h fstab.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF FOUND_MNT=1;break fi done test $FOUND_MNT || as_fn_error $? "Can't find getmntent() or getfsent()" "$LINENO" 5 for ac_header in linux/types.h sys/types.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF FOUND_TYPES=1;break fi done test $FOUND_TYPES || as_fn_error $? "Can't find system types" "$LINENO" 5 if test "$PLATFORM" != "linux"; then for ac_header in ufs/ufs/quota.h do : ac_fn_c_check_header_compile "$LINENO" "ufs/ufs/quota.h" "ac_cv_header_ufs_ufs_quota_h" "$ac_includes_default" if test "x$ac_cv_header_ufs_ufs_quota_h" = xyes then : printf "%s\n" "#define HAVE_UFS_UFS_QUOTA_H 1" >>confdefs.h FOUND_QUOTA=1;break fi done test $FOUND_QUOTA || as_fn_error $? "Can't find quota defs" "$LINENO" 5 fi for ac_header in linux/fs.h do : ac_fn_c_check_header_compile "$LINENO" "linux/fs.h" "ac_cv_header_linux_fs_h" "$ac_includes_default" if test "x$ac_cv_header_linux_fs_h" = xyes then : printf "%s\n" "#define HAVE_LINUX_FS_H 1" >>confdefs.h FOUND_BSIZE=1 fi done test $FOUND_BSIZE || { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Using hard-coded default BLOCK_SIZE" >&5 printf "%s\n" "$as_me: WARNING: Using hard-coded default BLOCK_SIZE" >&2;} ac_fn_c_check_header_compile "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" if test "x$ac_cv_header_inttypes_h" = xyes then : printf "%s\n" "#define HAVE_INTTYPES_H 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 printf %s "checking for an ANSI C-conforming const... " >&6; } if test ${ac_cv_c_const+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* IBM XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* IBM XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_const=yes else $as_nop ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 printf "%s\n" "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then printf "%s\n" "#define const /**/" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 printf %s "checking for uid_t in sys/types.h... " >&6; } if test ${ac_cv_type_uid_t+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1 then : ac_cv_type_uid_t=yes else $as_nop ac_cv_type_uid_t=no fi rm -rf conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 printf "%s\n" "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then printf "%s\n" "#define uid_t int" >>confdefs.h printf "%s\n" "#define gid_t int" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 printf %s "checking for inline... " >&6; } if test ${ac_cv_c_inline+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo (void) {return 0; } $ac_kw foo_t foo (void) {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 printf "%s\n" "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "$ac_includes_default" if test "x$ac_cv_type_u_int64_t" = xyes then : HAVE_U_INT64_T=1 else $as_nop HAVE_U_INT64_T=0 fi printf "%s\n" "#define HAVE_U_INT64_T $HAVE_U_INT64_T" >>confdefs.h ac_func= for ac_item in $ac_func_c_list do if test $ac_func; then ac_fn_c_check_func "$LINENO" $ac_func ac_cv_func_$ac_func if eval test \"x\$ac_cv_func_$ac_func\" = xyes; then echo "#define $ac_item 1" >> confdefs.h fi ac_func= else ac_func=$ac_item fi done if test "x$ac_cv_func_vprintf" = xno then : ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" if test "x$ac_cv_func__doprnt" = xyes then : printf "%s\n" "#define HAVE_DOPRNT 1" >>confdefs.h fi fi ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" if test "x$ac_cv_func_strdup" = xyes then : printf "%s\n" "#define HAVE_STRDUP 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" if test "x$ac_cv_func_strerror" = xyes then : printf "%s\n" "#define HAVE_STRERROR 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol" if test "x$ac_cv_func_strtol" = xyes then : printf "%s\n" "#define HAVE_STRTOL 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod" if test "x$ac_cv_func_strtod" = xyes then : printf "%s\n" "#define HAVE_STRTOD 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr" if test "x$ac_cv_func_strchr" = xyes then : printf "%s\n" "#define HAVE_STRCHR 1" >>confdefs.h fi test x$PLATFORM = xlinux && printf "%s\n" "#define HAVE_GNU_GETOPT 1" >>confdefs.h ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" if test "x$ac_cv_func_strlcpy" = xyes then : printf "%s\n" "#define HAVE_STRLCPY 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" if test "x$ac_cv_func_strlcat" = xyes then : printf "%s\n" "#define HAVE_STRLCAT 1" >>confdefs.h fi # Check whether --with-gnu-getopt was given. if test ${with_gnu_getopt+y} then : withval=$with_gnu_getopt; \ test x$withval != xno || printf "%s\n" "#define HAVE_GNU_GETOPT 1" >>confdefs.h fi ac_config_headers="$ac_config_headers src/config.h" ac_config_files="$ac_config_files local.mk" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; "local.mk") CONFIG_FILES="$CONFIG_FILES local.mk" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi quotatool-1.8.0/configure.ac000066400000000000000000000063721515710035100160430ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_AUX_DIR(tools) dnl Main program/version info settings: dnl --------------------------------------------------------------------------- MAJOR_VERSION=1 MINOR_VERSION=8 PATCHLEVEL=0 COPYRIGHT_NOTICE="Copyright (c) 1999-2026 Mike Glover / Johan Ekenberg" WWW_URL="https://github.com/ekenberg/quotatool | http://quotatool.ekenberg.se" dnl --------------------------------------------------------------------------- dnl Set program, version info PROGNAME=quotatool AC_SUBST(PROGNAME) AC_DEFINE_UNQUOTED(PROGNAME, "$PROGNAME", [Name of the current program]) AC_SUBST(MAJOR_VERSION) AC_DEFINE_UNQUOTED(MAJOR_VERSION, $MAJOR_VERSION, [Major version number]) AC_SUBST(MINOR_VERSION) AC_DEFINE_UNQUOTED(MINOR_VERSION, $MINOR_VERSION, [Minor version number]) AC_SUBST(PATCHLEVEL) AC_DEFINE_UNQUOTED(PATCHLEVEL, "$PATCHLEVEL", [Patch level version number]) AC_DEFINE_UNQUOTED(COPYRIGHT_NOTICE, "$COPYRIGHT_NOTICE", [Copyright notice]) AC_DEFINE_UNQUOTED(WWW_URL, "$WWW_URL", [Upstream homepage]) dnl get the system type (for the makefile) AC_CANONICAL_HOST case [$host] in *linux*) PLATFORM=linux AC_DEFINE(PLATFORM_LINUX, 1, [Is this a Linux platform?]) ;; *freebsd*|*openbsd*) PLATFORM=bsd AC_DEFINE(PLATFORM_BSD, 1, [Is this a *BSD platform?]) ;; *) PLATFORM=unknown AC_DEFINE(PLATFORM_UNKNOWN, 1, [Is this an unknown platform?]) ;; esac AC_SUBST(PLATFORM) AC_DEFINE_UNQUOTED(PLATFORM, $PLATFORM, [Name of the current platform]) dnl Check for programs. AC_PROG_CC AC_PROG_INSTALL dnl Check for absolutely required header files. AC_CHECK_HEADERS(unistd.h fcntl.h limits.h, ,\ AC_MSG_ERROR([Missing required headers])) dnl Check for pick-one header files (required) AC_CHECK_HEADERS(mntent.h fstab.h, FOUND_MNT=1;break) test [$FOUND_MNT] || AC_MSG_ERROR([Can't find getmntent() or getfsent()]) AC_CHECK_HEADERS(linux/types.h sys/types.h, FOUND_TYPES=1;break) test [$FOUND_TYPES] || AC_MSG_ERROR([Can't find system types]) dnl Check for quota header files except for linux (we ship our own) if test "$PLATFORM" != "linux"; then AC_CHECK_HEADERS(ufs/ufs/quota.h, FOUND_QUOTA=1;break) test [$FOUND_QUOTA] || AC_MSG_ERROR([Can't find quota defs]) fi dnl Check for pick-one header files (optional) AC_CHECK_HEADERS(linux/fs.h, FOUND_BSIZE=1) test [$FOUND_BSIZE] || AC_MSG_WARN([Using hard-coded default BLOCK_SIZE]) AC_CHECK_HEADERS(inttypes.h) dnl Check for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_UID_T AC_C_INLINE AC_CHECK_TYPE(u_int64_t, HAVE_U_INT64_T=1, HAVE_U_INT64_T=0) AC_DEFINE_UNQUOTED(HAVE_U_INT64_T, $HAVE_U_INT64_T, [Can we use uint64_t?]) dnl Check for library functions. AC_FUNC_VPRINTF AC_CHECK_FUNCS(strdup strerror strtol strtod strchr) test [x$PLATFORM] = [xlinux] && AC_DEFINE(HAVE_GNU_GETOPT, 1, [Can we use GNU getopt?]) dnl check for strlcpy and strlcat (mostly BSD) AC_CHECK_FUNCS(strlcpy strlcat) dnl Check the commandline AC_ARG_WITH(gnu-getopt, \ [--with-gnu-getopt getopt() is GNU getopt],\ test [x$withval] != [xno] || AC_DEFINE(HAVE_GNU_GETOPT, 1, [Can we use GNU getopt?])) dnl Create output files AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_FILES([local.mk]) AC_OUTPUT quotatool-1.8.0/local.mk.in000066400000000000000000000021101515710035100155670ustar00rootroot00000000000000# # config.mk # local site configuration # # @configure_input@ # what are we making? package := @PROGNAME@ version := @MAJOR_VERSION@.@MINOR_VERSION@.@PATCHLEVEL@ prog := $(package) build_platform := @PLATFORM@ # programs to use SHELL := /bin/sh CC := @CC@ CFLAGS := @CFLAGS@ LDFLAGS := @LDFLAGS@ CPPFLAGS = @CPPFLAGS@ $(inc) @DEFS@ INSTALL := @INSTALL@ INSTALL_DATA := @INSTALL_DATA@ INSTALL_PROGRAM := @INSTALL_PROGRAM@ # filesystem locations prefix := @prefix@ exec_prefix := @exec_prefix@ bindir := @bindir@ sbindir := @sbindir@ libdir := @libdir@ libexecdir := @libexecdir@ datarootdir := @datarootdir@ mandir := @mandir@ infodir := @infodir@ includedir := @includedir@ oldincludedir := @oldincludedir@ sysconfdir := @sysconfdir@ datadir := @datadir@ localstatedir := @localstatedir@ sharedstatedir := @sharedstatedir@ srcdir := @srcdir@ quotatool-1.8.0/man/000077500000000000000000000000001515710035100143205ustar00rootroot00000000000000quotatool-1.8.0/man/quotatool.8000066400000000000000000000122771515710035100164510ustar00rootroot00000000000000.TH QUOTATOOL 8 "1999 - 2026" "version 1.8.0" .SH NAME quotatool \- manipulate filesystem quotas .SH SYNOPSIS .B quotatool [-u [:]uid | -g [:]gid] [-b | -i] [-r | -l NUM | -q NUM] [-nvR] [-d] .I filesystem .br .B quotatool (-u | -g) (-b | -i) -t TIME [-nv] .I filesystem .br .B quotatool [-hV] .br .SH DESCRIPTION .B quotatool is a tool for manipulating filesystem quotas. Depending on the commandline options given, it can set hard or soft limits on block and inode usage, set and reset grace periods, for both users and (if your system supports this) groups. The filesystem to set the quota on is given as the first (and only) non-option element, and it is either the block special file (i.e /dev/sda3) or the mount point (i.e. /home) for the filesystem. .SH OPTIONS .TP -u [[:]uid] Set user quotas .TP -g [[:]gid] Set group quotas .LP .IR uid and .IR gid are either the numerical ID of the user or group, or its name in the .B /etc/passwd and .B /etc/group files. Prefix .IR : allows using numerical uid/gid not present in /etc/passwd or /etc/group. .TP -b Set block quotas [default] .TP -i Set inode quotas .LP The -b and -i options are persistent -- they stay in effect until they are overridden. .TP -R Only raise quotas, never lower. Makes sure you don't accidentally lower quotas for a user/group. .TP -t TIME Set the system-wide grace period to TIME. TIME consists of an optional '-' or '+' character, a number, and optionally one of the following modifiers: "seconds", "minutes", "hours", "days", "weeks", or "months". Abbreviations of at least two characters for ambiguous units are required: "mi" for minutes, "mo" for months. Bare "m" is rejected as ambiguous. The default is "seconds". The argument should be preceded by -u|-g and -b|-i .TP -r Reset the grace period .TP -l NUM Set hard limit to NUM .TP -q NUM Set soft limit (quota) to NUM .LP NUM consists of an optional '-' or '+' character, a number (integer or floating point), and optionally one of the following modifiers: "Kb", "Mb", "Gb", "Tb", "bytes", or "blocks". Unique abbreviations are also accepted. The default is "blocks". Modifiers are base 2 for block quotas (1k = 1024), and base 10 for inode quotas (1k = 1000) .PP If +/- is supplied, the existing quota is increased or reduced by the specified amount. .TP .I -d Dump quota info for user/group in a machine readable format: .IP |------- BLOCKS --------| |-------- FILES --------| .br .B uid/gid mountpoint current quota limit grace current quota limit grace .IP .B grace is the number of seconds remaining until the grace time ends. Zero when quota is not exceeded or grace has expired. .TP -n dry-run: show what would have been done but don't change anything. Use together with -v .TP -v Verbose output. Use twice or thrice for even more output (debugging) .TP .I -h Print a usage message to stdout and exit successfully .TP .I -V Print version information to stdout and exit successfully .SH FILESYSTEMS / FORMATS On Linux, .B quotatool works with both "old", "vfsv0" and "vfsv1" + "generic" kernel-quota formats. Supported filesystems: ext2, ext3, ext4, ReiserFS and XFS. FreeBSD / OpenBSD: filesystems UFS and FFS .SH EXAMPLES Set soft block limit to 800Mb, hard block limit to 1.2 Gb for user mpg4 on /home: quotatool -u mpg4 -b -q 800M -l 1.2G /home Raise soft block limit by 100M for non-existent gid 12345 on /dev/loop3: quotatool -g :12345 -b -q +100M /dev/loop3 Set soft inode limit to 1.8k (1800), hard inode limit to 2000 for user johan on /var: quotatool -u johan -i -q 1.8K -l 2000 /var Set the global block grace period to one week on /home: quotatool -u -b -t "1 week" /home Restart inode grace period for user johan on root filesystem: quotatool -u johan -i -r / .SH NOTES Grace periods are set on a "global per quotatype and filesystem" basis only. Each quotatype (usrquota / grpquota) on each filesystem has two grace periods - one for block limits and one for inode limits. It is not possible to set different grace periods for users on the same filesystem. On BSD (FreeBSD, OpenBSD), the grace period is cached by the kernel at quotaon time. After setting the grace period with -t, a quotaoff/quotaon cycle is required for the new value to take effect. This is the same behavior as edquota -t on BSD \(em it is a BSD kernel design choice, not a limitation of quotatool. Using non-existent uids/gids like ":12345" can be useful when configuring quotas on a mounted filesystem which is a separate system in it self, like when preparing an install image or repairing a filesystem from another installation. Limit arguments can be specified in several ways, these are all equivalent: 1M 1m 1Mb 1 "Mb" Use +/- to raise/lower quotas relative to current limits Use -v (or -v -v) to see verbose/debug info when running commands .SH FILES .B quota.user , .B quota.group (Linux, FreeBSD, OpenBSD) .SH BUGS Please check https://github.com/ekenberg/quotatool for any open issues. Feel free to add a new issue if you find an unresolved bug! .PP Calling .B quotatool with more than one -v option may cause a segfault on some systems if vprintf (3) fails to check for NULL arguments. .SH SEE ALSO .BR quota (1), .BR quotactl (2), .BR edquota (8), .BR quotacheck (8), .BR quotaon (8), .BR repquota (8) quotatool-1.8.0/src/000077500000000000000000000000001515710035100143345ustar00rootroot00000000000000quotatool-1.8.0/src/bsd/000077500000000000000000000000001515710035100151045ustar00rootroot00000000000000quotatool-1.8.0/src/bsd/dir.mk000066400000000000000000000006571515710035100162230ustar00rootroot00000000000000# # Makefile fragment for src/bsd # thisdir := bsd svdir := $(dir) dir := $(dir)/bsd dirs += $(dir) auto += $(wildcard $(dir)/*.in) ifeq "$(build_platform)" "$(thisdir)" srcs += $(wildcard $(dir)/*.c) inc += -I$(dir) libs += subdirs := ifneq ($(strip $(subdirs)),) -include $(foreach sdir,$(subdirs),$(dir)/$(sdir)/dir.mk) endif endif dir := $(svdir) quotatool-1.8.0/src/bsd/quota.c000066400000000000000000000134171515710035100164070ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * quota.c * middle layer to talk to quotactl */ #include #include #include #include #include #include "output.h" #include "system.h" #include "quota.h" #include "quotatool.h" quota_t *quota_new (int q_type, int id, char *fs_spec) { quota_t *myquota; fs_t *fs; char *qfile; if (q_type > MAXQUOTAS) { output_error ("Unknown quota type: %d", q_type); return 0; } --q_type; /* see defs in quota.h */ myquota = (quota_t *) calloc (1, sizeof(quota_t)); if (! myquota) { output_error ("Insufficient memory"); exit (ERR_MEM); } fs = system_getfs (fs_spec); if ( ! fs ) { free (myquota); return NULL; } /* Pass the mount point directly to quotactl(). The kernel uses * namei() to resolve any path to its mount point, so the old * approach of appending "/quota.user" was unnecessary. Using the * mount point directly is simpler and matches what edquota(8) does. */ qfile = strdup(fs->mount_pt); if (! qfile) { output_error ("Insufficient memory"); free (myquota); free (fs); exit (ERR_MEM); } output_debug ("qfile is \"%s\"\n", qfile); myquota->_id = id; myquota->_id_type = q_type; myquota->_qfile = qfile; free (fs); return myquota; } inline void quota_delete (quota_t *myquota) { free (myquota->_qfile); free (myquota); } int quota_get (quota_t *myquota) { struct dqblk sysquota; int retval; output_debug ("fetching quotas: device='%s',id='%d'", myquota->_qfile, myquota->_id); retval = quotactl (myquota->_qfile, QCMD(Q_GETQUOTA, myquota->_id_type), myquota->_id, (caddr_t) &sysquota); if ( retval < 0 ) { output_error ("Failed fetching quotas: %s", strerror (errno)); return 0; } /* here, linux.c does a memcpy(), it should also work for bsd, * but it's better to be on the safe side */ myquota->block_hard = sysquota.dqb_bhardlimit; myquota->block_soft = sysquota.dqb_bsoftlimit; myquota->diskspace_used = sysquota.dqb_curblocks * BLOCK_SIZE; myquota->inode_hard = sysquota.dqb_ihardlimit; myquota->inode_soft = sysquota.dqb_isoftlimit; myquota->inode_used = sysquota.dqb_curinodes ; myquota->block_time = (time_t) sysquota.dqb_btime; myquota->inode_time = (time_t) sysquota.dqb_itime; /* Initialize grace fields from the kernel's timer values. * Without this, block_grace/inode_grace contain garbage from * malloc, which quota_set() would then write to dqb_btime/itime. */ myquota->block_grace = (time_t) sysquota.dqb_btime; myquota->inode_grace = (time_t) sysquota.dqb_itime; return 1; } int quota_set (quota_t *myquota){ struct dqblk sysquota; int retval; if ( geteuid() != 0 ) { output_error ("Only root can set quotas"); return 0; } /* Zero the struct to avoid passing uninitialized padding bytes * or extra fields to the kernel via quotactl. */ memset(&sysquota, 0, sizeof(sysquota)); sysquota.dqb_bhardlimit = myquota->block_hard; sysquota.dqb_bsoftlimit = myquota->block_soft; sysquota.dqb_ihardlimit = myquota->inode_hard; sysquota.dqb_isoftlimit = myquota->inode_soft; sysquota.dqb_btime = myquota->block_grace; sysquota.dqb_itime = myquota->inode_grace; /* make the syscall */ retval = quotactl (myquota->_qfile, QCMD(Q_SETQUOTA, myquota->_id_type), myquota->_id, (caddr_t) &sysquota); if ( retval < 0 ) { output_error ("Failed setting quota: %s", strerror (errno)); return 0; } /* Set global grace period via uid 0's dqb_btime/dqb_itime. * On BSD, the kernel ignores dqb_btime/dqb_itime for non-root * users in Q_SETQUOTA. The global default grace period is stored * on uid 0. This matches what edquota -t does. */ if (myquota->_do_set_global_block_gracetime || myquota->_do_set_global_inode_gracetime) { struct dqblk grace_dq; memset(&grace_dq, 0, sizeof(grace_dq)); /* Read uid 0's current quota to preserve existing fields */ retval = quotactl(myquota->_qfile, QCMD(Q_GETQUOTA, myquota->_id_type), 0, (caddr_t) &grace_dq); if (retval < 0) { output_error("Failed reading global grace period: %s", strerror(errno)); return 0; } if (myquota->_do_set_global_block_gracetime) { output_debug(">> set global block gracetime = %d", (int) myquota->block_grace); grace_dq.dqb_btime = myquota->block_grace; } if (myquota->_do_set_global_inode_gracetime) { output_debug(">> set global inode gracetime = %d", (int) myquota->inode_grace); grace_dq.dqb_itime = myquota->inode_grace; } retval = quotactl(myquota->_qfile, QCMD(Q_SETQUOTA, myquota->_id_type), 0, (caddr_t) &grace_dq); if (retval < 0) { output_error("Failed setting global grace period: %s", strerror(errno)); return 0; } } /* Q_SYNC removed: Q_SETQUOTA already persists quota data via the * kernel's internal dqrele()/dqsync() path. An explicit Q_SYNC is * redundant — BSD edquota(8) doesn't use it either. On OpenBSD, * Q_SYNC hangs indefinitely on vnd-backed FFS due to dquot lock * contention or buffer cache stalls (softdep disabled since 2023). */ return 1; } int quota_reset_grace(quota_t *myquota, int grace_type) { quota_t temp_quota; memcpy(&temp_quota, myquota, sizeof(quota_t)); if (grace_type == GRACE_BLOCK) temp_quota.block_hard = temp_quota.block_soft = BYTES_TO_BLOCKS(temp_quota.diskspace_used) + 1; else temp_quota.inode_hard = temp_quota.inode_soft = temp_quota.inode_used + 1; if (quota_set(&temp_quota) && quota_set(myquota)) return 1; output_error("Cannot reset grace period!"); return 0; // error, on success we return above } quotatool-1.8.0/src/config.h.in000066400000000000000000000032421515710035100163600ustar00rootroot00000000000000 #ifndef INCLUDE_QUOTATOOL_CONFIG #define INCLUDE_QUOTATOOL_CONFIG /* #undef inline */ /* #undef uid_t */ /* #undef gid_t */ /* #undef const */ /* give a broad hint as to what system we're on (linux, bsd) */ #define PLATFORM_LINUX 0 #define PLATFORM_BSD 0 #define PLATFORM_UNKNOWN 0 /* define if setmntent() is defined in */ #define HAVE_MNTENT_H 0 /* define if setfsent() is defined in */ #define HAVE_FSTAB_H 0 /* define if the quotactl ioctl() is defined in */ #define HAVE_UFS_UFS_QUOTA_H 0 /* define if PATH_MAX is defined in */ #define HAVE_LINUX_LIMITS_H 0 /* define if PATH_MAX is defined in */ #define HAVE_LIMITS_H 0 /* define if BLOCK_SIZE is defined in */ #define HAVE_LINUX_FS_H 0 /* define if getopt is GNU getopt */ #define HAVE_GNU_GETOPT 0 /* define if we have u_int64_t */ #define HAVE_U_INT64_T 0 /* define if we have the header file */ #define HAVE_INTTYPES_H 0 /* define if we have the function strlcat */ #define HAVE_STRLCAT 0 /* define if we have the function strlcpy */ #define HAVE_STRLCPY 0 /***************************************************************** * That's it! Stop reading! There's nothing else to see! *****************************************************************/ /***************************************************************** * Hey! What are you doing! I told you to go away! *****************************************************************/ #define PROGNAME "" #define MAJOR_VERSION 0 #define MINOR_VERSION 0 #define PATCHLEVEL "" #define COPYRIGHT_NOTICE "" #define WWW_URL "" #endif /* INCLUDE_QUOTATOOL_CONFIG */ quotatool-1.8.0/src/dir.mk000066400000000000000000000005641515710035100154500ustar00rootroot00000000000000# # Makefile fragment for src # svdir := $(dir) dir := $(dir)/src dirs += $(dir) srcs += $(wildcard $(dir)/*.c) inc += -I$(dir) auto += $(wildcard $(dir)/*.in) libs += subdirs := linux bsd ifneq ($(strip $(subdirs)),) -include $(foreach sdir,$(subdirs),$(dir)/$(sdir)/dir.mk) endif dir := $(svdir) quotatool-1.8.0/src/linux/000077500000000000000000000000001515710035100154735ustar00rootroot00000000000000quotatool-1.8.0/src/linux/dir.mk000066400000000000000000000006741515710035100166110ustar00rootroot00000000000000# # Makefile fragment for src/linux # thisdir := linux svdir := $(dir) dir := $(dir)/linux dirs += $(dir) auto += $(wildcard $(dir)/*.in) ifeq "$(build_platform)" "$(thisdir)" srcs += $(wildcard $(dir)/*.c) inc += -I$(dir) libs += subdirs := ifneq ($(strip $(subdirs)),) -include $(foreach sdir,$(subdirs),$(dir)/$(sdir)/dir.mk) endif endif dir := $(svdir) quotatool-1.8.0/src/linux/dqblk_old.h000066400000000000000000000016731515710035100176060ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * dqblk_old.h * Headerfile for old quotafile format */ #ifndef _DQBLK_OLD_H #define _DQBLK_OLD_H /* Structure of quota for communication with kernel */ struct old_kern_dqblk { u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */ u_int32_t dqb_curblocks; /* current block count */ u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */ u_int32_t dqb_isoftlimit; /* preferred inode limit */ u_int32_t dqb_curinodes; /* current # allocated inodes */ time_t dqb_btime; /* time limit for excessive disk use */ time_t dqb_itime; /* time limit for excessive files */ }; /* Values of quota calls */ #define Q_OLD_RSQUASH 0x1000 #define Q_OLD_GETQUOTA 0x300 #define Q_OLD_SETQUOTA 0x400 #define Q_OLD_GETSTATS 0x800 #endif quotatool-1.8.0/src/linux/dqblk_v0.h000066400000000000000000000026651515710035100173570ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * dqblk_v0.h * Header file for disk format of new quotafile format */ #ifndef _DQBLK_V0_H #define _DQBLK_V0_H #include #define Q_V0_GETQUOTA 0x0D00 /* Get limits and usage */ #define Q_V0_SETQUOTA 0x0E00 /* Set limits and usage */ #define Q_V0_GETINFO 0x0900 /* Get information about quota */ #define Q_V0_SETINFO 0x0A00 /* Set information about quota */ #define Q_V0_SETGRACE 0x0B00 /* set inode and block grace */ #define Q_V0_GETSTATS 0x1100 /* get collected stats (before proc was used) */ /* Structure of quota for communication with kernel */ struct v0_kern_dqblk { unsigned int dqb_ihardlimit; unsigned int dqb_isoftlimit; unsigned int dqb_curinodes; unsigned int dqb_bhardlimit; unsigned int dqb_bsoftlimit; qsize_t dqb_curspace; time_t dqb_btime; time_t dqb_itime; }; /* Structure of quotafile info for communication with kernel */ struct v0_kern_dqinfo { unsigned int dqi_bgrace; unsigned int dqi_igrace; unsigned int dqi_flags; unsigned int dqi_blocks; unsigned int dqi_free_blk; unsigned int dqi_free_entry; }; /* Structure with gathered statistics from kernel */ struct v0_dqstats { u_int32_t lookups; u_int32_t drops; u_int32_t reads; u_int32_t writes; u_int32_t cache_hits; u_int32_t allocated_dquots; u_int32_t free_dquots; u_int32_t syncs; u_int32_t version; }; #endif quotatool-1.8.0/src/linux/linux_quota.h000066400000000000000000000107221515710035100202160ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * linux/quota.h * * quota defs for linux * We don't use */ #ifndef LINUX_QUOTA_H #define LINUX_QUOTA_H #include #include "system.h" typedef u_int32_t qid_t; /* Type in which we store ids in memory */ typedef u_int64_t qsize_t; /* Type in which we store size limitations */ #define MAXQUOTAS 2 #define USRQUOTA 0 /* element used for user quotas */ #define GRPQUOTA 1 /* element used for group quotas */ /* * Command definitions for the 'quotactl' system call. * The commands are broken into a main command defined below * and a subcommand that is used to convey the type of * quota that is being manipulated (see above). */ #define SUBCMDMASK 0x00ff #define SUBCMDSHIFT 8 #define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) /* Interface versions */ #define IFACE_VFSOLD 1 #define IFACE_VFSV0 2 #define IFACE_GENERIC 3 /* _6_5_ are the older defs */ #define Q_6_5_SYNC 0x0600 /* sync disk copy of a filesystems quotas */ #if 0 /* not used */ #define Q_6_5_QUOTAOFF 0x0200 /* disable quotas */ #define Q_6_5_QUOTAON 0x0100 /* enable quotas */ #endif #define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */ #if 0 /* not used */ #define Q_QUOTAON 0x800002 /* turn quotas on */ #define Q_QUOTAOFF 0x800003 /* turn quotas off */ #endif #define Q_GETFMT 0x800004 /* get quota format used on given filesystem */ #define Q_GETINFO 0x800005 /* get information about quota files */ #define Q_SETINFO 0x800006 /* set information about quota files */ #define Q_GETQUOTA 0x800007 /* get user quota structure */ #define Q_SETQUOTA 0x800008 /* set user quota structure */ /* * Quota structure used for communication with userspace via quotactl * Following flags are used to specify which fields are valid */ #define QIF_BLIMITS 1 #define QIF_SPACE 2 #define QIF_ILIMITS 4 #define QIF_INODES 8 #define QIF_BTIME 16 #define QIF_ITIME 32 #define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS) #define QIF_USAGE (QIF_SPACE | QIF_INODES) #define QIF_TIMES (QIF_BTIME | QIF_ITIME) #define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES) /* The generic diskblock-struct: */ struct if_dqblk { u_int64_t dqb_bhardlimit; u_int64_t dqb_bsoftlimit; u_int64_t dqb_curspace; u_int64_t dqb_ihardlimit; u_int64_t dqb_isoftlimit; u_int64_t dqb_curinodes; u_int64_t dqb_btime; u_int64_t dqb_itime; u_int32_t dqb_valid; }; /* version-specific info */ struct v0_mem_dqinfo {}; struct old_mem_dqinfo { unsigned int dqi_blocks; unsigned int dqi_free_blk; unsigned int dqi_free_entry; }; /* According to 'man quotactl' these are defined in sys/quota.h but that seems to not always be the case */ #ifndef IIF_BGRACE #define IIF_BGRACE 1 #endif #ifndef IIF_IGRACE #define IIF_IGRACE 2 #endif #ifndef IIF_FLAGS #define IIF_FLAGS 4 #endif #ifndef IIF_ALL #define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS) #endif /* The generic diskinfo-struct: */ struct if_dqinfo { u_int64_t dqi_bgrace; u_int64_t dqi_igrace; u_int32_t dqi_flags; u_int32_t dqi_valid; }; /* Ioctl for getting quota size */ #include #ifndef FIOQSIZE #if defined(__alpha__) || defined(__powerpc__) || defined(__sh__) || defined(__sparc__) || defined(__sparc64__) #define FIOQSIZE _IOR('f', 128, loff_t) #elif defined(__arm__) || defined(__mc68000__) || defined(__s390__) #define FIOQSIZE 0x545E #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__ia64__) || defined(__parisc__) || defined(__cris__) || defined(__hppa__) #define FIOQSIZE 0x5460 #elif defined(__mips__) || defined(__mips64__) #define FIOQSIZE 0x6667 #endif #endif long quotactl (int, const char *, qid_t, caddr_t); /* * runtime detection of quota format */ /* Values for format handling */ #define QF_TOONEW -2 /* Quota format is too new to handle */ #define QF_ERROR -1 /* There was error while detecting format (maybe unknown format...) */ #define QF_VFSOLD 0 /* Old quota format */ #define QF_VFSV0 1 /* New quota format - version 0 */ #define QF_VFSV1 2 /* Newer quota format - version 1 */ #define QF_XFS 3 /* XFS quota */ #define KERN_KNOWN_QUOTA_VERSION (6*10000 + 5*100 + 2) int kern_quota_format(fs_t *, int); #include "dqblk_old.h" #include "dqblk_v0.h" #include "xfs_quota.h" #endif /* _QUOTA_ */ quotatool-1.8.0/src/linux/quota.c000066400000000000000000000530631515710035100167770ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * quota.c * middle layer to talk to quotactl */ #include #include #include #include #include #include #include #include #include "output.h" #include "system.h" #include "quota.h" #include "quotatool.h" #ifndef ENOTSUP #define ENOTSUP EOPNOTSUPP #endif /* Handy macros */ #define QF_IS_OLD(qf) (qf & (1 << QF_VFSOLD)) #define QF_IS_V0(qf) (qf & (1 << QF_VFSV0)) #define QF_IS_V1(qf) (qf & (1 << QF_VFSV1)) #define QF_IS_XFS(qf) (qf & (1 << QF_XFS)) #define QF_IS_TOO_NEW(qf) (qf == QF_TOONEW) #define IF_GENERIC (kernel_iface == IFACE_GENERIC) static int quota_format; static int kernel_iface; static int old_quota_get(quota_t *); static int old_quota_set(quota_t *); static int v0_quota_get(quota_t *); static int v0_quota_set(quota_t *); static int generic_quota_get(quota_t *); static int generic_quota_set(quota_t *); static int xfs_quota_get(quota_t *); static int xfs_quota_set(quota_t *); quota_t *quota_new(int q_type, int id, char *fs_spec) { quota_t *myquota; fs_t *fs; char *qfile; q_type--; /* see defs in quota.h */ if (q_type >= MAXQUOTAS) { output_error("Unknown quota type: %d", q_type); return 0; } myquota = (quota_t *) calloc(1, sizeof(quota_t)); if (! myquota) { output_error("Insufficient memory"); exit(ERR_MEM); } fs = system_getfs(fs_spec); if (! fs) { free(myquota); return NULL; } /* * Detect quota format */ output_debug("Detecting quota format"); if (kern_quota_format(fs, q_type) == QF_ERROR) { output_error("Cannot determine quota format!"); exit(ERR_SYS); } if (QF_IS_TOO_NEW(quota_format)) { output_error("Quota format too new (?)"); exit(ERR_SYS); } if (QF_IS_XFS(quota_format)) { output_debug("Detected quota format: XFS"); } if (QF_IS_V0(quota_format)) { output_debug("Detected quota format: VFSV0"); if (IF_GENERIC) { output_debug("Detected quota interface: GENERIC"); } else { myquota->_v0_quotainfo = (struct v0_kern_dqinfo *) 0; myquota->_v0_quotainfo = (struct v0_kern_dqinfo *) malloc (sizeof(struct v0_kern_dqinfo)); if (! myquota->_v0_quotainfo) { output_error("Insufficient memory"); exit(ERR_MEM); } } } else if (QF_IS_V1(quota_format)) { output_debug("Detected quota format: VFSV1"); if (IF_GENERIC) { output_debug("Detected quota interface: GENERIC"); } else { output_error("Unsupported quota format: VFSV1 but not GENERIC, please report Issue on github: https://github.com/ekenberg/quotatool"); exit(ERR_SYS); } } else if (QF_IS_OLD(quota_format)) { output_debug("Detected quota format: OLD"); if (IF_GENERIC) { output_debug("Detected quota interface: GENERIC"); } } else if (! QF_IS_XFS(quota_format)) { output_error("Unknown quota format!"); exit(ERR_SYS); } if (IF_GENERIC) { myquota->_generic_quotainfo = (struct if_dqinfo *) 0; myquota->_generic_quotainfo = (struct if_dqinfo *) malloc(sizeof(struct if_dqinfo)); if (! myquota->_generic_quotainfo) { output_error("Insufficient memory"); exit(ERR_MEM); } } qfile = strdup(fs->device); myquota->_id = id; myquota->_id_type = q_type; myquota->_qfile = qfile; free(fs); return myquota; } inline void quota_delete(quota_t *myquota) { free(myquota->_qfile); if (IF_GENERIC) { free(myquota->_generic_quotainfo); } else if (QF_IS_V0(quota_format)) { free(myquota->_v0_quotainfo); } free(myquota); } int quota_get(quota_t *myquota) { int retval; output_debug("fetching quotas: device='%s',id='%d'", myquota->_qfile, myquota->_id); if (QF_IS_XFS(quota_format)) { retval = xfs_quota_get(myquota); } else if (IF_GENERIC) { retval = generic_quota_get(myquota); } else if (QF_IS_V0(quota_format)) { retval = v0_quota_get(myquota); } else { retval = old_quota_get(myquota); } return retval; } static int old_quota_get(quota_t *myquota) { struct old_kern_dqblk sysquota; int retval; retval = quotactl(QCMD(Q_OLD_GETQUOTA,myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) &sysquota); if (retval < 0) { output_error("Failed fetching quotas (old): %s", strerror(errno)); return 0; } /* copy the linux-formatted quota info into our struct */ myquota->block_hard = sysquota.dqb_bhardlimit; myquota->block_soft = sysquota.dqb_bsoftlimit; myquota->diskspace_used = sysquota.dqb_curblocks; myquota->inode_hard = sysquota.dqb_ihardlimit; myquota->inode_soft = sysquota.dqb_isoftlimit; myquota->inode_used = sysquota.dqb_curinodes; myquota->block_time = sysquota.dqb_btime; myquota->inode_time = sysquota.dqb_itime; /* yes, something fishy here. quota old seems to lack separate fields for user grace times and global grace times. is it like XFS - root's limits sets global? */ myquota->block_grace = sysquota.dqb_btime; myquota->inode_grace = sysquota.dqb_itime; return 1; } static int v0_quota_get(quota_t *myquota) { struct v0_kern_dqblk sysquota; int retval; retval = quotactl(QCMD(Q_V0_GETQUOTA,myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) &sysquota); if (retval < 0) { output_error("Failed fetching quotas (vfsv0): %s", strerror(errno)); return 0; } /* copy the linux-formatted quota info into our struct */ myquota->block_hard = sysquota.dqb_bhardlimit; myquota->block_soft = sysquota.dqb_bsoftlimit; myquota->diskspace_used = sysquota.dqb_curspace; myquota->inode_hard = sysquota.dqb_ihardlimit; myquota->inode_soft = sysquota.dqb_isoftlimit; myquota->inode_used = sysquota.dqb_curinodes; myquota->block_time = sysquota.dqb_btime; myquota->inode_time = sysquota.dqb_itime; retval = quotactl(QCMD(Q_V0_GETINFO,myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) myquota->_v0_quotainfo); if (retval < 0) { output_error("Failed fetching quotainfo: %s", strerror(errno)); return 0; } myquota->block_grace = ((struct v0_kern_dqinfo *) myquota->_v0_quotainfo)->dqi_bgrace; myquota->inode_grace = ((struct v0_kern_dqinfo *) myquota->_v0_quotainfo)->dqi_igrace; return 1; } static int generic_quota_get(quota_t *myquota) { struct if_dqblk sysquota; long retval; retval = quotactl(QCMD(Q_GETQUOTA,myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) &sysquota); if (retval < 0) { output_error("Failed fetching quotas (generic): %s", strerror(errno)); return 0; } /* copy the linux-formatted quota info into our struct */ myquota->block_hard = sysquota.dqb_bhardlimit; myquota->block_soft = sysquota.dqb_bsoftlimit; myquota->diskspace_used = sysquota.dqb_curspace; myquota->inode_hard = sysquota.dqb_ihardlimit; myquota->inode_soft = sysquota.dqb_isoftlimit; myquota->inode_used = sysquota.dqb_curinodes; myquota->block_time = sysquota.dqb_btime; myquota->inode_time = sysquota.dqb_itime; retval = quotactl(QCMD(Q_GETINFO,myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) myquota->_generic_quotainfo); if (retval < 0) { output_error("Failed fetching quotainfo (generic): %s", strerror(errno)); return 0; } myquota->block_grace = ((struct if_dqinfo *) myquota->_generic_quotainfo)->dqi_bgrace; myquota->inode_grace = ((struct if_dqinfo *) myquota->_generic_quotainfo)->dqi_igrace; return 1; } static int xfs_quota_get(quota_t *myquota) { fs_disk_quota_t sysquota; fs_quota_stat_t quotastat; int block_diff; // XFS quota always uses BB (Basic Blocks = 512 bytes) int retval; block_diff = BLOCK_SIZE / 512; retval = quotactl(QCMD(Q_XGETQUOTA, myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) &sysquota); /* ** 2005-04-26 : fmicaux@actilis.net - handling a non-set quota for a user/group who owns nothing here */ if (retval < 0) { // This error has to be explained : // if UID/GID has no quota defined, and owns no data, ENOENT error occures // but at this point of the code, whe know that this XFS has quotas. // We make the choice to produce a "0 0 0 0 0 0 0 0" line. if (errno == ENOENT) { myquota->block_hard = 0; myquota->block_soft = 0; myquota->diskspace_used = 0; myquota->inode_hard = 0; myquota->inode_soft = 0; myquota->inode_used = 0; myquota->block_grace = 0; myquota->inode_grace = 0; myquota->block_time = 0; myquota->inode_time = 0; return 1; } output_error ("Failed fetching quotas: errno=%d, %s", errno, strerror(errno)); return 0; } retval = quotactl(QCMD(Q_XGETQSTAT, myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) "astat); /* copy the linux-xfs-formatted quota info into our struct */ myquota->block_hard = sysquota.d_blk_hardlimit / block_diff; myquota->block_soft = sysquota.d_blk_softlimit / block_diff; // XFS really uses blocks, all other formats in this file use bytes myquota->diskspace_used = (sysquota.d_bcount * 1024) / block_diff; myquota->inode_hard = sysquota.d_ino_hardlimit; myquota->inode_soft = sysquota.d_ino_softlimit; myquota->inode_used = sysquota.d_icount; myquota->block_grace = quotastat.qs_btimelimit; myquota->inode_grace = quotastat.qs_itimelimit; myquota->block_time = sysquota.d_btimer; myquota->inode_time = sysquota.d_itimer; return 1; } int quota_set(quota_t *myquota){ int retval; if (geteuid() != 0) { output_error("Only root can set quotas"); return 0; } /* set quota */ if (QF_IS_XFS(quota_format)) { retval = xfs_quota_set(myquota); } else if (IF_GENERIC) { retval = generic_quota_set(myquota); } else if (QF_IS_V0(quota_format)) { retval = v0_quota_set(myquota); } else { retval = old_quota_set(myquota); } if (! retval) return retval; if (QF_IS_XFS(quota_format)) return 1; // no sync needed for XFS /* sync */ retval = quotactl(QCMD(IF_GENERIC ? Q_SYNC : Q_6_5_SYNC ,myquota->_id_type), myquota->_qfile, 0, NULL); if (retval < 0) { output_error("Failed syncing quotas on %s: %s", myquota->_qfile, strerror(errno)); return 0; } return 1; } static int generic_quota_set(quota_t *myquota) { struct if_dqblk sysquota; int retval; /* copy our data into the linux dqblk */ sysquota.dqb_bhardlimit = myquota->block_hard; sysquota.dqb_bsoftlimit = myquota->block_soft; sysquota.dqb_curspace = myquota->diskspace_used; sysquota.dqb_ihardlimit = myquota->inode_hard; sysquota.dqb_isoftlimit = myquota->inode_soft; sysquota.dqb_curinodes = myquota->inode_used; /* Per-user timers (btime/itime) not set here — dqb_valid only includes QIF_LIMITS so the kernel would ignore them anyway. Timer setting is handled by quota_reset_grace() when needed. */ sysquota.dqb_valid = QIF_LIMITS; retval = quotactl(QCMD(Q_SETQUOTA,myquota->_id_type),myquota->_qfile, myquota->_id, (caddr_t) &sysquota); if (retval < 0) { output_error("Failed setting quota (generic): %s", strerror(errno)); return 0; } /* update quotainfo (global gracetimes) */ if (myquota->_do_set_global_block_gracetime || myquota->_do_set_global_inode_gracetime) { struct if_dqinfo *foo = ((struct if_dqinfo *) myquota->_generic_quotainfo); u_int32_t old_dqi_valid = foo->dqi_valid; // Save now, restore later if (myquota->_do_set_global_block_gracetime) { output_debug(">> set global block gracetime"); foo->dqi_bgrace = myquota->block_grace; foo->dqi_valid = IIF_BGRACE; } if (myquota->_do_set_global_inode_gracetime) { output_debug(">> set global inode gracetime"); foo->dqi_igrace = myquota->inode_grace; foo->dqi_valid = IIF_IGRACE; } retval = quotactl(QCMD(Q_SETINFO, myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) myquota->_generic_quotainfo); foo->dqi_valid = old_dqi_valid; // restore if (retval < 0) { output_error("Failed setting gracetime (generic): %s", strerror(errno)); return 0; } } /* success */ return 1; } static int v0_quota_set(quota_t *myquota) { struct v0_kern_dqblk sysquota; int retval; /* copy our data into the linux dqblk */ sysquota.dqb_bhardlimit = myquota->block_hard; sysquota.dqb_bsoftlimit = myquota->block_soft; sysquota.dqb_curspace = myquota->diskspace_used; sysquota.dqb_ihardlimit = myquota->inode_hard; sysquota.dqb_isoftlimit = myquota->inode_soft; sysquota.dqb_curinodes = myquota->inode_used; /* 2024-05-01: Completely forgot why these are commented out? */ // sysquota.dqb_btime = myquota->block_time; // sysquota.dqb_itime = myquota->inode_time; /* make the syscall */ retval = quotactl(QCMD(Q_V0_SETQUOTA,myquota->_id_type),myquota->_qfile, myquota->_id, (caddr_t) &sysquota); if (retval < 0) { output_error("Failed setting quota (vfsv0): %s", strerror(errno)); return 0; } /* update quotainfo (global gracetimes) */ if (myquota->_do_set_global_block_gracetime || myquota->_do_set_global_inode_gracetime) { if (myquota->_do_set_global_block_gracetime) ((struct v0_kern_dqinfo *) myquota->_v0_quotainfo)->dqi_bgrace = myquota->block_grace; if (myquota->_do_set_global_inode_gracetime) ((struct v0_kern_dqinfo *) myquota->_v0_quotainfo)->dqi_igrace = myquota->inode_grace; retval = quotactl(QCMD(Q_V0_SETGRACE, myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) myquota->_v0_quotainfo); if (retval < 0) { output_error("Failed setting gracetime: %s", strerror(errno)); return 0; } } /* success */ return 1; } static int old_quota_set(quota_t *myquota) { struct old_kern_dqblk sysquota; int retval; /* copy our data into the linux dqblk */ sysquota.dqb_bhardlimit = myquota->block_hard; sysquota.dqb_bsoftlimit = myquota->block_soft; sysquota.dqb_curblocks = myquota->diskspace_used; sysquota.dqb_ihardlimit = myquota->inode_hard; sysquota.dqb_isoftlimit = myquota->inode_soft; sysquota.dqb_curinodes = myquota->inode_used; /* is old like xfs - global grace set by root's limits? */ sysquota.dqb_btime = myquota->block_grace; sysquota.dqb_itime = myquota->inode_grace; /* make the syscall */ retval = quotactl(QCMD(Q_OLD_SETQUOTA,myquota->_id_type),myquota->_qfile, myquota->_id, (caddr_t) &sysquota); if (retval < 0) { output_error("Failed setting quota (old): %s", strerror(errno)); return 0; } /* success */ return 1; } static int xfs_quota_set(quota_t *myquota) { fs_disk_quota_t sysquota; int retval; int block_diff= BLOCK_SIZE / 512; memset(&sysquota, 0, sizeof(fs_disk_quota_t)); /* copy our data into the linux dqblk */ sysquota.d_blk_hardlimit = myquota->block_hard * block_diff; sysquota.d_blk_softlimit = myquota->block_soft * block_diff; // XFS really uses blocks, all other formats in this file use bytes sysquota.d_bcount = DIV_UP(myquota->diskspace_used * block_diff, 1024); sysquota.d_ino_hardlimit = myquota->inode_hard; sysquota.d_ino_softlimit = myquota->inode_soft; sysquota.d_icount = myquota->inode_used; /* For XFS, global grace time limits are set by the values set for root */ sysquota.d_btimer = myquota->block_grace; sysquota.d_itimer = myquota->inode_grace; sysquota.d_fieldmask = FS_DQ_LIMIT_MASK; if (myquota->_do_set_global_block_gracetime || myquota->_do_set_global_inode_gracetime) sysquota.d_fieldmask |= FS_DQ_TIMER_MASK; retval = quotactl(QCMD(Q_XSETQLIM,myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) &sysquota); if (retval < 0) { output_error("Failed setting quota (xfs): %s", strerror(errno)); return(0); } /* success */ return 1; } /* * Check kernel quota version * (ripped from quota-utils, all credits to Honza!) */ int kern_quota_format(fs_t *fs, int q_type) { u_int32_t version; struct v0_dqstats v0_stats; FILE *f; int ret = 0; struct stat st; if (strcasecmp(fs->mnt_type, "xfs") == 0) { if (stat("/proc/fs/xfs/stat", &st) == 0) { quota_format |= (1 << QF_XFS); return ret; } else { output_error("%s is mounted as XFS but no kernel support for XFS quota!", fs->device); exit(ERR_SYS); } } if ((f = fopen("/proc/fs/quota", "r"))) { if (fscanf(f, "Version %u", &version) != 1) { fclose(f); return QF_TOONEW; } fclose(f); } else if (stat("/proc/sys/fs/quota", &st) == 0) { /* Either QF_VFSOLD or QF_VFSV0 or QF_VFSV1 */ int actfmt, retval; kernel_iface = IFACE_GENERIC; retval = quotactl(QCMD(Q_GETFMT, q_type), fs->device, 0, (void *) &actfmt); if (retval < 0) { if (! QF_IS_XFS(quota_format)) { if (errno == 3) { output_error("Quotatool cannot function while quotas are disabled. " "Please enable quotas by running `quotaon -a`.\n"); } else { output_error("Error while detecting kernel quota version: %i, %s\n", errno, strerror(errno)); } exit(ERR_SYS); } } else { if (actfmt == 1) /* Q_GETFMT retval for QF_VFSOLD */ quota_format |= (1 << QF_VFSOLD); else if (actfmt == 2) /* Q_GETFMT retval for QF_VFSV0 */ quota_format |= (1 << QF_VFSV0); else if (actfmt == 4) /* Q_GETFMT retval for QF_VFSV1 */ quota_format |= (1 << QF_VFSV1); else { output_debug("Unknown Q_GETFMT: %d\n", actfmt); return QF_ERROR; } } return ret; } else if (quotactl(QCMD(Q_V0_GETSTATS, 0), NULL, 0, (void *) &v0_stats) >= 0) { version = v0_stats.version; /* Copy the version */ } else { if (errno == ENOSYS || errno == ENOTSUP) /* Quota not compiled? */ return QF_ERROR; if (errno == EINVAL || errno == EFAULT || errno == EPERM) { /* Old quota compiled? */ /* RedHat 7.1 (2.4.2-2) newquota check * Q_V0_GETSTATS in it's old place, Q_GETQUOTA in the new place * (they haven't moved Q_GETSTATS to its new value) */ int err_stat = 0; int err_quota = 0; char tmp[1024]; /* Just temporary buffer */ if (quotactl(QCMD(Q_OLD_GETSTATS, 0), NULL, 0, tmp)) err_stat = errno; if (quotactl(QCMD(Q_OLD_GETQUOTA, 0), "/dev/null", 0, tmp)) err_quota = errno; /* On a RedHat 2.4.2-2 we expect 0, EINVAL * On a 2.4.x we expect 0, ENOENT * On a 2.4.x-ac we wont get here */ if (err_stat == 0 && err_quota == EINVAL) { quota_format |= (1 << QF_VFSV0); /* New format supported */ kernel_iface = IFACE_VFSV0; } else { quota_format |= (1 << QF_VFSOLD); kernel_iface = IFACE_VFSOLD; } return ret; } output_error("Error while detecting kernel quota version: %s\n", strerror(errno)); exit(ERR_SYS); } if (version > KERN_KNOWN_QUOTA_VERSION) /* Newer kernel than we know? */ quota_format = QF_TOONEW; if (version <= 6*10000+4*100+0) { /* Old quota format? */ quota_format |= (1 << QF_VFSOLD); kernel_iface = IFACE_VFSOLD; } else { quota_format |= (1 << QF_VFSV0); /* New format supported */ kernel_iface = IFACE_VFSOLD; } return ret; } int quota_reset_grace(quota_t *myquota, int grace_type) { if (QF_IS_XFS(quota_format)) { /* * XFS grace reset uses two mechanisms for portability: * * 1. Raise/restore hack: temporarily set limits above usage * (clears grace), then restore. On old kernels (<=5.4), * the next user write re-triggers grace. * * 2. Direct timer set via Q_XSETQLIM with FS_DQ_BTIMER: * sets d_btimer to now + grace_period. Honored by kernels * >=5.10. Needed because newer kernels (6.19+) block * writes when over soft with no timer, preventing the * hack's re-trigger from working. * * Both are applied: the hack works on old kernels (where * direct set is ignored), the direct set works on new kernels * (where the hack's re-trigger may fail). */ quota_t temp_quota; fs_disk_quota_t sysquota; /* Step 1: raise/restore hack */ memcpy(&temp_quota, myquota, sizeof(quota_t)); if (grace_type == GRACE_BLOCK) temp_quota.block_hard = temp_quota.block_soft = BYTES_TO_BLOCKS(temp_quota.diskspace_used) + 1; else temp_quota.inode_hard = temp_quota.inode_soft = temp_quota.inode_used + 1; xfs_quota_set(&temp_quota); xfs_quota_set(myquota); /* Step 2: direct timer set (ignored on old kernels, needed on new) */ memset(&sysquota, 0, sizeof(fs_disk_quota_t)); if (grace_type == GRACE_BLOCK) { sysquota.d_btimer = (__s32)(time(NULL) + myquota->block_grace); sysquota.d_fieldmask = FS_DQ_BTIMER; } else { sysquota.d_itimer = (__s32)(time(NULL) + myquota->inode_grace); sysquota.d_fieldmask = FS_DQ_ITIMER; } quotactl(QCMD(Q_XSETQLIM, myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) &sysquota); return 1; } else { /* * Non-XFS: raise/restore hack. Temporarily set limits above * usage (clears grace), then restore original limits. The * kernel re-triggers grace on the next user write. */ quota_t temp_quota; memcpy(&temp_quota, myquota, sizeof(quota_t)); if (grace_type == GRACE_BLOCK) temp_quota.block_hard = temp_quota.block_soft = BYTES_TO_BLOCKS(temp_quota.diskspace_used) + 1; else temp_quota.inode_hard = temp_quota.inode_soft = temp_quota.inode_used + 1; if (quota_set(&temp_quota) && quota_set(myquota)) return 1; } output_error("Cannot reset grace period!"); return 0; } quotatool-1.8.0/src/linux/xfs_quota.h000066400000000000000000000113311515710035100176540ustar00rootroot00000000000000 #define XQM_CMD(x) (('X'<<8)+(x)) /* note: forms first QCMD argument */ #define Q_XQUOTAON XQM_CMD(0x1) /* enable accounting/enforcement */ #define Q_XQUOTAOFF XQM_CMD(0x2) /* disable accounting/enforcement */ #define Q_XGETQUOTA XQM_CMD(0x3) /* get disk limits and usage */ #define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits */ #define Q_XGETQSTAT XQM_CMD(0x5) /* get quota subsystem status */ #define Q_XQUOTARM XQM_CMD(0x6) /* free disk space used by dquots */ /* * fs_disk_quota structure: */ #define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */ typedef struct fs_disk_quota { __s8 d_version; /* version of this structure */ __s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */ __u16 d_fieldmask; /* field specifier */ __u32 d_id; /* user, project, or group ID */ __u64 d_blk_hardlimit;/* absolute limit on disk blks */ __u64 d_blk_softlimit;/* preferred limit on disk blks */ __u64 d_ino_hardlimit;/* maximum # allocated inodes */ __u64 d_ino_softlimit;/* preferred inode limit */ __u64 d_bcount; /* # disk blocks owned by the user */ __u64 d_icount; /* # inodes owned by the user */ __s32 d_itimer; /* zero if within inode limits */ /* if not, we refuse service */ __s32 d_btimer; /* similar to above; for disk blocks */ __u16 d_iwarns; /* # warnings issued wrt num inodes */ __u16 d_bwarns; /* # warnings issued wrt disk blocks */ __s32 d_padding2; /* padding2 - for future use */ __u64 d_rtb_hardlimit;/* absolute limit on realtime blks */ __u64 d_rtb_softlimit;/* preferred limit on RT disk blks */ __u64 d_rtbcount; /* # realtime blocks owned */ __s32 d_rtbtimer; /* similar to above; for RT disk blks */ __u16 d_rtbwarns; /* # warnings issued wrt RT disk blks */ __s16 d_padding3; /* padding3 - for future use */ char d_padding4[8]; /* yet more padding */ } fs_disk_quota_t; /* * These fields are sent to Q_XSETQLIM to specify fields that need to change. */ #define FS_DQ_ISOFT (1<<0) #define FS_DQ_IHARD (1<<1) #define FS_DQ_BSOFT (1<<2) #define FS_DQ_BHARD (1<<3) #define FS_DQ_RTBSOFT (1<<4) #define FS_DQ_RTBHARD (1<<5) #define FS_DQ_LIMIT_MASK (FS_DQ_ISOFT | FS_DQ_IHARD | FS_DQ_BSOFT | \ FS_DQ_BHARD | FS_DQ_RTBSOFT | FS_DQ_RTBHARD) /* * These timers can only be set in super user's dquot. For others, timers are * automatically started and stopped. Superusers timer values set the limits * for the rest. In case these values are zero, the DQ_{F,B}TIMELIMIT values * defined below are used. * These values also apply only to the d_fieldmask field for Q_XSETQLIM. */ #define FS_DQ_BTIMER (1<<6) #define FS_DQ_ITIMER (1<<7) #define FS_DQ_RTBTIMER (1<<8) #define FS_DQ_TIMER_MASK (FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER) /* * The following constants define the default amount of time given a user * before the soft limits are treated as hard limits (usually resulting * in an allocation failure). These may be modified by the quotactl(2) * system call with the Q_XSETQLIM command. */ #define DQ_FTIMELIMIT (7 * 24*60*60) /* 1 week */ #define DQ_BTIMELIMIT (7 * 24*60*60) /* 1 week */ /* * Various flags related to quotactl(2). Only relevant to XFS filesystems. */ #define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */ #define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */ #define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */ #define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */ #define XFS_USER_QUOTA (1<<0) /* user quota type */ #define XFS_PROJ_QUOTA (1<<1) /* (IRIX) project quota type */ #define XFS_GROUP_QUOTA (1<<2) /* group quota type */ /* * fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system. * Provides a centralized way to get meta infomation about the quota subsystem. * eg. space taken up for user and group quotas, number of dquots currently * incore. */ #define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */ /* * Some basic infomation about 'quota files'. */ typedef struct fs_qfilestat { __u64 qfs_ino; /* inode number */ __u64 qfs_nblks; /* number of BBs 512-byte-blks */ __u32 qfs_nextents; /* number of extents */ } fs_qfilestat_t; typedef struct fs_quota_stat { __s8 qs_version; /* version number for future changes */ __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */ __s8 qs_pad; /* unused */ fs_qfilestat_t qs_uquota; /* user quota storage information */ fs_qfilestat_t qs_gquota; /* group quota storage information */ __u32 qs_incoredqs; /* number of dquots incore */ __s32 qs_btimelimit; /* limit for blks timer */ __s32 qs_itimelimit; /* limit for inodes timer */ __s32 qs_rtbtimelimit;/* limit for rt blks timer */ __u16 qs_bwarnlimit; /* limit for num warnings */ __u16 qs_iwarnlimit; /* limit for num warnings */ } fs_quota_stat_t; quotatool-1.8.0/src/main.c000066400000000000000000000147741515710035100154410ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * parse.c * command line parsing routines */ #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #include "quotatool.h" #include "output.h" #include "parse.h" #include "quota.h" #include "system.h" int main (int argc, char **argv) { u_int64_t old_quota; int id; time_t old_grace; argdata_t *argdata; quota_t *quota; char* tmpstr; /* parse commandline and fill argdata */ argdata = parse_commandline (argc, argv); if ( ! argdata ) { exit (ERR_PARSE); } /* initialize the id to use */ if ( ! argdata->id ) { id = 0; } /* numerical uid starting with ':', don't check uid/gid against system users/groups */ else if ( strlen(argdata->id) > 1 && argdata->id[0] == ':' && isdigit(argdata->id[1]) ) { argdata->id++; // skip leading ':' id = strtol(argdata->id, &tmpstr, 10); } else if ( argdata->id_type == QUOTA_USER ) { id = (int) system_getuid (argdata->id); } else { id = (int) system_getgid (argdata->id); } if ( id < 0 ) { exit (ERR_ARG); } /* get the quota info */ quota = quota_new (argdata->id_type, id, argdata->qfile); if ( ! quota ) { exit (ERR_SYS); } if ( ! quota_get(quota) ) { exit (ERR_SYS); } if (argdata->dump_info) { time_t now = time(NULL); u_int64_t display_blocks_used = 0; output_info (""); output_info ("%s Filesystem blocks quota limit grace files quota limit grace", argdata->id_type == QUOTA_USER ? "uid" : "gid"); // quota->diskspace_used is bytes. Display in Kb display_blocks_used = DIV_UP(quota->diskspace_used, 1024); #ifdef HAVE_INTTYPES_H printf("%d %s %" PRIu64 " %" PRIu64 " %" PRIu64 " %lu %" PRIu64 " %" PRIu64 " %" PRIu64 " %lu\n", #else printf("%d %s %llu %llu %llu %lu %llu %llu %llu %lu\n", #endif id, argdata->qfile, display_blocks_used, BLOCKS_TO_KB(quota->block_soft), BLOCKS_TO_KB(quota->block_hard), #if ANY_BSD /* Check both: user is over limit AND timer hasn't expired. * Without the > now check, expired timers wrap to huge * unsigned values (bug #36). */ (unsigned long) (( (quota->block_soft && (BYTES_TO_BLOCKS(quota->diskspace_used) >= quota->block_soft)) || (quota->block_hard && (BYTES_TO_BLOCKS(quota->diskspace_used) >= quota->block_hard)) ) && quota->block_time > now ? quota->block_time - now : 0), #else (unsigned long)(quota->block_time > now ? quota->block_time - now : 0), #endif /* ANY_BSD */ quota->inode_used, quota->inode_soft, quota->inode_hard, #if ANY_BSD (unsigned long) (( (quota->inode_soft && (quota->inode_used >= quota->inode_soft)) || (quota->inode_hard && (quota->inode_used >= quota->inode_hard)) ) && quota->inode_time > now ? quota->inode_time - now : 0)); #else (unsigned long)(quota->inode_time > now ? quota->inode_time - now : 0)); #endif /* ANY_BSD */ exit(0); } /* print a header for verbose info */ output_info (""); output_info ("%-14s %-16s %-16s", "Limit", "Old", "New"); output_info ("%-14s %-16s %-16s", "-----", "---", "---"); /* * BEGIN setting global grace periods */ if ( argdata->block_grace ) { old_grace = quota->block_grace; quota->block_grace = parse_timespan (old_grace, argdata->block_grace); if (quota->block_grace == (time_t) -1) { exit (ERR_ARG); } quota->_do_set_global_block_gracetime = 1; output_info ("%-14s %-16d %-16d", "block grace:", old_grace, quota->block_grace); } if ( argdata->inode_grace ) { old_grace = quota->inode_grace; quota->inode_grace = parse_timespan (old_grace, argdata->inode_grace); if (quota->inode_grace == (time_t) -1) { exit (ERR_ARG); } quota->_do_set_global_inode_gracetime = 1; output_info ("%-14s %-16d %-16d", "inode grace:", old_grace, quota->inode_grace); } /* * FINISH setting global grace periods * BEGIN preparing to set quotas */ /* update quota info from the command line */ if ( argdata->block_hard ) { old_quota = quota->block_hard; quota->block_hard = parse_size (old_quota, argdata->block_hard, PARSE_BLOCKS); if ( argdata->raise_only && quota->block_hard <= old_quota) { output_info ("New block quota not higher than current, won't change"); quota->block_hard = old_quota; } output_info ("%-14s %-16llu %llu", "block hard:", BLOCKS_TO_KB(old_quota), BLOCKS_TO_KB(quota->block_hard)); } if ( argdata->block_soft ) { old_quota = quota->block_soft; quota->block_soft= parse_size (old_quota, argdata->block_soft, PARSE_BLOCKS); if ( argdata->raise_only && quota->block_soft <= old_quota) { output_info ("New block soft limit not higher than current, won't change"); quota->block_soft = old_quota; } output_info ("%-14s %-16llu %-16llu", "block soft:", BLOCKS_TO_KB(old_quota), BLOCKS_TO_KB(quota->block_soft)); } if ( argdata->inode_hard ) { old_quota = quota->inode_hard; quota->inode_hard = parse_size (old_quota, argdata->inode_hard, PARSE_INODES); if ( argdata->raise_only && quota->inode_hard <= old_quota) { output_info ("New inode quota not higher than current, won't change"); quota->inode_hard = old_quota; } output_info ("%-14s %-16llu %-16llu", "inode hard:", old_quota, quota->inode_hard); } if ( argdata->inode_soft ) { old_quota = quota->inode_soft; quota->inode_soft = parse_size (old_quota, argdata->inode_soft, PARSE_INODES); if ( argdata->raise_only && quota->inode_soft <= old_quota) { output_info ("New inode soft limit not higher than current, won't change"); quota->inode_soft = old_quota; } output_info ("%-14s %-16llu %-16llu", "inode soft:", old_quota, quota->inode_soft); } /* Reset grace-time? */ if (argdata->block_reset || argdata->inode_reset) { output_info("Resetting %s grace-time for %s %d\n", (argdata->block_reset ? "block" : "inode"), (argdata->id_type == QUOTA_USER ? "uid" : "gid"), id); if (! argdata->noaction) if (! quota_reset_grace(quota, (argdata->block_reset ? GRACE_BLOCK : GRACE_INODE))) exit(ERR_SYS); quota_delete(quota); exit(0); } /* Set new quota? */ if (! argdata->noaction) if (! quota_set (quota)) exit(ERR_SYS); quota_delete (quota); exit (0); } quotatool-1.8.0/src/output.c000066400000000000000000000054521515710035100160460ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * output.c * talk to the nice people */ #include #include #include #include #include "output.h" #include "quotatool.h" #define OUTPUT_NOTHING 0 #define OUTPUT_ERROR 1 #define OUTPUT_INFO 2 #define OUTPUT_DEBUG 3 int output_level = OUTPUT_ERROR; /* * output_version * print version and copyright info */ void output_version () { fprintf (stderr, " %s version %d.%d.%s\n", PROGNAME, MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL); fprintf (stderr, " %s\n", COPYRIGHT_NOTICE); fprintf (stderr, " Distributed under the GNU General Public License\n\n"); fprintf (stderr, " %s\n", WWW_URL); } /* * output_help * print a short usage message */ void output_help () { output_version (); fprintf (stderr, "\nUsage: quotatool -u uid | -g gid options [...] filesystem\n"); fprintf (stderr, " quotatool -u | -g -i | -b -t time filesystem\n"); fprintf (stderr, "Options:\n"); fprintf (stderr, " -b : set block limits\n"); fprintf (stderr, " -i : set inode limits\n"); fprintf (stderr, "\n"); fprintf (stderr, " -q n : set soft limit to n blocks/inodes\n"); fprintf (stderr, " -l n : set hard limit to n blocks/inodes\n"); fprintf (stderr, " limits accept optional modifiers: Kb, Mb, Gb, Tb (see manpage)\n"); fprintf (stderr, "\n"); fprintf (stderr, " -t time : set global grace period to time\n"); fprintf (stderr, " -r : restart grace period for uid or gid\n"); fprintf (stderr, " -R : raise-only, never lower quotas for uid/gid\n"); fprintf (stderr, " -d : dump quota info in machine readable format (see manpage)\n"); fprintf (stderr, " -h : show this help\n"); fprintf (stderr, " -v : be verbose (twice or thrice for debugging)\n"); fprintf (stderr, " -V : show version\n"); fprintf (stderr, " -n : do nothing (useful with -v)\n"); fprintf (stderr, "\nSee 'man quotatool' for detailed information\n"); } /* * _output * print status messages if we're supposed to */ static inline void _output (int level, const char *format, va_list arglist) { if ( level <= output_level ) { fprintf (stderr, "%s: ", PROGNAME); vfprintf (stderr, format, arglist); fprintf (stderr, "\n"); } } void output_error (const char *format, ...) { va_list arglist; va_start (arglist, format); _output (OUTPUT_ERROR, format, arglist); va_end (arglist); } void output_info (const char *format, ...) { va_list arglist; va_start (arglist, format); _output (OUTPUT_INFO, format, arglist); va_end (arglist); } void output_debug (const char *format, ...) { va_list arglist; va_start (arglist, format); _output (OUTPUT_DEBUG, format, arglist); va_end (arglist); } quotatool-1.8.0/src/output.h000066400000000000000000000007631515710035100160530ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * output.h * talk to the nice people */ #ifndef INCLUDE_QUOTATOOL_OUTPUT #define INCLUDE_QUOTATOOL_OUTPUT 1 #include #include extern int output_level; void output_version (void); void output_help (void); void output_debug (const char *format, ...); void output_info (const char *format, ...); void output_error (const char *format, ...); #endif /* INCLUDE_QUOTATOOL_OUTPUT */ quotatool-1.8.0/src/parse.c000066400000000000000000000251031515710035100156130ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * parse.c * command line parsing routines */ #include #include #include #include #include #include #include #include "quotatool.h" #include "output.h" #include "parse.h" #include "quota.h" #include "system.h" #define WHITESPACE " \t\n" #define ABC "abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ" #if HAVE_GNU_GETOPT # define OPTSTRING "hVvnu::g::birq:l:t:dR" #else # define OPTSTRING "hVvnu:g:birq:l:t:dR" #endif #define _PARSE_UNDEF 0x00 #define _PARSE_BLOCK 0x01 #define _PARSE_INODE 0x02 /* * parse_commandline * read our args, parse them * and return a struct of the data */ argdata_t *parse_commandline (int argc, char **argv) { argdata_t *data; extern char *optarg; extern int optind, opterr, optopt; int done, fail; int quota_type; int opt; if (argc == 1) { output_help (); return NULL; } data = (argdata_t *) calloc (1,sizeof(argdata_t)); if ( ! data ) { output_error ("Insufficient memory"); exit (ERR_MEM); } quota_type = _PARSE_UNDEF; optarg = NULL; opterr = 0; done = fail = 0; while ( ! done && ! fail ) { opt = getopt(argc, argv, OPTSTRING); if (opt > 0) output_debug ("option: '%c', argument: '%s'", opt, optarg); switch (opt) { case EOF: done = 1; break; case 'h': output_help (); exit (0); case 'V': output_version(); exit (0); case 'v': output_level++; break; case 'n': data->noaction = 1; break; case 'u': /* set username */ if ( data->id_type ) { output_error("Only one quota (user or group) can be set"); fail = 1; continue; } data->id_type = QUOTA_USER; #if HAVE_GNU_GETOPT /* -uuser */ if ( optarg ) { output_debug ("not mangling: optarg='%s', next='%s'", optarg, argv[optind]); data->id = optarg; } /* -u [-next-opt] */ else if ( ! argv[optind] || argv[optind][0] == '-' ) { output_debug ("not mangling: NULL user"); data->id = NULL; } /* -u user */ else { output_debug ("mangling everything: next='%s'", argv[optind]); data->id = argv[optind]; optind++; } #else if (optarg && ((data->block_grace || data->inode_grace) || (optarg[0] == '-'))) { /* -u [-next-opt] */ optind--; data->id = NULL; } else { /* -u user */ data->id = optarg; } #endif output_info ("using uid %s", data->id); break; case 'g': /* set groupname */ if ( data->id_type ) { output_error("Only one quota (user or group) can be set"); fail = 1; continue; } data->id_type = QUOTA_GROUP; #if HAVE_GNU_GETOPT if ( optarg ) { output_debug ("not mangling: optarg='%s', next='%s'", optarg, argv[optind]); data->id = optarg; } else if ( ! argv[optind] || argv[optind][0] == '-' ) { output_debug ("not mangling: NULL user"); data->id = NULL; } else { output_debug ("mangling everything: next='%s', argv[optind]"); data->id = argv[optind]; optind++; } #else data->id = optarg; #endif output_info ("using gid %s", data->id); break; case 'b': // Work with block limits output_info ("working with block limits"); quota_type = _PARSE_BLOCK; break; case 'i': // Work with inode limits output_info ("working with inode limits"); quota_type = _PARSE_INODE; break; case 'q': // soft limit switch ( quota_type ) { case _PARSE_UNDEF: output_error ("Must specify either block (-b) or inode (-i) before -q"); fail = 1; break; case _PARSE_BLOCK: data->block_soft = optarg; break; case _PARSE_INODE: data->inode_soft = optarg; break; default: output_error ("Impossible error #42q: evacuate the building!"); break; } output_info ("setting soft limit to %s", optarg); break; case 'l': // hard limit switch ( quota_type ) { case _PARSE_UNDEF: output_error ("Must specify either block (-b) or inode (-i) before -l"); fail = 1; break; case _PARSE_BLOCK: data->block_hard = optarg; break; case _PARSE_INODE: data->inode_hard = optarg; break; default: output_error ("Impossible error #42l: evacuate the building!"); break; } output_info ("setting hard limit to %s", optarg); break; case 't': // set grace period data->id = NULL; switch ( quota_type ) { case _PARSE_UNDEF: output_error ("Must specify either block (-b) or inode (-i) before -t"); fail = 1; break; case _PARSE_BLOCK: data->block_grace = optarg; break; case _PARSE_INODE: data->inode_grace = optarg; break; default: output_error ("Impossible error #42t: evacuate the building!"); break; } break; case 'r': // reset grace time switch ( quota_type ) { case _PARSE_UNDEF: output_error ("Must specify either block (-b) or inode (-i) before -r"); fail = 1; break; case _PARSE_BLOCK: data->block_reset = 1; break; case _PARSE_INODE: data->inode_reset = 1; break; default: output_error ("Impossible error #42r: evacuate the building!"); break; } break; case 'd': data->dump_info = 1; break; case 'R': data->raise_only = 1; break; case ':': output_error ("Option '%c' requires an argument", optopt); break; case '?': output_error ("Unrecognized option: '%c'", optopt); // fall through default: output_help(); fail = 1; break; } } if ( fail ) { free (data); return NULL; } if ( ! data->id_type ) { output_error ("Must specify either user or group quota"); return NULL; } if ( data->dump_info) { output_info("Option 'd' => just dumping quota-info for %s", data->id_type == QUOTA_USER ? "user" : "group"); } /* the remaining arg is the filesystem */ data->qfile = argv[optind]; if ( ! data->qfile || strlen(data->qfile) == 0) { output_error ("No filesystem specified"); return NULL; } /* remove trailing slash(es) except for / filesystem */ while (strlen(data->qfile) > 1) { if (data->qfile[strlen(data->qfile) - 1] != '/') break; data->qfile[strlen(data->qfile) - 1] = '\0'; } /* check for mixing -t with other options in the wrong way */ if (data->block_grace || data->inode_grace) { if (data->block_hard || data->block_soft || data->inode_hard || data->inode_soft || data->id) { output_error("Wrong options for -t, please see manpage for usage instructions!"); return NULL; } } /* check for mixing -r with other options in the wrong way */ if (data->block_reset || data->inode_reset) { if (data->block_hard || data->block_soft || data->inode_hard || data->inode_soft) { output_error("Wrong options for -r, please see manpage for usage instructions!"); return NULL; } } output_info ("using filesystem %s", data->qfile); return data; } #define _PARSE_OP_ADD '+' #define _PARSE_OP_SUB '-' /* MIN may be defined by system headers (e.g. sys/param.h on BSD) */ #undef MIN #define SEC 1 #define MIN 60*SEC #define HOUR 60*MIN #define DAY 24*HOUR #define WEEK 7*DAY #define MONTH 30*DAY /* * parse_timespan * understands seconds, minutes, hours, days, weeks, months * returns the number of seconds represented */ time_t parse_timespan (time_t orig, char *string) { char *cp; int count, unit; char op; op = '\0'; if ( ( *string == _PARSE_OP_ADD ) || ( *string == _PARSE_OP_SUB ) ) { op = *string; string++; } count = strtol (string, &cp, 10); if ( cp == string ) { /* No numeric argument */ output_error ("Invalid format: %s", string); return -1; } /* remove whitespace */ while ( strchr(WHITESPACE, *cp) ) cp++; if ( ! strncasecmp(cp, "s", 1) ) { unit = SEC; } else if ( ! strncasecmp(cp, "mi", 2) ) { unit = MIN; } else if ( ! strncasecmp(cp, "h", 1) ) { unit = HOUR; } else if ( ! strncasecmp(cp, "d", 1) ) { unit = DAY; } else if ( ! strncasecmp(cp, "w", 1) ) { unit = WEEK; } else if ( ! strncasecmp(cp, "mo", 2) ) { unit = MONTH; } else if (strchr(ABC, *cp)) { output_error ("Invalid format: %s", string); return -1; } else { unit = SEC; } switch (op) { case _PARSE_OP_ADD: return (time_t) orig + (count*unit); case _PARSE_OP_SUB: return (time_t) orig - (count*unit); default: return (time_t) count*unit; } } #define KILO 1024ul #define MEGA KILO * KILO #define GIGA KILO * MEGA #define TERA KILO * GIGA #define KILO_10 1000ul #define MEGA_10 KILO_10 * KILO_10 #define GIGA_10 KILO_10 * MEGA_10 #define TERA_10 KILO_10 * GIGA_10 /* * parse_size * understands Kb, Mb, Gb, Tb, bytes, and disk blocks * returns the number of bytes represented */ u_int64_t parse_size (u_int64_t orig, char *string, int parse_type) { char *cp; u_int64_t size, multiplier; double count; char op; op = '\0'; if ( ( *string == _PARSE_OP_ADD ) || ( *string == _PARSE_OP_SUB ) ) { op = *string; string++; } /* get the number */ count = strtod(string, &cp); if (count == 0 && string == cp) { // No numeric argument return orig; } /* negative sizes make no sense */ if (count<0) { exit (ERR_ARG); } /* remove whitespace */ while ( strchr(WHITESPACE, *cp) ) cp++; /* get the units */ if ( ! strncasecmp(cp, "by", 2) ) { multiplier = 1; } else if ( ! strncasecmp(cp, "bl", 2) ) { multiplier = (parse_type == PARSE_BLOCKS ? BLOCK_SIZE : 1); } else if ( ! strncasecmp(cp, "k", 1) ) { multiplier = (parse_type == PARSE_BLOCKS ? KILO : KILO_10); } else if ( ! strncasecmp(cp, "m", 1) ) { multiplier = (parse_type == PARSE_BLOCKS ? MEGA : MEGA_10); } else if ( ! strncasecmp(cp, "g", 1) ) { multiplier = (parse_type == PARSE_BLOCKS ? GIGA : GIGA_10); } else if ( ! strncasecmp(cp, "t", 1) ) { multiplier = (parse_type == PARSE_BLOCKS ? TERA : TERA_10); } else { // default to blocks or inodes multiplier = (parse_type == PARSE_BLOCKS ? BLOCK_SIZE : 1); } /* calculate size (blocks or inodes) */ if (count == 0) { size = 0; } else if (parse_type == PARSE_BLOCKS) { size = (u_int64_t) (((double) count * multiplier - 1) / BLOCK_SIZE) + 1; } else { // inodes size = (u_int64_t) (count * multiplier); } switch (op) { case _PARSE_OP_ADD: return orig + size; case _PARSE_OP_SUB: return orig - size; default: return size; } } quotatool-1.8.0/src/parse.h000066400000000000000000000017551515710035100156270ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * parse.h * */ #ifndef INCLUDE_QUOTATOOL_PARSE #define INCLUDE_QUOTATOOL_PARSE 1 enum { PARSE_BLOCKS = 1, PARSE_INODES = 2 }; #include #include /* *BSD */ #include struct _argdata_t { char *id; char *qfile; short id_type; short silent; short noaction; short dump_info; // don't touch anything, just dump machine-readable info for user/group short raise_only; // When changing quotas, don't lower - just raise char *block_hard; char *block_soft; char *block_grace; short block_reset; char *inode_hard; char *inode_soft; char *inode_grace; short inode_reset; }; typedef struct _argdata_t argdata_t; argdata_t * parse_commandline (int argc, char **argv); time_t parse_timespan (time_t orig, char *string); u_int64_t parse_size (u_int64_t orig, char *string, int parse_type); #endif /* INCLUDE_QUOTATOOL_PARSE */ quotatool-1.8.0/src/quota.h000066400000000000000000000044031515710035100156370ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * quota.h * middle layer to talk to quotactl */ #ifndef INCLUDE_QUOTATOOL_QUOTA #define INCLUDE_QUOTATOOL_QUOTA #include "quotatool.h" #include /* Find out the system BLOCK_SIZE */ #if HAVE_LINUX_FS_H # include # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) # define BLOCK_SIZE 1024 # else # include # endif #elif HAVE_UFS_UFS_QUOTA_H # define BLOCK_SIZE 512 #else /* WARNING: Making up a block-size */ # define BLOCK_SIZE 1024 #endif /* Include system quota headers */ #if PLATFORM_LINUX # include # include "linux/linux_quota.h" # define QUOTA_USER USRQUOTA + 1 # define QUOTA_GROUP GRPQUOTA + 1 #elif HAVE_UFS_UFS_QUOTA_H /* FreeBSD || OpenBSD */ # include # include # define QUOTA_USER USRQUOTA + 1 # define QUOTA_GROUP GRPQUOTA + 1 #else # error "no quota headers found" #endif // Upwards integer division, always make room for remainder #define DIV_UP(a, b) ( (a) % (b) == 0 ? (a) / (b) : ((a) / (b) + 1)) // Convert bytes to system blocks #define BYTES_TO_BLOCKS(bytes) DIV_UP(bytes, BLOCK_SIZE) // Convert from system block-size to Kb. The constant 8 allows for BLOCK_SIZE >= 1024 / 8 (= 128 bytes) #define BLOCKS_TO_KB(num_blocks) ((BLOCK_SIZE == 1) ? DIV_UP(num_blocks, 1024) : DIV_UP((num_blocks) * ((BLOCK_SIZE * 8) / 1024), 8)) struct _quota_t { u_int64_t block_hard; u_int64_t block_soft; u_int64_t diskspace_used; u_int64_t inode_hard; u_int64_t inode_soft; u_int64_t inode_used; time_t block_time; time_t inode_time; time_t block_grace; time_t inode_grace; int _id; int _id_type; char * _qfile; int _do_set_global_block_gracetime; int _do_set_global_inode_gracetime; void * _v0_quotainfo; void * _generic_quotainfo; }; #define GRACE_BLOCK 1 #define GRACE_INODE 2 typedef struct _quota_t quota_t; quota_t * quota_new (int q_type, int id, char *device); void quota_delete (quota_t *myquota); int quota_get (quota_t *myquota); int quota_set (quota_t *myquota); int quota_reset_grace(quota_t *myquota, int grace_type); #endif /* INCLUDE_QUOTATOOL_QUOTA */ quotatool-1.8.0/src/quotatool.h000066400000000000000000000006531515710035100165400ustar00rootroot00000000000000/* * quotatool.h * system-wide definitions */ #ifndef INCLUDE_QUOTATOOL #define INCLUDE_QUOTATOOL 1 #include /* error codes */ #define ERR_PARSE 1 #define ERR_ARG 2 #define ERR_SYS 3 #define ERR_MEM 4 #if HAVE_U_INT64_T == 0 typedef unsigned long long int u_int64_t; #endif /* check for BSD variants */ #define ANY_BSD (__FreeBSD__ || __FreeBSD_kernel__ || __OpenBSD__) #endif /* INCLUDE_QUOTATOOL */ quotatool-1.8.0/src/system.c000066400000000000000000000140401515710035100160230ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * system.c * interact with various system databases */ #include #include #include #include #include #include #include #if HAVE_MNTENT_H # include # define MOUNTFILE "/etc/mtab" # define mnt_special mnt_fsname # define mnt_mountp mnt_dir #elif HAVE_FSTAB_H /* *BSD && ! GNU/kFreeBSD */ # include # define MOUNTFILE _PATH_FSTAB #endif #if HAVE_FSTAB_H /* *BSD */ struct mntent { char *mnt_fsname; char *mnt_dir; char *mnt_special; char *mnt_mountp; }; #endif /* *BSD */ #include #include "output.h" #include "quotatool.h" #include "system.h" /* * system_getfs * find and verify the device file for * a given filesystem */ fs_t *system_getfs (char *fs_spec) { struct mntent *current_fs; FILE *etc_mtab; fs_t *ent; int done; #if HAVE_FSTAB_H /* *BSD */ struct fstab *entry; #endif ent = (fs_t *) malloc (sizeof(fs_t)); if ( ! ent ) { output_error ("Insufficient Memory"); exit (ERR_MEM); } #if HAVE_FSTAB_H /* *BSD */ if (! setfsent()) { output_error("Failed opening fstab: %s", strerror(errno)); return NULL; } current_fs = (struct mntent*) malloc(sizeof(struct mntent)); if (! current_fs) { output_error("Out of memory"); exit (ERR_MEM); } #else etc_mtab = setmntent (MOUNTFILE, "r"); if ( ! etc_mtab ) { output_error ("Failed opening %s for reading: %s", MOUNTFILE, strerror(errno)); return NULL; } #endif output_debug ("Looking for fs_spec '%s'", fs_spec); done = 0; /* loop through mtab until we get a match */ do { /* read the next entry */ #if HAVE_MNTENT_H current_fs=getmntent(etc_mtab); if ( ! current_fs ) { #elif HAVE_FSTAB_H /* *BSD */ if ( ((entry = getfsfile(fs_spec)) != NULL) || ((entry = getfsspec(fs_spec)) != NULL)) { current_fs->mnt_special = strdup(entry->fs_spec); current_fs->mnt_mountp = strdup(entry->fs_file); done = 1; } else { free(current_fs); #endif output_error ("Filesystem %s does not exist", fs_spec); return NULL; } output_debug ("Checking device '%s', mounted at '%s'", current_fs->mnt_special, current_fs->mnt_mountp); /* Ignore 'rootfs' if looking for mountpoint '/' - created and mounted by Linux initramfs */ if (strcmp("/", fs_spec) == 0 && strcmp(current_fs->mnt_special, "rootfs") == 0) { output_debug ("Ignoring initramfs 'rootfs'\n"); continue; } /* does the name given match the mount pt or device file ? */ if ( ! strcmp(current_fs->mnt_special, fs_spec) || ! strcmp(current_fs->mnt_mountp, fs_spec) ) { #if HAVE_MNTENT_H #define LOOP_PREFIX "loop=" char *loopd_start = NULL, *loopd_end = NULL; #if PLATFORM_LINUX strncpy(ent->mnt_type, current_fs->mnt_type, PATH_MAX-1); ent->mnt_type[PATH_MAX-1] = '\0'; #endif if ((loopd_start = strstr(current_fs->mnt_opts, LOOP_PREFIX "/")) != NULL) { loopd_start += strlen(LOOP_PREFIX); output_debug("%s looks like a loop device, trying to grok opts: %s", current_fs->mnt_special, current_fs->mnt_opts); for (loopd_end = loopd_start; *loopd_end != '\0' && *loopd_end != ','; loopd_end++); if (loopd_end > loopd_start) { strncpy(ent->device, loopd_start, loopd_end - loopd_start); ent->device[loopd_end - loopd_start] = '\0'; output_debug("found loop device %s", ent->device); } else { output_error("%s seems like a loop device but I " "can't grok the device from opts: %s\n", current_fs->mnt_special, current_fs->mnt_opts); endmntent(etc_mtab); return NULL; } } else { #endif /* HAVE_MNTENT_H */ strncpy (ent->device, current_fs->mnt_special, PATH_MAX-1); ent->device[PATH_MAX-1] = '\0'; strncpy (ent->mount_pt, current_fs->mnt_mountp, PATH_MAX-1); ent->mount_pt[PATH_MAX-1] = '\0'; #if HAVE_MNTENT_H } #endif done = 1; continue; } } while ( ! done ) ; /* can we write to the device? */ #if HAVE_FSTAB_H /* *BSD */ // BSD: fs_type can be 'ro', 'rw', 'sw' (swap) or 'xx' (ignore) - we want 'rw' if (! strstr(entry->fs_type, "rw")) { output_error ("Filesystem %s is mounted read-only\n", fs_spec); if (current_fs->mnt_special) free(current_fs->mnt_special); if (current_fs->mnt_mountp) free(current_fs->mnt_mountp); free(current_fs); endfsent(); #else if ( hasmntopt(current_fs, "ro") ) { output_error ("Filesystem %s is mounted read-only\n", fs_spec); endmntent (etc_mtab); #endif return NULL; } /* we're good -- cleanup and return */ output_info ("filesystem %s has device node %s", fs_spec, ent->device); #if HAVE_FSTAB_H /* *BSD */ if (current_fs->mnt_special) free(current_fs->mnt_special); if (current_fs->mnt_mountp) free(current_fs->mnt_mountp); free(current_fs); endfsent(); #else endmntent (etc_mtab); #endif return ent; } /* * system_getuser * get the uid of the given user (or uid) */ uid_t system_getuid (char *user) { struct passwd *pwent; int uid; char *temp_str; /* seach by name first */ pwent = getpwnam (user); if ( pwent == NULL ) { /* maybe we were given a numerical id */ uid = strtol(user, &temp_str, 10); pwent = getpwuid ((uid_t) uid); if ( (user == temp_str) || ( pwent == NULL ) ) { output_error ("User %s does not exist\n", user); return -1; } } output_info ("user '%s' has uid %d", user, pwent->pw_uid); return (pwent->pw_uid); } gid_t system_getgid (char *group) { struct group *grent; int gid; char *temp_str; /* check for group name first */ grent = getgrnam (group); if ( grent == NULL ) { gid = strtol(group, &temp_str, 10); grent = getgrgid ((gid_t) gid); // numeric gid if ( (group == temp_str) || ( grent == NULL ) ) { output_error ("Group %s does not exist\n", group); return (gid_t) -1; } } output_info ("group '%s' has gid %d", group, grent->gr_gid); return (grent->gr_gid); } quotatool-1.8.0/src/system.h000066400000000000000000000013201515710035100160250ustar00rootroot00000000000000/* * Mike Glover * mpg4@duluoz.net * * Johan Ekenberg * johan@ekenberg.se * * system.h * interact with various system databases */ #ifndef INCLUDE_SYSTEM #define INCLUDE_SYSTEM 1 #include #if HAVE_LIMITS_H # include #else # warn "ignorantly setting PATH_MAX" # define PATH_MAX 256 #endif #include /* for [gu]id_t */ struct _fs_t { char device[PATH_MAX]; char mount_pt[PATH_MAX]; #if PLATFORM_LINUX char mnt_type[PATH_MAX]; /* xfs, reiserfs, ext2 etc */ #endif /* PLATFORM_LINUX */ }; typedef struct _fs_t fs_t; fs_t * system_getfs (char *fs_spec); uid_t system_getuid (char *user); gid_t system_getgid (char *group); #endif /* INCLUDE_SYSTEM */ quotatool-1.8.0/steps/000077500000000000000000000000001515710035100147035ustar00rootroot00000000000000quotatool-1.8.0/steps/01-testing.org000066400000000000000000001416251515710035100173200ustar00rootroot00000000000000#+TITLE: M1: Multi-Kernel Test Framework — Step Plan #+DATE: 2026-03-08 (completed 2026-03-15) *Status: DONE.* All phases complete. Branch =m1-testing= pushed. Merges to =master= as part of v1.7.0 release (after M3 bug fixes). * Overview Build a local-first, CI-agnostic test framework that tests quotatool across 15-20+ Linux kernel versions (including vendor-patched kernels) and two filesystem types (ext4, XFS). Architecture: #+begin_example test/ ← workspace (all test framework code) run-tests ← entry point: "run one command, get results" lib/ boot.sh ← kernel boot layer (virtme-ng / raw QEMU) fs-setup.sh ← loopback filesystem create/mount/teardown tap.sh ← TAP output helpers tests/ t-block-limits.sh ← individual test scripts t-inode-limits.sh t-grace-period.sh ... kernels/ kernels.conf ← matrix definition (name, vmlinuz path, boot method) download.sh ← fetch + extract vendor kernels initramfs/ ← custom initramfs for legacy kernels results/ ← output (gitignored) .github/workflows/test.yml ← thin CI wrapper (calls run-tests) .cirrus.yml ← FreeBSD testing #+end_example Background: =research/testing-infrastructure.org=, =research/multi-kernel-testing.org=, =research/quotatool-build-analysis.org= Key finding: quotatool ships its own quota struct definitions (=src/linux/linux_quota.h=, =xfs_quota.h=, =dqblk_old.h=, =dqblk_v0.h=) and does runtime detection of the kernel's quota interface in =src/linux/quota.c:kern_quota_format()=. *One binary works across all kernel versions.* Build once, test everywhere. But the runtime detection code is the critical fragile point — it was last updated around the 4.x kernel era and likely needs fixes for modern kernels. * Progress tracking Each task has an org-mode TODO keyword: =TODO=, =DOING=, =WAITING=, =DONE=, =CANCELLED=. Update status in this file at every checkpoint. This file is the single source of truth for M1 progress. * Phase 1: Foundation [3/5] Minimal working loop: boot ONE kernel, run ONE test, get a result. Everything else builds on this. ** DONE 1.1 Create workspace and directory structure Set up =test/= directory tree as shown above. Skeleton files only. /Verification/: =ls -R test/= shows expected layout. ** DONE 1.2 Build the kernel boot layer (=test/lib/boot.sh=) A function that takes a kernel path and a test script, boots QEMU, runs the script inside the VM, returns exit code + stdout. Two code paths: - *Modern (≥5.4)*: virtme-ng with virtiofs - *Legacy (<5.4)*: raw QEMU with =-kernel=, custom initramfs, 9p filesystem sharing (msize=524288) - *RHEL (no 9p)*: raw QEMU with virtio-blk rootfs disk image /Subtasks/: - [ ] Detect virtme-ng availability, fall back to raw QEMU - [ ] Modern path: =vng -r --disk --