1
0
mirror of https://repo.or.cz/libtar.git synced 2025-04-18 05:04:01 +03:00

libtar-1.2.11 tarball sources, taken from Debian's orig tar

The main site, feep.net, has a broken ftp link, so can't download
tarball from there.
This commit is contained in:
Chris Frey 2009-04-28 16:35:00 -04:00
commit 1fc76aab90
70 changed files with 26812 additions and 0 deletions

3
.cvsignore Normal file
View File

@ -0,0 +1,3 @@
autom4te.cache
config.h.in
configure

35
COPYRIGHT Normal file
View File

@ -0,0 +1,35 @@
Copyright (c) 1998-2003 University of Illinois Board of Trustees
Copyright (c) 1998-2003 Mark D. Roth
All rights reserved.
Developed by: Campus Information Technologies and Educational Services,
University of Illinois at Urbana-Champaign
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal with the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of Campus Information Technologies and Educational
Services, University of Illinois at Urbana-Champaign, nor the names
of its contributors may be used to endorse or promote products derived
from this Software without specific prior written permission.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.

243
ChangeLog Normal file
View File

@ -0,0 +1,243 @@
libtar 1.2.11 - 3/2/03
-------------
- updated autoconf macros, compat code, and listhash code
- fixed tar_extract_regfile() to pass mode argument to open()
(caused EPERM on Solaris NFS clients)
- updated README
------------------------------------------------------------------------------
libtar 1.2.10 - 12/15/02
-------------
- updated README
- minor Makefile fixes
- fixed TH_ISREG() macro to not return true for hard links
------------------------------------------------------------------------------
libtar 1.2.9 - 11/19/02
------------
- fixed th_read() to return 1 on EOF
(thanks to Yves Crespin <Crespin.Quartz@WANADOO.FR> for the bug report)
- minor portability fixes
(thanks to Yves Crespin <Crespin.Quartz@WANADOO.FR> for the bug report)
- fixed segfault on extracting filenames with 8-bit ASCII characters
(thanks to Per Liden <per@FUKT.BTH.SE> for the patch)
- fixed TH_ISDIR() macro and th_get_mode() function to handle old
archives that don't set the typeflag field right for directories
- use 0777 instead of 0755 in mkdirhier()
(thanks to Yves Crespin <Crespin.Quartz@WANADOO.FR> for the bug report)
------------------------------------------------------------------------------
libtar 1.2.8 - 9/13/02
------------
- added "-I../listhash" to CPPFLAGS in libtar/Makefile.in
(thanks to Kris Warkentin <kewarken@QNX.COM> for the bug report)
- added .PHONY target to Makefile.in
(thanks to Steven Engelhardt <sengelha@YAHOO.COM> for the bug report)
------------------------------------------------------------------------------
libtar 1.2.7 - 9/12/02
------------
- fixed minor bugs in listhash code
(thanks to Jim Knoble <jmknoble@pobox.com> for the bug reports)
------------------------------------------------------------------------------
libtar 1.2.6 - 9/10/02
------------
- updated COPYRIGHT file
- do not check magic field by default
(replaced TAR_IGNORE_MAGIC option with TAR_CHECK_MAGIC to enable check)
- fixed th_get_mode() not to modify S_IFMT bits if they were already set
- fixed TH_IS*() macros to check the S_IFMT mode bits in addition to typeflag
(this allows us to handle old tar archives that set mode bits but not
typeflag field for directories and other special files)
- updated to autoconf-2.53
- restructured autoconf macros
- added "b" to gzoflags in gzopen_frontend() for win32 compatibility
(thanks to Kris Eric Warkentin <kewarken@QNX.COM> for reporting this)
- if O_BINARY is defined (as on win32), set that bit in oflags in tar_open()
(thanks to Kris Eric Warkentin <kewarken@QNX.COM> for reporting this)
- also use O_BINARY in when calling open() from tar_extract_regfile()
(based on patch from Graeme Peterson <gp@qnx.com>)
- added COMPAT_FUNC_MAKEDEV macro to handle 3-arg version of makedev()
(based on patch from Graeme Peterson <gp@qnx.com>)
------------------------------------------------------------------------------
libtar 1.2.5 - 2/20/02
------------
- updated to autoconf-2.52
- improved Makefile portability
- fixed memory leak in hard-link detection code
(thanks to Michael Kamp <kamp@HITT.NL> for the bug report)
- fixed memory leak in symlink handling code
(thanks to Michael Kamp <kamp@HITT.NL> for the bug report)
- fixed memory leak in GNU long filename code
------------------------------------------------------------------------------
libtar 1.2.4 - 7/24/01
------------
- code cleanups to make gcc -Wall happy
(thanks to Jim Knoble <jmknoble@POBOX.COM> for the patch)
- call utime() before chmod() in tar_set_file_perms() for cygwin
(thanks to Kris Eric Warkentin <kewarken@QNX.COM> for reporting this)
- added "-g" flag to trigger GNU extensions in libtar binary
- fixed buffer termination bugs in POSIX filename prefix encoding
(thanks to Joerg Schilling <schilling@fokus.gmd.de> for reporting this)
- fixed bug in th_crc_calc() for filenames with 8-bit ASCII characters
(thanks to Hamdouni El Bachir <bach@zehc.net> for reporting the bug
and Antoniu-George SAVU <santoniu@libertysurf.fr> for the patch)
- fixed backwards conditional expression in th_read()
(thanks to Antoniu-George SAVU <santoniu@LIBERTYSURF.FR> for the patch)
- added new tar_open() options to replace compile-time settings:
TAR_IGNORE_EOT, TAR_IGNORE_MAGIC, TAR_CHECK_VERSION, TAR_IGNORE_CRC
(based on feedback from Kris Eric Warkentin <kewarken@QNX.COM>)
------------------------------------------------------------------------------
libtar 1.2.3 - 6/26/01
------------
- misc portability fixes for OpenBSD
- fixed libtar.h to work with C++ programs
- fixed tar_extract_file() to properly check for pre-existing symlinks
(based on patch from Per Lid?n <per@fukt.hk-r.se>)
- fixed hash creation in tar_init()
- replaced mkdirhier() with non-recursive version
- updated autoconf macros, compat code, and listhash code
- reformatted code for readability
------------------------------------------------------------------------------
libtar 1.2.2 - 1/12/01
------------
- fixed th_print_long_ls() to not truncate user and group names
- code cleanups to make -Wall happy
------------------------------------------------------------------------------
libtar 1.2.1 - 1/8/01
------------
- updated WSG_ENCAP autoconf macro
- fixed autoconf macros to behave properly when a config.cache file
is present
- fixed doc/Makefile.in to create links during compilation, not
installation
- fixed listhash manpage .so link lists
------------------------------------------------------------------------------
libtar 1.2 - 1/4/01
----------
- minor code cleanups
------------------------------------------------------------------------------
libtar 1.1.b8 - 1/2/01
-------------
- updated WSG_ENCAP autoconf macro
------------------------------------------------------------------------------
libtar 1.1.b7 - 12/13/00
-------------
- fixed autoconf snprintf() test to make sure it NUL-terminates
------------------------------------------------------------------------------
libtar 1.1.b6 - 11/30/00
-------------
- added $(DESTDIR) to Makefiles
- Makefile changes to support WSG_PKG and WSG_ENCAP autoconf macros
- changed lib/output.c to use strftime() where available
------------------------------------------------------------------------------
libtar 1.1.b5 - 10/29/00
-------------
- Makefile fix
------------------------------------------------------------------------------
libtar 1.1.b4 - 10/29/00
-------------
- more directory reorganization
- minor Makefile cleanups
- minor portability fixes
- added function typecasting to avoid compiler warnings
------------------------------------------------------------------------------
libtar 1.1.b3 - 10/26/00
-------------
- updated aclocal.m4
- updated README
- updated manpages
- minor directory structure changes because of CVS setup
------------------------------------------------------------------------------
libtar 1.1.b2 - 10/5/00
-------------
- added --without-zlib configure option
- minor portability fixes
------------------------------------------------------------------------------
libtar 1.1.b1 - 8/21/00
-------------
- API changes:
- implemented tar_fdopen()
- implemented tar_fd()
- added TAR **t argument to tar_open() instead of returning dynamic memory
- if TAR_NOOVERWRITE is set in options and O_CREAT is set in oflags,
tar_open() automatically sets O_EXCL as well
------------------------------------------------------------------------------
libtar 1.1.b0 - 7/10/00
-------------
- API changes:
- replaced internal table of tar file types with a tartype_t passed to
tar_open() by the caller
(allows file access methods to be defined dynamically)
- fixed tar_append_tree() to grok normal files as well as directories
- replaced mk_dirs_for_file() with mkdirhier() from epkg
- replaced strtok_r() with strsep()
- updated list/hash code to new interface
- autoconf changes:
- added aclocal.m4 to clean up configure.in
- minor portability fixes related to lib/fnmatch.c
- fixed a bug in tar_open() where the result of open() was being
checked for 0 instead of -1 to detect error
- updated libtar driver program to handle both .tar.gz and ordinary .tar
via the -z option

141
ChangeLog-1.0.x Normal file
View File

@ -0,0 +1,141 @@
libtar 1.0.2 - 6/21/00
------------
- tar_set_file_perms() now calls chown() only if the effective user ID is 0
(workaround for IRIX and HP-UX, which allow file giveaways)
- tar_set_file_perms() now calls chmod() or lchmod() after chown()
(this fixes a problem with extracting setuid files under Linux)
- removed calls to fchown() and fchmod() from tar_extract_regfile()
- fixed bugs in th_read() which didn't set errno properly
- removed various unused variables
----------------------------------------------------------------------
libtar 1.0.1 - 4/1/00
------------
- removed libgen.h include from dirname and basename compat code
- added lib/fnmatch.c compatability module from OpenBSD
- fixed several objdirs bugs in libtar/Makefile.in
- misc Makefile changes (added $CPPFLAGS support, added -o flag to compile
commands, use $CFLAGS on link line, etc)
- removed "inline" keyword from all source files to prevent portability
problems
- updated README
----------------------------------------------------------------------
libtar 1.0 - 1/2/00
----------
- various portability fixes
- "make install" now runs mkencap and epkg if they're available
- libmisc is now integrated into libtar
----------------------------------------------------------------------
libtar 0.5.6 beta - 12/16/99
-----------------
- changed API to allow better error reporting via errno
- added manpages to document libtar API
- replaced symbolic_mode() call with strmode() compatibility code
----------------------------------------------------------------------
libtar 0.5.5 beta - 11/16/99
-----------------
- fixed conditional expression in extract.c to check if we're overwriting
a pre-existing file
- many improvements to libtar.c driver program (better error checking,
added -C and -v options, etc)
- changed API to include list of canned file types, instead of passing
function pointers to tar_open()
- fixed tar_set_file_perms() to not complain about chown() if not root
and not to call utime() on a symlink
- added hash code for extracting hard links in other directory paths
- fixed tar_extract_glob() to only print filenames if TAR_VERBOSE option
is set
- replaced GNU basename(), dirname(), and strdup() compatibility code
with OpenBSD versions
- configure performs super-anal checking of basename() and dirname()
----------------------------------------------------------------------
libtar 0.5.4 beta - 11/13/99
-----------------
- portability fix: use ranlib instead of ar -s
- misc fixes in append.c, extract.c, and wrapper.c to do error checking
- fixed a bug in tar_append_file() in append.c which added some garbage
characters to encoded symlink names (wasn't NULL-terminating the result
of readlink())
- fixed a bug in symbolic_mode() in output.c concerning setuid and setgid
bit displaying
- fixed tar_extract_all() in wrapper.c to only call print_long_ls() if
the TAR_VERBOSE option is set
- added libtar_version constant string to handle.c for external configure
scripts to detect what version of libtar is installed
----------------------------------------------------------------------
libtar 0.5.3 beta - 09/27/99
-----------------
- fixed mk_dirs_for_file() to avoid broken dirname() implementations
- misc portability fixes
- merged old "compat" and "libds" directories into new "misc" directory
and cleaned up Makefiles
----------------------------------------------------------------------
libtar 0.5.2 beta - 09/10/99
-----------------
- use calloc() instead of malloc() in tar_open() to fix a bounds-checking
bug in tar_extract_all()
- fix tar_extract_all() to properly honor the prefix argument
----------------------------------------------------------------------
libtar 0.5.1 beta - 08/27/99
-----------------
- misc portability fixes
----------------------------------------------------------------------
libtar 0.5 beta - 07/05/99
---------------
- first public release

183
INSTALL Normal file
View File

@ -0,0 +1,183 @@
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 awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
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.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
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. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--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.

51
Makefile.in Normal file
View File

@ -0,0 +1,51 @@
# @configure_input@
### Path settings
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
libdir = @libdir@
includedir = @includedir@
top_srcdir = @top_srcdir@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@ENCAP_DEFS@
@SET_MAKE@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
SUBDIRS = lib libtar doc
all:
for n in $(SUBDIRS); do \
( cd $$n && $(MAKE) $@ $(MAKE_FLAGS) ) || exit 1; \
done
.PHONY: install install-recurse postinstall-encap clean distclean
install: install-recurse @ENCAP_INSTALL_TARGET@
install-recurse:
for n in $(SUBDIRS); do \
( cd $$n && $(MAKE) install $(MAKE_FLAGS) ) || exit 1; \
done
postinstall-encap:
@ENCAP_INSTALL_RULES@
clean:
for n in $(SUBDIRS); do \
( cd $$n && $(MAKE) $@ $(MAKE_FLAGS) ) || exit 1; \
done
distclean:
for n in $(SUBDIRS); do \
( cd $$n && $(MAKE) $@ $(MAKE_FLAGS) ) || exit 1; \
done
rm -f config.cache config.log config.status config.h Makefile

121
README Normal file
View File

@ -0,0 +1,121 @@
libtar - C library for manipulating tar files
======
libtar is a library for manipulating tar files from within C programs.
Here are some of its features:
* Handles both POSIX tar file format and the GNU extensions.
* API provides functions for easy use, such as tar_extract_all().
* Also provides functions for more granular use, such as
tar_append_regfile().
Installation
------------
To build libtar, you should be able to simply run these commands:
./configure
make
make install
Encap Package Support
---------------------
To build this software as an Encap package, you can pass the
--enable-encap option to configure. This will be automatically
enabled if the epkg or mkencap programs are detected on the system,
but can be overridden by the --disable-encap option.
When building an Encap package, the configure script will automatically
adjust the installation prefix to use an appropriate Encap package
directory. It does this using a heuristic algorithm which examines the
values of the ${ENCAP_SOURCE} and ${ENCAP_TARGET} environment variables
and the argument to configure's --prefix option.
If mkencap was detected on the system, it will be automatically run during
"make install". By default, epkg will also be run, but this can be
inhibited with the --disable-epkg-install configure option.
For information on the Encap package management system, see the WSG
Encap Archive:
http://www.encap.org/
zlib Support
------------
The configure script will attempt to find the zlib library on your system
for use with the libtar driver program. The zlib package is available from:
http://www.gzip.org/zlib/
If zlib is installed on your system, but you do not wish to use it,
specify the --without-zlib option when you invoke configure.
More Information
----------------
For documentation of the libtar API, see the enclosed manpages. For more
information on the libtar package, see:
http://www-dev.cites.uiuc.edu/libtar/
Source code for the latest version of libtar will be available there, as
well as Encap binary distributions for many common platforms.
Supported Platforms
-------------------
I develop and test libtar on the following platforms:
AIX 4.3.3 and 5.1
HP-UX 11.00
IRIX 6.5
RedHat Linux 7.2
Solaris 8 and 9
It should also build on the following platforms, but I do not actively
support them:
AIX 3.2.5
AIX 4.2.1
Cygwin
FreeBSD
HP-UX 10.20
Linux/libc5
OpenBSD
Solaris 2.5
Solaris 2.6
Solaris 7
If you successfully build libtar on another platform, please email me a
patch and/or configuration information.
Compatibility Code
------------------
libtar depends on some library calls which are not available or not
usable on some platforms. To accomodate these systems, I've included
a version of these calls in the compat subdirectory.
I've slightly modified these functions for integration into this source
tree, but the functionality has not been modified from the original
source. Please note that while this code should work for you, I didn't
write it, so please don't send me bug reports on it.
Author
------
Feedback and bug reports are welcome.
Mark D. Roth <roth@uiuc.edu>
Campus Information Technologies and Educational Services
University of Illinois at Urbana-Champaign

10
TODO Normal file
View File

@ -0,0 +1,10 @@
* library API:
- revamp API (make analogs for Unix fs access calls)
- add dircache list to tar handle
- support star format(s)?
- add support for POSIX.1-2001 pax format
- large file support?
- support reading from tape devices with different block sizes?
* libtar program:
- make the libtar program a much more fully-featured tar
- move output.c and wrapper.c from lib directory to libtar directory

136
autoconf/ac_path_generic.m4 Normal file
View File

@ -0,0 +1,136 @@
dnl @synopsis AC_PATH_GENERIC(LIBRARY [, MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl
dnl Runs a LIBRARY-config script and defines LIBRARY_CFLAGS and LIBRARY_LIBS
dnl
dnl The script must support `--cflags' and `--libs' args.
dnl If MINIMUM-VERSION is specified, the script must also support the
dnl `--version' arg.
dnl If the `--with-library-[exec-]prefix' arguments to ./configure are given,
dnl it must also support `--prefix' and `--exec-prefix'.
dnl (In other words, it must be like gtk-config.)
dnl
dnl For example:
dnl
dnl AC_PATH_GENERIC(Foo, 1.0.0)
dnl
dnl would run `foo-config --version' and check that it is at least 1.0.0
dnl
dnl If so, the following would then be defined:
dnl
dnl FOO_CFLAGS to `foo-config --cflags`
dnl FOO_LIBS to `foo-config --libs`
dnl
dnl At present there is no support for additional "MODULES" (see AM_PATH_GTK)
dnl (shamelessly stolen from gtk.m4 and then hacked around a fair amount)
dnl
dnl @author Angus Lees <gusl@cse.unsw.edu.au>
dnl @version $Id: ac_path_generic.m4,v 1.1.4.1 2002/09/06 19:43:55 roth Exp $
AC_DEFUN([AC_PATH_GENERIC],
[dnl
dnl we're going to need uppercase, lowercase and user-friendly versions of the
dnl string `LIBRARY'
pushdef([UP], translit([$1], [a-z], [A-Z]))dnl
pushdef([DOWN], translit([$1], [A-Z], [a-z]))dnl
dnl
dnl Get the cflags and libraries from the LIBRARY-config script
dnl
AC_ARG_WITH(DOWN-prefix,[ --with-]DOWN[-prefix=PFX Prefix where $1 is installed (optional)],
DOWN[]_config_prefix="$withval", DOWN[]_config_prefix="")
AC_ARG_WITH(DOWN-exec-prefix,[ --with-]DOWN[-exec-prefix=PFX Exec prefix where $1 is installed (optional)],
DOWN[]_config_exec_prefix="$withval", DOWN[]_config_exec_prefix="")
if test x$DOWN[]_config_exec_prefix != x ; then
DOWN[]_config_args="$DOWN[]_config_args --exec-prefix=$DOWN[]_config_exec_prefix"
if test x${UP[]_CONFIG+set} != xset ; then
UP[]_CONFIG=$DOWN[]_config_exec_prefix/bin/DOWN-config
fi
fi
if test x$DOWN[]_config_prefix != x ; then
DOWN[]_config_args="$DOWN[]_config_args --prefix=$DOWN[]_config_prefix"
if test x${UP[]_CONFIG+set} != xset ; then
UP[]_CONFIG=$DOWN[]_config_prefix/bin/DOWN-config
fi
fi
AC_PATH_PROG(UP[]_CONFIG, DOWN-config, no)
ifelse([$2], ,
AC_MSG_CHECKING(for $1),
AC_MSG_CHECKING(for $1 - version >= $2)
)
no_[]DOWN=""
if test "$UP[]_CONFIG" = "no" ; then
no_[]DOWN=yes
else
UP[]_CFLAGS="`$UP[]_CONFIG $DOWN[]_config_args --cflags`"
UP[]_LIBS="`$UP[]_CONFIG $DOWN[]_config_args --libs`"
ifelse([$2], , ,[
DOWN[]_config_major_version=`$UP[]_CONFIG $DOWN[]_config_args \
--version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
DOWN[]_config_minor_version=`$UP[]_CONFIG $DOWN[]_config_args \
--version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
DOWN[]_config_micro_version=`$UP[]_CONFIG $DOWN[]_config_args \
--version | sed 's/[[^0-9]]*\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
DOWN[]_wanted_major_version="regexp($2, [\<\([0-9]*\)], [\1])"
DOWN[]_wanted_minor_version="regexp($2, [\<\([0-9]*\)\.\([0-9]*\)], [\2])"
DOWN[]_wanted_micro_version="regexp($2, [\<\([0-9]*\).\([0-9]*\).\([0-9]*\)], [\3])"
# Compare wanted version to what config script returned.
# If I knew what library was being run, i'd probably also compile
# a test program at this point (which also extracted and tested
# the version in some library-specific way)
if test "$DOWN[]_config_major_version" -lt \
"$DOWN[]_wanted_major_version" \
-o \( "$DOWN[]_config_major_version" -eq \
"$DOWN[]_wanted_major_version" \
-a "$DOWN[]_config_minor_version" -lt \
"$DOWN[]_wanted_minor_version" \) \
-o \( "$DOWN[]_config_major_version" -eq \
"$DOWN[]_wanted_major_version" \
-a "$DOWN[]_config_minor_version" -eq \
"$DOWN[]_wanted_minor_version" \
-a "$DOWN[]_config_micro_version" -lt \
"$DOWN[]_wanted_micro_version" \) ; then
# older version found
no_[]DOWN=yes
echo -n "*** An old version of $1 "
echo -n "($DOWN[]_config_major_version"
echo -n ".$DOWN[]_config_minor_version"
echo ".$DOWN[]_config_micro_version) was found."
echo -n "*** You need a version of $1 newer than "
echo -n "$DOWN[]_wanted_major_version"
echo -n ".$DOWN[]_wanted_minor_version"
echo ".$DOWN[]_wanted_micro_version."
echo "***"
echo "*** If you have already installed a sufficiently new version, this error"
echo "*** probably means that the wrong copy of the DOWN-config shell script is"
echo "*** being found. The easiest way to fix this is to remove the old version"
echo "*** of $1, but you can also set the UP[]_CONFIG environment to point to the"
echo "*** correct copy of DOWN-config. (In this case, you will have to"
echo "*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf"
echo "*** so that the correct libraries are found at run-time)"
fi
])
fi
if test "x$no_[]DOWN" = x ; then
AC_MSG_RESULT(yes)
ifelse([$3], , :, [$3])
else
AC_MSG_RESULT(no)
if test "$UP[]_CONFIG" = "no" ; then
echo "*** The DOWN-config script installed by $1 could not be found"
echo "*** If $1 was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the UP[]_CONFIG environment variable to the"
echo "*** full path to DOWN-config."
fi
UP[]_CFLAGS=""
UP[]_LIBS=""
ifelse([$4], , :, [$4])
fi
AC_SUBST(UP[]_CFLAGS)
AC_SUBST(UP[]_LIBS)
popdef([UP])
popdef([DOWN])
])

199
autoconf/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,199 @@
m4_include([encap.m4])
m4_include([ac_path_generic.m4])
# PSG_LIB_READLINE
# ----------------
# Check for GNU readline library.
AC_DEFUN([PSG_LIB_READLINE], [
AC_CHECK_HEADERS([readline/readline.h])
AC_CHECK_HEADERS([readline/history.h])
if test "$ac_cv_header_readline_readline_h" = "yes"; then
AC_SEARCH_LIBS([tputs], [termcap curses])
AC_CHECK_LIB([readline], [rl_callback_handler_install])
fi
])
# PSG_LIB_TAR
# -----------
# Check for usable version of libtar library.
AC_DEFUN([PSG_LIB_TAR], [
psg_old_libs="$LIBS"
LIBS="$LIBS -ltar"
AC_CACHE_CHECK([for usable version of libtar],
[psg_cv_lib_tar_usable],
[AC_TRY_RUN([
#include <stdio.h>
#include <string.h>
#include <libtar.h>
int main(int argc, char *argv[]) {
return (strcmp(libtar_version, "1.2") >= 0 ? 0 : 1);
}
],
[psg_cv_lib_tar_usable=yes],
[psg_cv_lib_tar_usable=no],
[psg_cv_lib_tar_usable=no]
)]
)
if test "$psg_cv_lib_tar_usable" = "yes"; then
AC_DEFINE([HAVE_LIBTAR], 1,
[Define if your system has a current version of libtar])
else
LIBS="$psg_old_libs"
fi
])
# PSG_LIB_FGET
# ------------
# Check for usable version of libfget library.
AC_DEFUN([PSG_LIB_FGET], [
psg_old_libs="$LIBS"
AC_CHECK_LIB([socket], [socket])
AC_CHECK_LIB([nsl], [gethostbyname])
LIBS="$LIBS -lfget"
AC_CACHE_CHECK([for usable version of libfget],
[psg_cv_lib_fget_usable],
[AC_TRY_COMPILE([
#include <libfget.h>
], [
FTP *ftp;
char buf[10240];
struct ftp_url fu;
ftp_url_parse("ftp://host.com/dir/file.txt", &fu);
ftp_connect(&ftp, fu.fu_hostname, buf, sizeof(buf), 0, 0,
-1, -1, NULL, NULL);
],
[psg_cv_lib_fget_usable=yes],
[psg_cv_lib_fget_usable=no]
)]
)
if test "$psg_cv_lib_fget_usable" = "yes"; then
AC_DEFINE([HAVE_LIBFGET], 1,
[Define if your system has a current version of libfget])
else
LIBS="$psg_old_libs";
fi
])
# PSG_LIB_WRAP
# ------------
# Check for TCP Wrapper library.
AC_DEFUN([PSG_LIB_WRAP], [
AC_CHECK_HEADERS([tcpd.h])
if test "$ac_cv_header_tcpd_h" = "yes"; then
psg_old_libs="$LIBS"
LIBS="$LIBS -lwrap"
AC_CACHE_CHECK([for libwrap library],
[psg_cv_lib_wrap_hosts_ctl],
AC_TRY_LINK([
#include <stdio.h>
#include <tcpd.h>
int allow_severity;
int deny_severity;
], [
hosts_ctl("test", STRING_UNKNOWN, "10.0.0.1", STRING_UNKNOWN);
],
[psg_cv_lib_wrap_hosts_ctl=yes],
[psg_cv_lib_wrap_hosts_ctl=no]
)
)
if test "$psg_cv_lib_wrap_hosts_ctl" = "yes"; then
AC_DEFINE([HAVE_LIBWRAP], 1, [Define if you have libwrap])
else
LIBS="$psg_old_libs"
fi
fi
])
# PSG_REPLACE_TYPE(type_t, default, [includes])
# ---------------------------------------------
# Check for arbitrary type in arbitrary header file(s).
AC_DEFUN([PSG_REPLACE_TYPE],
[AC_CHECK_TYPES([$1],
,
[AC_DEFINE($1, $2,
[Define to `$2' if not defined in system header files.]
)],
$3
)]
)
# PSG_SHLIB(includes, code)
# -------------------------
# Check how to build shared libraries containing the specified code
# (very rudimentary).
AC_DEFUN([PSG_SHLIB], [
AC_MSG_CHECKING([how to build shared libraries])
cflag_options="-fpic";
ldflag_options="-G -shared";
if test "$CC" != "gcc"; then
case "`uname`" in
HP-UX)
cflag_options="+Z $cflag_options";
ldflag_options="-Wl,-b $ldflag_options";
;;
SunOS)
cflag_options="-Kpic $cflag_options";
;;
esac
fi
for SHLIB_CFLAGS in $cflag_options ""; do
for SHLIB_LDFLAGS in $ldflag_options ""; do
psg_old_cflags="$CFLAGS";
CFLAGS="$CFLAGS $SHLIB_CFLAGS";
psg_old_ldflags="$LDFLAGS";
LDFLAGS="$LDFLAGS $SHLIB_LDFLAGS";
AC_LINK_IFELSE([AC_LANG_SOURCE([[
$1
int
dummy(void)
{
$2
return 0;
}
]])],
[psg_cv_flags_shlib="CFLAGS=$SHLIB_CFLAGS LDFLAGS=$SHLIB_LDFLAGS"],
[psg_cv_flags_shlib=no]
)
CFLAGS="$psg_old_cflags";
LDFLAGS="$psg_old_ldflags";
if test "$psg_cv_flags_shlib" != "no"; then
break;
fi
done
if test "$psg_cv_flags_shlib" != "no"; then
break;
fi
done
if test "$psg_cv_flags_shlib" = "no"; then
SHLIB_CFLAGS="";
SHLIB_LDFLAGS="";
fi
AC_SUBST([SHLIB_CFLAGS])
AC_SUBST([SHLIB_LDFLAGS])
AC_MSG_RESULT([$psg_cv_flags_shlib])
])
# PSG_MODULE(subdir, [args, ...])
# -------------------------------
# Process the module.ac file in subdir. If the module.ac file defines a
# macro called subdir[]_INIT, call it with the arguments passed to
# PSG_MODULE().
AC_DEFUN([PSG_MODULE], [
m4_define([subdir], [$1])dnl
m4_include([$1/module.ac])dnl
m4_ifdef([$1][_INIT], [$1][_INIT($@)])dnl
m4_undefine([subdir])dnl
])

133
autoconf/encap.m4 Normal file
View File

@ -0,0 +1,133 @@
# ENCAP_PKG([mkencap-options], [install target if enabled],
# [install target if disabled])
# ---------------------------------------------------------
# Check for Encap tools.
AC_DEFUN([ENCAP_PKG], [
MKENCAP_OPTS=$1;
# allow user to disable Encap support
AC_ARG_ENABLE([encap],
[ --disable-encap Do not configure as an Encap package],
[],
[enable_encap=default])
if test "$enable_encap" != "no"; then
# look for epkg and mkencap
AC_PATH_PROG([EPKG], [epkg])
AC_PATH_PROG([MKENCAP], [mkencap])
# enable by default if epkg or mkencap are found
if test "${EPKG:+set}" = "set" || test "${MKENCAP:+set}" = "set" && test "$enable_encap" = "default"; then
enable_encap=yes;
fi
fi
if test "$enable_encap" = "yes"; then
# generate fallback values for ${ENCAP_SOURCE} and ${ENCAP_TARGET}
# from the environment or the default prefix
if test -z "${ENCAP_SOURCE}" && test -z "${ENCAP_TARGET}"; then
ENCAP_SOURCE="${ac_default_prefix}/encap";
ENCAP_TARGET="${ac_default_prefix}";
elif test -z "${ENCAP_TARGET}"; then
ENCAP_TARGET="`dirname ${ENCAP_SOURCE}`";
elif test -z "${ENCAP_SOURCE}"; then
ENCAP_SOURCE="${ENCAP_TARGET}/encap";
fi
# if --prefix is specified:
# 1) if its next-to-last component is "encap", assume that it
# points to the package directory
# 2) otherwise, assume it points to the target directory
if test "${prefix}" != "NONE"; then
prefixdir="`dirname ${prefix}`";
prefixbase="`basename ${prefix}`";
if test "`basename ${prefixdir}`" = "encap"; then
ENCAP_SOURCE="${prefixdir}";
ENCAP_TARGET="`dirname ${ENCAP_SOURCE}`";
elif test "${prefixdir}" != "${ENCAP_SOURCE}"; then
ENCAP_SOURCE="${prefix}/encap";
ENCAP_TARGET="${prefix}";
fi
if ( test "`basename ${prefixdir}`" = "encap" || \
test "${prefixdir}" = "${ENCAP_SOURCE}" ) && \
test "${prefixbase}" != "${PACKAGE_NAME}-${PACKAGE_VERSION}"; then
ENCAP_PKGSPEC="${prefixbase}";
fi
fi
# display results
AC_MSG_CHECKING([for Encap source directory])
AC_MSG_RESULT([${ENCAP_SOURCE}])
AC_MSG_CHECKING([for Encap target directory])
AC_MSG_RESULT([${ENCAP_TARGET}])
AC_MSG_CHECKING([for Encap package directory])
if test "${ENCAP_PKGSPEC:-unset}" = "unset"; then
ENCAP_PKGSPEC='${PACKAGE_NAME}-${PACKAGE_VERSION}';
AC_MSG_RESULT([${ENCAP_SOURCE}/${PACKAGE_NAME}-${PACKAGE_VERSION}])
else
AC_MSG_RESULT([${ENCAP_SOURCE}/${ENCAP_PKGSPEC}])
fi
prefix='${ENCAP_SOURCE}/${ENCAP_PKGSPEC}';
# override default sysconfdir and localstatedir
if test "$sysconfdir" = '${prefix}/etc'; then
sysconfdir='${ENCAP_TARGET}/etc';
fi
if test "$localstatedir" = '${prefix}/var'; then
localstatedir='/var/lib/${PACKAGE_NAME}';
fi
# check for --disable-epkg-install
AC_ARG_ENABLE([epkg-install],
[ --disable-epkg-install Do not run epkg during make install],
[],
[enable_epkg_install=yes])
if test "$enable_epkg_install" = "no"; then
EPKG=":";
fi
# generate Makefile variables
dnl AC_SUBST([ENCAP_SOURCE])
dnl AC_SUBST([ENCAP_TARGET])
dnl AC_SUBST([ENCAP_PKGSPEC])
dnl AC_SUBST([EPKG])
dnl AC_SUBST([MKENCAP])
dnl AC_SUBST([MKENCAP_OPTS])
dnl
dnl m4_ifdef([EM_MAKEFILE_END], [
dnl # generate rules for make install target
dnl EM_MAKEFILE_END([[
dnl target modify <install>:
dnl command \\\${MKENCAP} \\\`test -f \\\${srcdir}/COPYRIGHT && echo -I \\\${srcdir}/COPYRIGHT\\\` \\\${MKENCAP_OPTS} -s \\\${DESTDIR}\\\${ENCAP_SOURCE} -e \\\${ENCAP_PKGSPEC}
dnl command if test -z \\\\\"\\\${DESTDIR}\\\\\"; then \
dnl \\\${EPKG} -s \\\${ENCAP_SOURCE} -t \\\${ENCAP_TARGET} \\\${ENCAP_PKGSPEC}; \
dnl fi
dnl ]])])
ENCAP_DEFS="ENCAP_SOURCE = ${ENCAP_SOURCE}\\
ENCAP_TARGET = ${ENCAP_TARGET}\\
ENCAP_PKGSPEC = ${ENCAP_PKGSPEC}\\
EPKG = ${EPKG:-:}\\
MKENCAP = ${MKENCAP:-:}\\
MKENCAP_OPTS = ${MKENCAP_OPTS}";
AC_SUBST([ENCAP_DEFS])
dnl ### generate rules for make install target
ENCAP_INSTALL_RULES='if test -f ${top_srcdir}/COPYRIGHT; then \\\
${INSTALL_DATA} ${top_srcdir}/COPYRIGHT ${ENCAP_SOURCE}/${ENCAP_PKGSPEC}; \\\
fi\
${MKENCAP} ${MKENCAP_OPTS} -s ${DESTDIR}${ENCAP_SOURCE} -e ${ENCAP_PKGSPEC};\
if test -z \"${DESTDIR}\"; then \\\
${EPKG} -s ${ENCAP_SOURCE} -t ${ENCAP_TARGET} ${ENCAP_PKGSPEC}; \\\
fi';
AC_SUBST([ENCAP_INSTALL_RULES])
ENCAP_INSTALL_TARGET=$2
else
ENCAP_INSTALL_TARGET=$3
fi
AC_SUBST([ENCAP_INSTALL_TARGET])
])

251
autoconf/install-sh Executable file
View File

@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

8102
autom4te.cache/output.0 Normal file

File diff suppressed because it is too large Load Diff

112
autom4te.cache/requests Normal file
View File

@ -0,0 +1,112 @@
# This file was created by autom4te.
# It contains the lists of macros which have been traced.
# It can be safely removed.
@request = (
bless( [
'0',
1,
[
'/usr/local/encap/autoconf-2.57/share/autoconf',
'autoconf'
],
[
'/usr/local/encap/autoconf-2.57/share/autoconf/autoconf/autoconf.m4f',
'autoconf/aclocal.m4',
'configure.ac'
],
{
'AC_PROG_GCC_TRADITIONAL' => 1,
'AM_CONDITIONAL' => 1,
'AC_FUNC_STRERROR_R' => 1,
'AC_CONFIG_AUX_DIR' => 1,
'AC_PROG_LN_S' => 1,
'AC_PATH_X' => 1,
'AC_CANONICAL_HOST' => 1,
'AC_CHECK_MEMBERS' => 1,
'AC_LIBSOURCE' => 1,
'AC_FUNC_SETVBUF_REVERSED' => 1,
'AC_FUNC_CHOWN' => 1,
'AC_FUNC_STRTOD' => 1,
'AC_HEADER_DIRENT' => 1,
'AC_FUNC_CLOSEDIR_VOID' => 1,
'AC_FUNC_OBSTACK' => 1,
'AC_FUNC_MMAP' => 1,
'AC_HEADER_STDC' => 1,
'AH_OUTPUT' => 1,
'AC_FUNC_ALLOCA' => 1,
'm4_pattern_allow' => 1,
'AC_TYPE_MODE_T' => 1,
'AC_PROG_AWK' => 1,
'AC_HEADER_SYS_WAIT' => 1,
'AC_CHECK_FUNCS' => 1,
'AC_FUNC_FORK' => 1,
'AC_PROG_LEX' => 1,
'include' => 1,
'AC_FUNC_GETMNTENT' => 1,
'AC_STRUCT_TM' => 1,
'AC_FUNC_STAT' => 1,
'AC_CONFIG_FILES' => 1,
'AC_STRUCT_ST_BLOCKS' => 1,
'AC_FUNC_FSEEKO' => 1,
'AC_FUNC_UTIME_NULL' => 1,
'AC_FUNC_MBRTOWC' => 1,
'AC_CANONICAL_SYSTEM' => 1,
'AC_FUNC_STRCOLL' => 1,
'AC_PROG_RANLIB' => 1,
'AC_TYPE_OFF_T' => 1,
'AC_TYPE_SIZE_T' => 1,
'AC_FUNC_STRNLEN' => 1,
'AC_CONFIG_SUBDIRS' => 1,
'AC_SUBST' => 1,
'AC_FUNC_LSTAT' => 1,
'AC_DECL_SYS_SIGLIST' => 1,
'AC_INIT' => 1,
'AM_MAINTAINER_MODE' => 1,
'AC_FUNC_SELECT_ARGTYPES' => 1,
'AC_PROG_CPP' => 1,
'AC_PROG_CC' => 1,
'AC_PROG_MAKE_SET' => 1,
'AC_HEADER_STAT' => 1,
'AM_AUTOMAKE_VERSION' => 1,
'AC_FUNC_GETLOADAVG' => 1,
'AC_FUNC_MEMCMP' => 1,
'AC_PROG_CXX' => 1,
'AC_FUNC_GETGROUPS' => 1,
'AC_STRUCT_TIMEZONE' => 1,
'm4_pattern_forbid' => 1,
'AC_CONFIG_HEADERS' => 1,
'AC_TYPE_PID_T' => 1,
'AC_CHECK_LIB' => 1,
'AC_TYPE_UID_T' => 1,
'AM_PROG_CC_C_O' => 1,
'AC_HEADER_TIME' => 1,
'AM_GNU_GETTEXT' => 1,
'AC_FUNC_STRFTIME' => 1,
'AC_REPLACE_FNMATCH' => 1,
'AC_TYPE_SIGNAL' => 1,
'AC_HEADER_MAJOR' => 1,
'AC_C_INLINE' => 1,
'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1,
'm4_include' => 1,
'AC_C_VOLATILE' => 1,
'AC_FUNC_MALLOC' => 1,
'AC_FUNC_GETPGRP' => 1,
'AC_DEFINE_TRACE_LITERAL' => 1,
'AC_C_CONST' => 1,
'AC_PROG_LIBTOOL' => 1,
'AC_FUNC_REALLOC' => 1,
'AC_PROG_INSTALL' => 1,
'AC_FUNC_ERROR_AT_LINE' => 1,
'AC_FUNC_SETPGRP' => 1,
'AC_CHECK_TYPES' => 1,
'AC_FUNC_MKTIME' => 1,
'AC_FUNC_WAIT3' => 1,
'AC_FUNC_VPRINTF' => 1,
'AM_INIT_AUTOMAKE' => 1,
'AC_PROG_YACC' => 1,
'AC_CHECK_HEADERS' => 1
}
], 'Request' )
);

382
autom4te.cache/traces.0 Normal file
View File

@ -0,0 +1,382 @@
m4trace:autoconf/aclocal.m4:1: -1- m4_include([encap.m4])
m4trace:autoconf/aclocal.m4:2: -1- m4_include([ac_path_generic.m4])
m4trace:configure.ac:2: -1- AC_INIT([libtar], [1.2.11])
m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?A[CHUM]_])
m4trace:configure.ac:2: -1- m4_pattern_forbid([_AC_])
m4trace:configure.ac:2: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
m4trace:configure.ac:2: -1- m4_pattern_allow([^AS_FLAGS$])
m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?m4_])
m4trace:configure.ac:2: -1- m4_pattern_forbid([^dnl$])
m4trace:configure.ac:2: -1- m4_pattern_forbid([^_?AS_])
m4trace:configure.ac:2: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}])
m4trace:configure.ac:2: -1- AC_SUBST([PATH_SEPARATOR])
m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])])
m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])])
m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])])
m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])])
m4trace:configure.ac:2: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
m4trace:configure.ac:2: -1- AC_SUBST([exec_prefix], [NONE])
m4trace:configure.ac:2: -1- AC_SUBST([prefix], [NONE])
m4trace:configure.ac:2: -1- AC_SUBST([program_transform_name], [s,x,x,])
m4trace:configure.ac:2: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
m4trace:configure.ac:2: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
m4trace:configure.ac:2: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
m4trace:configure.ac:2: -1- AC_SUBST([datadir], ['${prefix}/share'])
m4trace:configure.ac:2: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
m4trace:configure.ac:2: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
m4trace:configure.ac:2: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
m4trace:configure.ac:2: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
m4trace:configure.ac:2: -1- AC_SUBST([includedir], ['${prefix}/include'])
m4trace:configure.ac:2: -1- AC_SUBST([oldincludedir], ['/usr/include'])
m4trace:configure.ac:2: -1- AC_SUBST([infodir], ['${prefix}/info'])
m4trace:configure.ac:2: -1- AC_SUBST([mandir], ['${prefix}/man'])
m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
#undef PACKAGE_NAME])
m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME])
m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
#undef PACKAGE_VERSION])
m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
#undef PACKAGE_STRING])
m4trace:configure.ac:2: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
m4trace:configure.ac:2: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT])
m4trace:configure.ac:2: -1- AC_SUBST([build_alias])
m4trace:configure.ac:2: -1- AC_SUBST([host_alias])
m4trace:configure.ac:2: -1- AC_SUBST([target_alias])
m4trace:configure.ac:2: -1- AC_SUBST([DEFS])
m4trace:configure.ac:2: -1- AC_SUBST([ECHO_C])
m4trace:configure.ac:2: -1- AC_SUBST([ECHO_N])
m4trace:configure.ac:2: -1- AC_SUBST([ECHO_T])
m4trace:configure.ac:2: -1- AC_SUBST([LIBS])
m4trace:configure.ac:4: -1- AC_CONFIG_AUX_DIR([autoconf])
m4trace:configure.ac:5: -1- AC_CONFIG_HEADERS([config.h])
m4trace:configure.ac:12: -1- AC_SUBST([EPKG], [$ac_cv_path_EPKG])
m4trace:configure.ac:12: -1- AC_SUBST([MKENCAP], [$ac_cv_path_MKENCAP])
m4trace:configure.ac:12: -1- AC_SUBST([ENCAP_DEFS])
m4trace:configure.ac:12: -1- AC_SUBST([ENCAP_INSTALL_RULES])
m4trace:configure.ac:12: -1- AC_SUBST([ENCAP_INSTALL_TARGET])
m4trace:configure.ac:16: -1- m4_include([compat/module.ac])
m4trace:configure.ac:17: -1- m4_include([listhash/module.ac])
m4trace:configure.ac:17: -1- AC_DEFINE_TRACE_LITERAL([NEED_STRLCPY])
m4trace:configure.ac:17: -1- AH_OUTPUT([NEED_STRLCPY], [/* Define if you want to use the strlcpy function */
#undef NEED_STRLCPY])
m4trace:configure.ac:17: -1- AC_PROG_CC
m4trace:configure.ac:17: -1- AC_SUBST([CC])
m4trace:configure.ac:17: -1- AC_SUBST([CFLAGS])
m4trace:configure.ac:17: -1- AC_SUBST([LDFLAGS])
m4trace:configure.ac:17: -1- AC_SUBST([CPPFLAGS])
m4trace:configure.ac:17: -1- AC_SUBST([CC])
m4trace:configure.ac:17: -1- AC_SUBST([ac_ct_CC])
m4trace:configure.ac:17: -1- AC_SUBST([CC])
m4trace:configure.ac:17: -1- AC_SUBST([ac_ct_CC])
m4trace:configure.ac:17: -1- AC_SUBST([CC])
m4trace:configure.ac:17: -1- AC_SUBST([CC])
m4trace:configure.ac:17: -1- AC_SUBST([ac_ct_CC])
m4trace:configure.ac:17: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext])
m4trace:configure.ac:17: -1- AC_SUBST([OBJEXT], [$ac_cv_objext])
m4trace:configure.ac:17: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRLCPY])
m4trace:configure.ac:17: -1- AH_OUTPUT([HAVE_STRLCPY], [/* Define if you have the strlcpy function */
#undef HAVE_STRLCPY])
m4trace:configure.ac:17: -1- AC_LIBSOURCE([strlcpy.c])
m4trace:configure.ac:17: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:17: -1- AC_DEFINE_TRACE_LITERAL([NEED_STRSEP])
m4trace:configure.ac:17: -1- AH_OUTPUT([NEED_STRSEP], [/* Define if you want to use the strsep function */
#undef NEED_STRSEP])
m4trace:configure.ac:17: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRSEP])
m4trace:configure.ac:17: -1- AH_OUTPUT([HAVE_STRSEP], [/* Define if you have the strsep function */
#undef HAVE_STRSEP])
m4trace:configure.ac:17: -1- AC_LIBSOURCE([strsep.c])
m4trace:configure.ac:17: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:17: -1- AC_SUBST([LISTHASH_PREFIX])
m4trace:configure.ac:17: -1- AC_SUBST([LISTHASH_DIR])
m4trace:configure.ac:17: -1- AC_CONFIG_FILES([listhash/${LISTHASH_PREFIX}_listhash.h:listhash/listhash.h.in])
m4trace:configure.ac:17: -1- AC_CONFIG_FILES([listhash/${LISTHASH_PREFIX}_list.c:listhash/list.c.in])
m4trace:configure.ac:17: -1- AC_CONFIG_FILES([listhash/${LISTHASH_PREFIX}_hash.c:listhash/hash.c.in])
m4trace:configure.ac:17: -1- AC_CONFIG_FILES([listhash/${LISTHASH_PREFIX}_list_new.3:listhash/list_new.3.in])
m4trace:configure.ac:17: -1- AC_CONFIG_FILES([listhash/${LISTHASH_PREFIX}_hash_new.3:listhash/hash_new.3.in])
m4trace:configure.ac:25: -1- AC_SUBST([MKDIR])
m4trace:configure.ac:29: -1- AC_PROG_CC
m4trace:configure.ac:29: -1- AC_SUBST([CC])
m4trace:configure.ac:29: -1- AC_SUBST([CFLAGS])
m4trace:configure.ac:29: -1- AC_SUBST([LDFLAGS])
m4trace:configure.ac:29: -1- AC_SUBST([CPPFLAGS])
m4trace:configure.ac:29: -1- AC_SUBST([CC])
m4trace:configure.ac:29: -1- AC_SUBST([ac_ct_CC])
m4trace:configure.ac:29: -1- AC_SUBST([CC])
m4trace:configure.ac:29: -1- AC_SUBST([ac_ct_CC])
m4trace:configure.ac:29: -1- AC_SUBST([CC])
m4trace:configure.ac:29: -1- AC_SUBST([CC])
m4trace:configure.ac:29: -1- AC_SUBST([ac_ct_CC])
m4trace:configure.ac:30: -1- AC_PROG_RANLIB
m4trace:configure.ac:30: -1- AC_SUBST([RANLIB])
m4trace:configure.ac:30: -1- AC_SUBST([ac_ct_RANLIB])
m4trace:configure.ac:31: -1- AC_PROG_INSTALL
m4trace:configure.ac:31: -1- AC_SUBST([INSTALL_PROGRAM])
m4trace:configure.ac:31: -1- AC_SUBST([INSTALL_SCRIPT])
m4trace:configure.ac:31: -1- AC_SUBST([INSTALL_DATA])
m4trace:configure.ac:32: -1- AC_PROG_LN_S
m4trace:configure.ac:32: -1- AC_SUBST([LN_S], [$as_ln_s])
m4trace:configure.ac:33: -1- AC_PROG_MAKE_SET
m4trace:configure.ac:33: -1- AC_SUBST([SET_MAKE])
m4trace:configure.ac:37: -1- AH_OUTPUT([_ALL_SOURCE], [/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
@%:@ifndef _ALL_SOURCE
@%:@ undef _ALL_SOURCE
@%:@endif])
m4trace:configure.ac:37: -1- AC_PROG_CPP
m4trace:configure.ac:37: -1- AC_SUBST([CPP])
m4trace:configure.ac:37: -1- AC_SUBST([CPPFLAGS])
m4trace:configure.ac:37: -1- AC_SUBST([CPP])
m4trace:configure.ac:37: -1- AC_SUBST([EGREP])
m4trace:configure.ac:37: -1- AC_DEFINE_TRACE_LITERAL([_ALL_SOURCE])
m4trace:configure.ac:38: -1- AC_C_CONST
m4trace:configure.ac:38: -1- AC_DEFINE_TRACE_LITERAL([const])
m4trace:configure.ac:38: -1- AH_OUTPUT([const], [/* Define to empty if `const\' does not conform to ANSI C. */
#undef const])
m4trace:configure.ac:42: -1- AC_HEADER_STDC
m4trace:configure.ac:42: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS])
m4trace:configure.ac:42: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS])
m4trace:configure.ac:43: -1- AC_CHECK_HEADERS([unistd.h])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H])
m4trace:configure.ac:43: -1- AC_CHECK_HEADERS([sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
inttypes.h stdint.h unistd.h], [], [], [$ac_includes_default])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H])
m4trace:configure.ac:43: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H])
m4trace:configure.ac:44: -1- AC_HEADER_MAJOR
m4trace:configure.ac:44: -1- AC_DEFINE_TRACE_LITERAL([MAJOR_IN_MKDEV])
m4trace:configure.ac:44: -1- AH_OUTPUT([MAJOR_IN_MKDEV], [/* Define to 1 if `major\', `minor\', and `makedev\' are declared in <mkdev.h>.
*/
#undef MAJOR_IN_MKDEV])
m4trace:configure.ac:44: -1- AC_DEFINE_TRACE_LITERAL([MAJOR_IN_SYSMACROS])
m4trace:configure.ac:44: -1- AH_OUTPUT([MAJOR_IN_SYSMACROS], [/* Define to 1 if `major\', `minor\', and `makedev\' are declared in
<sysmacros.h>. */
#undef MAJOR_IN_SYSMACROS])
m4trace:configure.ac:54: -1- AC_CHECK_TYPES([major_t], [], [AC_DEFINE(major_t, unsigned int,
[Define to `unsigned int' if not defined in system header files.]
)], [#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
#else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
#endif
])
m4trace:configure.ac:54: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MAJOR_T])
m4trace:configure.ac:54: -1- AH_OUTPUT([HAVE_MAJOR_T], [/* Define to 1 if the system has the type `major_t\'. */
#undef HAVE_MAJOR_T])
m4trace:configure.ac:54: -1- AC_DEFINE_TRACE_LITERAL([major_t])
m4trace:configure.ac:54: -1- AH_OUTPUT([major_t], [/* Define to `unsigned int\' if not defined in system header files. */
#undef major_t])
m4trace:configure.ac:64: -1- AC_CHECK_TYPES([minor_t], [], [AC_DEFINE(minor_t, unsigned int,
[Define to `unsigned int' if not defined in system header files.]
)], [#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
#else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
#endif
])
m4trace:configure.ac:64: -1- AC_DEFINE_TRACE_LITERAL([HAVE_MINOR_T])
m4trace:configure.ac:64: -1- AH_OUTPUT([HAVE_MINOR_T], [/* Define to 1 if the system has the type `minor_t\'. */
#undef HAVE_MINOR_T])
m4trace:configure.ac:64: -1- AC_DEFINE_TRACE_LITERAL([minor_t])
m4trace:configure.ac:64: -1- AH_OUTPUT([minor_t], [/* Define to `unsigned int\' if not defined in system header files. */
#undef minor_t])
m4trace:configure.ac:74: -1- AC_CHECK_TYPES([dev_t], [], [AC_DEFINE(dev_t, unsigned long,
[Define to `unsigned long' if not defined in system header files.]
)], [#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
#else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
#endif
])
m4trace:configure.ac:74: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DEV_T])
m4trace:configure.ac:74: -1- AH_OUTPUT([HAVE_DEV_T], [/* Define to 1 if the system has the type `dev_t\'. */
#undef HAVE_DEV_T])
m4trace:configure.ac:74: -1- AC_DEFINE_TRACE_LITERAL([dev_t])
m4trace:configure.ac:74: -1- AH_OUTPUT([dev_t], [/* Define to `unsigned long\' if not defined in system header files. */
#undef dev_t])
m4trace:configure.ac:78: -1- AC_CHECK_TYPES([socklen_t], [], [AC_DEFINE(socklen_t, unsigned long,
[Define to `unsigned long' if not defined in system header files.]
)], [#include <sys/types.h>
#include <sys/socket.h>
])
m4trace:configure.ac:78: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SOCKLEN_T])
m4trace:configure.ac:78: -1- AH_OUTPUT([HAVE_SOCKLEN_T], [/* Define to 1 if the system has the type `socklen_t\'. */
#undef HAVE_SOCKLEN_T])
m4trace:configure.ac:78: -1- AC_DEFINE_TRACE_LITERAL([socklen_t])
m4trace:configure.ac:78: -1- AH_OUTPUT([socklen_t], [/* Define to `unsigned long\' if not defined in system header files. */
#undef socklen_t])
m4trace:configure.ac:79: -1- AC_CHECK_TYPES([uint64_t], [], [AC_DEFINE(uint64_t, long long,
[Define to `long long' if not defined in system header files.]
)], [])
m4trace:configure.ac:79: -1- AC_DEFINE_TRACE_LITERAL([HAVE_UINT64_T])
m4trace:configure.ac:79: -1- AH_OUTPUT([HAVE_UINT64_T], [/* Define to 1 if the system has the type `uint64_t\'. */
#undef HAVE_UINT64_T])
m4trace:configure.ac:79: -1- AC_DEFINE_TRACE_LITERAL([uint64_t])
m4trace:configure.ac:79: -1- AH_OUTPUT([uint64_t], [/* Define to `long long\' if not defined in system header files. */
#undef uint64_t])
m4trace:configure.ac:80: -1- AC_TYPE_MODE_T
m4trace:configure.ac:80: -1- AC_DEFINE_TRACE_LITERAL([mode_t])
m4trace:configure.ac:80: -1- AH_OUTPUT([mode_t], [/* Define to `int\' if <sys/types.h> does not define. */
#undef mode_t])
m4trace:configure.ac:81: -1- AC_TYPE_OFF_T
m4trace:configure.ac:81: -1- AC_DEFINE_TRACE_LITERAL([off_t])
m4trace:configure.ac:81: -1- AH_OUTPUT([off_t], [/* Define to `long\' if <sys/types.h> does not define. */
#undef off_t])
m4trace:configure.ac:82: -1- AC_TYPE_SIZE_T
m4trace:configure.ac:82: -1- AC_DEFINE_TRACE_LITERAL([size_t])
m4trace:configure.ac:82: -1- AH_OUTPUT([size_t], [/* Define to `unsigned\' if <sys/types.h> does not define. */
#undef size_t])
m4trace:configure.ac:83: -1- AC_TYPE_UID_T
m4trace:configure.ac:83: -1- AC_DEFINE_TRACE_LITERAL([uid_t])
m4trace:configure.ac:83: -1- AH_OUTPUT([uid_t], [/* Define to `int\' if <sys/types.h> doesn\'t define. */
#undef uid_t])
m4trace:configure.ac:83: -1- AC_DEFINE_TRACE_LITERAL([gid_t])
m4trace:configure.ac:83: -1- AH_OUTPUT([gid_t], [/* Define to `int\' if <sys/types.h> doesn\'t define. */
#undef gid_t])
m4trace:configure.ac:84: -1- AC_CHECK_TYPES([nlink_t], [], [AC_DEFINE(nlink_t, unsigned short,
[Define to `unsigned short' if not defined in system header files.]
)], [])
m4trace:configure.ac:84: -1- AC_DEFINE_TRACE_LITERAL([HAVE_NLINK_T])
m4trace:configure.ac:84: -1- AH_OUTPUT([HAVE_NLINK_T], [/* Define to 1 if the system has the type `nlink_t\'. */
#undef HAVE_NLINK_T])
m4trace:configure.ac:84: -1- AC_DEFINE_TRACE_LITERAL([nlink_t])
m4trace:configure.ac:84: -1- AH_OUTPUT([nlink_t], [/* Define to `unsigned short\' if not defined in system header files. */
#undef nlink_t])
m4trace:configure.ac:88: -1- AC_DEFINE_TRACE_LITERAL([NEED_BASENAME])
m4trace:configure.ac:88: -1- AH_OUTPUT([NEED_BASENAME], [/* Define if you want to use the basename function */
#undef NEED_BASENAME])
m4trace:configure.ac:88: -1- AC_CHECK_HEADERS([libgen.h])
m4trace:configure.ac:88: -1- AH_OUTPUT([HAVE_LIBGEN_H], [/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H])
m4trace:configure.ac:88: -1- AC_DEFINE_TRACE_LITERAL([HAVE_BASENAME])
m4trace:configure.ac:88: -1- AH_OUTPUT([HAVE_BASENAME], [/* Define if your system has a working basename */
#undef HAVE_BASENAME])
m4trace:configure.ac:88: -1- AC_LIBSOURCE([basename.c])
m4trace:configure.ac:88: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:89: -1- AC_DEFINE_TRACE_LITERAL([NEED_DIRNAME])
m4trace:configure.ac:89: -1- AH_OUTPUT([NEED_DIRNAME], [/* Define if you want to use the dirname function */
#undef NEED_DIRNAME])
m4trace:configure.ac:89: -1- AC_CHECK_HEADERS([libgen.h])
m4trace:configure.ac:89: -1- AH_OUTPUT([HAVE_LIBGEN_H], [/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H])
m4trace:configure.ac:89: -1- AC_DEFINE_TRACE_LITERAL([HAVE_DIRNAME])
m4trace:configure.ac:89: -1- AH_OUTPUT([HAVE_DIRNAME], [/* Define if your system has a working dirname */
#undef HAVE_DIRNAME])
m4trace:configure.ac:89: -1- AC_LIBSOURCE([dirname.c])
m4trace:configure.ac:89: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:90: -1- AC_DEFINE_TRACE_LITERAL([NEED_FNMATCH])
m4trace:configure.ac:90: -1- AH_OUTPUT([NEED_FNMATCH], [/* Define if you want to use the fnmatch function */
#undef NEED_FNMATCH])
m4trace:configure.ac:90: -1- AC_CHECK_HEADERS([fnmatch.h])
m4trace:configure.ac:90: -1- AH_OUTPUT([HAVE_FNMATCH_H], [/* Define to 1 if you have the <fnmatch.h> header file. */
#undef HAVE_FNMATCH_H])
m4trace:configure.ac:90: -1- AC_DEFINE_TRACE_LITERAL([HAVE_FNMATCH])
m4trace:configure.ac:90: -1- AH_OUTPUT([HAVE_FNMATCH], [/* Define to 1 if your system has a working POSIX `fnmatch\' function. */
#undef HAVE_FNMATCH])
m4trace:configure.ac:90: -1- AC_CHECK_HEADERS([ctype.h])
m4trace:configure.ac:90: -1- AH_OUTPUT([HAVE_CTYPE_H], [/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H])
m4trace:configure.ac:90: -1- AC_LIBSOURCE([fnmatch.c])
m4trace:configure.ac:90: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:91: -1- AC_CHECK_FUNCS([lchown])
m4trace:configure.ac:91: -1- AH_OUTPUT([HAVE_LCHOWN], [/* Define to 1 if you have the `lchown\' function. */
#undef HAVE_LCHOWN])
m4trace:configure.ac:92: -1- AC_DEFINE_TRACE_LITERAL([NEED_MAKEDEV])
m4trace:configure.ac:92: -1- AH_OUTPUT([NEED_MAKEDEV], [/* Define if you want to use the makedev function */
#undef NEED_MAKEDEV])
m4trace:configure.ac:92: -1- AC_DEFINE_TRACE_LITERAL([MAKEDEV_THREE_ARGS])
m4trace:configure.ac:92: -1- AH_OUTPUT([MAKEDEV_THREE_ARGS], [/* Define as 1 if makedev expects three arguments */
#undef MAKEDEV_THREE_ARGS])
m4trace:configure.ac:93: -1- AC_DEFINE_TRACE_LITERAL([NEED_SNPRINTF])
m4trace:configure.ac:93: -1- AH_OUTPUT([NEED_SNPRINTF], [/* Define if you want to use the snprintf function */
#undef NEED_SNPRINTF])
m4trace:configure.ac:93: -1- AC_DEFINE_TRACE_LITERAL([HAVE_SNPRINTF])
m4trace:configure.ac:93: -1- AH_OUTPUT([HAVE_SNPRINTF], [/* Define if your system has a working snprintf */
#undef HAVE_SNPRINTF])
m4trace:configure.ac:93: -1- AC_LIBSOURCE([snprintf.c])
m4trace:configure.ac:93: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:94: -1- AC_DEFINE_TRACE_LITERAL([NEED_STRDUP])
m4trace:configure.ac:94: -1- AH_OUTPUT([NEED_STRDUP], [/* Define if you want to use the strdup function */
#undef NEED_STRDUP])
m4trace:configure.ac:94: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRDUP])
m4trace:configure.ac:94: -1- AH_OUTPUT([HAVE_STRDUP], [/* Define if you have the strdup function */
#undef HAVE_STRDUP])
m4trace:configure.ac:94: -1- AC_LIBSOURCE([strdup.c])
m4trace:configure.ac:94: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:95: -1- AC_FUNC_STRFTIME
m4trace:configure.ac:95: -1- AC_CHECK_FUNCS([strftime], [], [# strftime is in -lintl on SCO UNIX.
AC_CHECK_LIB(intl, strftime,
[AC_DEFINE(HAVE_STRFTIME)
LIBS="-lintl $LIBS"])])
m4trace:configure.ac:95: -1- AH_OUTPUT([HAVE_STRFTIME], [/* Define to 1 if you have the `strftime\' function. */
#undef HAVE_STRFTIME])
m4trace:configure.ac:95: -1- AC_CHECK_LIB([intl], [strftime], [AC_DEFINE(HAVE_STRFTIME)
LIBS="-lintl $LIBS"])
m4trace:configure.ac:95: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRFTIME])
m4trace:configure.ac:96: -1- AC_DEFINE_TRACE_LITERAL([NEED_STRLCPY])
m4trace:configure.ac:96: -1- AH_OUTPUT([NEED_STRLCPY], [/* Define if you want to use the strlcpy function */
#undef NEED_STRLCPY])
m4trace:configure.ac:96: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRLCPY])
m4trace:configure.ac:96: -1- AH_OUTPUT([HAVE_STRLCPY], [/* Define if you have the strlcpy function */
#undef HAVE_STRLCPY])
m4trace:configure.ac:96: -1- AC_LIBSOURCE([strlcpy.c])
m4trace:configure.ac:96: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:97: -1- AC_DEFINE_TRACE_LITERAL([NEED_STRMODE])
m4trace:configure.ac:97: -1- AH_OUTPUT([NEED_STRMODE], [/* Define if you want to use the strmode function */
#undef NEED_STRMODE])
m4trace:configure.ac:97: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRMODE])
m4trace:configure.ac:97: -1- AH_OUTPUT([HAVE_STRMODE], [/* Define if you have the strmode function */
#undef HAVE_STRMODE])
m4trace:configure.ac:97: -1- AC_LIBSOURCE([strmode.c])
m4trace:configure.ac:97: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:98: -1- AC_DEFINE_TRACE_LITERAL([NEED_STRSEP])
m4trace:configure.ac:98: -1- AH_OUTPUT([NEED_STRSEP], [/* Define if you want to use the strsep function */
#undef NEED_STRSEP])
m4trace:configure.ac:98: -1- AC_DEFINE_TRACE_LITERAL([HAVE_STRSEP])
m4trace:configure.ac:98: -1- AH_OUTPUT([HAVE_STRSEP], [/* Define if you have the strsep function */
#undef HAVE_STRSEP])
m4trace:configure.ac:98: -1- AC_LIBSOURCE([strsep.c])
m4trace:configure.ac:98: -1- AC_SUBST([LIB@&t@OBJS])
m4trace:configure.ac:107: -1- AC_CHECK_LIB([z], [gzread])
m4trace:configure.ac:107: -1- AH_OUTPUT([HAVE_LIBZ], [/* Define to 1 if you have the `z\' library (-lz). */
#undef HAVE_LIBZ])
m4trace:configure.ac:107: -1- AC_DEFINE_TRACE_LITERAL([HAVE_LIBZ])
m4trace:configure.ac:112: -1- AC_CONFIG_FILES([Makefile lib/Makefile libtar/Makefile doc/Makefile])
m4trace:configure.ac:113: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs])
m4trace:configure.ac:113: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs])

31
compat/ChangeLog Normal file
View File

@ -0,0 +1,31 @@
2003-01-08 added COMPAT_FUNC_MAKEDEV macro
2002-12-20 added COMPAT_VAR___PROGNAME macro
2002-12-19 include necessary header files from gethostbyname_r.c
and getservbyname_r.c
check for size_t in COMPAT_FUNC_GETHOSTBYNAME_R and
COMPAT_FUNC_GETSERVBYNAME_R macros
2002-12-18 define _LINUX_SOURCE_COMPAT in compat.h if strsep()
is needed on AIX
avoid prototype syntax problem with IBM C compiler in
fnmatch.c
2002-11-24 added COMPAT_PROTO_MACRO macro
2002-11-22 updated gethostbyname_r() and getservbyname_r() code and
macros to detect and use weird AIX implementation
added warnings if thread-safe functions are not found
2002-10-18 new macros and corresponding compat code:
* COMPAT_FUNC_GETHOSTBYNAME_R
* COMPAT_FUNC_GETSERVBYNAME_R
2002-10-15 added COMPAT_FUNC_GETPWUID_R macro
2002-07-17 added inet_aton.c

12
compat/README Normal file
View File

@ -0,0 +1,12 @@
Compatibility Suite
-------------------
This directory contains a compatibility suite that provides alternate
implementations of various library functions which are not available or
not usable on some platforms.
The original copyright information for each function is included in
the source files. I've modified the files slightly for integration
into this suite, but the functionality has not been modified from
the original source.

4
compat/TODO Normal file
View File

@ -0,0 +1,4 @@
- fix COMPAT_FUNC_INET_ATON to check for existing function in -lresolv
- fix COMPAT_FUNC_MAKEDEV to avoid problems with IBM C compiler
(calling cpp macro with more args that necessary doesn't fail, but
calling it with too few macros does fail)

74
compat/basename.c Normal file
View File

@ -0,0 +1,74 @@
/* $OpenBSD: basename.c,v 1.4 1999/05/30 17:10:30 espie Exp $ */
/*
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$OpenBSD: basename.c,v 1.4 1999/05/30 17:10:30 espie Exp $";
#endif /* not lint */
#include <errno.h>
#include <string.h>
#include <sys/param.h>
char *
openbsd_basename(path)
const char *path;
{
static char bname[MAXPATHLEN];
register const char *endp, *startp;
/* Empty or NULL string gets treated as "." */
if (path == NULL || *path == '\0') {
(void)strcpy(bname, ".");
return(bname);
}
/* Strip trailing slashes */
endp = path + strlen(path) - 1;
while (endp > path && *endp == '/')
endp--;
/* All slashes becomes "/" */
if (endp == path && *endp == '/') {
(void)strcpy(bname, "/");
return(bname);
}
/* Find the start of the base */
startp = endp;
while (startp > path && *(startp - 1) != '/')
startp--;
if (endp - startp + 1 > sizeof(bname)) {
errno = ENAMETOOLONG;
return(NULL);
}
(void)strncpy(bname, startp, endp - startp + 1);
bname[endp - startp + 1] = '\0';
return(bname);
}

260
compat/compat.h Normal file
View File

@ -0,0 +1,260 @@
/* prototypes for borrowed "compatibility" code */
#include <config.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef STDC_HEADERS
# include <stdarg.h>
# include <stddef.h>
#else
# include <varargs.h>
#endif
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
#if defined(NEED_BASENAME) && !defined(HAVE_BASENAME)
# ifdef basename
# undef basename /* fix glibc brokenness */
# endif
char *openbsd_basename(const char *);
# define basename openbsd_basename
#endif /* NEED_BASENAME && ! HAVE_BASENAME */
#if defined(NEED_DIRNAME) && !defined(HAVE_DIRNAME)
char *openbsd_dirname(const char *);
# define dirname openbsd_dirname
#endif /* NEED_DIRNAME && ! HAVE_DIRNAME */
#ifdef NEED_FNMATCH
# ifndef HAVE_FNMATCH
# define FNM_NOMATCH 1 /* Match failed. */
# define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
# define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
# define FNM_PERIOD 0x04 /* Period must be matched by period. */
# define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
# define FNM_CASEFOLD 0x10 /* Case insensitive search. */
# define FNM_IGNORECASE FNM_CASEFOLD
# define FNM_FILE_NAME FNM_PATHNAME
int openbsd_fnmatch(const char *, const char *, int);
# define fnmatch openbsd_fnmatch
# else /* HAVE_FNMATCH */
# ifdef HAVE_FNMATCH_H
# include <fnmatch.h>
# endif
# endif /* ! HAVE_FNMATCH */
#endif /* NEED_FNMATCH */
#ifdef NEED_GETHOSTBYNAME_R
# include <netdb.h>
# if GETHOSTBYNAME_R_NUM_ARGS != 6
int compat_gethostbyname_r(const char *, struct hostent *,
char *, size_t, struct hostent **, int *);
# define gethostbyname_r compat_gethostbyname_r
# endif /* GETHOSTBYNAME_R_NUM_ARGS != 6 */
#endif /* NEED_GETHOSTBYNAME_R */
#if defined(NEED_GETHOSTNAME) && !defined(HAVE_GETHOSTNAME)
int gethostname(char *, size_t);
#endif /* NEED_GETHOSTNAME && ! HAVE_GETHOSTNAME */
#ifdef NEED_GETSERVBYNAME_R
# include <netdb.h>
# if GETSERVBYNAME_R_NUM_ARGS != 6
int compat_getservbyname_r(const char *, const char *, struct servent *,
char *, size_t, struct servent **);
# define getservbyname_r compat_getservbyname_r
# endif /* GETSERVBYNAME_R_NUM_ARGS != 6 */
#endif /* NEED_GETSERVBYNAME_R */
#ifdef NEED_GLOB
# ifndef HAVE_GLOB
typedef struct {
int gl_pathc; /* Count of total paths so far. */
int gl_matchc; /* Count of paths matching pattern. */
int gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
int (*gl_errfunc)(const char *, int);
/*
* Alternate filesystem access methods for glob; replacement
* versions of closedir(3), readdir(3), opendir(3), stat(2)
* and lstat(2).
*/
void (*gl_closedir)(void *);
struct dirent *(*gl_readdir)(void *);
void *(*gl_opendir)(const char *);
int (*gl_lstat)(const char *, struct stat *);
int (*gl_stat)(const char *, struct stat *);
} glob_t;
/* Flags */
# define GLOB_APPEND 0x0001 /* Append to output from previous call. */
# define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
# define GLOB_ERR 0x0004 /* Return on error. */
# define GLOB_MARK 0x0008 /* Append / to matching directories. */
# define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
# define GLOB_NOSORT 0x0020 /* Don't sort. */
# define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
# define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
# define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
# define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
# define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
# define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
# define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */
/* Error values returned by glob(3) */
# define GLOB_NOSPACE (-1) /* Malloc call failed. */
# define GLOB_ABORTED (-2) /* Unignored error. */
# define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */
# define GLOB_NOSYS (-4) /* Function not supported. */
# define GLOB_ABEND GLOB_ABORTED
int openbsd_glob(const char *, int, int (*)(const char *, int), glob_t *);
void openbsd_globfree(glob_t *);
# define glob openbsd_glob
# define globfree openbsd_globfree
# else /* HAVE_GLOB */
# ifdef HAVE_GLOB_H
# include <glob.h>
# endif
# endif /* ! HAVE_GLOB */
#endif /* NEED_GLOB */
#if defined(NEED_INET_ATON) && !defined(HAVE_INET_ATON)
int inet_aton(const char *, struct in_addr *);
#endif /* NEED_INET_ATON && ! HAVE_INET_ATON */
#ifdef NEED_MAKEDEV
# ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
# else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
# endif
/*
** On most systems makedev() has two args.
** Some weird systems, like QNX6, have makedev() functions that expect
** an extra first argument for "node", which can be 0 for a local
** machine.
*/
# ifdef MAKEDEV_THREE_ARGS
# define compat_makedev(maj, min) makedev(0, maj, min)
# else
# define compat_makedev makedev
# endif
#endif /* NEED_MAKEDEV */
#if defined(NEED_SNPRINTF) && !defined(HAVE_SNPRINTF)
int mutt_snprintf(char *, size_t, const char *, ...);
int mutt_vsnprintf(char *, size_t, const char *, va_list);
#define snprintf mutt_snprintf
#define vsnprintf mutt_vsnprintf
#endif /* NEED_SNPRINTF && ! HAVE_SNPRINTF */
#if defined(NEED_STRLCAT) && !defined(HAVE_STRLCAT)
size_t strlcat(char *, const char *, size_t);
#endif /* NEED_STRLCAT && ! HAVE_STRLCAT */
#if defined(NEED_STRLCPY) && !defined(HAVE_STRLCPY)
size_t strlcpy(char *, const char *, size_t);
#endif /* NEED_STRLCPY && ! HAVE_STRLCPY */
#if defined(NEED_STRDUP) && !defined(HAVE_STRDUP)
char *openbsd_strdup(const char *);
# define strdup openbsd_strdup
#endif /* NEED_STRDUP && ! HAVE_STRDUP */
#if defined(NEED_STRMODE) && !defined(HAVE_STRMODE)
void strmode(register mode_t, register char *);
#endif /* NEED_STRMODE && ! HAVE_STRMODE */
#if defined(NEED_STRRSTR) && !defined(HAVE_STRRSTR)
char *strrstr(char *, char *);
#endif /* NEED_STRRSTR && ! HAVE_STRRSTR */
#ifdef NEED_STRSEP
# ifdef HAVE_STRSEP
# define _LINUX_SOURCE_COMPAT /* needed on AIX 4.3.3 */
# else
char *strsep(register char **, register const char *);
# endif
#endif /* NEED_STRSEP */

77
compat/dirname.c Normal file
View File

@ -0,0 +1,77 @@
/* $OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $ */
/*
* Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
static char rcsid[] = "$OpenBSD: dirname.c,v 1.4 1999/05/30 17:10:30 espie Exp $";
#endif /* not lint */
#include <errno.h>
#include <string.h>
#include <sys/param.h>
char *
openbsd_dirname(path)
const char *path;
{
static char bname[MAXPATHLEN];
register const char *endp;
/* Empty or NULL string gets treated as "." */
if (path == NULL || *path == '\0') {
(void)strcpy(bname, ".");
return(bname);
}
/* Strip trailing slashes */
endp = path + strlen(path) - 1;
while (endp > path && *endp == '/')
endp--;
/* Find the start of the dir */
while (endp > path && *endp != '/')
endp--;
/* Either the dir is "/" or there are no slashes */
if (endp == path) {
(void)strcpy(bname, *endp == '/' ? "/" : ".");
return(bname);
} else {
do {
endp--;
} while (endp > path && *endp == '/');
}
if (endp - path + 1 > sizeof(bname)) {
errno = ENAMETOOLONG;
return(NULL);
}
(void)strncpy(bname, path, endp - path + 1);
bname[endp - path + 1] = '\0';
return(bname);
}

237
compat/fnmatch.c Normal file
View File

@ -0,0 +1,237 @@
/* $OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert Exp $ */
/*
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
#else
static char rcsid[] = "$OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
/*
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
* Compares a filename or pathname to a pattern.
*/
#include <config.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
#ifdef HAVE_CTYPE_H
# include <ctype.h>
#endif
#include <compat.h>
#define EOS '\0'
#define RANGE_MATCH 1
#define RANGE_NOMATCH 0
#define RANGE_ERROR (-1)
#ifdef NO_IBM_COMPILER_HORKAGE
static int rangematch (const char *, char, int, char **);
#else
static int rangematch ();
#endif
int
fnmatch(pattern, string, flags)
const char *pattern, *string;
int flags;
{
const char *stringstart;
char *newp;
char c, test;
for (stringstart = string;;)
switch (c = *pattern++) {
case EOS:
if ((flags & FNM_LEADING_DIR) && *string == '/')
return (0);
return (*string == EOS ? 0 : FNM_NOMATCH);
case '?':
if (*string == EOS)
return (FNM_NOMATCH);
if (*string == '/' && (flags & FNM_PATHNAME))
return (FNM_NOMATCH);
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
return (FNM_NOMATCH);
++string;
break;
case '*':
c = *pattern;
/* Collapse multiple stars. */
while (c == '*')
c = *++pattern;
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
return (FNM_NOMATCH);
/* Optimize for pattern with * at end or before /. */
if (c == EOS) {
if (flags & FNM_PATHNAME)
return ((flags & FNM_LEADING_DIR) ||
strchr(string, '/') == NULL ?
0 : FNM_NOMATCH);
else
return (0);
} else if (c == '/' && (flags & FNM_PATHNAME)) {
if ((string = strchr(string, '/')) == NULL)
return (FNM_NOMATCH);
break;
}
/* General case, use recursion. */
while ((test = *string) != EOS) {
if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
return (0);
if (test == '/' && (flags & FNM_PATHNAME))
break;
++string;
}
return (FNM_NOMATCH);
case '[':
if (*string == EOS)
return (FNM_NOMATCH);
if (*string == '/' && (flags & FNM_PATHNAME))
return (FNM_NOMATCH);
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
return (FNM_NOMATCH);
switch (rangematch(pattern, *string, flags, &newp)) {
case RANGE_ERROR:
/* not a good range, treat as normal text */
goto normal;
case RANGE_MATCH:
pattern = newp;
break;
case RANGE_NOMATCH:
return (FNM_NOMATCH);
}
++string;
break;
case '\\':
if (!(flags & FNM_NOESCAPE)) {
if ((c = *pattern++) == EOS) {
c = '\\';
--pattern;
}
}
/* FALLTHROUGH */
default:
normal:
if (c != *string && !((flags & FNM_CASEFOLD) &&
(tolower((unsigned char)c) ==
tolower((unsigned char)*string))))
return (FNM_NOMATCH);
++string;
break;
}
/* NOTREACHED */
}
static int
rangematch(pattern, test, flags, newp)
const char *pattern;
char test;
int flags;
char **newp;
{
int negate, ok;
char c, c2;
/*
* A bracket expression starting with an unquoted circumflex
* character produces unspecified results (IEEE 1003.2-1992,
* 3.13.2). This implementation treats it like '!', for
* consistency with the regular expression syntax.
* J.T. Conklin (conklin@ngai.kaleida.com)
*/
if ((negate = (*pattern == '!' || *pattern == '^')))
++pattern;
if (flags & FNM_CASEFOLD)
test = tolower((unsigned char)test);
/*
* A right bracket shall lose its special meaning and represent
* itself in a bracket expression if it occurs first in the list.
* -- POSIX.2 2.8.3.2
*/
ok = 0;
c = *pattern++;
do {
if (c == '\\' && !(flags & FNM_NOESCAPE))
c = *pattern++;
if (c == EOS)
return (RANGE_ERROR);
if (c == '/' && (flags & FNM_PATHNAME))
return (RANGE_NOMATCH);
if ((flags & FNM_CASEFOLD))
c = tolower((unsigned char)c);
if (*pattern == '-'
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
pattern += 2;
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
c2 = *pattern++;
if (c2 == EOS)
return (RANGE_ERROR);
if (flags & FNM_CASEFOLD)
c2 = tolower((unsigned char)c2);
if (c <= test && test <= c2)
ok = 1;
} else if (c == test)
ok = 1;
} while ((c = *pattern++) != ']');
*newp = (char *)pattern;
return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
}

41
compat/gethostbyname_r.c Normal file
View File

@ -0,0 +1,41 @@
/*
** Copyright 2002 University of Illinois Board of Trustees
** Copyright 2002 Mark D. Roth
** All rights reserved.
**
** gethostbyname_r.c - gethostbyname_r() function for compatibility library
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <netdb.h>
int
compat_gethostbyname_r(const char *name, struct hostent *hp,
char *buf, size_t buflen,
struct hostent **hpp, int *herr)
{
#if GETHOSTBYNAME_R_NUM_ARGS == 5
*hpp = gethostbyname_r(name, hp, buf, buflen, herr);
if (*hpp == NULL)
return -1;
return 0;
#elif GETHOSTBYNAME_R_NUM_ARGS == 3
struct hostent_data hdata;
if (gethostbyname_r(name, hp, &hdata) == -1)
return -1;
*hpp = hp;
return 0;
#endif /* GETHOSTBYNAME_R_NUM_ARGS == 5 */
}

36
compat/gethostname.c Normal file
View File

@ -0,0 +1,36 @@
/* gethostname.c: minimal substitute for missing gethostname() function
* created 2000-Mar-02 jmk
* requires SVR4 uname() and -lc
*
* by Jim Knoble <jmknoble@pobox.com>
* Copyright ? 2000 Jim Knoble
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear in
* supporting documentation.
*
* This software is provided "as is", without warranty of any kind,
* express or implied, including but not limited to the warranties of
* merchantability, fitness for a particular purpose and
* noninfringement. In no event shall the author(s) be liable for any
* claim, damages or other liability, whether in an action of contract,
* tort or otherwise, arising from, out of or in connection with the
* software or the use or other dealings in the software.
*/
#include <string.h>
#include <sys/utsname.h>
int gethostname(char *name, size_t len)
{
struct utsname u;
int status = uname(&u);
if (-1 != status) {
strncpy(name, u.nodename, len);
name[len - 1] = '\0';
}
return(status);
}

41
compat/getservbyname_r.c Normal file
View File

@ -0,0 +1,41 @@
/*
** Copyright 2002 University of Illinois Board of Trustees
** Copyright 2002 Mark D. Roth
** All rights reserved.
**
** getservbyname_r.c - getservbyname_r() function for compatibility library
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <netdb.h>
int
compat_getservbyname_r(const char *name, const char *proto,
struct servent *sp, char *buf, size_t buflen,
struct servent **spp)
{
#if GETSERVBYNAME_R_NUM_ARGS == 5
*spp = getservbyname_r(name, proto, sp, buf, buflen);
if (*spp == NULL)
return -1;
return 0;
#elif GETSERVBYNAME_R_NUM_ARGS == 4
struct servent_data sdata;
if (getservbyname_r(name, proto, sp, &sdata) == -1)
return -1;
*spp = sp;
return 0;
#endif /* GETSERVBYNAME_R_NUM_ARGS == 5 */
}

873
compat/glob.c Normal file
View File

@ -0,0 +1,873 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
#else
static char rcsid[] = "$OpenBSD: glob.c,v 1.8 1998/08/14 21:39:30 deraadt Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
/*
* glob(3) -- a superset of the one defined in POSIX 1003.2.
*
* The [!...] convention to negate a range is supported (SysV, Posix, ksh).
*
* Optional extra services, controlled by flags not defined by POSIX:
*
* GLOB_QUOTE:
* Escaping convention: \ inhibits any special meaning the following
* character might have (except \ at end of string is retained).
* GLOB_MAGCHAR:
* Set in gl_flags if pattern contained a globbing character.
* GLOB_NOMAGIC:
* Same as GLOB_NOCHECK, but it will only append pattern if it did
* not contain any magic characters. [Used in csh style globbing]
* GLOB_ALTDIRFUNC:
* Use alternately specified directory access functions.
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
* expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
*/
#include <config.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <compat.h>
#define DOLLAR '$'
#define DOT '.'
#define EOS '\0'
#define LBRACKET '['
#define NOT '!'
#define QUESTION '?'
#define QUOTE '\\'
#define RANGE '-'
#define RBRACKET ']'
#define SEP '/'
#define STAR '*'
#define TILDE '~'
#define UNDERSCORE '_'
#define LBRACE '{'
#define RBRACE '}'
#define SLASH '/'
#define COMMA ','
#ifndef DEBUG
#define M_QUOTE 0x8000
#define M_PROTECT 0x4000
#define M_MASK 0xffff
#define M_ASCII 0x00ff
typedef u_short Char;
#else
#define M_QUOTE 0x80
#define M_PROTECT 0x40
#define M_MASK 0xff
#define M_ASCII 0x7f
typedef char Char;
#endif
#define CHAR(c) ((Char)((c)&M_ASCII))
#define META(c) ((Char)((c)|M_QUOTE))
#define M_ALL META('*')
#define M_END META(']')
#define M_NOT META('!')
#define M_ONE META('?')
#define M_RNG META('-')
#define M_SET META('[')
#define ismeta(c) (((c)&M_QUOTE) != 0)
static int compare (const void *, const void *);
static void g_Ctoc (const Char *, char *);
static int g_lstat (Char *, struct stat *, glob_t *);
static DIR *g_opendir (Char *, glob_t *);
static Char *g_strchr (Char *, int);
#ifdef notdef
static Char *g_strcat (Char *, const Char *);
#endif
static int g_stat (Char *, struct stat *, glob_t *);
static int glob0 (const Char *, glob_t *);
static int glob1 (Char *, glob_t *);
static int glob2 (Char *, Char *, Char *, glob_t *);
static int glob3 (Char *, Char *, Char *, Char *, glob_t *);
static int globextend (const Char *, glob_t *);
static const Char * globtilde (const Char *, Char *, size_t, glob_t *);
static int globexp1 (const Char *, glob_t *);
static int globexp2 (const Char *, const Char *, glob_t *, int *);
static int match (Char *, Char *, Char *);
#ifdef DEBUG
static void qprintf (const char *, Char *);
#endif
int
openbsd_glob(pattern, flags, errfunc, pglob)
const char *pattern;
int flags, (*errfunc) __P((const char *, int));
glob_t *pglob;
{
const u_char *patnext;
int c;
Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];
patnext = (u_char *) pattern;
if (!(flags & GLOB_APPEND)) {
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
if (!(flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
}
pglob->gl_flags = flags & ~GLOB_MAGCHAR;
pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;
bufnext = patbuf;
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_NOESCAPE)
while (bufnext < bufend && (c = *patnext++) != EOS)
*bufnext++ = c;
else {
/* Protect the quoted characters. */
while (bufnext < bufend && (c = *patnext++) != EOS)
if (c == QUOTE) {
if ((c = *patnext++) == EOS) {
c = QUOTE;
--patnext;
}
*bufnext++ = c | M_PROTECT;
}
else
*bufnext++ = c;
}
*bufnext = EOS;
if (flags & GLOB_BRACE)
return globexp1(patbuf, pglob);
else
return glob0(patbuf, pglob);
}
/*
* Expand recursively a glob {} pattern. When there is no more expansion
* invoke the standard globbing routine to glob the rest of the magic
* characters
*/
static int globexp1(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char* ptr = pattern;
int rv;
/* Protect a single {}, for find(1), like csh */
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
return glob0(pattern, pglob);
while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
if (!globexp2(ptr, pattern, pglob, &rv))
return rv;
return glob0(pattern, pglob);
}
/*
* Recursive brace globbing helper. Tries to expand a single brace.
* If it succeeds then it invokes globexp1 with the new pattern.
* If it fails then it tries to glob the rest of the pattern and returns.
*/
static int globexp2(ptr, pattern, pglob, rv)
const Char *ptr, *pattern;
glob_t *pglob;
int *rv;
{
int i;
Char *lm, *ls;
const Char *pe, *pm, *pl;
Char patbuf[MAXPATHLEN + 1];
/* copy part up to the brace */
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
continue;
ls = lm;
/* Find the balanced brace */
for (i = 0, pe = ++ptr; *pe; pe++)
if (*pe == LBRACKET) {
/* Ignore everything between [] */
for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
continue;
if (*pe == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pe = pm;
}
}
else if (*pe == LBRACE)
i++;
else if (*pe == RBRACE) {
if (i == 0)
break;
i--;
}
/* Non matching braces; just glob the pattern */
if (i != 0 || *pe == EOS) {
*rv = glob0(patbuf, pglob);
return 0;
}
for (i = 0, pl = pm = ptr; pm <= pe; pm++)
switch (*pm) {
case LBRACKET:
/* Ignore everything between [] */
for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
continue;
if (*pm == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pm = pl;
}
break;
case LBRACE:
i++;
break;
case RBRACE:
if (i) {
i--;
break;
}
/* FALLTHROUGH */
case COMMA:
if (i && *pm == COMMA)
break;
else {
/* Append the current string */
for (lm = ls; (pl < pm); *lm++ = *pl++)
continue;
/*
* Append the rest of the pattern after the
* closing brace
*/
for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
continue;
/* Expand the current pattern */
#ifdef DEBUG
qprintf("globexp2:", patbuf);
#endif
*rv = globexp1(patbuf, pglob);
/* move after the comma, to the next string */
pl = pm + 1;
}
break;
default:
break;
}
*rv = 0;
return 0;
}
/*
* expand tilde from the passwd file.
*/
static const Char *
globtilde(pattern, patbuf, patbuf_len, pglob)
const Char *pattern;
Char *patbuf;
size_t patbuf_len;
glob_t *pglob;
{
struct passwd *pwd;
char *h;
const Char *p;
Char *b, *eb;
if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
eb = &patbuf[patbuf_len - 1];
for (p = pattern + 1, h = (char *) patbuf;
h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
continue;
*h = EOS;
if (((char *) patbuf)[0] == EOS) {
/*
* handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
*/
#ifdef HAVE_ISSETUGID
if (issetugid() != 0 || (h = getenv("HOME")) == NULL) {
#endif
if ((pwd = getpwuid(getuid())) == NULL)
return pattern;
else
h = pwd->pw_dir;
#ifdef HAVE_ISSETUGID
}
#endif
}
else {
/*
* Expand a ~user
*/
if ((pwd = getpwnam((char*) patbuf)) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
/* Copy the home directory */
for (b = patbuf; b < eb && *h; *b++ = *h++)
continue;
/* Append the rest of the pattern */
while (b < eb && (*b++ = *p++) != EOS)
continue;
*b = EOS;
return patbuf;
}
/*
* The main glob() routine: compiles the pattern (optionally processing
* quotes), calls glob1() to do the real pattern matching, and finally
* sorts the list (unless unsorted operation is requested). Returns 0
* if things went well, nonzero if errors occurred. It is not an error
* to find no matches.
*/
static int
glob0(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char *qpatnext;
int c, err, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN+1];
qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char),
pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
/* We don't need to check for buffer overflow any more. */
while ((c = *qpatnext++) != EOS) {
switch (c) {
case LBRACKET:
c = *qpatnext;
if (c == NOT)
++qpatnext;
if (*qpatnext == EOS ||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
*bufnext++ = LBRACKET;
if (c == NOT)
--qpatnext;
break;
}
*bufnext++ = M_SET;
if (c == NOT)
*bufnext++ = M_NOT;
c = *qpatnext++;
do {
*bufnext++ = CHAR(c);
if (*qpatnext == RANGE &&
(c = qpatnext[1]) != RBRACKET) {
*bufnext++ = M_RNG;
*bufnext++ = CHAR(c);
qpatnext += 2;
}
} while ((c = *qpatnext++) != RBRACKET);
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_END;
break;
case QUESTION:
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_ONE;
break;
case STAR:
pglob->gl_flags |= GLOB_MAGCHAR;
/* collapse adjacent stars to one,
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
*bufnext++ = M_ALL;
break;
default:
*bufnext++ = CHAR(c);
break;
}
}
*bufnext = EOS;
#ifdef DEBUG
qprintf("glob0:", patbuf);
#endif
if ((err = glob1(patbuf, pglob)) != 0)
return(err);
/*
* If there was no match we are going to append the pattern
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
* and the pattern did not contain any magic characters
* GLOB_NOMAGIC is there just for compatibility with csh.
*/
if (pglob->gl_pathc == oldpathc) {
if ((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR)))
return(globextend(pattern, pglob));
else
return(GLOB_NOMATCH);
}
if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
return(0);
}
static int
compare(p, q)
const void *p, *q;
{
return(strcmp(*(char **)p, *(char **)q));
}
static int
glob1(pattern, pglob)
Char *pattern;
glob_t *pglob;
{
Char pathbuf[MAXPATHLEN+1];
/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
if (*pattern == EOS)
return(0);
return(glob2(pathbuf, pathbuf, pattern, pglob));
}
/*
* The functions glob2 and glob3 are mutually recursive; there is one level
* of recursion for each segment in the pattern that contains one or more
* meta characters.
*/
static int
glob2(pathbuf, pathend, pattern, pglob)
Char *pathbuf, *pathend, *pattern;
glob_t *pglob;
{
struct stat sb;
Char *p, *q;
int anymeta;
/*
* Loop over pattern segments until end of pattern or until
* segment with meta character found.
*/
for (anymeta = 0;;) {
if (*pattern == EOS) { /* End of pattern? */
*pathend = EOS;
if (g_lstat(pathbuf, &sb, pglob))
return(0);
if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
|| (S_ISLNK(sb.st_mode) &&
(g_stat(pathbuf, &sb, pglob) == 0) &&
S_ISDIR(sb.st_mode)))) {
*pathend++ = SEP;
*pathend = EOS;
}
++pglob->gl_matchc;
return(globextend(pathbuf, pglob));
}
/* Find end of next segment, copy tentatively to pathend. */
q = pathend;
p = pattern;
while (*p != EOS && *p != SEP) {
if (ismeta(*p))
anymeta = 1;
*q++ = *p++;
}
if (!anymeta) { /* No expansion, do next segment. */
pathend = q;
pattern = p;
while (*pattern == SEP)
*pathend++ = *pattern++;
} else /* Need expansion, recurse. */
return(glob3(pathbuf, pathend, pattern, p, pglob));
}
/* NOTREACHED */
}
static int
glob3(pathbuf, pathend, pattern, restpattern, pglob)
Char *pathbuf, *pathend, *pattern, *restpattern;
glob_t *pglob;
{
register struct dirent *dp;
DIR *dirp;
int err;
char buf[MAXPATHLEN];
/*
* The readdirfunc declaration can't be prototyped, because it is
* assigned, below, to two functions which are prototyped in glob.h
* and dirent.h as taking pointers to differently typed opaque
* structures.
*/
struct dirent *(*readdirfunc)();
*pathend = EOS;
errno = 0;
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
/* TODO: don't call for ENOENT or ENOTDIR? */
if (pglob->gl_errfunc) {
g_Ctoc(pathbuf, buf);
if (pglob->gl_errfunc(buf, errno) ||
pglob->gl_flags & GLOB_ERR)
return (GLOB_ABORTED);
}
return(0);
}
err = 0;
/* Search directory for matching names. */
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
readdirfunc = pglob->gl_readdir;
else
readdirfunc = readdir;
while ((dp = (*readdirfunc)(dirp))) {
register u_char *sc;
register Char *dc;
/* Initial DOT must be matched literally. */
if (dp->d_name[0] == DOT && *pattern != DOT)
continue;
for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
if (!match(pathend, pattern, restpattern)) {
*pathend = EOS;
continue;
}
err = glob2(pathbuf, --dc, restpattern, pglob);
if (err)
break;
}
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
(*pglob->gl_closedir)(dirp);
else
closedir(dirp);
return(err);
}
/*
* Extend the gl_pathv member of a glob_t structure to accomodate a new item,
* add the new item, and update gl_pathc.
*
* This assumes the BSD realloc, which only copies the block when its size
* crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
* behavior.
*
* Return 0 if new item added, error code if memory couldn't be allocated.
*
* Invariant of the glob_t structure:
* Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
*/
static int
globextend(path, pglob)
const Char *path;
glob_t *pglob;
{
register char **pathv;
register int i;
u_int newsize;
char *copy;
const Char *p;
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
pathv = pglob->gl_pathv ?
realloc((char *)pglob->gl_pathv, newsize) :
malloc(newsize);
if (pathv == NULL) {
if (pglob->gl_pathv)
free(pglob->gl_pathv);
return(GLOB_NOSPACE);
}
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
/* first time around -- clear initial gl_offs items */
pathv += pglob->gl_offs;
for (i = pglob->gl_offs; --i >= 0; )
*--pathv = NULL;
}
pglob->gl_pathv = pathv;
for (p = path; *p++;)
continue;
if ((copy = malloc(p - path)) != NULL) {
g_Ctoc(path, copy);
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
}
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
return(copy == NULL ? GLOB_NOSPACE : 0);
}
/*
* pattern matching function for filenames. Each occurrence of the *
* pattern causes a recursion level.
*/
static int
match(name, pat, patend)
register Char *name, *pat, *patend;
{
int ok, negate_range;
Char c, k;
while (pat < patend) {
c = *pat++;
switch (c & M_MASK) {
case M_ALL:
if (pat == patend)
return(1);
do
if (match(name, pat, patend))
return(1);
while (*name++ != EOS);
return(0);
case M_ONE:
if (*name++ == EOS)
return(0);
break;
case M_SET:
ok = 0;
if ((k = *name++) == EOS)
return(0);
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END)
if ((*pat & M_MASK) == M_RNG) {
if (c <= k && k <= pat[1])
ok = 1;
pat += 2;
} else if (c == k)
ok = 1;
if (ok == negate_range)
return(0);
break;
default:
if (*name++ != c)
return(0);
break;
}
}
return(*name == EOS);
}
/* Free allocated data belonging to a glob_t structure. */
void
openbsd_globfree(pglob)
glob_t *pglob;
{
register int i;
register char **pp;
if (pglob->gl_pathv != NULL) {
pp = pglob->gl_pathv + pglob->gl_offs;
for (i = pglob->gl_pathc; i--; ++pp)
if (*pp)
free(*pp);
free(pglob->gl_pathv);
}
}
static DIR *
g_opendir(str, pglob)
register Char *str;
glob_t *pglob;
{
char buf[MAXPATHLEN];
if (!*str)
strcpy(buf, ".");
else
g_Ctoc(str, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_opendir)(buf));
return(opendir(buf));
}
static int
g_lstat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_lstat)(buf, sb));
return(lstat(buf, sb));
}
static int
g_stat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_stat)(buf, sb));
return(stat(buf, sb));
}
static Char *
g_strchr(str, ch)
Char *str;
int ch;
{
do {
if (*str == ch)
return (str);
} while (*str++);
return (NULL);
}
#ifdef notdef
static Char *
g_strcat(dst, src)
Char *dst;
const Char* src;
{
Char *sdst = dst;
while (*dst++)
continue;
--dst;
while((*dst++ = *src++) != EOS)
continue;
return (sdst);
}
#endif
static void
g_Ctoc(str, buf)
register const Char *str;
char *buf;
{
register char *dc;
for (dc = buf; (*dc++ = *str++) != EOS;)
continue;
}
#ifdef DEBUG
static void
qprintf(str, s)
const char *str;
register Char *s;
{
register Char *p;
(void)printf("%s:\n", str);
for (p = s; *p; p++)
(void)printf("%c", CHAR(*p));
(void)printf("\n");
for (p = s; *p; p++)
(void)printf("%c", *p & M_PROTECT ? '"' : ' ');
(void)printf("\n");
for (p = s; *p; p++)
(void)printf("%c", ismeta(*p) ? '_' : ' ');
(void)printf("\n");
}
#endif

27
compat/inet_aton.c Normal file
View File

@ -0,0 +1,27 @@
/*
** Copyright 2002 University of Illinois Board of Trustees
** Copyright 2002 Mark D. Roth
** All rights reserved.
**
** inet_aton.c - inet_aton() function for compatibility library
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int
inet_aton(const char *cp, struct in_addr *inp)
{
inp->s_addr = inet_addr(cp);
if (inp->s_addr == -1)
return 0;
return 1;
}

591
compat/module.ac Normal file
View File

@ -0,0 +1,591 @@
# COMPAT_VAR___PROGNAME
# ---------------------
# Check if libc defines the __progname variable.
AC_DEFUN([COMPAT_VAR___PROGNAME], [
AC_CACHE_CHECK([if libc defines __progname],
[ac_cv_libc_defines___progname],
[AC_TRY_LINK([],
[
extern char *__progname;
printf("%s", __progname);
],
[ac_cv_libc_defines___progname=yes],
[ac_cv_libc_defines___progname=no]
)]
)
if test "$ac_cv_libc_defines___progname" = "yes"; then
AC_DEFINE([HAVE___PROGNAME], 1,
[Define if libc defines the __progname variable])
fi
])
# COMPAT_FUNC_BASENAME
# --------------------
# Check for working basename() function.
AC_DEFUN([COMPAT_FUNC_BASENAME], [
AC_DEFINE([NEED_BASENAME], 1,
[Define if you want to use the basename function])
AC_CHECK_HEADERS([libgen.h])
AC_CACHE_CHECK([for working basename],
[compat_cv_func_basename_works],
[AC_TRY_RUN([
#include <stdio.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
typedef struct {
char *test;
char *result;
} test_t;
const test_t tests[] = {
{ "/usr/local/foo", "foo" },
{ "/usr/local/foo/", "foo" },
{ NULL, NULL }
};
int main() {
char test1[1024];
int i;
for (i = 0; tests[i].test; i++) {
strcpy(test1, tests[i].test);
if (strcmp(basename(test1), tests[i].result) ||
strcmp(test1, tests[i].test))
exit(1);
}
exit(0);
}
],
[compat_cv_func_basename_works=yes],
[compat_cv_func_basename_works=no],
[compat_cv_func_basename_works=no]
)]
)
if test "$compat_cv_func_basename_works" = "yes"; then
AC_DEFINE([HAVE_BASENAME], 1,
[Define if your system has a working basename])
else
AC_LIBOBJ([basename])
fi
])
# COMPAT_FUNC_DIRNAME
# -------------------
# Check for working dirname() function.
AC_DEFUN([COMPAT_FUNC_DIRNAME], [
AC_DEFINE([NEED_DIRNAME], 1,
[Define if you want to use the dirname function])
AC_CHECK_HEADERS([libgen.h])
AC_CACHE_CHECK([for working dirname],
[compat_cv_func_dirname_works],
[AC_TRY_RUN([
#include <stdio.h>
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
typedef struct {
char *test;
char *result;
} test_t;
const test_t tests[] = {
{ "foobar", "." },
{ "/usr/local/foo", "/usr/local" },
{ "/usr/local/foo/", "/usr/local" },
{ "/", "/" },
{ "", "." },
{ NULL, NULL }
};
int main() {
char test1[1024];
int i;
for (i = 0; tests[i].test; i++) {
strcpy(test1, tests[i].test);
if (strcmp(dirname(test1), tests[i].result) ||
strcmp(test1, tests[i].test))
exit(1);
}
exit(0);
}
],
[compat_cv_func_dirname_works=yes],
[compat_cv_func_dirname_works=no],
[compat_cv_func_dirname_works=no]
)]
)
if test "$compat_cv_func_dirname_works" = "yes"; then
AC_DEFINE([HAVE_DIRNAME], 1,
[Define if your system has a working dirname])
else
AC_LIBOBJ([dirname])
fi
])
# COMPAT_FUNC_FNMATCH
# -------------------
# Check for working fnmatch() function.
AC_DEFUN([COMPAT_FUNC_FNMATCH], [
AC_DEFINE([NEED_FNMATCH], 1, [Define if you want to use the fnmatch function])
AC_CHECK_HEADERS([fnmatch.h])
if test "$ac_cv_header_fnmatch_h" = "yes"; then
AC_FUNC_FNMATCH
fi
if test "$ac_cv_func_fnmatch_works" != "yes"; then
AC_CHECK_HEADERS([ctype.h])
AC_LIBOBJ([fnmatch])
fi
])
# COMPAT_FUNC_GLOB
# ----------------
# Check for working glob() function.
AC_DEFUN([COMPAT_FUNC_GLOB], [
AC_DEFINE([NEED_GLOB], 1, [Define if you want to use the glob function])
AC_CHECK_HEADERS([glob.h])
AC_CACHE_CHECK([for working glob],
[compat_cv_func_glob_works],
[AC_TRY_RUN([
#include <stdio.h>
#ifdef HAVE_GLOB_H
# include <glob.h>
#endif
#ifndef GLOB_ABORTED
# define GLOB_ABORTED GLOB_ABEND
#endif
int main() {
glob_t g;
int status;
status = glob("conf*", 0, NULL, &g);
switch (status) {
case 0:
case GLOB_NOSPACE:
case GLOB_ABORTED:
case GLOB_NOMATCH:
exit(0);
break;
default:
exit(1);
break;
}
}
],
[compat_cv_func_glob_works=yes],
[compat_cv_func_glob_works=no],
[compat_cv_func_glob_works=no]
)]
)
if test "$compat_cv_func_glob_works" = "yes"; then
AC_DEFINE([HAVE_GLOB], 1, [Define if your system has a working glob])
else
AC_LIBOBJ([glob])
AC_CHECK_FUNCS([issetugid])
fi
])
# COMPAT_FUNC_MAKEDEV
# -------------------
# Check for number of arguments expected by makedev().
AC_DEFUN([COMPAT_FUNC_MAKEDEV], [
AC_REQUIRE([AC_HEADER_MAJOR])
AC_DEFINE([NEED_MAKEDEV], 1,
[Define if you want to use the makedev function])
AC_CACHE_CHECK([whether makedev expects three arguments],
[compat_cv_func_makedev_three_args],
[AC_RUN_IFELSE([
AC_LANG_PROGRAM([[
#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
#else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
#endif
]], [[
dev_t dev;
major_t maj = 5;
minor_t min = 7;
dev = makedev(0, maj, min);
if (major(dev) != maj
|| minor(dev) != min)
exit(1);
exit(0);
]])],
[compat_cv_func_makedev_three_args=yes],
[compat_cv_func_makedev_three_args=no]
)]
)
if test "$compat_cv_func_makedev_three_args" = "yes"; then
AC_DEFINE([MAKEDEV_THREE_ARGS], 1,
[Define as 1 if makedev expects three arguments])
fi
])
# COMPAT_FUNC_SNPRINTF
# --------------------
# Check for working snprintf() function.
AC_DEFUN([COMPAT_FUNC_SNPRINTF], [
AC_DEFINE([NEED_SNPRINTF], 1,
[Define if you want to use the snprintf function])
AC_CACHE_CHECK([for working snprintf],
[compat_cv_func_snprintf_works],
[AC_TRY_RUN([
#include <stdio.h>
typedef struct {
int length;
char *test;
int retval;
char *result;
} test_t;
const test_t tests[] = {
{ 10, "12345678901234567890", 20, "123456789" },
#if 0
{ 0, "12345678901234567890", 20, NULL },
{ -1, "12345678901234567890", -1, NULL },
#endif
{ 0, NULL, 0, NULL }
};
int main() {
char test1[1024];
int i;
for (i = 0; tests[i].test; i++) {
memset(test1, 'X', sizeof(test1));
if ((snprintf(test1, tests[i].length, "%s", tests[i].test)
!= tests[i].retval) ||
(tests[i].result && strcmp(tests[i].result, test1)))
exit(1);
}
exit(0);
}
],
[compat_cv_func_snprintf_works=yes],
[compat_cv_func_snprintf_works=no],
[compat_cv_func_snprintf_works=no]
)]
)
if test "$compat_cv_func_snprintf_works" = "yes"; then
AC_DEFINE([HAVE_SNPRINTF], 1,
[Define if your system has a working snprintf])
else
AC_LIBOBJ([snprintf])
fi
])
# COMPAT_PROTO_MACRO(FUNCTION, HEADER, MACRO-LIST, [BODY])
# --------------------------------------------------------
# Determine which C preprocessor macro is needed to expose prototype of
# FUNCTION in HEADER. First, we try with nothing special defined; then we
# try with each macro from MACRO-LIST. We stop as soon as it's found
# and adjust $CFLAGS appropriately.
AC_DEFUN([COMPAT_PROTO_MACRO],
[AC_CACHE_CHECK([what to define for $1 prototype],
[compat_cv_proto_]$1[_macro],
[AC_TRY_COMPILE(
[
#include <$2>
],
[
void *funcptr;
$4
funcptr = $1;
],
[compat_cv_proto_]$1[_macro="none"],
[for macro in $3; do
AC_TRY_COMPILE(
[
#define $macro
#include <$2>
],
[
void *funcptr;
$4
funcptr = $1;
],
[
compat_cv_proto_]$1[_macro="$macro"
break
],
[compat_cv_proto_]$1[_macro="not found"]
)
done]
)]
)]
if test -n "$compat_cv_proto_$1_macro" -a "$compat_cv_proto_$1_macro" != "not found" -a "$compat_cv_proto_$1_macro" != "none"; then
CFLAGS="${CFLAGS} -D$compat_cv_proto_$1_macro";
fi
)
# COMPAT_FUNC_STRTOK_R
# --------------------
# Check for working strtok_r().
AC_DEFUN([COMPAT_FUNC_STRTOK_R], [
AC_DEFINE([NEED_STRTOK_R], 1,
[Define if you want to use the strtok_r function])
AC_REPLACE_FUNCS([strtok_r])
COMPAT_PROTO_MACRO([strtok_r], [string.h], [_REENTRANT _THREAD_SAFE])
])
# COMPAT_FUNC_GETPWUID_R
# ----------------------
# Check for POSIX-compliant getpwuid_r().
AC_DEFUN([COMPAT_FUNC_GETPWUID_R], [
COMPAT_PROTO_MACRO([getpwuid_r], [pwd.h],
[_POSIX_PTHREAD_SEMANTICS _REENTRANT],
[
struct passwd pwd, *pwdp;
char buf[10240];
getpwuid_r(0, &pwd, buf, sizeof(buf), &pwdp);
]
)
if test "$compat_cv_proto_getpwuid_r_macro" != "not found"; then
AC_DEFINE([HAVE_GETPWUID_R], 1,
[Define if your system has a POSIX-compliant getpwuid_r])
else
AC_MSG_WARN([cannot find usable getpwuid_r - resulting libraries will not be thread-safe])
fi
])
# COMPAT_FUNC_GETHOSTBYNAME_R
# ---------------------------
# Check for gethostbyname_r().
AC_DEFUN([COMPAT_FUNC_GETHOSTBYNAME_R], [
AC_REQUIRE([AC_TYPE_SIZE_T])
AC_DEFINE([NEED_GETHOSTBYNAME_R], 1,
[Define if you want to use the gethostbyname_r function])
AC_SEARCH_LIBS([gethostbyname_r], [nsl])
if test "$ac_cv_search_gethostbyname_r" != "no"; then
COMPAT_PROTO_MACRO([gethostbyname_r], [netdb.h], [_REENTRANT])
AC_CACHE_CHECK(
[for number of arguments to gethostbyname_r],
[compat_cv_gethostbyname_r_args],
[AC_TRY_COMPILE(
[
#include <netdb.h>
],
[
struct hostent hent;
char buf[10240];
int herr;
gethostbyname_r("localhost", &hent, buf, sizeof(buf), &herr);
],
[compat_cv_gethostbyname_r_args=5],
[AC_TRY_COMPILE(
[
#include <netdb.h>
],
[
struct hostent hent, *hp;
char buf[10240];
int herr;
gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &herr);
],
[compat_cv_gethostbyname_r_args=6],
[AC_TRY_COMPILE(
[
#include <netdb.h>
],
[
struct hostent hent;
struct hostent_data hdata;
gethostbyname_r("localhost", &hent, &hdata);
],
[compat_cv_gethostbyname_r_args=3],
[compat_cv_gethostbyname_r_args=no]
)]
)]
)]
)
if test "$compat_cv_gethostbyname_r_args" != "no"; then
AC_DEFINE([HAVE_GETHOSTBYNAME_R], 1,
[Define if you have the gethostbyname_r function])
AC_DEFINE_UNQUOTED([GETHOSTBYNAME_R_NUM_ARGS],
[$compat_cv_gethostbyname_r_args],
[Define to number of arguments for gethostbyname_r])
if test "$compat_cv_gethostbyname_r_args" != "6"; then
AC_LIBOBJ([gethostbyname_r])
fi
else
AC_MSG_WARN([unknown form of gethostbyname_r - resulting libraries will not be thread-safe])
fi
else
AC_MSG_WARN([cannot find gethostbyname_r - resulting libraries will not be thread-safe])
fi
])
# COMPAT_FUNC_GETSERVBYNAME_R
# ---------------------------
# Check for getservbyname_r().
AC_DEFUN([COMPAT_FUNC_GETSERVBYNAME_R], [
AC_REQUIRE([AC_TYPE_SIZE_T])
AC_DEFINE([NEED_GETSERVBYNAME_R], 1,
[Define if you want to use the getservbyname_r function])
AC_SEARCH_LIBS([getservbyname_r], [socket nsl])
if test "$ac_cv_search_getservbyname_r" != "no"; then
COMPAT_PROTO_MACRO([getservbyname_r], [netdb.h], [_REENTRANT])
AC_CACHE_CHECK(
[for number of arguments to getservbyname_r],
[compat_cv_getservbyname_r_args],
[AC_TRY_COMPILE(
[
#include <netdb.h>
],
[
struct servent sent;
char buf[10240];
getservbyname_r("telnet", "tcp", &sent, buf, sizeof(buf));
],
[compat_cv_getservbyname_r_args=5],
[AC_TRY_COMPILE(
[
#include <netdb.h>
],
[
struct servent sent, *sp;
char buf[10240];
getservbyname_r("telnet", "tcp", &sent, buf, sizeof(buf), &sp);
],
[compat_cv_getservbyname_r_args=6],
[AC_TRY_COMPILE(
[
#include <netdb.h>
],
[
struct servent sent;
struct servent_data sdata;
getservbyname_r("telnet", "tcp", &sent, &sdata);
],
[compat_cv_getservbyname_r_args=4],
[compat_cv_getservbyname_r_args=no]
)]
)]
)]
)
if test "$compat_cv_getservbyname_r_args" != "no"; then
AC_DEFINE([HAVE_GETSERVBYNAME_R], 1,
[Define if you have the getservbyname_r function])
AC_DEFINE_UNQUOTED([GETSERVBYNAME_R_NUM_ARGS],
[$compat_cv_getservbyname_r_args],
[Define to number of arguments for getservbyname_r])
if test "$compat_cv_getservbyname_r_args" != "6"; then
AC_LIBOBJ([getservbyname_r])
fi
else
AC_MSG_WARN([unknown form of getservbyname_r - resulting libraries will not be thread-safe])
fi
else
AC_MSG_WARN([cannot find getservbyname_r - resulting libraries will not be thread-safe])
fi
])
# COMPAT_REPLACE_FUNC(function)
# -----------------------------
# Replacement for AC_REPLACE_FUNCS.
AC_DEFUN([COMPAT_REPLACE_FUNC], [
AC_DEFINE([NEED_]translit($1,[a-z],[A-Z]), 1,
[Define if you want to use the ]$1[ function])
AC_CHECK_FUNC($1,
[AC_DEFINE([HAVE_]translit($1,[a-z],[A-Z]), 1,
[Define if you have the ]$1[ function])],
[AC_LIBOBJ(]$1[)]
)
])
# COMPAT_FUNC_GETHOSTNAME
# -----------------------
# Check for gethostname().
AC_DEFUN([COMPAT_FUNC_GETHOSTNAME], [
COMPAT_REPLACE_FUNC([gethostname])
])
# COMPAT_FUNC_INET_ATON
# ---------------------
# Check for inet_aton().
AC_DEFUN([COMPAT_FUNC_INET_ATON], [
COMPAT_REPLACE_FUNC([inet_aton])
])
# COMPAT_FUNC_STRDUP
# ------------------
# Check for strdup().
AC_DEFUN([COMPAT_FUNC_STRDUP], [
COMPAT_REPLACE_FUNC([strdup])
])
# COMPAT_FUNC_STRLCAT
# -------------------
# Check for strlcat().
AC_DEFUN([COMPAT_FUNC_STRLCAT], [
COMPAT_REPLACE_FUNC([strlcat])
])
# COMPAT_FUNC_STRLCPY
# -------------------
# Check for strlcpy().
AC_DEFUN([COMPAT_FUNC_STRLCPY], [
COMPAT_REPLACE_FUNC([strlcpy])
])
# COMPAT_FUNC_STRMODE
# -------------------
# Check for strmode().
AC_DEFUN([COMPAT_FUNC_STRMODE], [
COMPAT_REPLACE_FUNC([strmode])
])
# COMPAT_FUNC_STRRSTR
# -------------------
# Check for strrstr().
AC_DEFUN([COMPAT_FUNC_STRRSTR], [
COMPAT_REPLACE_FUNC([strrstr])
])
# COMPAT_FUNC_STRSEP
# ------------------
# Check for strsep().
AC_DEFUN([COMPAT_FUNC_STRSEP], [
COMPAT_REPLACE_FUNC([strsep])
])

788
compat/snprintf.c Normal file
View File

@ -0,0 +1,788 @@
/**************************************************************
* Original:
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
* A bombproof version of doprnt (dopr) included.
* Sigh. This sort of thing is always nasty do deal with. Note that
* the version here does not include floating point...
*
* snprintf() is used instead of sprintf() as it does limit checks
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
* causing nast effects.
*
* More Recently:
* Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
* This was ugly. It is still ugly. I opted out of floating point
* numbers, but the formatter understands just about everything
* from the normal C string format, at least as far as I can tell from
* the Solaris 2.5 printf(3S) man page.
*
* Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
* Ok, added some minimal floating point support, which means this
* probably requires libm on most operating systems. Don't yet
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
* was pretty badly broken, it just wasn't being exercised in ways
* which showed it, so that's been fixed. Also, formated the code
* to mutt conventions, and removed dead code left over from the
* original. Also, there is now a builtin-test, just compile with:
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
* and run snprintf for results.
*
* Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
* The PGP code was using unsigned hexadecimal formats.
* Unfortunately, unsigned formats simply didn't work.
*
* Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
* The original code assumed that both snprintf() and vsnprintf() were
* missing. Some systems only have snprintf() but not vsnprintf(), so
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
*
**************************************************************/
#include <config.h>
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
#include <string.h>
# include <ctype.h>
#include <sys/types.h>
/* Define this as a fall through, HAVE_STDARG_H is probably already set */
#define HAVE_VARARGS_H
/* varargs declarations: */
#if defined(HAVE_STDARG_H)
# include <stdarg.h>
# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
# define VA_LOCAL_DECL va_list ap
# define VA_START(f) va_start(ap, f)
# define VA_SHIFT(v,t) ; /* no-op for ANSI */
# define VA_END va_end(ap)
#else
# if defined(HAVE_VARARGS_H)
# include <varargs.h>
# undef HAVE_STDARGS
# define VA_LOCAL_DECL va_list ap
# define VA_START(f) va_start(ap) /* f is ignored! */
# define VA_SHIFT(v,t) v = va_arg(ap,t)
# define VA_END va_end(ap)
# else
/*XX ** NO VARARGS ** XX*/
# endif
#endif
/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
static void dopr (char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags);
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
long double fvalue, int min, int max, int flags);
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
/*
* dopr(): poor man's version of doprintf
*/
/* format read states */
#define DP_S_DEFAULT 0
#define DP_S_FLAGS 1
#define DP_S_MIN 2
#define DP_S_DOT 3
#define DP_S_MAX 4
#define DP_S_MOD 5
#define DP_S_CONV 6
#define DP_S_DONE 7
/* format flags - Bits */
#define DP_F_MINUS (1 << 0)
#define DP_F_PLUS (1 << 1)
#define DP_F_SPACE (1 << 2)
#define DP_F_NUM (1 << 3)
#define DP_F_ZERO (1 << 4)
#define DP_F_UP (1 << 5)
#define DP_F_UNSIGNED (1 << 6)
/* Conversion Flags */
#define DP_C_SHORT 1
#define DP_C_LONG 2
#define DP_C_LDOUBLE 3
#define char_to_int(p) (p - '0')
#define MAX(p,q) ((p >= q) ? p : q)
static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
{
char ch;
long value;
long double fvalue;
char *strvalue;
int min;
int max;
int state;
int flags;
int cflags;
size_t currlen;
state = DP_S_DEFAULT;
currlen = flags = cflags = min = 0;
max = -1;
ch = *format++;
while (state != DP_S_DONE)
{
if ((ch == '\0') || (currlen >= maxlen))
state = DP_S_DONE;
switch(state)
{
case DP_S_DEFAULT:
if (ch == '%')
state = DP_S_FLAGS;
else
dopr_outch (buffer, &currlen, maxlen, ch);
ch = *format++;
break;
case DP_S_FLAGS:
switch (ch)
{
case '-':
flags |= DP_F_MINUS;
ch = *format++;
break;
case '+':
flags |= DP_F_PLUS;
ch = *format++;
break;
case ' ':
flags |= DP_F_SPACE;
ch = *format++;
break;
case '#':
flags |= DP_F_NUM;
ch = *format++;
break;
case '0':
flags |= DP_F_ZERO;
ch = *format++;
break;
default:
state = DP_S_MIN;
break;
}
break;
case DP_S_MIN:
if (isdigit((unsigned char)ch))
{
min = 10*min + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
{
min = va_arg (args, int);
ch = *format++;
state = DP_S_DOT;
}
else
state = DP_S_DOT;
break;
case DP_S_DOT:
if (ch == '.')
{
state = DP_S_MAX;
ch = *format++;
}
else
state = DP_S_MOD;
break;
case DP_S_MAX:
if (isdigit((unsigned char)ch))
{
if (max < 0)
max = 0;
max = 10*max + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
{
max = va_arg (args, int);
ch = *format++;
state = DP_S_MOD;
}
else
state = DP_S_MOD;
break;
case DP_S_MOD:
/* Currently, we don't support Long Long, bummer */
switch (ch)
{
case 'h':
cflags = DP_C_SHORT;
ch = *format++;
break;
case 'l':
cflags = DP_C_LONG;
ch = *format++;
break;
case 'L':
cflags = DP_C_LDOUBLE;
ch = *format++;
break;
default:
break;
}
state = DP_S_CONV;
break;
case DP_S_CONV:
switch (ch)
{
case 'd':
case 'i':
if (cflags == DP_C_SHORT)
value = va_arg (args, short int);
else if (cflags == DP_C_LONG)
value = va_arg (args, long int);
else
value = va_arg (args, int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'o':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned short int);
else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int);
else
value = va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
break;
case 'u':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned short int);
else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int);
else
value = va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'X':
flags |= DP_F_UP;
case 'x':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned short int);
else if (cflags == DP_C_LONG)
value = va_arg (args, unsigned long int);
else
value = va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
break;
case 'f':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, long double);
else
fvalue = va_arg (args, double);
/* um, floating point? */
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'E':
flags |= DP_F_UP;
case 'e':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, long double);
else
fvalue = va_arg (args, double);
break;
case 'G':
flags |= DP_F_UP;
case 'g':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, long double);
else
fvalue = va_arg (args, double);
break;
case 'c':
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
break;
case 's':
strvalue = va_arg (args, char *);
if (max < 0)
max = maxlen; /* ie, no max */
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break;
case 'p':
strvalue = va_arg (args, void *);
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
break;
case 'n':
if (cflags == DP_C_SHORT)
{
short int *num;
num = va_arg (args, short int *);
*num = currlen;
}
else if (cflags == DP_C_LONG)
{
long int *num;
num = va_arg (args, long int *);
*num = currlen;
}
else
{
int *num;
num = va_arg (args, int *);
*num = currlen;
}
break;
case '%':
dopr_outch (buffer, &currlen, maxlen, ch);
break;
case 'w':
/* not supported yet, treat as next char */
ch = *format++;
break;
default:
/* Unknown, skip */
break;
}
ch = *format++;
state = DP_S_DEFAULT;
flags = cflags = min = 0;
max = -1;
break;
case DP_S_DONE:
break;
default:
/* hmm? */
break; /* some picky compilers need this */
}
}
if (currlen < maxlen - 1)
buffer[currlen] = '\0';
else
buffer[maxlen - 1] = '\0';
}
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max)
{
int padlen, strln; /* amount to pad */
int cnt = 0;
if (value == 0)
{
value = "<NULL>";
}
for (strln = 0; value[strln]; ++strln); /* strlen */
padlen = min - strln;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justify */
while ((padlen > 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
++cnt;
}
while (*value && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, *value++);
++cnt;
}
while ((padlen < 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
++cnt;
}
}
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags)
{
int signvalue = 0;
unsigned long uvalue;
char convert[20];
int place = 0;
int spadlen = 0; /* amount to space pad */
int zpadlen = 0; /* amount to zero pad */
int caps = 0;
if (max < 0)
max = 0;
uvalue = value;
if(!(flags & DP_F_UNSIGNED))
{
if( value < 0 ) {
signvalue = '-';
uvalue = -value;
}
else
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
signvalue = '+';
else
if (flags & DP_F_SPACE)
signvalue = ' ';
}
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
do {
convert[place++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")
[uvalue % (unsigned)base ];
uvalue = (uvalue / (unsigned)base );
} while(uvalue && (place < 20));
if (place == 20) place--;
convert[place] = 0;
zpadlen = max - place;
spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
if (zpadlen < 0) zpadlen = 0;
if (spadlen < 0) spadlen = 0;
if (flags & DP_F_ZERO)
{
zpadlen = MAX(zpadlen, spadlen);
spadlen = 0;
}
if (flags & DP_F_MINUS)
spadlen = -spadlen; /* Left Justifty */
#ifdef DEBUG_SNPRINTF
dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
zpadlen, spadlen, min, max, place));
#endif
/* Spaces */
while (spadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
--spadlen;
}
/* Sign */
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
/* Zeros */
if (zpadlen > 0)
{
while (zpadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
}
/* Digits */
while (place > 0)
dopr_outch (buffer, currlen, maxlen, convert[--place]);
/* Left Justified spaces */
while (spadlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
++spadlen;
}
}
static long double abs_val (long double value)
{
long double result = value;
if (value < 0)
result = -value;
return result;
}
static long double pow10 (int exp)
{
long double result = 1;
while (exp)
{
result *= 10;
exp--;
}
return result;
}
static long round (long double value)
{
long intpart;
intpart = value;
value = value - intpart;
if (value >= 0.5)
intpart++;
return intpart;
}
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
long double fvalue, int min, int max, int flags)
{
int signvalue = 0;
long double ufvalue;
char iconvert[20];
char fconvert[20];
int iplace = 0;
int fplace = 0;
int padlen = 0; /* amount to pad */
int zpadlen = 0;
int caps = 0;
long intpart;
long fracpart;
/*
* AIX manpage says the default is 0, but Solaris says the default
* is 6, and sprintf on AIX defaults to 6
*/
if (max < 0)
max = 6;
ufvalue = abs_val (fvalue);
if (fvalue < 0)
signvalue = '-';
else
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
signvalue = '+';
else
if (flags & DP_F_SPACE)
signvalue = ' ';
#if 0
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
#endif
intpart = ufvalue;
/*
* Sorry, we only support 9 digits past the decimal because of our
* conversion method
*/
if (max > 9)
max = 9;
/* We "cheat" by converting the fractional part to integer by
* multiplying by a factor of 10
*/
fracpart = round ((pow10 (max)) * (ufvalue - intpart));
if (fracpart >= pow10 (max))
{
intpart++;
fracpart -= pow10 (max);
}
#ifdef DEBUG_SNPRINTF
dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
#endif
/* Convert integer part */
do {
iconvert[iplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
intpart = (intpart / 10);
} while(intpart && (iplace < 20));
if (iplace == 20) iplace--;
iconvert[iplace] = 0;
/* Convert fractional part */
do {
fconvert[fplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
fracpart = (fracpart / 10);
} while(fracpart && (fplace < 20));
if (fplace == 20) fplace--;
fconvert[fplace] = 0;
/* -1 for decimal point, another -1 if we are printing a sign */
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
zpadlen = max - fplace;
if (zpadlen < 0)
zpadlen = 0;
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justifty */
if ((flags & DP_F_ZERO) && (padlen > 0))
{
if (signvalue)
{
dopr_outch (buffer, currlen, maxlen, signvalue);
--padlen;
signvalue = 0;
}
while (padlen > 0)
{
dopr_outch (buffer, currlen, maxlen, '0');
--padlen;
}
}
while (padlen > 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
}
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
while (iplace > 0)
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
/*
* Decimal point. This should probably use locale to find the correct
* char to print out.
*/
dopr_outch (buffer, currlen, maxlen, '.');
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
while (zpadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
while (padlen < 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
}
}
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
{
if (*currlen < maxlen)
buffer[(*currlen)++] = c;
}
#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
#ifndef HAVE_VSNPRINTF
int mutt_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
str[0] = 0;
dopr(str, count, fmt, args);
return(strlen(str));
}
#endif /* !HAVE_VSNPRINTF */
#ifndef HAVE_SNPRINTF
/* VARARGS3 */
#ifdef HAVE_STDARGS
int mutt_snprintf (char *str,size_t count,const char *fmt,...)
#else
int mutt_snprintf (va_alist) va_dcl
#endif
{
#ifndef HAVE_STDARGS
char *str;
size_t count;
char *fmt;
#endif
VA_LOCAL_DECL;
VA_START (fmt);
VA_SHIFT (str, char *);
VA_SHIFT (count, size_t );
VA_SHIFT (fmt, char *);
(void) mutt_vsnprintf(str, count, fmt, ap);
VA_END;
return(strlen(str));
}
#ifdef TEST_SNPRINTF
#ifndef LONG_STRING
#define LONG_STRING 1024
#endif
int main (void)
{
char buf1[LONG_STRING];
char buf2[LONG_STRING];
char *fp_fmt[] = {
"%-1.5f",
"%1.5f",
"%123.9f",
"%10.5f",
"% 10.5f",
"%+22.9f",
"%+4.9f",
"%01.3f",
"%4f",
"%3.1f",
"%3.2f",
NULL
};
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
"%123.9d",
"%5.5d",
"%10.5d",
"% 10.5d",
"%+22.33d",
"%01.3d",
"%4d",
NULL
};
long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
int x, y;
int fail = 0;
int num = 0;
printf ("Testing snprintf format codes against system sprintf...\n");
for (x = 0; fp_fmt[x] != NULL ; x++)
for (y = 0; fp_nums[y] != 0 ; y++)
{
mutt_snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
sprintf (buf2, fp_fmt[x], fp_nums[y]);
if (strcmp (buf1, buf2))
{
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
fp_fmt[x], buf1, buf2);
fail++;
}
num++;
}
for (x = 0; int_fmt[x] != NULL ; x++)
for (y = 0; int_nums[y] != 0 ; y++)
{
mutt_snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
sprintf (buf2, int_fmt[x], int_nums[y]);
if (strcmp (buf1, buf2))
{
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
int_fmt[x], buf1, buf2);
fail++;
}
num++;
}
printf ("%d tests failed out of %d.\n", fail, num);
}
#endif /* SNPRINTF_TEST */
#endif /* !HAVE_SNPRINTF */

62
compat/strdup.c Normal file
View File

@ -0,0 +1,62 @@
/* $OpenBSD: strdup.c,v 1.3 1997/08/20 04:18:52 millert Exp $ */
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strdup.c 8.1 (Berkeley) 6/4/93";
#else
static char *rcsid = "$OpenBSD: strdup.c,v 1.3 1997/08/20 04:18:52 millert Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
char *
openbsd_strdup(str)
const char *str;
{
size_t siz;
char *copy;
siz = strlen(str) + 1;
if ((copy = malloc(siz)) == NULL)
return(NULL);
(void)memcpy(copy, str, siz);
return(copy);
}

72
compat/strlcat.c Normal file
View File

@ -0,0 +1,72 @@
/* $OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(initial dst) + strlen(src); if retval >= siz,
* truncation occurred.
*/
size_t strlcat(dst, src, siz)
char *dst;
const char *src;
size_t siz;
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

68
compat/strlcpy.c Normal file
View File

@ -0,0 +1,68 @@
/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t strlcpy(dst, src, siz)
char *dst;
const char *src;
size_t siz;
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}

152
compat/strmode.c Normal file
View File

@ -0,0 +1,152 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strmode.c,v 1.3 1997/06/13 13:57:20 deraadt Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void
strmode(mode, p)
register mode_t mode;
register char *p;
{
/* print type */
switch (mode & S_IFMT) {
case S_IFDIR: /* directory */
*p++ = 'd';
break;
case S_IFCHR: /* character special */
*p++ = 'c';
break;
case S_IFBLK: /* block special */
*p++ = 'b';
break;
case S_IFREG: /* regular */
*p++ = '-';
break;
case S_IFLNK: /* symbolic link */
*p++ = 'l';
break;
case S_IFSOCK: /* socket */
*p++ = 's';
break;
#ifdef S_IFIFO
case S_IFIFO: /* fifo */
*p++ = 'p';
break;
#endif
#ifdef S_IFWHT
case S_IFWHT: /* whiteout */
*p++ = 'w';
break;
#endif
default: /* unknown */
*p++ = '?';
break;
}
/* usr */
if (mode & S_IRUSR)
*p++ = 'r';
else
*p++ = '-';
if (mode & S_IWUSR)
*p++ = 'w';
else
*p++ = '-';
switch (mode & (S_IXUSR | S_ISUID)) {
case 0:
*p++ = '-';
break;
case S_IXUSR:
*p++ = 'x';
break;
case S_ISUID:
*p++ = 'S';
break;
case S_IXUSR | S_ISUID:
*p++ = 's';
break;
}
/* group */
if (mode & S_IRGRP)
*p++ = 'r';
else
*p++ = '-';
if (mode & S_IWGRP)
*p++ = 'w';
else
*p++ = '-';
switch (mode & (S_IXGRP | S_ISGID)) {
case 0:
*p++ = '-';
break;
case S_IXGRP:
*p++ = 'x';
break;
case S_ISGID:
*p++ = 'S';
break;
case S_IXGRP | S_ISGID:
*p++ = 's';
break;
}
/* other */
if (mode & S_IROTH)
*p++ = 'r';
else
*p++ = '-';
if (mode & S_IWOTH)
*p++ = 'w';
else
*p++ = '-';
switch (mode & (S_IXOTH | S_ISVTX)) {
case 0:
*p++ = '-';
break;
case S_IXOTH:
*p++ = 'x';
break;
case S_ISVTX:
*p++ = 'T';
break;
case S_IXOTH | S_ISVTX:
*p++ = 't';
break;
}
*p++ = ' '; /* will be a '+' if ACL's implemented */
*p = '\0';
}

40
compat/strrstr.c Normal file
View File

@ -0,0 +1,40 @@
/*
** Copyright 1998-2002 University of Illinois Board of Trustees
** Copyright 1998-2002 Mark D. Roth
** All rights reserved.
**
** strrstr.c - strrstr() function for compatibility library
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
/*
** find the last occurrance of find in string
*/
char *
strrstr(char *string, char *find)
{
size_t stringlen, findlen;
char *cp;
findlen = strlen(find);
stringlen = strlen(string);
if (findlen > stringlen)
return NULL;
for (cp = string + stringlen - findlen; cp >= string; cp--)
if (strncmp(cp, find, findlen) == 0)
return cp;
return NULL;
}

87
compat/strsep.c Normal file
View File

@ -0,0 +1,87 @@
/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
#include <stdio.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
#else
static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
#ifndef HAVE_STRSEP
/*
* Get next token from string *stringp, where tokens are possibly-empty
* strings separated by characters from delim.
*
* Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call.
* On return, *stringp points past the last NUL written (if there might
* be further tokens), or is NULL (if there are definitely no more tokens).
*
* If *stringp is NULL, strsep returns NULL.
*/
char *
strsep(stringp, delim)
register char **stringp;
register const char *delim;
{
register char *s;
register const char *spanp;
register int c, sc;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*stringp = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
#endif /* ! HAVE_STRSEP */

187
config.h.in Normal file
View File

@ -0,0 +1,187 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if your system has a working basename */
#undef HAVE_BASENAME
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if the system has the type `dev_t'. */
#undef HAVE_DEV_T
/* Define if your system has a working dirname */
#undef HAVE_DIRNAME
/* Define to 1 if your system has a working POSIX `fnmatch' function. */
#undef HAVE_FNMATCH
/* Define to 1 if you have the <fnmatch.h> header file. */
#undef HAVE_FNMATCH_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `lchown' function. */
#undef HAVE_LCHOWN
/* Define to 1 if you have the <libgen.h> header file. */
#undef HAVE_LIBGEN_H
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ
/* Define to 1 if the system has the type `major_t'. */
#undef HAVE_MAJOR_T
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if the system has the type `minor_t'. */
#undef HAVE_MINOR_T
/* Define to 1 if the system has the type `nlink_t'. */
#undef HAVE_NLINK_T
/* Define if your system has a working snprintf */
#undef HAVE_SNPRINTF
/* Define to 1 if the system has the type `socklen_t'. */
#undef HAVE_SOCKLEN_T
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the strdup function */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the strlcpy function */
#undef HAVE_STRLCPY
/* Define if you have the strmode function */
#undef HAVE_STRMODE
/* Define if you have the strsep function */
#undef HAVE_STRSEP
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if the system has the type `uint64_t'. */
#undef HAVE_UINT64_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
*/
#undef MAJOR_IN_MKDEV
/* Define to 1 if `major', `minor', and `makedev' are declared in
<sysmacros.h>. */
#undef MAJOR_IN_SYSMACROS
/* Define as 1 if makedev expects three arguments */
#undef MAKEDEV_THREE_ARGS
/* Define if you want to use the basename function */
#undef NEED_BASENAME
/* Define if you want to use the dirname function */
#undef NEED_DIRNAME
/* Define if you want to use the fnmatch function */
#undef NEED_FNMATCH
/* Define if you want to use the makedev function */
#undef NEED_MAKEDEV
/* Define if you want to use the snprintf function */
#undef NEED_SNPRINTF
/* Define if you want to use the strdup function */
#undef NEED_STRDUP
/* Define if you want to use the strlcpy function */
#undef NEED_STRLCPY
/* Define if you want to use the strmode function */
#undef NEED_STRMODE
/* Define if you want to use the strsep function */
#undef NEED_STRSEP
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `unsigned long' if not defined in system header files. */
#undef dev_t
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define to `unsigned int' if not defined in system header files. */
#undef major_t
/* Define to `unsigned int' if not defined in system header files. */
#undef minor_t
/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t
/* Define to `unsigned short' if not defined in system header files. */
#undef nlink_t
/* Define to `long' if <sys/types.h> does not define. */
#undef off_t
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* Define to `unsigned long' if not defined in system header files. */
#undef socklen_t
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Define to `long long' if not defined in system header files. */
#undef uint64_t

8102
configure vendored Executable file

File diff suppressed because it is too large Load Diff

114
configure.ac Normal file
View File

@ -0,0 +1,114 @@
dnl ### Normal initialization. ######################################
AC_INIT([libtar], [1.2.11])
AC_PREREQ([2.57])
AC_CONFIG_AUX_DIR([autoconf])
AC_CONFIG_HEADERS([config.h])
AC_COPYRIGHT([[
Copyright (c) 1998-2003 University of Illinois Board of Trustees
Copyright (c) 1998-2003 Mark D. Roth
All rights reserved.
]])
AC_CONFIG_SRCDIR([lib/libtar.h])
ENCAP_PKG([], [postinstall-encap])
dnl ### Load subdirectory modules. ##################################
PSG_MODULE([compat])
PSG_MODULE([listhash], [libtar])
dnl ### Set some option defaults. ###################################
if test -z "$CFLAGS"; then
CFLAGS="-O"
fi
MKDIR="mkdir -p -m 755"
AC_SUBST([MKDIR])
dnl ### Check for compiler et al. ###################################
AC_PROG_CC
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
dnl ### Compiler characteristics. ##################################
AC_AIX
AC_C_CONST
dnl ### Checks for header files. ###################################
AC_HEADER_STDC
AC_CHECK_HEADERS([unistd.h])
AC_HEADER_MAJOR
PSG_REPLACE_TYPE([major_t], [unsigned int], [
#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
#else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
#endif
])
PSG_REPLACE_TYPE([minor_t], [unsigned int], [
#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
#else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
#endif
])
PSG_REPLACE_TYPE([dev_t], [unsigned long], [
#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
# include <sys/mkdev.h>
#else
# ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
# endif
#endif
])
PSG_REPLACE_TYPE([socklen_t], [unsigned long], [
#include <sys/types.h>
#include <sys/socket.h>
])
PSG_REPLACE_TYPE([uint64_t], [long long])
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T
PSG_REPLACE_TYPE([nlink_t], [unsigned short])
dnl ### Check for needed functions. ################################
COMPAT_FUNC_BASENAME
COMPAT_FUNC_DIRNAME
COMPAT_FUNC_FNMATCH
AC_CHECK_FUNCS([lchown])
COMPAT_FUNC_MAKEDEV
COMPAT_FUNC_SNPRINTF
COMPAT_FUNC_STRDUP
AC_FUNC_STRFTIME
COMPAT_FUNC_STRLCPY
COMPAT_FUNC_STRMODE
COMPAT_FUNC_STRSEP
dnl ### Check for libraries. #######################################
AC_ARG_WITH([zlib],
[ --without-zlib Use external gzip binary instead of zlib],
[],
[with_zlib=yes])
if test "$with_zlib" = "yes"; then
AC_CHECK_LIB([z], [gzread])
fi
dnl ### Create output files. #######################################
AC_CONFIG_FILES([Makefile lib/Makefile libtar/Makefile doc/Makefile])
AC_OUTPUT

152
doc/Makefile.in Normal file
View File

@ -0,0 +1,152 @@
# @configure_input@
### Path settings
srcdir = @srcdir@
top_srcdir = @top_srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
libdir = @libdir@
includedir = @includedir@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@ENCAP_DEFS@
### Installation programs and flags
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
INSTALL_DATA = @INSTALL_DATA@
LN_S = @LN_S@
MKDIR = @MKDIR@
@SET_MAKE@
### Makefile rules - no user-servicable parts below
TAR_OPEN_SO = tar_fdopen \
tar_fd \
tar_close
TAR_APPEND_FILE_SO = tar_append_eof \
tar_append_regfile
TAR_BLOCK_READ_SO = tar_block_write
TH_READ_SO = th_write
TH_SET_FROM_STAT_SO = th_finish \
th_set_device \
th_set_group \
th_set_link \
th_set_mode \
th_set_path \
th_set_type \
th_set_user
TAR_EXTRACT_FILE_SO = tar_extract_blockdev \
tar_extract_chardev \
tar_extract_dir \
tar_extract_fifo \
tar_extract_hardlink \
tar_extract_regfile \
tar_extract_symlink \
tar_skip_regfile \
tar_set_file_perms
TH_GET_PATHNAME_SO = TH_ISBLK \
TH_ISCHR \
TH_ISDIR \
TH_ISFIFO \
TH_ISLNK \
TH_ISLONGLINK \
TH_ISLONGNAME \
TH_ISREG \
TH_ISSYM \
th_get_crc \
th_get_devmajor \
th_get_devminor \
th_get_gid \
th_get_linkname \
th_get_mode \
th_get_mtime \
th_get_size \
th_get_uid
TH_PRINT_LONG_LS_SO = th_print
TAR_EXTRACT_ALL_SO = tar_extract_glob \
tar_append_tree
@LISTHASH_PREFIX@_HASH_NEW_SO = \
@LISTHASH_PREFIX@_hash_free \
@LISTHASH_PREFIX@_hash_next \
@LISTHASH_PREFIX@_hash_prev \
@LISTHASH_PREFIX@_hash_search \
@LISTHASH_PREFIX@_hash_add \
@LISTHASH_PREFIX@_hash_getkey \
@LISTHASH_PREFIX@_hash_del
@LISTHASH_PREFIX@_LIST_NEW_SO = \
@LISTHASH_PREFIX@_list_free \
@LISTHASH_PREFIX@_list_next \
@LISTHASH_PREFIX@_list_prev \
@LISTHASH_PREFIX@_list_search \
@LISTHASH_PREFIX@_list_add \
@LISTHASH_PREFIX@_list_add_str \
@LISTHASH_PREFIX@_list_del \
@LISTHASH_PREFIX@_list_dup \
@LISTHASH_PREFIX@_list_merge
DISTCLEANFILES = ../listhash/@LISTHASH_PREFIX@_hash_new.3 \
../listhash/@LISTHASH_PREFIX@_list_new.3
all:
.PHONY: clean distclean install
clean:
distclean: clean
rm -f Makefile ${DISTCLEANFILES}
install: all
${MKDIR} ${DESTDIR}${mandir}/man3
${INSTALL_DATA} ${srcdir}/tar_open.3 ${DESTDIR}${mandir}/man3
for i in ${TAR_OPEN_SO}; do \
echo ".so man3/tar_open.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/tar_append_file.3 ${DESTDIR}${mandir}/man3
for i in ${TAR_APPEND_FILE_SO}; do \
echo ".so man3/tar_append_file.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/tar_block_read.3 ${DESTDIR}${mandir}/man3
for i in ${TAR_BLOCK_READ_SO}; do \
echo ".so man3/tar_block_read.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/th_read.3 ${DESTDIR}${mandir}/man3
for i in ${TH_READ_SO}; do \
echo ".so man3/th_read.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/th_set_from_stat.3 ${DESTDIR}${mandir}/man3
for i in ${TH_SET_FROM_STAT_SO}; do \
echo ".so man3/th_set_from_stat.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/tar_extract_file.3 ${DESTDIR}${mandir}/man3
for i in ${TAR_EXTRACT_FILE_SO}; do \
echo ".so man3/tar_extract_file.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/th_get_pathname.3 ${DESTDIR}${mandir}/man3
for i in ${TH_GET_PATHNAME_SO}; do \
echo ".so man3/th_get_pathname.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/th_print_long_ls.3 ${DESTDIR}${mandir}/man3
for i in ${TH_PRINT_LONG_LS_SO}; do \
echo ".so man3/th_print_long_ls.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ${srcdir}/tar_extract_all.3 ${DESTDIR}${mandir}/man3
for i in ${TAR_EXTRACT_ALL_SO}; do \
echo ".so man3/tar_extract_all.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ../listhash/@LISTHASH_PREFIX@_hash_new.3 ${DESTDIR}${mandir}/man3
for i in ${@LISTHASH_PREFIX@_HASH_NEW_SO}; do \
echo ".so man3/@LISTHASH_PREFIX@_hash_new.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done
${INSTALL_DATA} ../listhash/@LISTHASH_PREFIX@_list_new.3 ${DESTDIR}${mandir}/man3
for i in ${@LISTHASH_PREFIX@_LIST_NEW_SO}; do \
echo ".so man3/@LISTHASH_PREFIX@_list_new.3" > ${DESTDIR}${mandir}/man3/$${i}.3; \
done

50
doc/tar_append_file.3 Normal file
View File

@ -0,0 +1,50 @@
.TH tar_append_file 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
tar_append_file, tar_append_eof, tar_append_regfile \- append data to tar archives
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "int tar_append_file(TAR *" t ", char *" realname ","
.BI "char *" savename ");"
.BI "int tar_append_regfile(TAR *" t ", char *" realname ");"
.BI "int tar_append_eof(TAR *" t ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBtar_append_file\fP() function creates a tar file header block
describing the file named by the \fIrealname\fP argument, but with
the encoded filename of \fIsavename\fP. It then sets the current
header associated with the \fITAR\fP handle \fIt\fP to the newly created
header block, and writes this block to the tar archive associated with
\fIt\fP. If the file named by \fIrealname\fP is a regular file (and
is not encoded as a hard link), \fBtar_append_file\fP() will call
\fBtar_append_regfile\fP() to append the contents of the file.
The \fBtar_append_regfile\fP() function appends the contents of a regular
file to the tar archive associated with \fIt\fP. Since this function is
called by \fBtar_append_file\fP(), it should only be necessary for
applications that construct and write the tar file header on their own.
The \fBtar_append_eof\fP() function writes an EOF marker (two blocks of
all zeros) to the tar file associated with \fIt\fP.
.SH RETURN VALUES
On successful completion, these functions will return 0. On failure,
they will return -1 and set \fIerrno\fP to an appropriate value.
.SH ERRORS
The \fBtar_append_*\fP() functions will fail if:
.IP \fBEINVAL\fP
Less than \fBT_BLOCKSIZE\fP bytes were written to the tar archive.
.IP \fBEINVAL\fP
Less than \fBT_BLOCKSIZE\fP bytes were read from the \fIrealname\fP file.
.PP
They may also fail if any of the following functions fail: \fBlstat\fP(),
\fBmalloc\fP(), \fBopen\fP(), \fBread\fP(), \fBth_write\fP(), or the
write function for the file type associated with the \fITAR\fP handle
\fIt\fP.
.SH SEE ALSO
.BR read (2),
.BR open (2),
.BR lstat (2),
.BR th_write (3)

24
doc/tar_block_read.3 Normal file
View File

@ -0,0 +1,24 @@
.TH tar_block_read 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
tar_block_read, tar_block_write \- macros to call read and write functions
for the correct tar archive type
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "int tar_block_read(TAR *" t ", char *" buf ");"
.BI "int tar_block_write(TAR *" t ", char *" buf ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBtar_block_read\fP() and \fBtar_block_write\fP() macros call
the read and write functions for the tar archive type associated with the
\fITAR\fP handle \fIt\fP. This type is set when the \fITAR\fP handle
is created using \fBtar_open\fP().
.SH RETURN VALUE
These macros return the same values as the corresponding read and write
functions.
.SH SEE ALSO
.BR read (2),
.BR write (2),
.BR tar_open (3)

43
doc/tar_extract_all.3 Normal file
View File

@ -0,0 +1,43 @@
.TH tar_extract_all 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
tar_extract_all, tar_extract_glob, tar_append_tree \- high-level tar
archive manipulation functions
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "int tar_extract_all(TAR *" t ", char *" prefix ");"
.BI "int tar_extract_glob(TAR *" t ", char *" globname ","
.BI "char *" prefix ");"
.BI "int tar_append_tree(TAR *" t ", char *" realdir ","
.BI "char *" savedir ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBtar_extract_all\fP() function extracts all files from the tar
archive associated with the \fITAR\fP handle \fIt\fP into the path
named by the \fIprefix\fP argument.
The \fBtar_extract_glob\fP() function extracts all files matching
the given \fIglob\fP pattern from the tar archive associated with the
\fITAR\fP handle \fIt\fP into the path named by the \fIprefix\fP argument.
The \fBtar_append_tree\fP() function appends all files from the
directory tree named by \fIrealdir\fP to the tar archive associated with
the \fITAR\fP handle \fIt\fP. The pathnames stored in the tar archive
are modified by replacing \fIrealdir\fP with \fIsavedir\fP, so that the
files will be extracted into \fIsavedir\fP.
.SH RETURN VALUES
On successful completion, these functions will return 0. On failure,
they will return -1 and set \fIerrno\fP to an appropriate value.
.SH ERRORS
These functions will fail under the same conditions that the
\fBtar_skip_regfile\fP(), \fBtar_extract_regfile\fP(), \fBopendir\fP(),
\fBlstat\fP(), or \fBtar_append_file\fP() functions fail.
.SH SEE ALSO
.BR opendir (2),
.BR lstat (2),
.BR tar_skip_regfile (3),
.BR tar_extract_regfile (3),
.BR tar_append_file (3)

84
doc/tar_extract_file.3 Normal file
View File

@ -0,0 +1,84 @@
.TH tar_extract_file 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
tar_extract_file, tar_extract_regfile, tar_extract_hardlink,
tar_extract_symlink, tar_extract_chardev, tar_extract_blockdev,
tar_extract_dir, tar_extract_fifo, tar_skip_regfile, tar_set_file_perms \-
extract files from a tar archive
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "int tar_extract_file(TAR *" t ", char *" realname ");"
.BI "int tar_extract_regfile(TAR *" t ", char *" realname ");"
.BI "int tar_skip_regfile(TAR *" t ");"
.BI "int tar_extract_dir(TAR *" t ", char *" realname ");"
.BI "int tar_extract_hardlink(TAR *" t ", char *" realname ");"
.BI "int tar_extract_symlink(TAR *" t ", char *" realname ");"
.BI "int tar_extract_blockdev(TAR *" t ", char *" realname ");"
.BI "int tar_extract_chardev(TAR *" t ", char *" realname ");"
.BI "int tar_extract_fifo(TAR *" t ", char *" realname ");"
.BI "int tar_set_file_perms(TAR *" t ", char *" realname ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBtar_extract_file\fP() function acts as a front-end to the other
\fBtar_extract_*\fP() functions. It checks the current tar header
associated with the \fITAR\fP handle \fIt\fP (which must be initialized
first by calling \fBth_read\fP()) to determine what kind of file the
header refers to. It then calls the appropriate \fBtar_extract_*\fP()
function to extract that kind of file.
The \fBtar_skip_regfile\fP() function skips over the
file content blocks and positions the file pointer at the expected
location of the next tar header block.
The \fBtar_set_file_perms\fP() function sets the attributes of the
extracted file to match the encoded values. This includes the file's
modification time, mode, owner, and group. This function is automatically
called by \fBtar_extract_file\fP(), but applications which call the
other \fBtar_extract_*\fP() functions directly will need to call
\fBtar_set_file_perms\fP() manually if this behavior is desired.
.SH RETURN VALUES
On successful completion, the functions documented here will
return 0. On failure, they will return -1 and set \fIerrno\fP to an
appropriate value.
The \fBtar_extract_dir\fP() function will return 1 if the directory
already exists.
.SH ERRORS
The \fBtar_extract_file\fP() function will fail if:
.IP \fBEEXIST\fP
If the \fBO_NOOVERWRITE\fP flag is set and the file already exists.
.PP
The \fBtar_extract_*\fP() functions will fail if:
.IP \fBEINVAL\fP
An entry could not be added to the internal file hash.
.IP \fBEINVAL\fP
Less than \fBT_BLOCKSIZE\fP bytes were read from the tar archive.
.IP \fBEINVAL\fP
The current file header associated with \fIt\fP refers to a kind of file
other than the one which the called function knows about.
.PP
They may also fail if any of the following functions fail: \fBmkdir\fP(),
\fBwrite\fP(), \fBlink\fP(), \fBsymlink\fP(), \fBmknod\fP(), \fBmkfifo\fP(),
\fButime\fP(), \fBchown\fP(), \fBlchown\fP(), \fBchmod\fP(), or \fBlstat\fP().
.SH SEE ALSO
.BR mkdir (2),
.BR write (2),
.BR link (2),
.BR symlink (2),
.BR mknod (2),
.BR mkfifo (2),
.BR utime (2),
.BR chown (2),
.BR lchown (2),
.BR chmod (2),
.BR lstat (2)

97
doc/tar_open.3 Normal file
View File

@ -0,0 +1,97 @@
.TH tar_open 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
tar_open, tar_close \- access a tar archive via a handle
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "int tar_open(TAR **" t ", char *" pathname ","
.BI "tartype_t *" type ", int " oflags ","
.BI "int " mode ", int " options ");"
.BI "int tar_fdopen(TAR **" t ", int " fd ","
.BI "char *" pathname ", tartype_t *" type ","
.BI "int " oflags ", int " mode ","
.BI "int " options ");"
.BI "int tar_fd(TAR *" t");"
.BI "int tar_close(TAR *" t");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBtar_open\fP() function opens a tar archive file corresponding to
the filename named by the \fIpathname\fP argument. The \fIoflags\fP
argument must be either \fBO_RDONLY\fP or \fBO_WRONLY\fP.
The \fItype\fP argument specifies the access methods for the given file
type. The \fItartype_t\fP structure has members named \fIopenfunc\fP,
\fIclosefunc\fP, \fIreadfunc\fP() and \fIwritefunc\fP(), which are
pointers to the functions for opening, closing, reading, and writing
the file, respectively. If \fItype\fP is \fINULL\fP, the file type
defaults to a normal file, and the standard \fIopen\fP(), \fIclose\fP(),
\fIread\fP(), and \fIwrite\fP() functions are used.
The \fIoptions\fP argument is a logical-or'ed combination of zero or more
of the following:
.IP \fBTAR_GNU\fP
Use GNU extensions.
.IP \fBTAR_VERBOSE\fP
Send status messages to \fIstdout\fP.
.IP \fBTAR_NOOVERWRITE\fP
Do not overwrite pre-existing files.
.IP \fBTAR_IGNORE_EOT\fP
Skip all-zero blocks instead of treating them as EOT.
.IP \fBTAR_IGNORE_MAGIC\fP
Do not validate the magic field in file headers.
.IP \fBTAR_CHECK_VERSION\fP
Check the version field in file headers. (This field is normally ignored.)
.IP \fBTAR_IGNORE_CRC\fP
Do not validate the CRC of file headers.
.PP
The \fBtar_open\fP() function allocates memory for a \fITAR\fP handle,
and a pointer to the allocated memory is saved in the location specified
by \fIt\fP. The \fITAR\fP handle may be passed to other \fIlibtar\fP
calls to modify the opened tar archive. The \fITAR\fP handle maintains
all of the information about the open tar archive, including the archive
\fItype\fP, \fIoptions\fP, and \fIoflags\fP selected when \fBtar_open\fP()
was called.
The \fITAR\fP handle generated by \fBtar_open\fP() contains a file header
structure. When reading a tar archive, this structure contains the last
file header read from the tar archive. When writing a tar archive,
this structure is used as a staging area to construct the next file
header to be written to the archive. In addition, the \fITAR\fP handle
contains a hash table which is used to keep track of the device and
inode information for each file which gets written to the tar archive.
This is used to detect hard links, so that files do not need to be
duplicated in the archive.
The \fBtar_fdopen\fP() function is identical to the \fBtar_open\fP() function,
except that \fIfd\fP is used as the previously-opened file descriptor for
the tar file instead of calling \fItype->openfunc\fP() to open the file.
The \fBtar_fd\fP() function returns the file descriptor associated with
the \fITAR\fP handle \fIt\fP.
The \fBtar_close\fP() function closes the file descriptor associated
with the \fITAR\fP handle \fIt\fP and frees all dynamically-allocated
memory.
.SH RETURN VALUE
The \fBtar_open\fP(), \fBtar_fdopen\fP(), and \fBtar_close\fP() functions
return 0 on success. On failure, they return -1 and set \fIerrno\fP.
The \fBtar_fd\fP() function returns the file descriptor associated with
the \fITAR\fP handle \fIt\fP.
.SH ERRORS
\fBtar_open\fP() will fail if:
.IP \fBEINVAL\fP
The \fIoflags\fP argument was something other than \fBO_RDONLY\fP or \fBO_WRONLY\fP.
.PP
In addition, \fBtar_open\fP() and \fBtar_close\fP() may fail if it
cannot allocate memory using \fBcalloc\fP(), or if the
open or close functions for the specified tar archive \fItype\fP fail.
.SH SEE ALSO
.BR open (2),
.BR close (2),
.BR calloc (3)

63
doc/th_get_pathname.3 Normal file
View File

@ -0,0 +1,63 @@
.TH th_get_pathname 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
th_get_pathname, th_get_uid, th_get_gid, th_get_mode, th_get_crc, th_get_size, th_get_mtime, th_get_devmajor, th_get_devminor, th_get_linkname \- extract individual fields of a tar header
TH_ISREG, TH_ISLNK, TH_ISSYM, TH_ISCHR, TH_ISBLK, TH_ISDIR, TH_ISFIFO \- determine what kind of file a tar header refers to
TH_ISLONGNAME, TH_ISLONGLINK \- determine whether the GNU extensions are in use
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "char *th_get_linkname(TAR *" t ");"
.BI "char *th_get_pathname(TAR *" t ");"
.BI "mode_t th_get_mode(TAR *" t ");"
.BI "uid_t th_get_uid(TAR *" t ");"
.BI "gid_t th_get_gid(TAR *" t ");"
.BI "int th_get_crc(TAR *" t ");"
.BI "off_t th_get_size(TAR *" t ");"
.BI "time_t th_get_mtime(TAR *" t ");"
.BI "major_t th_get_devmajor(TAR *" t ");"
.BI "minor_t th_get_devminor(TAR *" t ");"
.BI "int TH_ISREG(TAR *" t ");"
.BI "int TH_ISLNK(TAR *" t ");"
.BI "int TH_ISSYM(TAR *" t ");"
.BI "int TH_ISCHR(TAR *" t ");"
.BI "int TH_ISBLK(TAR *" t ");"
.BI "int TH_ISDIR(TAR *" t ");"
.BI "int TH_ISFIFO(TAR *" t ");"
.BI "int TH_ISLONGNAME(TAR *" t ");"
.BI "int TH_ISLONGLINK(TAR *" t ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBth_get_*\fP() functions extract individual fields from the current
tar header associated with the \fITAR\fP handle \fIt\fP.
The \fBTH_IS*\fP() macros are used to evaluate what kind of file is
pointed to by the current tar header associated with the \fITAR\fP
handle \fIt\fP.
The \fBTH_ISLONGNAME\fP() and \fBTH_ISLONGLINK\fP() macros evaluate
whether or not the GNU extensions are used by the current tar header
associated with the \fITAR\fP handle \fIt\fP. This is only relevant
if the \fBTAR_GNU\fP option was used when \fItar_open\fP() was called.
.SH SEE ALSO
.BR tar_open (3)

22
doc/th_print_long_ls.3 Normal file
View File

@ -0,0 +1,22 @@
.TH th_print_long_ls 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
th_print, th_print_long_ls \- print out information about a tar file header
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "void th_print_long_ls(TAR *" t ");"
.BI "void th_print(TAR *" t ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBth_print_long_ls\fP() function prints a line to \fIstdout\fP which
describes the file pointed to by the current file header associated with
the \fITAR\fP handle \fIt\fP. The output is similar to that of "ls -l".
The \fBth_print\fP() function prints the value of each field of the
current file header associated with the \fITAR\fP handle \fIt\fP to
\fIstdout\fP. This is mainly used for debugging purposes.
.SH SEE ALSO
.BR tar_open (3),
.BR th_read (3)

34
doc/th_read.3 Normal file
View File

@ -0,0 +1,34 @@
.TH th_read 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
th_read, th_write \- read and write a file header block from a tar archive
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "int th_read(TAR *" t ");"
.BI "int th_write(TAR *" t ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBth_read\fP() function reads the next block from the tar archive
associated with the \fITAR\fP handle \fIt\fP. It then sets the
current tar header associated with \fIt\fP to the contents of the block
read.
The \fBth_write\fP() function writes the contents of the current
tar header associated with \fIt\fP to the tar archive associated
with \fIt\fP.
.SH RETURN VALUE
On successful completion, \fBth_read\fP() and \fBth_write\fP() will
return 0. On failure, they will return -1 and set \fIerrno\fP to an
appropriate value.
On \fIEOF\fP, \fBth_read\fP() will return 1.
.SH ERRORS
\fBth_read\fP() and \fBth_write\fP() will fail if:
.IP \fBEINVAL\fP
Less than \fBT_BLOCKSIZE\fP blocks were read or written.
.PP
.SH SEE ALSO
.BR tar_block_read (3),
.BR tar_block_write (3)

45
doc/th_set_from_stat.3 Normal file
View File

@ -0,0 +1,45 @@
.TH th_set_from_stat 3 "Jan 2001" "University of Illinois" "C Library Calls"
.SH NAME
th_set_from_stat, th_finish, th_set_type, th_set_path, th_set_link, th_set_device, th_set_user, th_set_group, th_set_mode, th_set_mtime, th_set_size \- set fields of a tar file header
.SH SYNOPSIS
.B #include <libtar.h>
.P
.BI "void th_set_from_stat(TAR *" t ", struct stat *" s ");"
.BI "void th_set_type(TAR *" t ", mode_t " mode ");"
.BI "void th_set_path(TAR *" t ", char *" pathname ");"
.BI "void th_set_link(TAR *" t ", char *" linkname ");"
.BI "void th_set_device(TAR *" t ", dev_t " device ");"
.BI "void th_set_user(TAR *" t ", uid_t " uid ");"
.BI "void th_set_group(TAR *" t ", gid_t " gid ");"
.BI "void th_set_mode(TAR *" t ", mode_t " mode ");"
.BI "void th_set_mtime(TAR *" t ", time_t " fmtime ");"
.BI "void th_set_size(TAR *" t ", off_t " fsize ");"
.BI "void th_finish(TAR *" t ");"
.SH VERSION
This man page documents version 1.2 of \fBlibtar\fP.
.SH DESCRIPTION
The \fBth_set_*\fP() functions each set an individual field of the
current tar header associated with the \fITAR\fP handle \fIt\fP. The
\fBth_set_user\fP() and \fBth_set_group\fP() functions set both the
numeric user/group ID fields and the user/group name text fields.
The other functions set only the field that they refer to.
The \fBth_set_from_stat\fP() function uses the other \fBth_set_*\fP()
functions to set all of the fields at once, based on the data passed to
it in the argument \fIs\fP.
The \fBth_finish\fP() function sets the appropriate constants for the
magic and version fields. It then calculates the header checksum and
fills in the checksum field.
.SH SEE ALSO
.BR lstat (2)

92
lib/Makefile.in Normal file
View File

@ -0,0 +1,92 @@
# @configure_input@
### Path settings
srcdir = @srcdir@
top_srcdir = @top_srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@ENCAP_DEFS@
### Installation programs and flags
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
INSTALL_DATA = @INSTALL_DATA@
LN_S = @LN_S@
MKDIR = @MKDIR@
### Compiler and link options
CC = @CC@
CPPFLAGS = -I. \
-I.. \
-I${srcdir} \
-I${top_srcdir}/compat \
-I../listhash \
@CPPFLAGS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
LIBOBJS = @LIBOBJS@
RANLIB = @RANLIB@
@SET_MAKE@
VPATH = @srcdir@:@top_srcdir@/compat:../listhash
### Makefile rules - no user-servicable parts below
LIBTAR_OBJS = append.o \
block.o \
decode.o \
encode.o \
extract.o \
handle.o \
libtar_hash.o \
libtar_list.o \
output.o \
util.o \
wrapper.o
LIBTAR_HDRS = ../config.h \
${top_srcdir}/compat/compat.h \
${srcdir}/libtar.h \
${srcdir}/internal.h \
../listhash/libtar_listhash.h
LIBTAR_LIBS = ./libtar.a
ALL = libtar.a
DISTCLEANFILES = ../listhash/libtar_listhash.h \
../listhash/libtar_list.c \
../listhash/libtar_hash.c
all: ${ALL}
.PHONY: clean distclean install
libtar.a: ${LIBTAR_OBJS} ${LIBOBJS}
${AR} rc libtar.a ${LIBTAR_OBJS} ${LIBOBJS}
${RANLIB} libtar.a
${LIBTAR_OBJS}: ${LIBTAR_HDRS}
.c.o:
${CC} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
clean:
rm -f *~ *.o ${ALL} core
distclean: clean
rm -f Makefile ${DISTCLEANFILES}
install: ${ALL}
${MKDIR} ${DESTDIR}${libdir}
${INSTALL_DATA} libtar.a ${DESTDIR}${libdir}
${MKDIR} ${DESTDIR}${includedir}
${INSTALL_DATA} ${srcdir}/libtar.h ${DESTDIR}${includedir}
${INSTALL_DATA} ../listhash/libtar_listhash.h ${DESTDIR}${includedir}

256
lib/append.c Normal file
View File

@ -0,0 +1,256 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** append.c - libtar code to append files to a tar archive
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/types.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
struct tar_dev
{
dev_t td_dev;
libtar_hash_t *td_h;
};
typedef struct tar_dev tar_dev_t;
struct tar_ino
{
ino_t ti_ino;
char ti_name[MAXPATHLEN];
};
typedef struct tar_ino tar_ino_t;
/* free memory associated with a tar_dev_t */
void
tar_dev_free(tar_dev_t *tdp)
{
libtar_hash_free(tdp->td_h, free);
free(tdp);
}
/* appends a file to the tar archive */
int
tar_append_file(TAR *t, char *realname, char *savename)
{
struct stat s;
int i;
libtar_hashptr_t hp;
tar_dev_t *td = NULL;
tar_ino_t *ti = NULL;
char path[MAXPATHLEN];
#ifdef DEBUG
printf("==> tar_append_file(TAR=0x%lx (\"%s\"), realname=\"%s\", "
"savename=\"%s\")\n", t, t->pathname, realname,
(savename ? savename : "[NULL]"));
#endif
if (lstat(realname, &s) != 0)
{
#ifdef DEBUG
perror("lstat()");
#endif
return -1;
}
/* set header block */
#ifdef DEBUG
puts(" tar_append_file(): setting header block...");
#endif
memset(&(t->th_buf), 0, sizeof(struct tar_header));
th_set_from_stat(t, &s);
/* set the header path */
#ifdef DEBUG
puts(" tar_append_file(): setting header path...");
#endif
th_set_path(t, (savename ? savename : realname));
/* check if it's a hardlink */
#ifdef DEBUG
puts(" tar_append_file(): checking inode cache for hardlink...");
#endif
libtar_hashptr_reset(&hp);
if (libtar_hash_getkey(t->h, &hp, &(s.st_dev),
(libtar_matchfunc_t)dev_match) != 0)
td = (tar_dev_t *)libtar_hashptr_data(&hp);
else
{
#ifdef DEBUG
printf("+++ adding hash for device (0x%lx, 0x%lx)...\n",
major(s.st_dev), minor(s.st_dev));
#endif
td = (tar_dev_t *)calloc(1, sizeof(tar_dev_t));
td->td_dev = s.st_dev;
td->td_h = libtar_hash_new(256, (libtar_hashfunc_t)ino_hash);
if (td->td_h == NULL)
return -1;
if (libtar_hash_add(t->h, td) == -1)
return -1;
}
libtar_hashptr_reset(&hp);
if (libtar_hash_getkey(td->td_h, &hp, &(s.st_ino),
(libtar_matchfunc_t)ino_match) != 0)
{
ti = (tar_ino_t *)libtar_hashptr_data(&hp);
#ifdef DEBUG
printf(" tar_append_file(): encoding hard link \"%s\" "
"to \"%s\"...\n", realname, ti->ti_name);
#endif
t->th_buf.typeflag = LNKTYPE;
th_set_link(t, ti->ti_name);
}
else
{
#ifdef DEBUG
printf("+++ adding entry: device (0x%lx,0x%lx), inode %ld "
"(\"%s\")...\n", major(s.st_dev), minor(s.st_dev),
s.st_ino, realname);
#endif
ti = (tar_ino_t *)calloc(1, sizeof(tar_ino_t));
if (ti == NULL)
return -1;
ti->ti_ino = s.st_ino;
snprintf(ti->ti_name, sizeof(ti->ti_name), "%s",
savename ? savename : realname);
libtar_hash_add(td->td_h, ti);
}
/* check if it's a symlink */
if (TH_ISSYM(t))
{
i = readlink(realname, path, sizeof(path));
if (i == -1)
return -1;
if (i >= MAXPATHLEN)
i = MAXPATHLEN - 1;
path[i] = '\0';
#ifdef DEBUG
printf(" tar_append_file(): encoding symlink \"%s\" -> "
"\"%s\"...\n", realname, path);
#endif
th_set_link(t, path);
}
/* print file info */
if (t->options & TAR_VERBOSE)
th_print_long_ls(t);
#ifdef DEBUG
puts(" tar_append_file(): writing header");
#endif
/* write header */
if (th_write(t) != 0)
{
#ifdef DEBUG
printf("t->fd = %d\n", t->fd);
#endif
return -1;
}
#ifdef DEBUG
puts(" tar_append_file(): back from th_write()");
#endif
/* if it's a regular file, write the contents as well */
if (TH_ISREG(t) && tar_append_regfile(t, realname) != 0)
return -1;
return 0;
}
/* write EOF indicator */
int
tar_append_eof(TAR *t)
{
int i, j;
char block[T_BLOCKSIZE];
memset(&block, 0, T_BLOCKSIZE);
for (j = 0; j < 2; j++)
{
i = tar_block_write(t, &block);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
}
return 0;
}
/* add file contents to a tarchive */
int
tar_append_regfile(TAR *t, char *realname)
{
char block[T_BLOCKSIZE];
int filefd;
int i, j;
size_t size;
filefd = open(realname, O_RDONLY);
if (filefd == -1)
{
#ifdef DEBUG
perror("open()");
#endif
return -1;
}
size = th_get_size(t);
for (i = size; i > T_BLOCKSIZE; i -= T_BLOCKSIZE)
{
j = read(filefd, &block, T_BLOCKSIZE);
if (j != T_BLOCKSIZE)
{
if (j != -1)
errno = EINVAL;
return -1;
}
if (tar_block_write(t, &block) == -1)
return -1;
}
if (i > 0)
{
j = read(filefd, &block, i);
if (j == -1)
return -1;
memset(&(block[i]), 0, T_BLOCKSIZE - i);
if (tar_block_write(t, &block) == -1)
return -1;
}
close(filefd);
return 0;
}

384
lib/block.c Normal file
View File

@ -0,0 +1,384 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** block.c - libtar code to handle tar archive header blocks
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <errno.h>
#ifdef STDC_HEADERS
# include <string.h>
# include <stdlib.h>
#endif
#define BIT_ISSET(bitmask, bit) ((bitmask) & (bit))
/* read a header block */
int
th_read_internal(TAR *t)
{
int i;
int num_zero_blocks = 0;
#ifdef DEBUG
printf("==> th_read_internal(TAR=\"%s\")\n", t->pathname);
#endif
while ((i = tar_block_read(t, &(t->th_buf))) == T_BLOCKSIZE)
{
/* two all-zero blocks mark EOF */
if (t->th_buf.name[0] == '\0')
{
num_zero_blocks++;
if (!BIT_ISSET(t->options, TAR_IGNORE_EOT)
&& num_zero_blocks >= 2)
return 0; /* EOF */
else
continue;
}
/* verify magic and version */
if (BIT_ISSET(t->options, TAR_CHECK_MAGIC)
&& strncmp(t->th_buf.magic, TMAGIC, TMAGLEN - 1) != 0)
{
#ifdef DEBUG
puts("!!! unknown magic value in tar header");
#endif
return -2;
}
if (BIT_ISSET(t->options, TAR_CHECK_VERSION)
&& strncmp(t->th_buf.version, TVERSION, TVERSLEN) != 0)
{
#ifdef DEBUG
puts("!!! unknown version value in tar header");
#endif
return -2;
}
/* check chksum */
if (!BIT_ISSET(t->options, TAR_IGNORE_CRC)
&& !th_crc_ok(t))
{
#ifdef DEBUG
puts("!!! tar header checksum error");
#endif
return -2;
}
break;
}
#ifdef DEBUG
printf("<== th_read_internal(): returning %d\n", i);
#endif
return i;
}
/* wrapper function for th_read_internal() to handle GNU extensions */
int
th_read(TAR *t)
{
int i, j;
size_t sz;
char *ptr;
#ifdef DEBUG
printf("==> th_read(t=0x%lx)\n", t);
#endif
if (t->th_buf.gnu_longname != NULL)
free(t->th_buf.gnu_longname);
if (t->th_buf.gnu_longlink != NULL)
free(t->th_buf.gnu_longlink);
memset(&(t->th_buf), 0, sizeof(struct tar_header));
i = th_read_internal(t);
if (i == 0)
return 1;
else if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
/* check for GNU long link extention */
if (TH_ISLONGLINK(t))
{
sz = th_get_size(t);
j = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0);
#ifdef DEBUG
printf(" th_read(): GNU long linkname detected "
"(%ld bytes, %d blocks)\n", sz, j);
#endif
t->th_buf.gnu_longlink = (char *)malloc(j * T_BLOCKSIZE);
if (t->th_buf.gnu_longlink == NULL)
return -1;
for (ptr = t->th_buf.gnu_longlink; j > 0;
j--, ptr += T_BLOCKSIZE)
{
#ifdef DEBUG
printf(" th_read(): reading long linkname "
"(%d blocks left, ptr == %ld)\n", j, ptr);
#endif
i = tar_block_read(t, ptr);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
#ifdef DEBUG
printf(" th_read(): read block == \"%s\"\n", ptr);
#endif
}
#ifdef DEBUG
printf(" th_read(): t->th_buf.gnu_longlink == \"%s\"\n",
t->th_buf.gnu_longlink);
#endif
i = th_read_internal(t);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
}
/* check for GNU long name extention */
if (TH_ISLONGNAME(t))
{
sz = th_get_size(t);
j = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0);
#ifdef DEBUG
printf(" th_read(): GNU long filename detected "
"(%ld bytes, %d blocks)\n", sz, j);
#endif
t->th_buf.gnu_longname = (char *)malloc(j * T_BLOCKSIZE);
if (t->th_buf.gnu_longname == NULL)
return -1;
for (ptr = t->th_buf.gnu_longname; j > 0;
j--, ptr += T_BLOCKSIZE)
{
#ifdef DEBUG
printf(" th_read(): reading long filename "
"(%d blocks left, ptr == %ld)\n", j, ptr);
#endif
i = tar_block_read(t, ptr);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
#ifdef DEBUG
printf(" th_read(): read block == \"%s\"\n", ptr);
#endif
}
#ifdef DEBUG
printf(" th_read(): t->th_buf.gnu_longname == \"%s\"\n",
t->th_buf.gnu_longname);
#endif
i = th_read_internal(t);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
}
#if 0
/*
** work-around for old archive files with broken typeflag fields
** NOTE: I fixed this in the TH_IS*() macros instead
*/
/*
** (directories are signified with a trailing '/')
*/
if (t->th_buf.typeflag == AREGTYPE
&& t->th_buf.name[strlen(t->th_buf.name) - 1] == '/')
t->th_buf.typeflag = DIRTYPE;
/*
** fallback to using mode bits
*/
if (t->th_buf.typeflag == AREGTYPE)
{
mode = (mode_t)oct_to_int(t->th_buf.mode);
if (S_ISREG(mode))
t->th_buf.typeflag = REGTYPE;
else if (S_ISDIR(mode))
t->th_buf.typeflag = DIRTYPE;
else if (S_ISFIFO(mode))
t->th_buf.typeflag = FIFOTYPE;
else if (S_ISCHR(mode))
t->th_buf.typeflag = CHRTYPE;
else if (S_ISBLK(mode))
t->th_buf.typeflag = BLKTYPE;
else if (S_ISLNK(mode))
t->th_buf.typeflag = SYMTYPE;
}
#endif
return 0;
}
/* write a header block */
int
th_write(TAR *t)
{
int i, j;
char type2;
size_t sz, sz2;
char *ptr;
char buf[T_BLOCKSIZE];
#ifdef DEBUG
printf("==> th_write(TAR=\"%s\")\n", t->pathname);
th_print(t);
#endif
if ((t->options & TAR_GNU) && t->th_buf.gnu_longlink != NULL)
{
#ifdef DEBUG
printf("th_write(): using gnu_longlink (\"%s\")\n",
t->th_buf.gnu_longlink);
#endif
/* save old size and type */
type2 = t->th_buf.typeflag;
sz2 = th_get_size(t);
/* write out initial header block with fake size and type */
t->th_buf.typeflag = GNU_LONGLINK_TYPE;
sz = strlen(t->th_buf.gnu_longlink);
th_set_size(t, sz);
th_finish(t);
i = tar_block_write(t, &(t->th_buf));
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
/* write out extra blocks containing long name */
for (j = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0),
ptr = t->th_buf.gnu_longlink; j > 1;
j--, ptr += T_BLOCKSIZE)
{
i = tar_block_write(t, ptr);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
}
memset(buf, 0, T_BLOCKSIZE);
strncpy(buf, ptr, T_BLOCKSIZE);
i = tar_block_write(t, &buf);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
/* reset type and size to original values */
t->th_buf.typeflag = type2;
th_set_size(t, sz2);
}
if ((t->options & TAR_GNU) && t->th_buf.gnu_longname != NULL)
{
#ifdef DEBUG
printf("th_write(): using gnu_longname (\"%s\")\n",
t->th_buf.gnu_longname);
#endif
/* save old size and type */
type2 = t->th_buf.typeflag;
sz2 = th_get_size(t);
/* write out initial header block with fake size and type */
t->th_buf.typeflag = GNU_LONGNAME_TYPE;
sz = strlen(t->th_buf.gnu_longname);
th_set_size(t, sz);
th_finish(t);
i = tar_block_write(t, &(t->th_buf));
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
/* write out extra blocks containing long name */
for (j = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0),
ptr = t->th_buf.gnu_longname; j > 1;
j--, ptr += T_BLOCKSIZE)
{
i = tar_block_write(t, ptr);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
}
memset(buf, 0, T_BLOCKSIZE);
strncpy(buf, ptr, T_BLOCKSIZE);
i = tar_block_write(t, &buf);
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
/* reset type and size to original values */
t->th_buf.typeflag = type2;
th_set_size(t, sz2);
}
th_finish(t);
#ifdef DEBUG
/* print tar header */
th_print(t);
#endif
i = tar_block_write(t, &(t->th_buf));
if (i != T_BLOCKSIZE)
{
if (i != -1)
errno = EINVAL;
return -1;
}
#ifdef DEBUG
puts("th_write(): returning 0");
#endif
return 0;
}

120
lib/decode.c Normal file
View File

@ -0,0 +1,120 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** decode.c - libtar code to decode tar header blocks
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <sys/param.h>
#include <pwd.h>
#include <grp.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
/* determine full path name */
char *
th_get_pathname(TAR *t)
{
char filename[MAXPATHLEN];
if (t->th_buf.gnu_longname)
return t->th_buf.gnu_longname;
if (t->th_buf.prefix[0] != '\0')
{
snprintf(filename, sizeof(filename), "%.155s/%.100s",
t->th_buf.prefix, t->th_buf.name);
return strdup(filename);
}
snprintf(filename, sizeof(filename), "%.100s", t->th_buf.name);
return strdup(filename);
}
uid_t
th_get_uid(TAR *t)
{
int uid;
struct passwd *pw;
pw = getpwnam(t->th_buf.uname);
if (pw != NULL)
return pw->pw_uid;
/* if the password entry doesn't exist */
sscanf(t->th_buf.uid, "%o", &uid);
return uid;
}
gid_t
th_get_gid(TAR *t)
{
int gid;
struct group *gr;
gr = getgrnam(t->th_buf.gname);
if (gr != NULL)
return gr->gr_gid;
/* if the group entry doesn't exist */
sscanf(t->th_buf.gid, "%o", &gid);
return gid;
}
mode_t
th_get_mode(TAR *t)
{
mode_t mode;
mode = (mode_t)oct_to_int(t->th_buf.mode);
if (! (mode & S_IFMT))
{
switch (t->th_buf.typeflag)
{
case SYMTYPE:
mode |= S_IFLNK;
break;
case CHRTYPE:
mode |= S_IFCHR;
break;
case BLKTYPE:
mode |= S_IFBLK;
break;
case DIRTYPE:
mode |= S_IFDIR;
break;
case FIFOTYPE:
mode |= S_IFIFO;
break;
case AREGTYPE:
if (t->th_buf.name[strlen(t->th_buf.name) - 1] == '/')
{
mode |= S_IFDIR;
break;
}
/* FALLTHROUGH */
case LNKTYPE:
case REGTYPE:
default:
mode |= S_IFREG;
}
}
return mode;
}

211
lib/encode.c Normal file
View File

@ -0,0 +1,211 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** encode.c - libtar code to encode tar header blocks
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#ifdef STDC_HEADERS
# include <string.h>
# include <stdlib.h>
#endif
/* magic, version, and checksum */
void
th_finish(TAR *t)
{
int i, sum = 0;
if (t->options & TAR_GNU)
strncpy(t->th_buf.magic, "ustar ", 8);
else
{
strncpy(t->th_buf.version, TVERSION, TVERSLEN);
strncpy(t->th_buf.magic, TMAGIC, TMAGLEN);
}
for (i = 0; i < T_BLOCKSIZE; i++)
sum += ((char *)(&(t->th_buf)))[i];
for (i = 0; i < 8; i++)
sum += (' ' - t->th_buf.chksum[i]);
int_to_oct(sum, t->th_buf.chksum, 8);
}
/* map a file mode to a typeflag */
void
th_set_type(TAR *t, mode_t mode)
{
if (S_ISLNK(mode))
t->th_buf.typeflag = SYMTYPE;
if (S_ISREG(mode))
t->th_buf.typeflag = REGTYPE;
if (S_ISDIR(mode))
t->th_buf.typeflag = DIRTYPE;
if (S_ISCHR(mode))
t->th_buf.typeflag = CHRTYPE;
if (S_ISBLK(mode))
t->th_buf.typeflag = BLKTYPE;
if (S_ISFIFO(mode) || S_ISSOCK(mode))
t->th_buf.typeflag = FIFOTYPE;
}
/* encode file path */
void
th_set_path(TAR *t, char *pathname)
{
char suffix[2] = "";
char *tmp;
#ifdef DEBUG
printf("in th_set_path(th, pathname=\"%s\")\n", pathname);
#endif
if (t->th_buf.gnu_longname != NULL)
free(t->th_buf.gnu_longname);
t->th_buf.gnu_longname = NULL;
if (pathname[strlen(pathname) - 1] != '/' && TH_ISDIR(t))
strcpy(suffix, "/");
if (strlen(pathname) > T_NAMELEN && (t->options & TAR_GNU))
{
/* GNU-style long name */
t->th_buf.gnu_longname = strdup(pathname);
strncpy(t->th_buf.name, t->th_buf.gnu_longname, T_NAMELEN);
}
else if (strlen(pathname) > T_NAMELEN)
{
/* POSIX-style prefix field */
tmp = strchr(&(pathname[strlen(pathname) - T_NAMELEN - 1]), '/');
if (tmp == NULL)
{
printf("!!! '/' not found in \"%s\"\n", pathname);
return;
}
snprintf(t->th_buf.name, 100, "%s%s", &(tmp[1]), suffix);
snprintf(t->th_buf.prefix,
((tmp - pathname + 1) <
155 ? (tmp - pathname + 1) : 155), "%s", pathname);
}
else
/* classic tar format */
snprintf(t->th_buf.name, 100, "%s%s", pathname, suffix);
#ifdef DEBUG
puts("returning from th_set_path()...");
#endif
}
/* encode link path */
void
th_set_link(TAR *t, char *linkname)
{
#ifdef DEBUG
printf("==> th_set_link(th, linkname=\"%s\")\n", linkname);
#endif
if (strlen(linkname) > T_NAMELEN && (t->options & TAR_GNU))
{
/* GNU longlink format */
t->th_buf.gnu_longlink = strdup(linkname);
strcpy(t->th_buf.linkname, "././@LongLink");
}
else
{
/* classic tar format */
strlcpy(t->th_buf.linkname, linkname,
sizeof(t->th_buf.linkname));
if (t->th_buf.gnu_longlink != NULL)
free(t->th_buf.gnu_longlink);
t->th_buf.gnu_longlink = NULL;
}
}
/* encode device info */
void
th_set_device(TAR *t, dev_t device)
{
#ifdef DEBUG
printf("th_set_device(): major = %d, minor = %d\n",
major(device), minor(device));
#endif
int_to_oct(major(device), t->th_buf.devmajor, 8);
int_to_oct(minor(device), t->th_buf.devminor, 8);
}
/* encode user info */
void
th_set_user(TAR *t, uid_t uid)
{
struct passwd *pw;
pw = getpwuid(uid);
if (pw != NULL)
strlcpy(t->th_buf.uname, pw->pw_name, sizeof(t->th_buf.uname));
int_to_oct(uid, t->th_buf.uid, 8);
}
/* encode group info */
void
th_set_group(TAR *t, gid_t gid)
{
struct group *gr;
gr = getgrgid(gid);
if (gr != NULL)
strlcpy(t->th_buf.gname, gr->gr_name, sizeof(t->th_buf.gname));
int_to_oct(gid, t->th_buf.gid, 8);
}
/* encode file mode */
void
th_set_mode(TAR *t, mode_t fmode)
{
if (S_ISSOCK(fmode))
{
fmode &= ~S_IFSOCK;
fmode |= S_IFIFO;
}
int_to_oct(fmode, (t)->th_buf.mode, 8);
}
void
th_set_from_stat(TAR *t, struct stat *s)
{
th_set_type(t, s->st_mode);
if (S_ISCHR(s->st_mode) || S_ISBLK(s->st_mode))
th_set_device(t, s->st_rdev);
th_set_user(t, s->st_uid);
th_set_group(t, s->st_gid);
th_set_mode(t, s->st_mode);
th_set_mtime(t, s->st_mtime);
if (S_ISREG(s->st_mode))
th_set_size(t, s->st_size);
else
th_set_size(t, 0);
}

529
lib/extract.c Normal file
View File

@ -0,0 +1,529 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** extract.c - libtar code to extract a file from a tar archive
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <utime.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
struct linkname
{
char ln_save[MAXPATHLEN];
char ln_real[MAXPATHLEN];
};
typedef struct linkname linkname_t;
static int
tar_set_file_perms(TAR *t, char *realname)
{
mode_t mode;
uid_t uid;
gid_t gid;
struct utimbuf ut;
char *filename;
filename = (realname ? realname : th_get_pathname(t));
mode = th_get_mode(t);
uid = th_get_uid(t);
gid = th_get_gid(t);
ut.modtime = ut.actime = th_get_mtime(t);
/* change owner/group */
if (geteuid() == 0)
#ifdef HAVE_LCHOWN
if (lchown(filename, uid, gid) == -1)
{
# ifdef DEBUG
fprintf(stderr, "lchown(\"%s\", %d, %d): %s\n",
filename, uid, gid, strerror(errno));
# endif
#else /* ! HAVE_LCHOWN */
if (!TH_ISSYM(t) && chown(filename, uid, gid) == -1)
{
# ifdef DEBUG
fprintf(stderr, "chown(\"%s\", %d, %d): %s\n",
filename, uid, gid, strerror(errno));
# endif
#endif /* HAVE_LCHOWN */
return -1;
}
/* change access/modification time */
if (!TH_ISSYM(t) && utime(filename, &ut) == -1)
{
#ifdef DEBUG
perror("utime()");
#endif
return -1;
}
/* change permissions */
if (!TH_ISSYM(t) && chmod(filename, mode) == -1)
{
#ifdef DEBUG
perror("chmod()");
#endif
return -1;
}
return 0;
}
/* switchboard */
int
tar_extract_file(TAR *t, char *realname)
{
int i;
linkname_t *lnp;
if (t->options & TAR_NOOVERWRITE)
{
struct stat s;
if (lstat(realname, &s) == 0 || errno != ENOENT)
{
errno = EEXIST;
return -1;
}
}
if (TH_ISDIR(t))
{
i = tar_extract_dir(t, realname);
if (i == 1)
i = 0;
}
else if (TH_ISLNK(t))
i = tar_extract_hardlink(t, realname);
else if (TH_ISSYM(t))
i = tar_extract_symlink(t, realname);
else if (TH_ISCHR(t))
i = tar_extract_chardev(t, realname);
else if (TH_ISBLK(t))
i = tar_extract_blockdev(t, realname);
else if (TH_ISFIFO(t))
i = tar_extract_fifo(t, realname);
else /* if (TH_ISREG(t)) */
i = tar_extract_regfile(t, realname);
if (i != 0)
return i;
i = tar_set_file_perms(t, realname);
if (i != 0)
return i;
lnp = (linkname_t *)calloc(1, sizeof(linkname_t));
if (lnp == NULL)
return -1;
strlcpy(lnp->ln_save, th_get_pathname(t), sizeof(lnp->ln_save));
strlcpy(lnp->ln_real, realname, sizeof(lnp->ln_real));
#ifdef DEBUG
printf("tar_extract_file(): calling libtar_hash_add(): key=\"%s\", "
"value=\"%s\"\n", th_get_pathname(t), realname);
#endif
if (libtar_hash_add(t->h, lnp) != 0)
return -1;
return 0;
}
/* extract regular file */
int
tar_extract_regfile(TAR *t, char *realname)
{
mode_t mode;
size_t size;
uid_t uid;
gid_t gid;
int fdout;
int i, k;
char buf[T_BLOCKSIZE];
char *filename;
#ifdef DEBUG
printf("==> tar_extract_regfile(t=0x%lx, realname=\"%s\")\n", t,
realname);
#endif
if (!TH_ISREG(t))
{
errno = EINVAL;
return -1;
}
filename = (realname ? realname : th_get_pathname(t));
mode = th_get_mode(t);
size = th_get_size(t);
uid = th_get_uid(t);
gid = th_get_gid(t);
if (mkdirhier(dirname(filename)) == -1)
return -1;
#ifdef DEBUG
printf(" ==> extracting: %s (mode %04o, uid %d, gid %d, %d bytes)\n",
filename, mode, uid, gid, size);
#endif
fdout = open(filename, O_WRONLY | O_CREAT | O_TRUNC
#ifdef O_BINARY
| O_BINARY
#endif
, 0666);
if (fdout == -1)
{
#ifdef DEBUG
perror("open()");
#endif
return -1;
}
#if 0
/* change the owner. (will only work if run as root) */
if (fchown(fdout, uid, gid) == -1 && errno != EPERM)
{
#ifdef DEBUG
perror("fchown()");
#endif
return -1;
}
/* make sure the mode isn't inheritted from a file we're overwriting */
if (fchmod(fdout, mode & 07777) == -1)
{
#ifdef DEBUG
perror("fchmod()");
#endif
return -1;
}
#endif
/* extract the file */
for (i = size; i > 0; i -= T_BLOCKSIZE)
{
k = tar_block_read(t, buf);
if (k != T_BLOCKSIZE)
{
if (k != -1)
errno = EINVAL;
return -1;
}
/* write block to output file */
if (write(fdout, buf,
((i > T_BLOCKSIZE) ? T_BLOCKSIZE : i)) == -1)
return -1;
}
/* close output file */
if (close(fdout) == -1)
return -1;
#ifdef DEBUG
printf("### done extracting %s\n", filename);
#endif
return 0;
}
/* skip regfile */
int
tar_skip_regfile(TAR *t)
{
int i, k;
size_t size;
char buf[T_BLOCKSIZE];
if (!TH_ISREG(t))
{
errno = EINVAL;
return -1;
}
size = th_get_size(t);
for (i = size; i > 0; i -= T_BLOCKSIZE)
{
k = tar_block_read(t, buf);
if (k != T_BLOCKSIZE)
{
if (k != -1)
errno = EINVAL;
return -1;
}
}
return 0;
}
/* hardlink */
int
tar_extract_hardlink(TAR * t, char *realname)
{
char *filename;
char *linktgt = NULL;
linkname_t *lnp;
libtar_hashptr_t hp;
if (!TH_ISLNK(t))
{
errno = EINVAL;
return -1;
}
filename = (realname ? realname : th_get_pathname(t));
if (mkdirhier(dirname(filename)) == -1)
return -1;
libtar_hashptr_reset(&hp);
if (libtar_hash_getkey(t->h, &hp, th_get_linkname(t),
(libtar_matchfunc_t)libtar_str_match) != 0)
{
lnp = (linkname_t *)libtar_hashptr_data(&hp);
linktgt = lnp->ln_real;
}
else
linktgt = th_get_linkname(t);
#ifdef DEBUG
printf(" ==> extracting: %s (link to %s)\n", filename, linktgt);
#endif
if (link(linktgt, filename) == -1)
{
#ifdef DEBUG
perror("link()");
#endif
return -1;
}
return 0;
}
/* symlink */
int
tar_extract_symlink(TAR *t, char *realname)
{
char *filename;
if (!TH_ISSYM(t))
{
errno = EINVAL;
return -1;
}
filename = (realname ? realname : th_get_pathname(t));
if (mkdirhier(dirname(filename)) == -1)
return -1;
if (unlink(filename) == -1 && errno != ENOENT)
return -1;
#ifdef DEBUG
printf(" ==> extracting: %s (symlink to %s)\n",
filename, th_get_linkname(t));
#endif
if (symlink(th_get_linkname(t), filename) == -1)
{
#ifdef DEBUG
perror("symlink()");
#endif
return -1;
}
return 0;
}
/* character device */
int
tar_extract_chardev(TAR *t, char *realname)
{
mode_t mode;
unsigned long devmaj, devmin;
char *filename;
if (!TH_ISCHR(t))
{
errno = EINVAL;
return -1;
}
filename = (realname ? realname : th_get_pathname(t));
mode = th_get_mode(t);
devmaj = th_get_devmajor(t);
devmin = th_get_devminor(t);
if (mkdirhier(dirname(filename)) == -1)
return -1;
#ifdef DEBUG
printf(" ==> extracting: %s (character device %ld,%ld)\n",
filename, devmaj, devmin);
#endif
if (mknod(filename, mode | S_IFCHR,
compat_makedev(devmaj, devmin)) == -1)
{
#ifdef DEBUG
perror("mknod()");
#endif
return -1;
}
return 0;
}
/* block device */
int
tar_extract_blockdev(TAR *t, char *realname)
{
mode_t mode;
unsigned long devmaj, devmin;
char *filename;
if (!TH_ISBLK(t))
{
errno = EINVAL;
return -1;
}
filename = (realname ? realname : th_get_pathname(t));
mode = th_get_mode(t);
devmaj = th_get_devmajor(t);
devmin = th_get_devminor(t);
if (mkdirhier(dirname(filename)) == -1)
return -1;
#ifdef DEBUG
printf(" ==> extracting: %s (block device %ld,%ld)\n",
filename, devmaj, devmin);
#endif
if (mknod(filename, mode | S_IFBLK,
compat_makedev(devmaj, devmin)) == -1)
{
#ifdef DEBUG
perror("mknod()");
#endif
return -1;
}
return 0;
}
/* directory */
int
tar_extract_dir(TAR *t, char *realname)
{
mode_t mode;
char *filename;
if (!TH_ISDIR(t))
{
errno = EINVAL;
return -1;
}
filename = (realname ? realname : th_get_pathname(t));
mode = th_get_mode(t);
if (mkdirhier(dirname(filename)) == -1)
return -1;
#ifdef DEBUG
printf(" ==> extracting: %s (mode %04o, directory)\n", filename,
mode);
#endif
if (mkdir(filename, mode) == -1)
{
if (errno == EEXIST)
{
if (chmod(filename, mode) == -1)
{
#ifdef DEBUG
perror("chmod()");
#endif
return -1;
}
else
{
#ifdef DEBUG
puts(" *** using existing directory");
#endif
return 1;
}
}
else
{
#ifdef DEBUG
perror("mkdir()");
#endif
return -1;
}
}
return 0;
}
/* FIFO */
int
tar_extract_fifo(TAR *t, char *realname)
{
mode_t mode;
char *filename;
if (!TH_ISFIFO(t))
{
errno = EINVAL;
return -1;
}
filename = (realname ? realname : th_get_pathname(t));
mode = th_get_mode(t);
if (mkdirhier(dirname(filename)) == -1)
return -1;
#ifdef DEBUG
printf(" ==> extracting: %s (fifo)\n", filename);
#endif
if (mkfifo(filename, mode) == -1)
{
#ifdef DEBUG
perror("mkfifo()");
#endif
return -1;
}
return 0;
}

129
lib/handle.c Normal file
View File

@ -0,0 +1,129 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** handle.c - libtar code for initializing a TAR handle
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef STDC_HEADERS
# include <stdlib.h>
#endif
const char libtar_version[] = PACKAGE_VERSION;
static tartype_t default_type = { open, close, read, write };
static int
tar_init(TAR **t, char *pathname, tartype_t *type,
int oflags, int mode, int options)
{
if ((oflags & O_ACCMODE) == O_RDWR)
{
errno = EINVAL;
return -1;
}
*t = (TAR *)calloc(1, sizeof(TAR));
if (*t == NULL)
return -1;
(*t)->pathname = pathname;
(*t)->options = options;
(*t)->type = (type ? type : &default_type);
(*t)->oflags = oflags;
if ((oflags & O_ACCMODE) == O_RDONLY)
(*t)->h = libtar_hash_new(256,
(libtar_hashfunc_t)path_hashfunc);
else
(*t)->h = libtar_hash_new(16, (libtar_hashfunc_t)dev_hash);
if ((*t)->h == NULL)
{
free(*t);
return -1;
}
return 0;
}
/* open a new tarfile handle */
int
tar_open(TAR **t, char *pathname, tartype_t *type,
int oflags, int mode, int options)
{
if (tar_init(t, pathname, type, oflags, mode, options) == -1)
return -1;
if ((options & TAR_NOOVERWRITE) && (oflags & O_CREAT))
oflags |= O_EXCL;
#ifdef O_BINARY
oflags |= O_BINARY;
#endif
(*t)->fd = (*((*t)->type->openfunc))(pathname, oflags, mode);
if ((*t)->fd == -1)
{
free(*t);
return -1;
}
return 0;
}
int
tar_fdopen(TAR **t, int fd, char *pathname, tartype_t *type,
int oflags, int mode, int options)
{
if (tar_init(t, pathname, type, oflags, mode, options) == -1)
return -1;
(*t)->fd = fd;
return 0;
}
int
tar_fd(TAR *t)
{
return t->fd;
}
/* close tarfile handle */
int
tar_close(TAR *t)
{
int i;
i = (*(t->type->closefunc))(t->fd);
if (t->h != NULL)
libtar_hash_free(t->h, ((t->oflags & O_ACCMODE) == O_RDONLY
? free
: (libtar_freefunc_t)tar_dev_free));
free(t);
return i;
}

17
lib/internal.h Normal file
View File

@ -0,0 +1,17 @@
/*
** Copyright 2002-2003 University of Illinois Board of Trustees
** Copyright 2002-2003 Mark D. Roth
** All rights reserved.
**
** internal.h - internal header file for libtar
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <config.h>
#include <compat.h>
#include <libtar.h>

295
lib/libtar.h Normal file
View File

@ -0,0 +1,295 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** libtar.h - header file for libtar library
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#ifndef LIBTAR_H
#define LIBTAR_H
#include <sys/types.h>
#include <sys/stat.h>
#include <tar.h>
#include <libtar_listhash.h>
#ifdef __cplusplus
extern "C"
{
#endif
/* useful constants */
#define T_BLOCKSIZE 512
#define T_NAMELEN 100
#define T_PREFIXLEN 155
#define T_MAXPATHLEN (T_NAMELEN + T_PREFIXLEN)
/* GNU extensions for typeflag */
#define GNU_LONGNAME_TYPE 'L'
#define GNU_LONGLINK_TYPE 'K'
/* our version of the tar header structure */
struct tar_header
{
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
char typeflag;
char linkname[100];
char magic[6];
char version[2];
char uname[32];
char gname[32];
char devmajor[8];
char devminor[8];
char prefix[155];
char padding[12];
char *gnu_longname;
char *gnu_longlink;
};
/***** handle.c ************************************************************/
typedef int (*openfunc_t)(const char *, int, ...);
typedef int (*closefunc_t)(int);
typedef ssize_t (*readfunc_t)(int, void *, size_t);
typedef ssize_t (*writefunc_t)(int, const void *, size_t);
typedef struct
{
openfunc_t openfunc;
closefunc_t closefunc;
readfunc_t readfunc;
writefunc_t writefunc;
}
tartype_t;
typedef struct
{
tartype_t *type;
char *pathname;
long fd;
int oflags;
int options;
struct tar_header th_buf;
libtar_hash_t *h;
}
TAR;
/* constant values for the TAR options field */
#define TAR_GNU 1 /* use GNU extensions */
#define TAR_VERBOSE 2 /* output file info to stdout */
#define TAR_NOOVERWRITE 4 /* don't overwrite existing files */
#define TAR_IGNORE_EOT 8 /* ignore double zero blocks as EOF */
#define TAR_CHECK_MAGIC 16 /* check magic in file header */
#define TAR_CHECK_VERSION 32 /* check version in file header */
#define TAR_IGNORE_CRC 64 /* ignore CRC in file header */
/* this is obsolete - it's here for backwards-compatibility only */
#define TAR_IGNORE_MAGIC 0
extern const char libtar_version[];
/* open a new tarfile handle */
int tar_open(TAR **t, char *pathname, tartype_t *type,
int oflags, int mode, int options);
/* make a tarfile handle out of a previously-opened descriptor */
int tar_fdopen(TAR **t, int fd, char *pathname, tartype_t *type,
int oflags, int mode, int options);
/* returns the descriptor associated with t */
int tar_fd(TAR *t);
/* close tarfile handle */
int tar_close(TAR *t);
/***** append.c ************************************************************/
/* forward declaration to appease the compiler */
struct tar_dev;
/* cleanup function */
void tar_dev_free(struct tar_dev *tdp);
/* Appends a file to the tar archive.
* Arguments:
* t = TAR handle to append to
* realname = path of file to append
* savename = name to save the file under in the archive
*/
int tar_append_file(TAR *t, char *realname, char *savename);
/* write EOF indicator */
int tar_append_eof(TAR *t);
/* add file contents to a tarchive */
int tar_append_regfile(TAR *t, char *realname);
/***** block.c *************************************************************/
/* macros for reading/writing tarchive blocks */
#define tar_block_read(t, buf) \
(*((t)->type->readfunc))((t)->fd, (char *)(buf), T_BLOCKSIZE)
#define tar_block_write(t, buf) \
(*((t)->type->writefunc))((t)->fd, (char *)(buf), T_BLOCKSIZE)
/* read/write a header block */
int th_read(TAR *t);
int th_write(TAR *t);
/***** decode.c ************************************************************/
/* determine file type */
#define TH_ISREG(t) ((t)->th_buf.typeflag == REGTYPE \
|| (t)->th_buf.typeflag == AREGTYPE \
|| (t)->th_buf.typeflag == CONTTYPE \
|| (S_ISREG((mode_t)oct_to_int((t)->th_buf.mode)) \
&& (t)->th_buf.typeflag != LNKTYPE))
#define TH_ISLNK(t) ((t)->th_buf.typeflag == LNKTYPE)
#define TH_ISSYM(t) ((t)->th_buf.typeflag == SYMTYPE \
|| S_ISLNK((mode_t)oct_to_int((t)->th_buf.mode)))
#define TH_ISCHR(t) ((t)->th_buf.typeflag == CHRTYPE \
|| S_ISCHR((mode_t)oct_to_int((t)->th_buf.mode)))
#define TH_ISBLK(t) ((t)->th_buf.typeflag == BLKTYPE \
|| S_ISBLK((mode_t)oct_to_int((t)->th_buf.mode)))
#define TH_ISDIR(t) ((t)->th_buf.typeflag == DIRTYPE \
|| S_ISDIR((mode_t)oct_to_int((t)->th_buf.mode)) \
|| ((t)->th_buf.typeflag == AREGTYPE \
&& ((t)->th_buf.name[strlen((t)->th_buf.name) - 1] == '/')))
#define TH_ISFIFO(t) ((t)->th_buf.typeflag == FIFOTYPE \
|| S_ISFIFO((mode_t)oct_to_int((t)->th_buf.mode)))
#define TH_ISLONGNAME(t) ((t)->th_buf.typeflag == GNU_LONGNAME_TYPE)
#define TH_ISLONGLINK(t) ((t)->th_buf.typeflag == GNU_LONGLINK_TYPE)
/* decode tar header info */
#define th_get_crc(t) oct_to_int((t)->th_buf.chksum)
#define th_get_size(t) oct_to_int((t)->th_buf.size)
#define th_get_mtime(t) oct_to_int((t)->th_buf.mtime)
#define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor)
#define th_get_devminor(t) oct_to_int((t)->th_buf.devminor)
#define th_get_linkname(t) ((t)->th_buf.gnu_longlink \
? (t)->th_buf.gnu_longlink \
: (t)->th_buf.linkname)
char *th_get_pathname(TAR *t);
mode_t th_get_mode(TAR *t);
uid_t th_get_uid(TAR *t);
gid_t th_get_gid(TAR *t);
/***** encode.c ************************************************************/
/* encode file info in th_header */
void th_set_type(TAR *t, mode_t mode);
void th_set_path(TAR *t, char *pathname);
void th_set_link(TAR *t, char *linkname);
void th_set_device(TAR *t, dev_t device);
void th_set_user(TAR *t, uid_t uid);
void th_set_group(TAR *t, gid_t gid);
void th_set_mode(TAR *t, mode_t fmode);
#define th_set_mtime(t, fmtime) \
int_to_oct_nonull((fmtime), (t)->th_buf.mtime, 12)
#define th_set_size(t, fsize) \
int_to_oct_nonull((fsize), (t)->th_buf.size, 12)
/* encode everything at once (except the pathname and linkname) */
void th_set_from_stat(TAR *t, struct stat *s);
/* encode magic, version, and crc - must be done after everything else is set */
void th_finish(TAR *t);
/***** extract.c ***********************************************************/
/* sequentially extract next file from t */
int tar_extract_file(TAR *t, char *realname);
/* extract different file types */
int tar_extract_dir(TAR *t, char *realname);
int tar_extract_hardlink(TAR *t, char *realname);
int tar_extract_symlink(TAR *t, char *realname);
int tar_extract_chardev(TAR *t, char *realname);
int tar_extract_blockdev(TAR *t, char *realname);
int tar_extract_fifo(TAR *t, char *realname);
/* for regfiles, we need to extract the content blocks as well */
int tar_extract_regfile(TAR *t, char *realname);
int tar_skip_regfile(TAR *t);
/***** output.c ************************************************************/
/* print the tar header */
void th_print(TAR *t);
/* print "ls -l"-like output for the file described by th */
void th_print_long_ls(TAR *t);
/***** util.c *************************************************************/
/* hashing function for pathnames */
int path_hashfunc(char *key, int numbuckets);
/* matching function for dev_t's */
int dev_match(dev_t *dev1, dev_t *dev2);
/* matching function for ino_t's */
int ino_match(ino_t *ino1, ino_t *ino2);
/* hashing function for dev_t's */
int dev_hash(dev_t *dev);
/* hashing function for ino_t's */
int ino_hash(ino_t *inode);
/* create any necessary dirs */
int mkdirhier(char *path);
/* calculate header checksum */
int th_crc_calc(TAR *t);
#define th_crc_ok(t) (th_get_crc(t) == th_crc_calc(t))
/* string-octal to integer conversion */
int oct_to_int(char *oct);
/* integer to NULL-terminated string-octal conversion */
#define int_to_oct(num, oct, octlen) \
snprintf((oct), (octlen), "%*lo ", (octlen) - 2, (unsigned long)(num))
/* integer to string-octal conversion, no NULL */
void int_to_oct_nonull(int num, char *oct, size_t octlen);
/***** wrapper.c **********************************************************/
/* extract groups of files */
int tar_extract_glob(TAR *t, char *globname, char *prefix);
int tar_extract_all(TAR *t, char *prefix);
/* add a whole tree of files */
int tar_append_tree(TAR *t, char *realdir, char *savedir);
#ifdef __cplusplus
}
#endif
#endif /* ! LIBTAR_H */

134
lib/output.c Normal file
View File

@ -0,0 +1,134 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** output.c - libtar code to print out tar header blocks
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <limits.h>
#include <sys/param.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
#ifndef _POSIX_LOGIN_NAME_MAX
# define _POSIX_LOGIN_NAME_MAX 9
#endif
void
th_print(TAR *t)
{
puts("\nPrinting tar header:");
printf(" name = \"%.100s\"\n", t->th_buf.name);
printf(" mode = \"%.8s\"\n", t->th_buf.mode);
printf(" uid = \"%.8s\"\n", t->th_buf.uid);
printf(" gid = \"%.8s\"\n", t->th_buf.gid);
printf(" size = \"%.12s\"\n", t->th_buf.size);
printf(" mtime = \"%.12s\"\n", t->th_buf.mtime);
printf(" chksum = \"%.8s\"\n", t->th_buf.chksum);
printf(" typeflag = \'%c\'\n", t->th_buf.typeflag);
printf(" linkname = \"%.100s\"\n", t->th_buf.linkname);
printf(" magic = \"%.6s\"\n", t->th_buf.magic);
/*printf(" version = \"%.2s\"\n", t->th_buf.version); */
printf(" version[0] = \'%c\',version[1] = \'%c\'\n",
t->th_buf.version[0], t->th_buf.version[1]);
printf(" uname = \"%.32s\"\n", t->th_buf.uname);
printf(" gname = \"%.32s\"\n", t->th_buf.gname);
printf(" devmajor = \"%.8s\"\n", t->th_buf.devmajor);
printf(" devminor = \"%.8s\"\n", t->th_buf.devminor);
printf(" prefix = \"%.155s\"\n", t->th_buf.prefix);
printf(" padding = \"%.12s\"\n", t->th_buf.padding);
printf(" gnu_longname = \"%s\"\n",
(t->th_buf.gnu_longname ? t->th_buf.gnu_longname : "[NULL]"));
printf(" gnu_longlink = \"%s\"\n",
(t->th_buf.gnu_longlink ? t->th_buf.gnu_longlink : "[NULL]"));
}
void
th_print_long_ls(TAR *t)
{
char modestring[12];
struct passwd *pw;
struct group *gr;
uid_t uid;
gid_t gid;
char username[_POSIX_LOGIN_NAME_MAX];
char groupname[_POSIX_LOGIN_NAME_MAX];
time_t mtime;
struct tm *mtm;
#ifdef HAVE_STRFTIME
char timebuf[18];
#else
const char *months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
#endif
uid = th_get_uid(t);
pw = getpwuid(uid);
if (pw == NULL)
snprintf(username, sizeof(username), "%d", uid);
else
strlcpy(username, pw->pw_name, sizeof(username));
gid = th_get_gid(t);
gr = getgrgid(gid);
if (gr == NULL)
snprintf(groupname, sizeof(groupname), "%d", gid);
else
strlcpy(groupname, gr->gr_name, sizeof(groupname));
strmode(th_get_mode(t), modestring);
printf("%.10s %-8.8s %-8.8s ", modestring, username, groupname);
if (TH_ISCHR(t) || TH_ISBLK(t))
printf(" %3d, %3d ", th_get_devmajor(t), th_get_devminor(t));
else
printf("%9ld ", (long)th_get_size(t));
mtime = th_get_mtime(t);
mtm = localtime(&mtime);
#ifdef HAVE_STRFTIME
strftime(timebuf, sizeof(timebuf), "%h %e %H:%M %Y", mtm);
printf("%s", timebuf);
#else
printf("%.3s %2d %2d:%02d %4d",
months[mtm->tm_mon],
mtm->tm_mday, mtm->tm_hour, mtm->tm_min, mtm->tm_year + 1900);
#endif
printf(" %s", th_get_pathname(t));
if (TH_ISSYM(t) || TH_ISLNK(t))
{
if (TH_ISSYM(t))
printf(" -> ");
else
printf(" link to ");
if ((t->options & TAR_GNU) && t->th_buf.gnu_longlink != NULL)
printf("%s", t->th_buf.gnu_longlink);
else
printf("%.100s", t->th_buf.linkname);
}
putchar('\n');
}

150
lib/util.c Normal file
View File

@ -0,0 +1,150 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** util.c - miscellaneous utility code for libtar
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <sys/param.h>
#include <errno.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
/* hashing function for pathnames */
int
path_hashfunc(char *key, int numbuckets)
{
char buf[MAXPATHLEN];
char *p;
strcpy(buf, key);
p = basename(buf);
return (((unsigned int)p[0]) % numbuckets);
}
/* matching function for dev_t's */
int
dev_match(dev_t *dev1, dev_t *dev2)
{
return !memcmp(dev1, dev2, sizeof(dev_t));
}
/* matching function for ino_t's */
int
ino_match(ino_t *ino1, ino_t *ino2)
{
return !memcmp(ino1, ino2, sizeof(ino_t));
}
/* hashing function for dev_t's */
int
dev_hash(dev_t *dev)
{
return *dev % 16;
}
/* hashing function for ino_t's */
int
ino_hash(ino_t *inode)
{
return *inode % 256;
}
/*
** mkdirhier() - create all directories in a given path
** returns:
** 0 success
** 1 all directories already exist
** -1 (and sets errno) error
*/
int
mkdirhier(char *path)
{
char src[MAXPATHLEN], dst[MAXPATHLEN] = "";
char *dirp, *nextp = src;
int retval = 1;
if (strlcpy(src, path, sizeof(src)) > sizeof(src))
{
errno = ENAMETOOLONG;
return -1;
}
if (path[0] == '/')
strcpy(dst, "/");
while ((dirp = strsep(&nextp, "/")) != NULL)
{
if (*dirp == '\0')
continue;
if (dst[0] != '\0')
strcat(dst, "/");
strcat(dst, dirp);
if (mkdir(dst, 0777) == -1)
{
if (errno != EEXIST)
return -1;
}
else
retval = 0;
}
return retval;
}
/* calculate header checksum */
int
th_crc_calc(TAR *t)
{
int i, sum = 0;
for (i = 0; i < T_BLOCKSIZE; i++)
sum += ((unsigned char *)(&(t->th_buf)))[i];
for (i = 0; i < 8; i++)
sum += (' ' - (unsigned char)t->th_buf.chksum[i]);
return sum;
}
/* string-octal to integer conversion */
int
oct_to_int(char *oct)
{
int i;
sscanf(oct, "%o", &i);
return i;
}
/* integer to string-octal conversion, no NULL */
void
int_to_oct_nonull(int num, char *oct, size_t octlen)
{
snprintf(oct, octlen, "%*lo", octlen - 1, (unsigned long)num);
oct[octlen - 1] = ' ';
}

152
lib/wrapper.c Normal file
View File

@ -0,0 +1,152 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** wrapper.c - libtar high-level wrapper code
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <internal.h>
#include <stdio.h>
#include <sys/param.h>
#include <dirent.h>
#include <errno.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
int
tar_extract_glob(TAR *t, char *globname, char *prefix)
{
char *filename;
char buf[MAXPATHLEN];
int i;
while ((i = th_read(t)) == 0)
{
filename = th_get_pathname(t);
if (fnmatch(globname, filename, FNM_PATHNAME | FNM_PERIOD))
{
if (TH_ISREG(t) && tar_skip_regfile(t))
return -1;
continue;
}
if (t->options & TAR_VERBOSE)
th_print_long_ls(t);
if (prefix != NULL)
snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
else
strlcpy(buf, filename, sizeof(buf));
if (tar_extract_file(t, filename) != 0)
return -1;
}
return (i == 1 ? 0 : -1);
}
int
tar_extract_all(TAR *t, char *prefix)
{
char *filename;
char buf[MAXPATHLEN];
int i;
#ifdef DEBUG
printf("==> tar_extract_all(TAR *t, \"%s\")\n",
(prefix ? prefix : "(null)"));
#endif
while ((i = th_read(t)) == 0)
{
#ifdef DEBUG
puts(" tar_extract_all(): calling th_get_pathname()");
#endif
filename = th_get_pathname(t);
if (t->options & TAR_VERBOSE)
th_print_long_ls(t);
if (prefix != NULL)
snprintf(buf, sizeof(buf), "%s/%s", prefix, filename);
else
strlcpy(buf, filename, sizeof(buf));
#ifdef DEBUG
printf(" tar_extract_all(): calling tar_extract_file(t, "
"\"%s\")\n", buf);
#endif
if (tar_extract_file(t, buf) != 0)
return -1;
}
return (i == 1 ? 0 : -1);
}
int
tar_append_tree(TAR *t, char *realdir, char *savedir)
{
char realpath[MAXPATHLEN];
char savepath[MAXPATHLEN];
struct dirent *dent;
DIR *dp;
struct stat s;
#ifdef DEBUG
printf("==> tar_append_tree(0x%lx, \"%s\", \"%s\")\n",
t, realdir, (savedir ? savedir : "[NULL]"));
#endif
if (tar_append_file(t, realdir, savedir) != 0)
return -1;
#ifdef DEBUG
puts(" tar_append_tree(): done with tar_append_file()...");
#endif
dp = opendir(realdir);
if (dp == NULL)
{
if (errno == ENOTDIR)
return 0;
return -1;
}
while ((dent = readdir(dp)) != NULL)
{
if (strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0)
continue;
snprintf(realpath, MAXPATHLEN, "%s/%s", realdir,
dent->d_name);
if (savedir)
snprintf(savepath, MAXPATHLEN, "%s/%s", savedir,
dent->d_name);
if (lstat(realpath, &s) != 0)
return -1;
if (S_ISDIR(s.st_mode))
{
if (tar_append_tree(t, realpath,
(savedir ? savepath : NULL)) != 0)
return -1;
continue;
}
if (tar_append_file(t, realpath,
(savedir ? savepath : NULL)) != 0)
return -1;
}
closedir(dp);
return 0;
}

73
libtar/Makefile.in Normal file
View File

@ -0,0 +1,73 @@
# @configure_input@
### Path settings
srcdir = @srcdir@
top_srcdir = @top_srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
@ENCAP_DEFS@
### Installation programs and flags
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
INSTALL_DATA = @INSTALL_DATA@
LN_S = @LN_S@
MKDIR = @MKDIR@
### Compiler and link options
CC = @CC@
CPPFLAGS = -I.. \
-I../lib \
-I../listhash \
-I${top_srcdir}/lib \
-I${top_srcdir}/compat \
@CPPFLAGS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
LIBOBJS = @LIBOBJS@
RANLIB = @RANLIB@
@SET_MAKE@
VPATH = @srcdir@
### Makefile rules - no user-servicable parts below
LIBTAR_OBJS = libtar.o
LIBTAR_HDRS = ../config.h \
${top_srcdir}/compat/compat.h \
${top_srcdir}/lib/libtar.h \
../listhash/libtar_listhash.h
LIBTAR_LIBS = ../lib/libtar.a
ALL = libtar
all: ${ALL}
.PHONY: clean distclean install
libtar: ${LIBTAR_OBJS} ${LIBTAR_LIBS} ${LIBTAR_HDRS}
${CC} ${CFLAGS} ${LDFLAGS} -o libtar libtar.o ${LIBTAR_LIBS} ${LIBS}
${LIBTAR_OBJS}: ${LIBTAR_HDRS}
.c.o:
${CC} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<
clean:
rm -f *~ *.o ${ALL} core
distclean: clean
rm -f Makefile
install: ${ALL}
${MKDIR} ${DESTDIR}${bindir}
${INSTALL_PROGRAM} libtar ${DESTDIR}${bindir}

363
libtar/libtar.c Normal file
View File

@ -0,0 +1,363 @@
/*
** Copyright 1998-2003 University of Illinois Board of Trustees
** Copyright 1998-2003 Mark D. Roth
** All rights reserved.
**
** libtar.c - demo driver program for libtar
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <config.h>
#include <libtar.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/param.h>
#ifdef STDC_HEADERS
# include <string.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef DEBUG
# include <signal.h>
#endif
#ifdef HAVE_LIBZ
# include <zlib.h>
#endif
#include <compat.h>
char *progname;
int verbose = 0;
int use_gnu = 0;
#ifdef DEBUG
void
segv_handler(int sig)
{
puts("OOPS! Caught SIGSEGV, bailing out...");
fflush(stdout);
fflush(stderr);
}
#endif
#ifdef HAVE_LIBZ
int use_zlib = 0;
int
gzopen_frontend(char *pathname, int oflags, int mode)
{
char *gzoflags;
gzFile gzf;
int fd;
switch (oflags & O_ACCMODE)
{
case O_WRONLY:
gzoflags = "wb";
break;
case O_RDONLY:
gzoflags = "rb";
break;
default:
case O_RDWR:
errno = EINVAL;
return -1;
}
fd = open(pathname, oflags, mode);
if (fd == -1)
return -1;
if ((oflags & O_CREAT) && fchmod(fd, mode))
return -1;
gzf = gzdopen(fd, gzoflags);
if (!gzf)
{
errno = ENOMEM;
return -1;
}
return (int)gzf;
}
tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
(readfunc_t) gzread, (writefunc_t) gzwrite
};
#endif /* HAVE_LIBZ */
int
create(char *tarfile, char *rootdir, libtar_list_t *l)
{
TAR *t;
char *pathname;
char buf[MAXPATHLEN];
libtar_listptr_t lp;
if (tar_open(&t, tarfile,
#ifdef HAVE_LIBZ
(use_zlib ? &gztype : NULL),
#else
NULL,
#endif
O_WRONLY | O_CREAT, 0644,
(verbose ? TAR_VERBOSE : 0)
| (use_gnu ? TAR_GNU : 0)) == -1)
{
fprintf(stderr, "tar_open(): %s\n", strerror(errno));
return -1;
}
libtar_listptr_reset(&lp);
while (libtar_list_next(l, &lp) != 0)
{
pathname = (char *)libtar_listptr_data(&lp);
if (pathname[0] != '/' && rootdir != NULL)
snprintf(buf, sizeof(buf), "%s/%s", rootdir, pathname);
else
strlcpy(buf, pathname, sizeof(buf));
if (tar_append_tree(t, buf, pathname) != 0)
{
fprintf(stderr,
"tar_append_tree(\"%s\", \"%s\"): %s\n", buf,
pathname, strerror(errno));
tar_close(t);
return -1;
}
}
if (tar_append_eof(t) != 0)
{
fprintf(stderr, "tar_append_eof(): %s\n", strerror(errno));
tar_close(t);
return -1;
}
if (tar_close(t) != 0)
{
fprintf(stderr, "tar_close(): %s\n", strerror(errno));
return -1;
}
return 0;
}
int
list(char *tarfile)
{
TAR *t;
int i;
if (tar_open(&t, tarfile,
#ifdef HAVE_LIBZ
(use_zlib ? &gztype : NULL),
#else
NULL,
#endif
O_RDONLY, 0,
(verbose ? TAR_VERBOSE : 0)
| (use_gnu ? TAR_GNU : 0)) == -1)
{
fprintf(stderr, "tar_open(): %s\n", strerror(errno));
return -1;
}
while ((i = th_read(t)) == 0)
{
th_print_long_ls(t);
#ifdef DEBUG
th_print(t);
#endif
if (TH_ISREG(t) && tar_skip_regfile(t) != 0)
{
fprintf(stderr, "tar_skip_regfile(): %s\n",
strerror(errno));
return -1;
}
}
#ifdef DEBUG
printf("th_read() returned %d\n", i);
printf("EOF mark encountered after %ld bytes\n",
# ifdef HAVE_LIBZ
(use_zlib
? gzseek((gzFile) t->fd, 0, SEEK_CUR)
:
# endif
lseek(t->fd, 0, SEEK_CUR)
# ifdef HAVE_LIBZ
)
# endif
);
#endif
if (tar_close(t) != 0)
{
fprintf(stderr, "tar_close(): %s\n", strerror(errno));
return -1;
}
return 0;
}
int
extract(char *tarfile, char *rootdir)
{
TAR *t;
#ifdef DEBUG
puts("opening tarfile...");
#endif
if (tar_open(&t, tarfile,
#ifdef HAVE_LIBZ
(use_zlib ? &gztype : NULL),
#else
NULL,
#endif
O_RDONLY, 0,
(verbose ? TAR_VERBOSE : 0)
| (use_gnu ? TAR_GNU : 0)) == -1)
{
fprintf(stderr, "tar_open(): %s\n", strerror(errno));
return -1;
}
#ifdef DEBUG
puts("extracting tarfile...");
#endif
if (tar_extract_all(t, rootdir) != 0)
{
fprintf(stderr, "tar_extract_all(): %s\n", strerror(errno));
return -1;
}
#ifdef DEBUG
puts("closing tarfile...");
#endif
if (tar_close(t) != 0)
{
fprintf(stderr, "tar_close(): %s\n", strerror(errno));
return -1;
}
return 0;
}
void
usage()
{
printf("Usage: %s [-C rootdir] [-g] [-z] -x|-t filename.tar\n",
progname);
printf(" %s [-C rootdir] [-g] [-z] -c filename.tar ...\n",
progname);
exit(-1);
}
#define MODE_LIST 1
#define MODE_CREATE 2
#define MODE_EXTRACT 3
int
main(int argc, char *argv[])
{
char *tarfile = NULL;
char *rootdir = NULL;
int c;
int mode = 0;
libtar_list_t *l;
progname = basename(argv[0]);
while ((c = getopt(argc, argv, "cC:gtvVxz")) != -1)
switch (c)
{
case 'V':
printf("libtar %s by Mark D. Roth <roth@uiuc.edu>\n",
libtar_version);
break;
case 'C':
rootdir = strdup(optarg);
break;
case 'v':
verbose = 1;
break;
case 'g':
use_gnu = 1;
break;
case 'c':
if (mode)
usage();
mode = MODE_CREATE;
break;
case 'x':
if (mode)
usage();
mode = MODE_EXTRACT;
break;
case 't':
if (mode)
usage();
mode = MODE_LIST;
break;
#ifdef HAVE_LIBZ
case 'z':
use_zlib = 1;
break;
#endif /* HAVE_LIBZ */
default:
usage();
}
if (!mode || ((argc - optind) < (mode == MODE_CREATE ? 2 : 1)))
{
#ifdef DEBUG
printf("argc - optind == %d\tmode == %d\n", argc - optind,
mode);
#endif
usage();
}
#ifdef DEBUG
signal(SIGSEGV, segv_handler);
#endif
switch (mode)
{
case MODE_EXTRACT:
return extract(argv[optind], rootdir);
case MODE_CREATE:
tarfile = argv[optind];
l = libtar_list_new(LIST_QUEUE, NULL);
for (c = optind + 1; c < argc; c++)
libtar_list_add(l, argv[c]);
return create(tarfile, rootdir, l);
case MODE_LIST:
return list(argv[optind]);
default:
break;
}
/* NOTREACHED */
return -2;
}

15
listhash/ChangeLog Normal file
View File

@ -0,0 +1,15 @@
2002-12-09 added list_empty() and hash_empty() functions
2002-09-12 fixed list_iterate function to return -1 if it gets
an invalid argument
include <config.h> and <compat.h> from source files, not
from header file, since header file is sometimes
installed as part of a user-visible API
(those APIs should eventually be redesigned without the
listhash code being publicly visible, but for now we
need to accomodate this)
2002-07-07 modified list iterate function to return int
(returns -1 if plugin function returns -1)

21
listhash/TODO Normal file
View File

@ -0,0 +1,21 @@
Functionality:
--------------
* add list mode to allow nodes to be inserted in any arbitrary location
* add "*_hash_iterate()" function
* add flags argument to *_list_del() that allows the listptr to be set
to the previous or next element
* add a generic pointer type to replace *_listptr_t and *_hashptr_t ???
Code Cleanup:
-------------
* rename functions:
*_list_next => *_listptr_next()
*_list_prev => *_listptr_prev()
*_hash_next => *_hashptr_next()
* start using "*_list_t" and "*_hash_t" instead of "*_list_t *" and
"*_hash_t *" ?
* add prefixes to structure member field names

344
listhash/hash.c.in Normal file
View File

@ -0,0 +1,344 @@
/* @configure_input@ */
/*
** Copyright 1998-2002 University of Illinois Board of Trustees
** Copyright 1998-2002 Mark D. Roth
** All rights reserved.
**
** @LISTHASH_PREFIX@_hash.c - hash table routines
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <config.h>
#include <compat.h>
#include <@LISTHASH_PREFIX@_listhash.h>
#include <stdio.h>
#include <errno.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
#endif
/*
** @LISTHASH_PREFIX@_hashptr_reset() - reset a hash pointer
*/
void
@LISTHASH_PREFIX@_hashptr_reset(@LISTHASH_PREFIX@_hashptr_t *hp)
{
@LISTHASH_PREFIX@_listptr_reset(&(hp->node));
hp->bucket = -1;
}
/*
** @LISTHASH_PREFIX@_hashptr_data() - retrieve the data being pointed to
*/
void *
@LISTHASH_PREFIX@_hashptr_data(@LISTHASH_PREFIX@_hashptr_t *hp)
{
return @LISTHASH_PREFIX@_listptr_data(&(hp->node));
}
/*
** @LISTHASH_PREFIX@_str_hashfunc() - default hash function, optimized for
** 7-bit strings
*/
unsigned int
@LISTHASH_PREFIX@_str_hashfunc(char *key, unsigned int num_buckets)
{
#if 0
register unsigned result = 0;
register int i;
if (key == NULL)
return 0;
for (i = 0; *key != '\0' && i < 32; i++)
result = result * 33U + *key++;
return (result % num_buckets);
#else
if (key == NULL)
return 0;
return (key[0] % num_buckets);
#endif
}
/*
** @LISTHASH_PREFIX@_hash_nents() - return number of elements from hash
*/
unsigned int
@LISTHASH_PREFIX@_hash_nents(@LISTHASH_PREFIX@_hash_t *h)
{
return h->nents;
}
/*
** @LISTHASH_PREFIX@_hash_new() - create a new hash
*/
@LISTHASH_PREFIX@_hash_t *
@LISTHASH_PREFIX@_hash_new(int num, @LISTHASH_PREFIX@_hashfunc_t hashfunc)
{
@LISTHASH_PREFIX@_hash_t *hash;
hash = (@LISTHASH_PREFIX@_hash_t *)calloc(1, sizeof(@LISTHASH_PREFIX@_hash_t));
if (hash == NULL)
return NULL;
hash->numbuckets = num;
if (hashfunc != NULL)
hash->hashfunc = hashfunc;
else
hash->hashfunc = (@LISTHASH_PREFIX@_hashfunc_t)@LISTHASH_PREFIX@_str_hashfunc;
hash->table = (@LISTHASH_PREFIX@_list_t **)calloc(num, sizeof(@LISTHASH_PREFIX@_list_t *));
if (hash->table == NULL)
{
free(hash);
return NULL;
}
return hash;
}
/*
** @LISTHASH_PREFIX@_hash_next() - get next element in hash
** returns:
** 1 data found
** 0 end of list
*/
int
@LISTHASH_PREFIX@_hash_next(@LISTHASH_PREFIX@_hash_t *h,
@LISTHASH_PREFIX@_hashptr_t *hp)
{
#ifdef DS_DEBUG
printf("==> @LISTHASH_PREFIX@_hash_next(h=0x%lx, hp={%d,0x%lx})\n",
h, hp->bucket, hp->node);
#endif
if (hp->bucket >= 0 && hp->node != NULL &&
@LISTHASH_PREFIX@_list_next(h->table[hp->bucket], &(hp->node)) != 0)
{
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_next(): found additional "
"data in current bucket (%d), returing 1\n",
hp->bucket);
#endif
return 1;
}
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_next(): done with bucket %d\n",
hp->bucket);
#endif
for (hp->bucket++; hp->bucket < h->numbuckets; hp->bucket++)
{
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_next(): "
"checking bucket %d\n", hp->bucket);
#endif
hp->node = NULL;
if (h->table[hp->bucket] != NULL &&
@LISTHASH_PREFIX@_list_next(h->table[hp->bucket],
&(hp->node)) != 0)
{
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_next(): "
"found data in bucket %d, returing 1\n",
hp->bucket);
#endif
return 1;
}
}
if (hp->bucket == h->numbuckets)
{
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_next(): hash pointer "
"wrapped to 0\n");
#endif
hp->bucket = -1;
hp->node = NULL;
}
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_hash_next(): no more data, "
"returning 0\n");
#endif
return 0;
}
/*
** @LISTHASH_PREFIX@_hash_del() - delete an entry from the hash
** returns:
** 0 success
** -1 (and sets errno) failure
*/
int
@LISTHASH_PREFIX@_hash_del(@LISTHASH_PREFIX@_hash_t *h,
@LISTHASH_PREFIX@_hashptr_t *hp)
{
if (hp->bucket < 0
|| hp->bucket >= h->numbuckets
|| h->table[hp->bucket] == NULL
|| hp->node == NULL)
{
errno = EINVAL;
return -1;
}
@LISTHASH_PREFIX@_list_del(h->table[hp->bucket], &(hp->node));
h->nents--;
return 0;
}
/*
** @LISTHASH_PREFIX@_hash_empty() - empty the hash
*/
void
@LISTHASH_PREFIX@_hash_empty(@LISTHASH_PREFIX@_hash_t *h, @LISTHASH_PREFIX@_freefunc_t freefunc)
{
int i;
for (i = 0; i < h->numbuckets; i++)
if (h->table[i] != NULL)
@LISTHASH_PREFIX@_list_empty(h->table[i], freefunc);
h->nents = 0;
}
/*
** @LISTHASH_PREFIX@_hash_free() - delete all of the nodes in the hash
*/
void
@LISTHASH_PREFIX@_hash_free(@LISTHASH_PREFIX@_hash_t *h, @LISTHASH_PREFIX@_freefunc_t freefunc)
{
int i;
for (i = 0; i < h->numbuckets; i++)
if (h->table[i] != NULL)
@LISTHASH_PREFIX@_list_free(h->table[i], freefunc);
free(h->table);
free(h);
}
/*
** @LISTHASH_PREFIX@_hash_search() - iterative search for an element in a hash
** returns:
** 1 match found
** 0 no match
*/
int
@LISTHASH_PREFIX@_hash_search(@LISTHASH_PREFIX@_hash_t *h,
@LISTHASH_PREFIX@_hashptr_t *hp, void *data,
@LISTHASH_PREFIX@_matchfunc_t matchfunc)
{
while (@LISTHASH_PREFIX@_hash_next(h, hp) != 0)
if ((*matchfunc)(data, @LISTHASH_PREFIX@_listptr_data(&(hp->node))) != 0)
return 1;
return 0;
}
/*
** @LISTHASH_PREFIX@_hash_getkey() - hash-based search for an element in a hash
** returns:
** 1 match found
** 0 no match
*/
int
@LISTHASH_PREFIX@_hash_getkey(@LISTHASH_PREFIX@_hash_t *h,
@LISTHASH_PREFIX@_hashptr_t *hp, void *key,
@LISTHASH_PREFIX@_matchfunc_t matchfunc)
{
#ifdef DS_DEBUG
printf("==> @LISTHASH_PREFIX@_hash_getkey(h=0x%lx, hp={%d,0x%lx}, "
"key=0x%lx, matchfunc=0x%lx)\n",
h, hp->bucket, hp->node, key, matchfunc);
#endif
if (hp->bucket == -1)
{
hp->bucket = (*(h->hashfunc))(key, h->numbuckets);
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_getkey(): hp->bucket "
"set to %d\n", hp->bucket);
#endif
}
if (h->table[hp->bucket] == NULL)
{
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_getkey(): no list "
"for bucket %d, returning 0\n", hp->bucket);
#endif
hp->bucket = -1;
return 0;
}
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_hash_getkey(): "
"returning @LISTHASH_PREFIX@_list_search()\n");
#endif
return @LISTHASH_PREFIX@_list_search(h->table[hp->bucket], &(hp->node),
key, matchfunc);
}
/*
** @LISTHASH_PREFIX@_hash_add() - add an element to the hash
** returns:
** 0 success
** -1 (and sets errno) failure
*/
int
@LISTHASH_PREFIX@_hash_add(@LISTHASH_PREFIX@_hash_t *h, void *data)
{
int bucket, i;
#ifdef DS_DEBUG
printf("==> @LISTHASH_PREFIX@_hash_add(h=0x%lx, data=0x%lx)\n",
h, data);
#endif
bucket = (*(h->hashfunc))(data, h->numbuckets);
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_add(): inserting in bucket %d\n",
bucket);
#endif
if (h->table[bucket] == NULL)
{
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_hash_add(): creating new list\n");
#endif
h->table[bucket] = @LISTHASH_PREFIX@_list_new(LIST_QUEUE, NULL);
}
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_hash_add(): "
"returning @LISTHASH_PREFIX@_list_add()\n");
#endif
i = @LISTHASH_PREFIX@_list_add(h->table[bucket], data);
if (i == 0)
h->nents++;
return i;
}

74
listhash/hash_new.3.in Normal file
View File

@ -0,0 +1,74 @@
.TH @LISTHASH_PREFIX@_hash_new 3 "Jan 2000" "University of Illinois" "C Library Calls"
\" @configure_input@
.SH NAME
@LISTHASH_PREFIX@_hash_new, @LISTHASH_PREFIX@_hash_free, @LISTHASH_PREFIX@_hash_next,
@LISTHASH_PREFIX@_hash_prev, @LISTHASH_PREFIX@_hash_getkey, @LISTHASH_PREFIX@_hash_search,
@LISTHASH_PREFIX@_hash_add, @LISTHASH_PREFIX@_hash_del \- hash table routines
.SH SYNOPSIS
.B #include <@LISTHASH_PREFIX@.h>
.P
.BI "@LISTHASH_PREFIX@_hash_t *@LISTHASH_PREFIX@_hash_new(int " num ", int (*" hashfunc ")());"
.br
.BI "void @LISTHASH_PREFIX@_hash_free(@LISTHASH_PREFIX@_hash_t *" h ", void (*" freefunc ")());"
.br
.BI "int @LISTHASH_PREFIX@_hash_next(@LISTHASH_PREFIX@_hash_t *" h ", @LISTHASH_PREFIX@_hashptr_t *" hp ");"
.br
.BI "int @LISTHASH_PREFIX@_hash_prev(@LISTHASH_PREFIX@_hash_t *" h ", @LISTHASH_PREFIX@_hashptr_t *" hp ");"
.br
.BI "int @LISTHASH_PREFIX@_hash_search(@LISTHASH_PREFIX@_hash_t *" h ", @LISTHASH_PREFIX@_hashptr_t *" hp ","
.BI "void *" data ", int (*" matchfunc ")());"
.br
.BI "int @LISTHASH_PREFIX@_hash_getkey(@LISTHASH_PREFIX@_hash_t *" h ", @LISTHASH_PREFIX@_hashptr_t *" hp ","
.BI "void *" data ", int (*" matchfunc ")());"
.br
.BI "int @LISTHASH_PREFIX@_hash_add(@LISTHASH_PREFIX@_hash_t *" h ", void *" data ");"
.br
.BI "int @LISTHASH_PREFIX@_hash_del(@LISTHASH_PREFIX@_hash_t *" h ", @LISTHASH_PREFIX@_hashptr_t *" hp ");"
.SH DESCRIPTION
The \fB@LISTHASH_PREFIX@_hash_new\fP() function creates a new hash with \fInum\fP
buckets and using hash function pointed to by \fIhashfunc\fP. If
\fIhashfunc\fP is \fINULL\fP, a default hash function designed for
7-bit ASCII strings is used.
The \fB@LISTHASH_PREFIX@_hash_free\fP() function deallocates all memory associated
with the hash structure \fIh\fP. If \fIfreefunc\fP is not \fINULL\fP,
it is called to free memory associated with each node in the hash.
The \fB@LISTHASH_PREFIX@_hash_next\fP() and \fB@LISTHASH_PREFIX@_hash_prev\fP() functions are
used to iterate through the hash. The \fI@LISTHASH_PREFIX@_hashptr_t\fP structure
has two fields: \fIbucket\fP, which indicates the current bucket in the
hash, and \fInode\fP, which is a pointer to the current node in the current
bucket. To start at the beginning or end of the hash, the caller should
initialize \fIhp.bucket\fP to -1 and \fIhp.node\fP to \fINULL\fP.
The \fB@LISTHASH_PREFIX@_hash_search\fP() function searches iteratively through the
hash \fIh\fP until it finds a node whose contents match \fIdata\fP using
the matching function \fImatchfunc\fP. Searching begins at the location
pointed to by \fIhp\fP.
The \fB@LISTHASH_PREFIX@_hash_getkey\fP() function uses the hash function associated
with \fIh\fP to determine which bucket \fIdata\fP should be in, and searches
only that bucket for a matching node using \fImatchfunc\fP. Searching
begins at the location pointed to by \fIhp\fP.
The \fB@LISTHASH_PREFIX@_hash_add\fP() function adds \fIdata\fP into hash \fIh\fP.
The \fB@LISTHASH_PREFIX@_hash_del\fP() function removes the node referenced by
\fIhp\fP.
.SH RETURN VALUE
The \fB@LISTHASH_PREFIX@_hash_new\fP() function returns a pointer to the new hash
structure, or \fINULL\fP on error.
The \fB@LISTHASH_PREFIX@_hash_next\fP() and \fB@LISTHASH_PREFIX@_hash_prev\fP() functions
return 1 when valid data is returned, and 0 at the end of the hash.
The \fB@LISTHASH_PREFIX@_hash_getkey\fP() and \fB@LISTHASH_PREFIX@_hash_search\fP() functions
return 1 when a match is found, or 0 otherwise.
The \fB@LISTHASH_PREFIX@_hash_add\fP() function returns 0 on success, or -1 on
error (and sets \fIerrno\fP).
The \fB@LISTHASH_PREFIX@_hash_del\fP() function returns 0 on success, or -1 on
error (and sets \fIerrno\fP).
.SH SEE ALSO
.BR @LISTHASH_PREFIX@_list_new (3)

458
listhash/list.c.in Normal file
View File

@ -0,0 +1,458 @@
/* @configure_input@ */
/*
** Copyright 1998-2002 University of Illinois Board of Trustees
** Copyright 1998-2002 Mark D. Roth
** All rights reserved.
**
** @LISTHASH_PREFIX@_list.c - linked list routines
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#include <config.h>
#include <compat.h>
#include <@LISTHASH_PREFIX@_listhash.h>
#include <stdio.h>
#include <errno.h>
#include <sys/param.h>
#ifdef STDC_HEADERS
# include <string.h>
# include <stdlib.h>
#endif
/*
** @LISTHASH_PREFIX@_listptr_reset() - reset a list pointer
*/
void
@LISTHASH_PREFIX@_listptr_reset(@LISTHASH_PREFIX@_listptr_t *lp)
{
*lp = NULL;
}
/*
** @LISTHASH_PREFIX@_listptr_data() - retrieve the data pointed to by lp
*/
void *
@LISTHASH_PREFIX@_listptr_data(@LISTHASH_PREFIX@_listptr_t *lp)
{
return (*lp)->data;
}
/*
** @LISTHASH_PREFIX@_list_new() - create a new, empty list
*/
@LISTHASH_PREFIX@_list_t *
@LISTHASH_PREFIX@_list_new(int flags, @LISTHASH_PREFIX@_cmpfunc_t cmpfunc)
{
@LISTHASH_PREFIX@_list_t *newlist;
#ifdef DS_DEBUG
printf("in @LISTHASH_PREFIX@_list_new(%d, 0x%lx)\n", flags, cmpfunc);
#endif
if (flags != LIST_USERFUNC
&& flags != LIST_STACK
&& flags != LIST_QUEUE)
{
errno = EINVAL;
return NULL;
}
newlist = (@LISTHASH_PREFIX@_list_t *)calloc(1, sizeof(@LISTHASH_PREFIX@_list_t));
if (cmpfunc != NULL)
newlist->cmpfunc = cmpfunc;
else
newlist->cmpfunc = (@LISTHASH_PREFIX@_cmpfunc_t)strcmp;
newlist->flags = flags;
return newlist;
}
/*
** @LISTHASH_PREFIX@_list_iterate() - call a function for every element
** in a list
*/
int
@LISTHASH_PREFIX@_list_iterate(@LISTHASH_PREFIX@_list_t *l,
@LISTHASH_PREFIX@_iterate_func_t plugin,
void *state)
{
@LISTHASH_PREFIX@_listptr_t n;
if (l == NULL)
return -1;
for (n = l->first; n != NULL; n = n->next)
{
if ((*plugin)(n->data, state) == -1)
return -1;
}
return 0;
}
/*
** @LISTHASH_PREFIX@_list_empty() - empty the list
*/
void
@LISTHASH_PREFIX@_list_empty(@LISTHASH_PREFIX@_list_t *l, @LISTHASH_PREFIX@_freefunc_t freefunc)
{
@LISTHASH_PREFIX@_listptr_t n;
for (n = l->first; n != NULL; n = l->first)
{
l->first = n->next;
if (freefunc != NULL)
(*freefunc)(n->data);
free(n);
}
l->nents = 0;
}
/*
** @LISTHASH_PREFIX@_list_free() - remove and free() the whole list
*/
void
@LISTHASH_PREFIX@_list_free(@LISTHASH_PREFIX@_list_t *l, @LISTHASH_PREFIX@_freefunc_t freefunc)
{
@LISTHASH_PREFIX@_list_empty(l, freefunc);
free(l);
}
/*
** @LISTHASH_PREFIX@_list_nents() - return number of elements in the list
*/
unsigned int
@LISTHASH_PREFIX@_list_nents(@LISTHASH_PREFIX@_list_t *l)
{
return l->nents;
}
/*
** @LISTHASH_PREFIX@_list_add() - adds an element to the list
** returns:
** 0 success
** -1 (and sets errno) failure
*/
int
@LISTHASH_PREFIX@_list_add(@LISTHASH_PREFIX@_list_t *l, void *data)
{
@LISTHASH_PREFIX@_listptr_t n, m;
#ifdef DS_DEBUG
printf("==> @LISTHASH_PREFIX@_list_add(\"%s\")\n", (char *)data);
#endif
n = (@LISTHASH_PREFIX@_listptr_t)malloc(sizeof(struct @LISTHASH_PREFIX@_node));
if (n == NULL)
return -1;
n->data = data;
l->nents++;
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_list_add(): allocated data\n");
#endif
/* if the list is empty */
if (l->first == NULL)
{
l->last = l->first = n;
n->next = n->prev = NULL;
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_list_add(): list was empty; "
"added first element and returning 0\n");
#endif
return 0;
}
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_list_add(): list not empty\n");
#endif
if (l->flags == LIST_STACK)
{
n->prev = NULL;
n->next = l->first;
if (l->first != NULL)
l->first->prev = n;
l->first = n;
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_list_add(): LIST_STACK set; "
"added in front\n");
#endif
return 0;
}
if (l->flags == LIST_QUEUE)
{
n->prev = l->last;
n->next = NULL;
if (l->last != NULL)
l->last->next = n;
l->last = n;
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_list_add(): LIST_QUEUE set; "
"added at end\n");
#endif
return 0;
}
for (m = l->first; m != NULL; m = m->next)
if ((*(l->cmpfunc))(data, m->data) < 0)
{
/*
** if we find one that's bigger,
** insert data before it
*/
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_list_add(): gotcha..."
"inserting data\n");
#endif
if (m == l->first)
{
l->first = n;
n->prev = NULL;
m->prev = n;
n->next = m;
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_list_add(): "
"added first, returning 0\n");
#endif
return 0;
}
m->prev->next = n;
n->prev = m->prev;
m->prev = n;
n->next = m;
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_list_add(): added middle,"
" returning 0\n");
#endif
return 0;
}
#ifdef DS_DEBUG
printf(" @LISTHASH_PREFIX@_list_add(): new data larger than current "
"list elements\n");
#endif
/* if we get here, data is bigger than everything in the list */
l->last->next = n;
n->prev = l->last;
l->last = n;
n->next = NULL;
#ifdef DS_DEBUG
printf("<== @LISTHASH_PREFIX@_list_add(): added end, returning 0\n");
#endif
return 0;
}
/*
** @LISTHASH_PREFIX@_list_del() - remove the element pointed to by n
** from the list l
*/
void
@LISTHASH_PREFIX@_list_del(@LISTHASH_PREFIX@_list_t *l, @LISTHASH_PREFIX@_listptr_t *n)
{
@LISTHASH_PREFIX@_listptr_t m;
#ifdef DS_DEBUG
printf("==> @LISTHASH_PREFIX@_list_del()\n");
#endif
l->nents--;
m = (*n)->next;
if ((*n)->prev)
(*n)->prev->next = (*n)->next;
else
l->first = (*n)->next;
if ((*n)->next)
(*n)->next->prev = (*n)->prev;
else
l->last = (*n)->prev;
free(*n);
*n = m;
}
/*
** @LISTHASH_PREFIX@_list_next() - get the next element in the list
** returns:
** 1 success
** 0 end of list
*/
int
@LISTHASH_PREFIX@_list_next(@LISTHASH_PREFIX@_list_t *l,
@LISTHASH_PREFIX@_listptr_t *n)
{
if (*n == NULL)
*n = l->first;
else
*n = (*n)->next;
return (*n != NULL ? 1 : 0);
}
/*
** @LISTHASH_PREFIX@_list_prev() - get the previous element in the list
** returns:
** 1 success
** 0 end of list
*/
int
@LISTHASH_PREFIX@_list_prev(@LISTHASH_PREFIX@_list_t *l,
@LISTHASH_PREFIX@_listptr_t *n)
{
if (*n == NULL)
*n = l->last;
else
*n = (*n)->prev;
return (*n != NULL ? 1 : 0);
}
/*
** @LISTHASH_PREFIX@_str_match() - string matching function
** returns:
** 1 match
** 0 no match
*/
int
@LISTHASH_PREFIX@_str_match(char *check, char *data)
{
return !strcmp(check, data);
}
/*
** @LISTHASH_PREFIX@_list_add_str() - splits string str into delim-delimited
** elements and adds them to list l
** returns:
** 0 success
** -1 (and sets errno) failure
*/
int
@LISTHASH_PREFIX@_list_add_str(@LISTHASH_PREFIX@_list_t *l,
char *str, char *delim)
{
char tmp[10240];
char *tokp, *nextp = tmp;
strlcpy(tmp, str, sizeof(tmp));
while ((tokp = strsep(&nextp, delim)) != NULL)
{
if (*tokp == '\0')
continue;
if (@LISTHASH_PREFIX@_list_add(l, strdup(tokp)))
return -1;
}
return 0;
}
/*
** @LISTHASH_PREFIX@_list_search() - find an entry in a list
** returns:
** 1 match found
** 0 no match
*/
int
@LISTHASH_PREFIX@_list_search(@LISTHASH_PREFIX@_list_t *l,
@LISTHASH_PREFIX@_listptr_t *n, void *data,
@LISTHASH_PREFIX@_matchfunc_t matchfunc)
{
#ifdef DS_DEBUG
printf("==> @LISTHASH_PREFIX@_list_search(l=0x%lx, n=0x%lx, \"%s\")\n",
l, n, (char *)data);
#endif
if (matchfunc == NULL)
matchfunc = (@LISTHASH_PREFIX@_matchfunc_t)@LISTHASH_PREFIX@_str_match;
if (*n == NULL)
*n = l->first;
else
*n = (*n)->next;
for (; *n != NULL; *n = (*n)->next)
{
#ifdef DS_DEBUG
printf("checking against \"%s\"\n", (char *)(*n)->data);
#endif
if ((*(matchfunc))(data, (*n)->data) != 0)
return 1;
}
#ifdef DS_DEBUG
printf("no matches found\n");
#endif
return 0;
}
/*
** @LISTHASH_PREFIX@_list_dup() - copy an existing list
*/
@LISTHASH_PREFIX@_list_t *
@LISTHASH_PREFIX@_list_dup(@LISTHASH_PREFIX@_list_t *l)
{
@LISTHASH_PREFIX@_list_t *newlist;
@LISTHASH_PREFIX@_listptr_t n;
newlist = @LISTHASH_PREFIX@_list_new(l->flags, l->cmpfunc);
for (n = l->first; n != NULL; n = n->next)
@LISTHASH_PREFIX@_list_add(newlist, n->data);
#ifdef DS_DEBUG
printf("returning from @LISTHASH_PREFIX@_list_dup()\n");
#endif
return newlist;
}
/*
** @LISTHASH_PREFIX@_list_merge() - merge two lists into a new list
*/
@LISTHASH_PREFIX@_list_t *
@LISTHASH_PREFIX@_list_merge(@LISTHASH_PREFIX@_cmpfunc_t cmpfunc, int flags,
@LISTHASH_PREFIX@_list_t *list1,
@LISTHASH_PREFIX@_list_t *list2)
{
@LISTHASH_PREFIX@_list_t *newlist;
@LISTHASH_PREFIX@_listptr_t n;
newlist = @LISTHASH_PREFIX@_list_new(flags, cmpfunc);
n = NULL;
while (@LISTHASH_PREFIX@_list_next(list1, &n) != 0)
@LISTHASH_PREFIX@_list_add(newlist, n->data);
n = NULL;
while (@LISTHASH_PREFIX@_list_next(list2, &n) != 0)
@LISTHASH_PREFIX@_list_add(newlist, n->data);
return newlist;
}

86
listhash/list_new.3.in Normal file
View File

@ -0,0 +1,86 @@
.TH @LISTHASH_PREFIX@_list_new 3 "Jan 2000" "University of Illinois" "C Library Calls"
\" @configure_input@
.SH NAME
@LISTHASH_PREFIX@_list_new, @LISTHASH_PREFIX@_list_free, @LISTHASH_PREFIX@_list_next,
@LISTHASH_PREFIX@_list_prev, @LISTHASH_PREFIX@_list_add, @LISTHASH_PREFIX@_list_del,
@LISTHASH_PREFIX@_list_search, @LISTHASH_PREFIX@_list_dup, @LISTHASH_PREFIX@_list_merge,
@LISTHASH_PREFIX@_list_add_str \- linked list routines
.SH SYNOPSIS
.B #include <@LISTHASH_PREFIX@.h>
.P
.BI "@LISTHASH_PREFIX@_list_t *@LISTHASH_PREFIX@_list_new(int " flags ","
.BI "int (*" cmpfunc ")());"
.br
.BI "void @LISTHASH_PREFIX@_list_free(@LISTHASH_PREFIX@_list_t *" l ", void (*" freefunc ")());"
.br
.BI "int @LISTHASH_PREFIX@_list_add_str(@LISTHASH_PREFIX@_list_t *" l ", char *" str ","
.BI "char *" delim ");"
.br
.BI "int @LISTHASH_PREFIX@_list_add(@LISTHASH_PREFIX@_list_t *" l ", void *" data ");"
.br
.BI "void @LISTHASH_PREFIX@_list_del(@LISTHASH_PREFIX@_list_t *" l ", @LISTHASH_PREFIX@_node_t **" n ");"
.br
.BI "int @LISTHASH_PREFIX@_list_search(@LISTHASH_PREFIX@_list_t *" l ", @LISTHASH_PREFIX@_node_t **" n ","
.BI "void *" data ", int (*" matchfunc ")());"
.br
.BI "int @LISTHASH_PREFIX@_list_next(@LISTHASH_PREFIX@_list_t *" l ", @LISTHASH_PREFIX@_node_t **" n ");"
.br
.BI "int @LISTHASH_PREFIX@_list_prev(@LISTHASH_PREFIX@_list_t *" l ", @LISTHASH_PREFIX@_node_t **" n ");"
.br
.BI "@LISTHASH_PREFIX@_list_t *@LISTHASH_PREFIX@_list_dup(@LISTHASH_PREFIX@_list_t *" l ");"
.br
.BI "@LISTHASH_PREFIX@_list_t *@LISTHASH_PREFIX@_list_merge(int (*" cmpfunc ")(), int " flags ","
.BI "@LISTHASH_PREFIX@_list_t *" list1 ", @LISTHASH_PREFIX@_list_t *" list2 ");"
.SH DESCRIPTION
The \fB@LISTHASH_PREFIX@_list_new\fP() function creates a new list. The \fIflags\fP
argument must be one of the following values:
.IP \fBLIST_USERFUNC\fP
The \fIcmpfunc\fP argument points to a user-supplied function which
determines the ordering of the list.
.IP \fBLIST_STACK\fP
Use the list as a stack. New elements are added to the front of the list.
.IP \fBLIST_QUEUE\fP
Use the list as a queue. New elements are added to the end of the list.
.PP
The \fB@LISTHASH_PREFIX@_list_free\fP() function deallocates all memory associated
with the list \fIl\fP. If \fIfreefunc\fP is not \fINULL\fP, it is called
to free memory associated with each node in the list.
The \fB@LISTHASH_PREFIX@_list_add\fP() function adds the element pointed to by
\fIdata\fP to the list \fIl\fP. The position of the new element will
be determined by the flags passed to \fB@LISTHASH_PREFIX@_list_new\fP() when the
list was created.
The \fB@LISTHASH_PREFIX@_list_add_str\fP() function tokenizes the string \fIstr\fP
using the delimiter characters in the string \fIdelim\fP. The resulting
tokens are added to list \fIl\fP using \fB@LISTHASH_PREFIX@_list_add\fP().
The \fB@LISTHASH_PREFIX@_list_search\fP() function searches for an element which
matches \fIdata\fP using the matching function \fImatchfunc\fP. If
\fImatchfunc\fP is \fINULL\fP, a default matching function designed for
ASCII strings is used. Searching begins from the node pointed to by
\fIn\fP.
The \fB@LISTHASH_PREFIX@_list_del\fP() function removes the entry pointed to by
\fIn\fP from the list pointed to by \fIl\fP.
The \fB@LISTHASH_PREFIX@_list_dup\fP() function creates a copy of the list \fIl\fP
using dynamically allocated memory.
The \fB@LISTHASH_PREFIX@_list_merge\fP() function creates a new
list with \fIflags\fP and \fIcmpfunc\fP, in the same way as
\fB@LISTHASH_PREFIX@_list_new\fP(). It then adds all elements from \fIlist1\fP
and \fIlist2\fP using \fB@LISTHASH_PREFIX@_list_add\fP().
.SH RETURN VALUE
The \fB@LISTHASH_PREFIX@_list_new\fP(), \fB@LISTHASH_PREFIX@_list_dup\fP(), and
\fB@LISTHASH_PREFIX@_list_merge\fP() functions return a pointer to the new list
structure, or \fINULL\fP on error.
The \fB@LISTHASH_PREFIX@_list_next\fP(), \fB@LISTHASH_PREFIX@_list_prev\fP(), and
\fB@LISTHASH_PREFIX@_list_search\fP() functions return 1 when valid data is
returned, or 0 otherwise.
The \fB@LISTHASH_PREFIX@_list_add\fP() and \fB@LISTHASH_PREFIX@_list_add_str\fP() functions
return 0 on success, or -1 on error.
.SH SEE ALSO
.BR @LISTHASH_PREFIX@_hash_new (3)

196
listhash/listhash.h.in Normal file
View File

@ -0,0 +1,196 @@
/* @configure_input@ */
/*
** Copyright 1998-2002 University of Illinois Board of Trustees
** Copyright 1998-2002 Mark D. Roth
** All rights reserved.
**
** @LISTHASH_PREFIX@_listhash.h - header file for listhash module
**
** Mark D. Roth <roth@uiuc.edu>
** Campus Information Technologies and Educational Services
** University of Illinois at Urbana-Champaign
*/
#ifndef @LISTHASH_PREFIX@_LISTHASH_H
#define @LISTHASH_PREFIX@_LISTHASH_H
/***** list.c **********************************************************/
/*
** Comparison function (used to determine order of elements in a list)
** returns less than, equal to, or greater than 0
** if data1 is less than, equal to, or greater than data2
*/
typedef int (*@LISTHASH_PREFIX@_cmpfunc_t)(void *, void *);
/*
** Free function (for freeing allocated memory in each element)
*/
typedef void (*@LISTHASH_PREFIX@_freefunc_t)(void *);
/*
** Plugin function for @LISTHASH_PREFIX@_list_iterate()
*/
typedef int (*@LISTHASH_PREFIX@_iterate_func_t)(void *, void *);
/*
** Matching function (used to find elements in a list)
** first argument is the data to search for
** second argument is the list element it's being compared to
** returns 0 if no match is found, non-zero otherwise
*/
typedef int (*@LISTHASH_PREFIX@_matchfunc_t)(void *, void *);
struct @LISTHASH_PREFIX@_node
{
void *data;
struct @LISTHASH_PREFIX@_node *next;
struct @LISTHASH_PREFIX@_node *prev;
};
typedef struct @LISTHASH_PREFIX@_node *@LISTHASH_PREFIX@_listptr_t;
struct @LISTHASH_PREFIX@_list
{
@LISTHASH_PREFIX@_listptr_t first;
@LISTHASH_PREFIX@_listptr_t last;
@LISTHASH_PREFIX@_cmpfunc_t cmpfunc;
int flags;
unsigned int nents;
};
typedef struct @LISTHASH_PREFIX@_list @LISTHASH_PREFIX@_list_t;
/* values for flags */
#define LIST_USERFUNC 0 /* use cmpfunc() to order */
#define LIST_STACK 1 /* new elements go in front */
#define LIST_QUEUE 2 /* new elements go at the end */
/* reset a list pointer */
void @LISTHASH_PREFIX@_listptr_reset(@LISTHASH_PREFIX@_listptr_t *);
/* retrieve the data being pointed to */
void *@LISTHASH_PREFIX@_listptr_data(@LISTHASH_PREFIX@_listptr_t *);
/* creates a new, empty list */
@LISTHASH_PREFIX@_list_t *@LISTHASH_PREFIX@_list_new(int, @LISTHASH_PREFIX@_cmpfunc_t);
/* call a function for every element in a list */
int @LISTHASH_PREFIX@_list_iterate(@LISTHASH_PREFIX@_list_t *,
@LISTHASH_PREFIX@_iterate_func_t, void *);
/* empty the list */
void @LISTHASH_PREFIX@_list_empty(@LISTHASH_PREFIX@_list_t *,
@LISTHASH_PREFIX@_freefunc_t);
/* remove and free() the entire list */
void @LISTHASH_PREFIX@_list_free(@LISTHASH_PREFIX@_list_t *,
@LISTHASH_PREFIX@_freefunc_t);
/* add elements */
int @LISTHASH_PREFIX@_list_add(@LISTHASH_PREFIX@_list_t *, void *);
/* removes an element from the list - returns -1 on error */
void @LISTHASH_PREFIX@_list_del(@LISTHASH_PREFIX@_list_t *,
@LISTHASH_PREFIX@_listptr_t *);
/* returns 1 when valid data is returned, or 0 at end of list */
int @LISTHASH_PREFIX@_list_next(@LISTHASH_PREFIX@_list_t *,
@LISTHASH_PREFIX@_listptr_t *);
/* returns 1 when valid data is returned, or 0 at end of list */
int @LISTHASH_PREFIX@_list_prev(@LISTHASH_PREFIX@_list_t *,
@LISTHASH_PREFIX@_listptr_t *);
/* return 1 if the data matches a list entry, 0 otherwise */
int @LISTHASH_PREFIX@_list_search(@LISTHASH_PREFIX@_list_t *,
@LISTHASH_PREFIX@_listptr_t *, void *,
@LISTHASH_PREFIX@_matchfunc_t);
/* return number of elements from list */
unsigned int @LISTHASH_PREFIX@_list_nents(@LISTHASH_PREFIX@_list_t *);
/* adds elements from a string delimited by delim */
int @LISTHASH_PREFIX@_list_add_str(@LISTHASH_PREFIX@_list_t *, char *, char *);
/* string matching function */
int @LISTHASH_PREFIX@_str_match(char *, char *);
/***** hash.c **********************************************************/
/*
** Hashing function (determines which bucket the given key hashes into)
** first argument is the key to hash
** second argument is the total number of buckets
** returns the bucket number
*/
typedef unsigned int (*@LISTHASH_PREFIX@_hashfunc_t)(void *, unsigned int);
struct @LISTHASH_PREFIX@_hashptr
{
int bucket;
@LISTHASH_PREFIX@_listptr_t node;
};
typedef struct @LISTHASH_PREFIX@_hashptr @LISTHASH_PREFIX@_hashptr_t;
struct @LISTHASH_PREFIX@_hash
{
int numbuckets;
@LISTHASH_PREFIX@_list_t **table;
@LISTHASH_PREFIX@_hashfunc_t hashfunc;
unsigned int nents;
};
typedef struct @LISTHASH_PREFIX@_hash @LISTHASH_PREFIX@_hash_t;
/* reset a hash pointer */
void @LISTHASH_PREFIX@_hashptr_reset(@LISTHASH_PREFIX@_hashptr_t *);
/* retrieve the data being pointed to */
void *@LISTHASH_PREFIX@_hashptr_data(@LISTHASH_PREFIX@_hashptr_t *);
/* default hash function, optimized for 7-bit strings */
unsigned int @LISTHASH_PREFIX@_str_hashfunc(char *, unsigned int);
/* return number of elements from hash */
unsigned int @LISTHASH_PREFIX@_hash_nents(@LISTHASH_PREFIX@_hash_t *);
/* create a new hash */
@LISTHASH_PREFIX@_hash_t *@LISTHASH_PREFIX@_hash_new(int, @LISTHASH_PREFIX@_hashfunc_t);
/* empty the hash */
void @LISTHASH_PREFIX@_hash_empty(@LISTHASH_PREFIX@_hash_t *,
@LISTHASH_PREFIX@_freefunc_t);
/* delete all the @LISTHASH_PREFIX@_nodes of the hash and clean up */
void @LISTHASH_PREFIX@_hash_free(@LISTHASH_PREFIX@_hash_t *,
@LISTHASH_PREFIX@_freefunc_t);
/* returns 1 when valid data is returned, or 0 at end of list */
int @LISTHASH_PREFIX@_hash_next(@LISTHASH_PREFIX@_hash_t *,
@LISTHASH_PREFIX@_hashptr_t *);
/* return 1 if the data matches a list entry, 0 otherwise */
int @LISTHASH_PREFIX@_hash_search(@LISTHASH_PREFIX@_hash_t *,
@LISTHASH_PREFIX@_hashptr_t *, void *,
@LISTHASH_PREFIX@_matchfunc_t);
/* return 1 if the key matches a list entry, 0 otherwise */
int @LISTHASH_PREFIX@_hash_getkey(@LISTHASH_PREFIX@_hash_t *,
@LISTHASH_PREFIX@_hashptr_t *, void *,
@LISTHASH_PREFIX@_matchfunc_t);
/* inserting data */
int @LISTHASH_PREFIX@_hash_add(@LISTHASH_PREFIX@_hash_t *, void *);
/* delete an entry */
int @LISTHASH_PREFIX@_hash_del(@LISTHASH_PREFIX@_hash_t *,
@LISTHASH_PREFIX@_hashptr_t *);
#endif /* ! @LISTHASH_PREFIX@_LISTHASH_H */

21
listhash/module.ac Normal file
View File

@ -0,0 +1,21 @@
AC_DEFUN(subdir[_INIT], [
AC_REQUIRE([COMPAT_FUNC_STRLCPY])
AC_REQUIRE([COMPAT_FUNC_STRSEP])
if test -z "$2"; then
LISTHASH_PREFIX="${PACKAGE_NAME}";
else
LISTHASH_PREFIX="$2";
fi
AC_SUBST([LISTHASH_PREFIX])
LISTHASH_DIR="$1";
AC_SUBST([LISTHASH_DIR])
AC_CONFIG_FILES([$1/${LISTHASH_PREFIX}_listhash.h:$1/listhash.h.in])
AC_CONFIG_FILES([$1/${LISTHASH_PREFIX}_list.c:$1/list.c.in])
AC_CONFIG_FILES([$1/${LISTHASH_PREFIX}_hash.c:$1/hash.c.in])
AC_CONFIG_FILES([$1/${LISTHASH_PREFIX}_list_new.3:$1/list_new.3.in])
AC_CONFIG_FILES([$1/${LISTHASH_PREFIX}_hash_new.3:$1/hash_new.3.in])
])