From 94855cd69248f0f90b6c828588afa012adc8bd45 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 17 Sep 2008 14:11:12 +0200 Subject: Move common libraries from root to lib/. --- compression/lzxpress.c | 312 --- compression/lzxpress.h | 50 - compression/mszip.c | 676 ------ compression/mszip.h | 33 - compression/testsuite.c | 30 - lib/compression/lzxpress.c | 312 +++ lib/compression/lzxpress.h | 50 + lib/compression/mszip.c | 676 ++++++ lib/compression/mszip.h | 33 + lib/compression/testsuite.c | 30 + lib/nss_wrapper/config.m4 | 19 + lib/nss_wrapper/config.mk | 7 + lib/nss_wrapper/nss_wrapper.c | 1130 +++++++++ lib/nss_wrapper/nss_wrapper.h | 165 ++ lib/nss_wrapper/nss_wrapper.pl | 265 +++ lib/popt/CHANGES | 46 + lib/popt/COPYING | 22 + lib/popt/README | 18 + lib/popt/config.mk | 5 + lib/popt/dummy.in | 0 lib/popt/findme.c | 50 + lib/popt/findme.h | 20 + lib/popt/libpopt.m4 | 43 + lib/popt/popt.c | 1249 ++++++++++ lib/popt/popt.h | 545 +++++ lib/popt/poptconfig.c | 190 ++ lib/popt/popthelp.c | 740 ++++++ lib/popt/poptint.h | 116 + lib/popt/poptparse.c | 227 ++ lib/popt/samba.m4 | 8 + lib/popt/system.h | 76 + lib/replace/.checker_innocent | 4 + lib/replace/Makefile.in | 63 + lib/replace/README | 113 + lib/replace/aclocal.m4 | 1 + lib/replace/autoconf-2.60.m4 | 210 ++ lib/replace/autogen.sh | 13 + lib/replace/config.guess | 1464 ++++++++++++ lib/replace/config.sub | 1577 +++++++++++++ lib/replace/configure.ac | 30 + lib/replace/dlfcn.c | 75 + lib/replace/dlfcn.m4 | 31 + lib/replace/getaddrinfo.c | 497 ++++ lib/replace/getaddrinfo.h | 89 + lib/replace/getifaddrs.c | 361 +++ lib/replace/getpass.c | 222 ++ lib/replace/getpass.m4 | 24 + lib/replace/inet_aton.c | 33 + lib/replace/inet_ntoa.c | 39 + lib/replace/inet_ntop.c | 191 ++ lib/replace/inet_pton.c | 213 ++ lib/replace/install-sh | 238 ++ lib/replace/libreplace.m4 | 308 +++ lib/replace/libreplace_cc.m4 | 182 ++ lib/replace/libreplace_ld.m4 | 319 +++ lib/replace/libreplace_macros.m4 | 332 +++ lib/replace/libreplace_network.m4 | 377 +++ lib/replace/repdir.m4 | 78 + lib/replace/repdir_getdents.c | 166 ++ lib/replace/repdir_getdirentries.c | 183 ++ lib/replace/replace.c | 616 +++++ lib/replace/replace.h | 582 +++++ lib/replace/samba.m4 | 35 + lib/replace/snprintf.c | 1530 ++++++++++++ lib/replace/socket.c | 35 + lib/replace/socketpair.c | 46 + lib/replace/strptime.c | 990 ++++++++ lib/replace/strptime.m4 | 13 + lib/replace/system/README | 4 + lib/replace/system/aio.h | 32 + lib/replace/system/capability.h | 55 + lib/replace/system/config.m4 | 130 + lib/replace/system/dir.h | 67 + lib/replace/system/filesys.h | 182 ++ lib/replace/system/glob.h | 37 + lib/replace/system/iconv.h | 57 + lib/replace/system/kerberos.h | 137 ++ lib/replace/system/locale.h | 38 + lib/replace/system/network.h | 332 +++ lib/replace/system/passwd.h | 110 + lib/replace/system/readline.h | 52 + lib/replace/system/select.h | 41 + lib/replace/system/shmem.h | 59 + lib/replace/system/syslog.h | 70 + lib/replace/system/terminal.h | 46 + lib/replace/system/time.h | 69 + lib/replace/system/wait.h | 55 + lib/replace/test/getifaddrs.c | 100 + lib/replace/test/os2_delete.c | 124 + lib/replace/test/shared_mmap.c | 68 + lib/replace/test/strptime.c | 172 ++ lib/replace/test/testsuite.c | 1080 +++++++++ lib/replace/timegm.c | 78 + lib/replace/timegm.m4 | 1 + lib/replace/win32.m4 | 20 + lib/replace/win32_replace.h | 159 ++ lib/socket_wrapper/config.m4 | 22 + lib/socket_wrapper/config.mk | 8 + lib/socket_wrapper/socket_wrapper.c | 1841 +++++++++++++++ lib/socket_wrapper/socket_wrapper.h | 136 ++ lib/socket_wrapper/testsuite.c | 105 + lib/talloc/Makefile.in | 43 + lib/talloc/NEWS | 13 + lib/talloc/aclocal.m4 | 1 + lib/talloc/autogen.sh | 14 + lib/talloc/config.guess | 1464 ++++++++++++ lib/talloc/config.mk | 7 + lib/talloc/config.sub | 1577 +++++++++++++ lib/talloc/configure.ac | 24 + lib/talloc/install-sh | 238 ++ lib/talloc/libtalloc.m4 | 33 + lib/talloc/rules.mk | 18 + lib/talloc/talloc.3.xml | 738 ++++++ lib/talloc/talloc.c | 1732 ++++++++++++++ lib/talloc/talloc.h | 183 ++ lib/talloc/talloc.i | 31 + lib/talloc/talloc.mk | 37 + lib/talloc/talloc.pc.in | 11 + lib/talloc/talloc_guide.txt | 685 ++++++ lib/talloc/testsuite.c | 1152 +++++++++ lib/talloc/web/index.html | 46 + lib/tdb/Makefile.in | 59 + lib/tdb/aclocal.m4 | 1 + lib/tdb/autogen.sh | 16 + lib/tdb/common/dump.c | 137 ++ lib/tdb/common/error.c | 57 + lib/tdb/common/freelist.c | 382 +++ lib/tdb/common/freelistcheck.c | 107 + lib/tdb/common/io.c | 473 ++++ lib/tdb/common/lock.c | 553 +++++ lib/tdb/common/open.c | 488 ++++ lib/tdb/common/tdb.c | 802 +++++++ lib/tdb/common/tdb_private.h | 213 ++ lib/tdb/common/transaction.c | 1119 +++++++++ lib/tdb/common/traverse.c | 348 +++ lib/tdb/config.guess | 1464 ++++++++++++ lib/tdb/config.mk | 57 + lib/tdb/config.sub | 1577 +++++++++++++ lib/tdb/configure.ac | 30 + lib/tdb/docs/README | 238 ++ lib/tdb/docs/tdb.magic | 10 + lib/tdb/include/tdb.h | 167 ++ lib/tdb/install-sh | 238 ++ lib/tdb/libtdb.m4 | 30 + lib/tdb/python.mk | 10 + lib/tdb/python/tdbdump.py | 12 + lib/tdb/python/tests/simple.py | 152 ++ lib/tdb/rules.mk | 21 + lib/tdb/tdb.i | 323 +++ lib/tdb/tdb.mk | 86 + lib/tdb/tdb.pc.in | 11 + lib/tdb/tdb.py | 341 +++ lib/tdb/tdb_wrap.c | 4307 ++++++++++++++++++++++++++++++++++ lib/tdb/tools/tdbbackup.c | 300 +++ lib/tdb/tools/tdbdump.c | 116 + lib/tdb/tools/tdbtest.c | 265 +++ lib/tdb/tools/tdbtool.c | 659 ++++++ lib/tdb/tools/tdbtorture.c | 318 +++ lib/tdb/web/index.html | 42 + nss_wrapper/config.m4 | 19 - nss_wrapper/config.mk | 7 - nss_wrapper/nss_wrapper.c | 1130 --------- nss_wrapper/nss_wrapper.h | 165 -- nss_wrapper/nss_wrapper.pl | 265 --- popt/CHANGES | 46 - popt/COPYING | 22 - popt/README | 18 - popt/config.mk | 5 - popt/dummy.in | 0 popt/findme.c | 50 - popt/findme.h | 20 - popt/libpopt.m4 | 43 - popt/popt.c | 1249 ---------- popt/popt.h | 545 ----- popt/poptconfig.c | 190 -- popt/popthelp.c | 740 ------ popt/poptint.h | 116 - popt/poptparse.c | 227 -- popt/samba.m4 | 8 - popt/system.h | 76 - replace/.checker_innocent | 4 - replace/Makefile.in | 63 - replace/README | 113 - replace/aclocal.m4 | 1 - replace/autoconf-2.60.m4 | 210 -- replace/autogen.sh | 13 - replace/config.guess | 1464 ------------ replace/config.sub | 1577 ------------- replace/configure.ac | 30 - replace/dlfcn.c | 75 - replace/dlfcn.m4 | 31 - replace/getaddrinfo.c | 497 ---- replace/getaddrinfo.h | 89 - replace/getifaddrs.c | 361 --- replace/getpass.c | 222 -- replace/getpass.m4 | 24 - replace/inet_aton.c | 33 - replace/inet_ntoa.c | 39 - replace/inet_ntop.c | 191 -- replace/inet_pton.c | 213 -- replace/install-sh | 238 -- replace/libreplace.m4 | 303 --- replace/libreplace_cc.m4 | 182 -- replace/libreplace_ld.m4 | 319 --- replace/libreplace_macros.m4 | 332 --- replace/libreplace_network.m4 | 377 --- replace/repdir.m4 | 78 - replace/repdir_getdents.c | 166 -- replace/repdir_getdirentries.c | 183 -- replace/replace.c | 616 ----- replace/replace.h | 582 ----- replace/samba.m4 | 35 - replace/snprintf.c | 1530 ------------ replace/socket.c | 35 - replace/socketpair.c | 46 - replace/strptime.c | 990 -------- replace/strptime.m4 | 13 - replace/system/README | 4 - replace/system/aio.h | 32 - replace/system/capability.h | 55 - replace/system/config.m4 | 130 - replace/system/dir.h | 67 - replace/system/filesys.h | 182 -- replace/system/glob.h | 37 - replace/system/iconv.h | 57 - replace/system/kerberos.h | 137 -- replace/system/locale.h | 38 - replace/system/network.h | 332 --- replace/system/passwd.h | 110 - replace/system/readline.h | 52 - replace/system/select.h | 41 - replace/system/shmem.h | 59 - replace/system/syslog.h | 70 - replace/system/terminal.h | 46 - replace/system/time.h | 69 - replace/system/wait.h | 55 - replace/test/getifaddrs.c | 100 - replace/test/os2_delete.c | 124 - replace/test/shared_mmap.c | 68 - replace/test/strptime.c | 172 -- replace/test/testsuite.c | 1080 --------- replace/timegm.c | 78 - replace/timegm.m4 | 1 - replace/win32.m4 | 20 - replace/win32_replace.h | 159 -- socket_wrapper/config.m4 | 22 - socket_wrapper/config.mk | 8 - socket_wrapper/socket_wrapper.c | 1841 --------------- socket_wrapper/socket_wrapper.h | 136 -- socket_wrapper/testsuite.c | 105 - source3/Makefile.in | 2 +- source3/autogen.sh | 2 +- source3/configure.in | 14 +- source3/m4/aclocal.m4 | 2 +- source3/samba4.m4 | 8 +- source4/Makefile | 12 +- source4/aclocal.m4 | 2 +- source4/autogen.sh | 2 +- source4/configure.ac | 20 +- source4/librpc/ndr/ndr_compression.c | 2 +- source4/main.mk | 4 +- source4/torture/local/config.mk | 14 +- talloc/Makefile.in | 43 - talloc/NEWS | 13 - talloc/aclocal.m4 | 1 - talloc/autogen.sh | 14 - talloc/config.guess | 1464 ------------ talloc/config.mk | 7 - talloc/config.sub | 1577 ------------- talloc/configure.ac | 24 - talloc/install-sh | 238 -- talloc/libtalloc.m4 | 33 - talloc/rules.mk | 18 - talloc/talloc.3.xml | 738 ------ talloc/talloc.c | 1732 -------------- talloc/talloc.h | 183 -- talloc/talloc.i | 31 - talloc/talloc.mk | 37 - talloc/talloc.pc.in | 11 - talloc/talloc_guide.txt | 685 ------ talloc/testsuite.c | 1152 --------- talloc/web/index.html | 46 - tdb/Makefile.in | 59 - tdb/aclocal.m4 | 1 - tdb/autogen.sh | 16 - tdb/common/dump.c | 137 -- tdb/common/error.c | 57 - tdb/common/freelist.c | 382 --- tdb/common/freelistcheck.c | 107 - tdb/common/io.c | 473 ---- tdb/common/lock.c | 553 ----- tdb/common/open.c | 488 ---- tdb/common/tdb.c | 802 ------- tdb/common/tdb_private.h | 213 -- tdb/common/transaction.c | 1119 --------- tdb/common/traverse.c | 348 --- tdb/config.guess | 1464 ------------ tdb/config.mk | 57 - tdb/config.sub | 1577 ------------- tdb/configure.ac | 30 - tdb/docs/README | 238 -- tdb/docs/tdb.magic | 10 - tdb/include/tdb.h | 167 -- tdb/install-sh | 238 -- tdb/libtdb.m4 | 30 - tdb/python.mk | 10 - tdb/python/tdbdump.py | 12 - tdb/python/tests/simple.py | 152 -- tdb/rules.mk | 21 - tdb/tdb.i | 323 --- tdb/tdb.mk | 86 - tdb/tdb.pc.in | 11 - tdb/tdb.py | 341 --- tdb/tdb_wrap.c | 4307 ---------------------------------- tdb/tools/tdbbackup.c | 300 --- tdb/tools/tdbdump.c | 116 - tdb/tools/tdbtest.c | 265 --- tdb/tools/tdbtool.c | 659 ------ tdb/tools/tdbtorture.c | 318 --- tdb/web/index.html | 42 - 320 files changed, 46427 insertions(+), 46422 deletions(-) delete mode 100644 compression/lzxpress.c delete mode 100644 compression/lzxpress.h delete mode 100644 compression/mszip.c delete mode 100644 compression/mszip.h delete mode 100644 compression/testsuite.c create mode 100644 lib/compression/lzxpress.c create mode 100644 lib/compression/lzxpress.h create mode 100644 lib/compression/mszip.c create mode 100644 lib/compression/mszip.h create mode 100644 lib/compression/testsuite.c create mode 100644 lib/nss_wrapper/config.m4 create mode 100644 lib/nss_wrapper/config.mk create mode 100644 lib/nss_wrapper/nss_wrapper.c create mode 100644 lib/nss_wrapper/nss_wrapper.h create mode 100644 lib/nss_wrapper/nss_wrapper.pl create mode 100644 lib/popt/CHANGES create mode 100644 lib/popt/COPYING create mode 100644 lib/popt/README create mode 100644 lib/popt/config.mk create mode 100644 lib/popt/dummy.in create mode 100644 lib/popt/findme.c create mode 100644 lib/popt/findme.h create mode 100644 lib/popt/libpopt.m4 create mode 100644 lib/popt/popt.c create mode 100644 lib/popt/popt.h create mode 100644 lib/popt/poptconfig.c create mode 100644 lib/popt/popthelp.c create mode 100644 lib/popt/poptint.h create mode 100644 lib/popt/poptparse.c create mode 100644 lib/popt/samba.m4 create mode 100644 lib/popt/system.h create mode 100644 lib/replace/.checker_innocent create mode 100644 lib/replace/Makefile.in create mode 100644 lib/replace/README create mode 100644 lib/replace/aclocal.m4 create mode 100644 lib/replace/autoconf-2.60.m4 create mode 100755 lib/replace/autogen.sh create mode 100755 lib/replace/config.guess create mode 100755 lib/replace/config.sub create mode 100644 lib/replace/configure.ac create mode 100644 lib/replace/dlfcn.c create mode 100644 lib/replace/dlfcn.m4 create mode 100644 lib/replace/getaddrinfo.c create mode 100644 lib/replace/getaddrinfo.h create mode 100644 lib/replace/getifaddrs.c create mode 100644 lib/replace/getpass.c create mode 100644 lib/replace/getpass.m4 create mode 100644 lib/replace/inet_aton.c create mode 100644 lib/replace/inet_ntoa.c create mode 100644 lib/replace/inet_ntop.c create mode 100644 lib/replace/inet_pton.c create mode 100755 lib/replace/install-sh create mode 100644 lib/replace/libreplace.m4 create mode 100644 lib/replace/libreplace_cc.m4 create mode 100644 lib/replace/libreplace_ld.m4 create mode 100644 lib/replace/libreplace_macros.m4 create mode 100644 lib/replace/libreplace_network.m4 create mode 100644 lib/replace/repdir.m4 create mode 100644 lib/replace/repdir_getdents.c create mode 100644 lib/replace/repdir_getdirentries.c create mode 100644 lib/replace/replace.c create mode 100644 lib/replace/replace.h create mode 100644 lib/replace/samba.m4 create mode 100644 lib/replace/snprintf.c create mode 100644 lib/replace/socket.c create mode 100644 lib/replace/socketpair.c create mode 100644 lib/replace/strptime.c create mode 100644 lib/replace/strptime.m4 create mode 100644 lib/replace/system/README create mode 100644 lib/replace/system/aio.h create mode 100644 lib/replace/system/capability.h create mode 100644 lib/replace/system/config.m4 create mode 100644 lib/replace/system/dir.h create mode 100644 lib/replace/system/filesys.h create mode 100644 lib/replace/system/glob.h create mode 100644 lib/replace/system/iconv.h create mode 100644 lib/replace/system/kerberos.h create mode 100644 lib/replace/system/locale.h create mode 100644 lib/replace/system/network.h create mode 100644 lib/replace/system/passwd.h create mode 100644 lib/replace/system/readline.h create mode 100644 lib/replace/system/select.h create mode 100644 lib/replace/system/shmem.h create mode 100644 lib/replace/system/syslog.h create mode 100644 lib/replace/system/terminal.h create mode 100644 lib/replace/system/time.h create mode 100644 lib/replace/system/wait.h create mode 100644 lib/replace/test/getifaddrs.c create mode 100644 lib/replace/test/os2_delete.c create mode 100644 lib/replace/test/shared_mmap.c create mode 100644 lib/replace/test/strptime.c create mode 100644 lib/replace/test/testsuite.c create mode 100644 lib/replace/timegm.c create mode 100644 lib/replace/timegm.m4 create mode 100644 lib/replace/win32.m4 create mode 100644 lib/replace/win32_replace.h create mode 100644 lib/socket_wrapper/config.m4 create mode 100644 lib/socket_wrapper/config.mk create mode 100644 lib/socket_wrapper/socket_wrapper.c create mode 100644 lib/socket_wrapper/socket_wrapper.h create mode 100644 lib/socket_wrapper/testsuite.c create mode 100644 lib/talloc/Makefile.in create mode 100644 lib/talloc/NEWS create mode 100644 lib/talloc/aclocal.m4 create mode 100755 lib/talloc/autogen.sh create mode 100755 lib/talloc/config.guess create mode 100644 lib/talloc/config.mk create mode 100755 lib/talloc/config.sub create mode 100644 lib/talloc/configure.ac create mode 100755 lib/talloc/install-sh create mode 100644 lib/talloc/libtalloc.m4 create mode 100644 lib/talloc/rules.mk create mode 100644 lib/talloc/talloc.3.xml create mode 100644 lib/talloc/talloc.c create mode 100644 lib/talloc/talloc.h create mode 100644 lib/talloc/talloc.i create mode 100644 lib/talloc/talloc.mk create mode 100644 lib/talloc/talloc.pc.in create mode 100644 lib/talloc/talloc_guide.txt create mode 100644 lib/talloc/testsuite.c create mode 100644 lib/talloc/web/index.html create mode 100644 lib/tdb/Makefile.in create mode 100644 lib/tdb/aclocal.m4 create mode 100755 lib/tdb/autogen.sh create mode 100644 lib/tdb/common/dump.c create mode 100644 lib/tdb/common/error.c create mode 100644 lib/tdb/common/freelist.c create mode 100644 lib/tdb/common/freelistcheck.c create mode 100644 lib/tdb/common/io.c create mode 100644 lib/tdb/common/lock.c create mode 100644 lib/tdb/common/open.c create mode 100644 lib/tdb/common/tdb.c create mode 100644 lib/tdb/common/tdb_private.h create mode 100644 lib/tdb/common/transaction.c create mode 100644 lib/tdb/common/traverse.c create mode 100755 lib/tdb/config.guess create mode 100644 lib/tdb/config.mk create mode 100755 lib/tdb/config.sub create mode 100644 lib/tdb/configure.ac create mode 100644 lib/tdb/docs/README create mode 100644 lib/tdb/docs/tdb.magic create mode 100644 lib/tdb/include/tdb.h create mode 100755 lib/tdb/install-sh create mode 100644 lib/tdb/libtdb.m4 create mode 100644 lib/tdb/python.mk create mode 100644 lib/tdb/python/tdbdump.py create mode 100644 lib/tdb/python/tests/simple.py create mode 100644 lib/tdb/rules.mk create mode 100644 lib/tdb/tdb.i create mode 100644 lib/tdb/tdb.mk create mode 100644 lib/tdb/tdb.pc.in create mode 100644 lib/tdb/tdb.py create mode 100644 lib/tdb/tdb_wrap.c create mode 100644 lib/tdb/tools/tdbbackup.c create mode 100644 lib/tdb/tools/tdbdump.c create mode 100644 lib/tdb/tools/tdbtest.c create mode 100644 lib/tdb/tools/tdbtool.c create mode 100644 lib/tdb/tools/tdbtorture.c create mode 100644 lib/tdb/web/index.html delete mode 100644 nss_wrapper/config.m4 delete mode 100644 nss_wrapper/config.mk delete mode 100644 nss_wrapper/nss_wrapper.c delete mode 100644 nss_wrapper/nss_wrapper.h delete mode 100644 nss_wrapper/nss_wrapper.pl delete mode 100644 popt/CHANGES delete mode 100644 popt/COPYING delete mode 100644 popt/README delete mode 100644 popt/config.mk delete mode 100644 popt/dummy.in delete mode 100644 popt/findme.c delete mode 100644 popt/findme.h delete mode 100644 popt/libpopt.m4 delete mode 100644 popt/popt.c delete mode 100644 popt/popt.h delete mode 100644 popt/poptconfig.c delete mode 100644 popt/popthelp.c delete mode 100644 popt/poptint.h delete mode 100644 popt/poptparse.c delete mode 100644 popt/samba.m4 delete mode 100644 popt/system.h delete mode 100644 replace/.checker_innocent delete mode 100644 replace/Makefile.in delete mode 100644 replace/README delete mode 100644 replace/aclocal.m4 delete mode 100644 replace/autoconf-2.60.m4 delete mode 100755 replace/autogen.sh delete mode 100755 replace/config.guess delete mode 100755 replace/config.sub delete mode 100644 replace/configure.ac delete mode 100644 replace/dlfcn.c delete mode 100644 replace/dlfcn.m4 delete mode 100644 replace/getaddrinfo.c delete mode 100644 replace/getaddrinfo.h delete mode 100644 replace/getifaddrs.c delete mode 100644 replace/getpass.c delete mode 100644 replace/getpass.m4 delete mode 100644 replace/inet_aton.c delete mode 100644 replace/inet_ntoa.c delete mode 100644 replace/inet_ntop.c delete mode 100644 replace/inet_pton.c delete mode 100755 replace/install-sh delete mode 100644 replace/libreplace.m4 delete mode 100644 replace/libreplace_cc.m4 delete mode 100644 replace/libreplace_ld.m4 delete mode 100644 replace/libreplace_macros.m4 delete mode 100644 replace/libreplace_network.m4 delete mode 100644 replace/repdir.m4 delete mode 100644 replace/repdir_getdents.c delete mode 100644 replace/repdir_getdirentries.c delete mode 100644 replace/replace.c delete mode 100644 replace/replace.h delete mode 100644 replace/samba.m4 delete mode 100644 replace/snprintf.c delete mode 100644 replace/socket.c delete mode 100644 replace/socketpair.c delete mode 100644 replace/strptime.c delete mode 100644 replace/strptime.m4 delete mode 100644 replace/system/README delete mode 100644 replace/system/aio.h delete mode 100644 replace/system/capability.h delete mode 100644 replace/system/config.m4 delete mode 100644 replace/system/dir.h delete mode 100644 replace/system/filesys.h delete mode 100644 replace/system/glob.h delete mode 100644 replace/system/iconv.h delete mode 100644 replace/system/kerberos.h delete mode 100644 replace/system/locale.h delete mode 100644 replace/system/network.h delete mode 100644 replace/system/passwd.h delete mode 100644 replace/system/readline.h delete mode 100644 replace/system/select.h delete mode 100644 replace/system/shmem.h delete mode 100644 replace/system/syslog.h delete mode 100644 replace/system/terminal.h delete mode 100644 replace/system/time.h delete mode 100644 replace/system/wait.h delete mode 100644 replace/test/getifaddrs.c delete mode 100644 replace/test/os2_delete.c delete mode 100644 replace/test/shared_mmap.c delete mode 100644 replace/test/strptime.c delete mode 100644 replace/test/testsuite.c delete mode 100644 replace/timegm.c delete mode 100644 replace/timegm.m4 delete mode 100644 replace/win32.m4 delete mode 100644 replace/win32_replace.h delete mode 100644 socket_wrapper/config.m4 delete mode 100644 socket_wrapper/config.mk delete mode 100644 socket_wrapper/socket_wrapper.c delete mode 100644 socket_wrapper/socket_wrapper.h delete mode 100644 socket_wrapper/testsuite.c delete mode 100644 talloc/Makefile.in delete mode 100644 talloc/NEWS delete mode 100644 talloc/aclocal.m4 delete mode 100755 talloc/autogen.sh delete mode 100755 talloc/config.guess delete mode 100644 talloc/config.mk delete mode 100755 talloc/config.sub delete mode 100644 talloc/configure.ac delete mode 100755 talloc/install-sh delete mode 100644 talloc/libtalloc.m4 delete mode 100644 talloc/rules.mk delete mode 100644 talloc/talloc.3.xml delete mode 100644 talloc/talloc.c delete mode 100644 talloc/talloc.h delete mode 100644 talloc/talloc.i delete mode 100644 talloc/talloc.mk delete mode 100644 talloc/talloc.pc.in delete mode 100644 talloc/talloc_guide.txt delete mode 100644 talloc/testsuite.c delete mode 100644 talloc/web/index.html delete mode 100644 tdb/Makefile.in delete mode 100644 tdb/aclocal.m4 delete mode 100755 tdb/autogen.sh delete mode 100644 tdb/common/dump.c delete mode 100644 tdb/common/error.c delete mode 100644 tdb/common/freelist.c delete mode 100644 tdb/common/freelistcheck.c delete mode 100644 tdb/common/io.c delete mode 100644 tdb/common/lock.c delete mode 100644 tdb/common/open.c delete mode 100644 tdb/common/tdb.c delete mode 100644 tdb/common/tdb_private.h delete mode 100644 tdb/common/transaction.c delete mode 100644 tdb/common/traverse.c delete mode 100755 tdb/config.guess delete mode 100644 tdb/config.mk delete mode 100755 tdb/config.sub delete mode 100644 tdb/configure.ac delete mode 100644 tdb/docs/README delete mode 100644 tdb/docs/tdb.magic delete mode 100644 tdb/include/tdb.h delete mode 100755 tdb/install-sh delete mode 100644 tdb/libtdb.m4 delete mode 100644 tdb/python.mk delete mode 100644 tdb/python/tdbdump.py delete mode 100644 tdb/python/tests/simple.py delete mode 100644 tdb/rules.mk delete mode 100644 tdb/tdb.i delete mode 100644 tdb/tdb.mk delete mode 100644 tdb/tdb.pc.in delete mode 100644 tdb/tdb.py delete mode 100644 tdb/tdb_wrap.c delete mode 100644 tdb/tools/tdbbackup.c delete mode 100644 tdb/tools/tdbdump.c delete mode 100644 tdb/tools/tdbtest.c delete mode 100644 tdb/tools/tdbtool.c delete mode 100644 tdb/tools/tdbtorture.c delete mode 100644 tdb/web/index.html diff --git a/compression/lzxpress.c b/compression/lzxpress.c deleted file mode 100644 index 0abbfc4d3d..0000000000 --- a/compression/lzxpress.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright (C) Matthieu Suiche 2008 - * - * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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 "replace.h" -#include "lzxpress.h" - - -#define __BUF_POS_CONST(buf,ofs)(((const uint8_t *)buf)+(ofs)) -#define __PULL_BYTE(buf,ofs) \ - ((uint8_t)((*__BUF_POS_CONST(buf,ofs)) & 0xFF)) - -#ifndef PULL_LE_UINT16 -#define PULL_LE_UINT16(buf,ofs) ((uint16_t)( \ - ((uint16_t)(((uint16_t)(__PULL_BYTE(buf,(ofs)+0))) << 0)) | \ - ((uint16_t)(((uint16_t)(__PULL_BYTE(buf,(ofs)+1))) << 8)) \ -)) -#endif - -#ifndef PULL_LE_UINT32 -#define PULL_LE_UINT32(buf,ofs) ((uint32_t)( \ - ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+0))) << 0)) | \ - ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+1))) << 8)) | \ - ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+2))) << 16)) | \ - ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+3))) << 24)) \ -)) -#endif - -ssize_t lzxpress_compress(const uint8_t *uncompressed, - uint32_t uncompressed_size, - uint8_t *compressed, - uint32_t max_compressed_size) -{ - uint32_t uncompressed_pos, compressed_pos, byte_left; - uint32_t max_offset, best_offset; - int32_t offset; - uint32_t max_len, len, best_len; - const uint8_t *str1, *str2; - uint32_t indic; - uint8_t *indic_pos; - uint32_t indic_bit, nibble_index; - - uint32_t metadata_size; - uint16_t metadata; - uint16_t *dest; - - if (!uncompressed_size) { - return 0; - } - - uncompressed_pos = 0; - indic = 0; - compressed_pos = sizeof(uint32_t); - indic_pos = &compressed[0]; - - byte_left = uncompressed_size; - indic_bit = 0; - nibble_index = 0; - - if (uncompressed_pos > XPRESS_BLOCK_SIZE) - return 0; - - do { - bool found = false; - - max_offset = uncompressed_pos; - - str1 = &uncompressed[uncompressed_pos]; - - best_len = 2; - best_offset = 0; - - max_offset = MIN(0x1FFF, max_offset); - - /* search for the longest match in the window for the lookahead buffer */ - for (offset = 1; (uint32_t)offset <= max_offset; offset++) { - str2 = &str1[-offset]; - - /* maximum len we can encode into metadata */ - max_len = MIN((255 + 15 + 7 + 3), byte_left); - - for (len = 0; (len < max_len) && (str1[len] == str2[len]); len++); - - /* - * We check if len is better than the value found before, including the - * sequence of identical bytes - */ - if (len > best_len) { - found = true; - best_len = len; - best_offset = offset; - } - } - - if (found) { - metadata_size = 0; - dest = (uint16_t *)&compressed[compressed_pos]; - - if (best_len < 10) { - /* Classical meta-data */ - metadata = (uint16_t)(((best_offset - 1) << 3) | (best_len - 3)); - dest[metadata_size / sizeof(uint16_t)] = metadata; - metadata_size += sizeof(uint16_t); - } else { - metadata = (uint16_t)(((best_offset - 1) << 3) | 7); - dest[metadata_size / sizeof(uint16_t)] = metadata; - metadata_size = sizeof(uint16_t); - - if (best_len < (15 + 7 + 3)) { - /* Shared byte */ - if (!nibble_index) { - compressed[compressed_pos + metadata_size] = (best_len - (3 + 7)) & 0xF; - metadata_size += sizeof(uint8_t); - } else { - compressed[nibble_index] &= 0xF; - compressed[nibble_index] |= (best_len - (3 + 7)) * 16; - } - } else if (best_len < (3 + 7 + 15 + 255)) { - /* Shared byte */ - if (!nibble_index) { - compressed[compressed_pos + metadata_size] = 15; - metadata_size += sizeof(uint8_t); - } else { - compressed[nibble_index] &= 0xF; - compressed[nibble_index] |= (15 * 16); - } - - /* Additionnal best_len */ - compressed[compressed_pos + metadata_size] = (best_len - (3 + 7 + 15)) & 0xFF; - metadata_size += sizeof(uint8_t); - } else { - /* Shared byte */ - if (!nibble_index) { - compressed[compressed_pos + metadata_size] |= 15; - metadata_size += sizeof(uint8_t); - } else { - compressed[nibble_index] |= 15 << 4; - } - - /* Additionnal best_len */ - compressed[compressed_pos + metadata_size] = 255; - - metadata_size += sizeof(uint8_t); - - compressed[compressed_pos + metadata_size] = (best_len - 3) & 0xFF; - compressed[compressed_pos + metadata_size + 1] = ((best_len - 3) >> 8) & 0xFF; - metadata_size += sizeof(uint16_t); - } - } - - indic |= 1 << (32 - ((indic_bit % 32) + 1)); - - if (best_len > 9) { - if (nibble_index == 0) { - nibble_index = compressed_pos + sizeof(uint16_t); - } else { - nibble_index = 0; - } - } - - compressed_pos += metadata_size; - uncompressed_pos += best_len; - byte_left -= best_len; - } else { - compressed[compressed_pos++] = uncompressed[uncompressed_pos++]; - byte_left--; - } - indic_bit++; - - if ((indic_bit - 1) % 32 > (indic_bit % 32)) { - *(uint32_t *)indic_pos = indic; - indic = 0; - indic_pos = &compressed[compressed_pos]; - compressed_pos += sizeof(uint32_t); - } - } while (byte_left > 3); - - do { - compressed[compressed_pos] = uncompressed[uncompressed_pos]; - indic_bit++; - - uncompressed_pos++; - compressed_pos++; - if (((indic_bit - 1) % 32) > (indic_bit % 32)){ - *(uint32_t *)indic_pos = indic; - indic = 0; - indic_pos = &compressed[compressed_pos]; - compressed_pos += sizeof(uint32_t); - } - } while (uncompressed_pos < uncompressed_size); - - if ((indic_bit % 32) > 0) { - for (; (indic_bit % 32) != 0; indic_bit++) - indic |= 0 << (32 - ((indic_bit % 32) + 1)); - - *(uint32_t *)indic_pos = indic; - compressed_pos += sizeof(uint32_t); - } - - return compressed_pos; -} - -ssize_t lzxpress_decompress(const uint8_t *input, - uint32_t input_size, - uint8_t *output, - uint32_t max_output_size) -{ - uint32_t output_index, input_index; - uint32_t indicator, indicator_bit; - uint32_t length; - uint32_t offset; - uint32_t nibble_index; - - output_index = 0; - input_index = 0; - indicator = 0; - indicator_bit = 0; - length = 0; - offset = 0; - nibble_index = 0; - - do { - if (indicator_bit == 0) { - indicator = PULL_LE_UINT32(input, input_index); - input_index += sizeof(uint32_t); - indicator_bit = 32; - } - indicator_bit--; - - /* - * check whether the bit specified by indicator_bit is set or not - * set in indicator. For example, if indicator_bit has value 4 - * check whether the 4th bit of the value in indicator is set - */ - if (((indicator >> indicator_bit) & 1) == 0) { - output[output_index] = input[input_index]; - input_index += sizeof(uint8_t); - output_index += sizeof(uint8_t); - } else { - length = PULL_LE_UINT16(input, input_index); - input_index += sizeof(uint16_t); - offset = length / 8; - length = length % 8; - - if (length == 7) { - if (nibble_index == 0) { - nibble_index = input_index; - length = input[input_index] % 16; - input_index += sizeof(uint8_t); - } else { - length = input[nibble_index] / 16; - nibble_index = 0; - } - - if (length == 15) { - length = input[input_index]; - input_index += sizeof(uint8_t); - if (length == 255) { - length = PULL_LE_UINT16(input, input_index); - input_index += sizeof(uint16_t); - length -= (15 + 7); - } - length += 15; - } - length += 7; - } - - length += 3; - - do { - if ((output_index >= max_output_size) || ((offset + 1) > output_index)) break; - - output[output_index] = output[output_index - offset - 1]; - - output_index += sizeof(uint8_t); - length -= sizeof(uint8_t); - } while (length != 0); - } - } while ((output_index < max_output_size) && (input_index < (input_size))); - - return output_index; -} diff --git a/compression/lzxpress.h b/compression/lzxpress.h deleted file mode 100644 index df0ee59a0e..0000000000 --- a/compression/lzxpress.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) Matthieu Suiche 2008 - * - * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. - * - */ - -#ifndef _LZXPRESS_H -#define _LZXPRESS_H - -#define XPRESS_BLOCK_SIZE 0x10000 - -ssize_t lzxpress_compress(const uint8_t *uncompressed, - uint32_t uncompressed_size, - uint8_t *compressed, - uint32_t max_compressed_size); - -ssize_t lzxpress_decompress(const uint8_t *input, - uint32_t input_size, - uint8_t *output, - uint32_t max_output_size); - -#endif /* _LZXPRESS_H */ diff --git a/compression/mszip.c b/compression/mszip.c deleted file mode 100644 index 9aa1772414..0000000000 --- a/compression/mszip.c +++ /dev/null @@ -1,676 +0,0 @@ -/* mszip decompression - based on cabextract.c code from - * Stuart Caie - * - * adapted for Samba by Andrew Tridgell and Stefan Metzmacher 2005 - * - * (C) 2000-2001 Stuart Caie - * reaktivate-specifics by Malte Starostik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" -#include "../compression/mszip.h" - -/*--------------------------------------------------------------------------*/ -/* our archiver information / state */ - -/* MSZIP stuff */ -#define ZIPWSIZE 0x8000 /* window size */ -#define ZIPLBITS 9 /* bits in base literal/length lookup table */ -#define ZIPDBITS 6 /* bits in base distance lookup table */ -#define ZIPBMAX 16 /* maximum bit length of any code */ -#define ZIPN_MAX 288 /* maximum number of codes in any set */ - -struct Ziphuft { - uint8_t e; /* number of extra bits or operation */ - uint8_t b; /* number of bits in this code or subcode */ - union { - uint16_t n; /* literal, length base, or distance base */ - struct Ziphuft *t; /* pointer to next level of table */ - } v; -}; - -struct ZIPstate { - uint32_t window_posn; /* current offset within the window */ - uint32_t bb; /* bit buffer */ - uint32_t bk; /* bits in bit buffer */ - uint32_t ll[288+32]; /* literal/length and distance code lengths */ - uint32_t c[ZIPBMAX+1]; /* bit length count table */ - int32_t lx[ZIPBMAX+1]; /* memory for l[-1..ZIPBMAX-1] */ - struct Ziphuft *u[ZIPBMAX]; /* table stack */ - uint32_t v[ZIPN_MAX]; /* values in order of bit length */ - uint32_t x[ZIPBMAX+1]; /* bit offsets, then code stack */ - uint8_t *inpos; -}; - -/* generic stuff */ -#define CAB(x) (decomp_state->x) -#define ZIP(x) (decomp_state->methods.zip.x) - -/* CAB data blocks are <= 32768 bytes in uncompressed form. Uncompressed - * blocks have zero growth. MSZIP guarantees that it won't grow above - * uncompressed size by more than 12 bytes. LZX guarantees it won't grow - * more than 6144 bytes. - */ -#define CAB_BLOCKMAX (32768) -#define CAB_INPUTMAX (CAB_BLOCKMAX+6144) - -struct decomp_state { - struct folder *current; /* current folder we're extracting from */ - uint32_t offset; /* uncompressed offset within folder */ - uint8_t *outpos; /* (high level) start of data to use up */ - uint16_t outlen; /* (high level) amount of data to use up */ - uint16_t split; /* at which split in current folder? */ - int (*decompress)(int, int); /* the chosen compression func */ - uint8_t inbuf[CAB_INPUTMAX+2]; /* +2 for lzx bitbuffer overflows! */ - uint8_t outbuf[CAB_BLOCKMAX]; - union { - struct ZIPstate zip; - } methods; -}; - - -/* MSZIP decruncher */ - -/* Dirk Stoecker wrote the ZIP decoder, based on the InfoZip deflate code */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -static const uint8_t Zipborder[] = /* Order of the bit length code lengths */ -{ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; -static const uint16_t Zipcplens[] = /* Copy lengths for literal codes 257..285 */ -{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, - 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; -static const uint16_t Zipcplext[] = /* Extra bits for literal codes 257..285 */ -{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, - 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ -static const uint16_t Zipcpdist[] = /* Copy offsets for distance codes 0..29 */ -{ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, -513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; -static const uint16_t Zipcpdext[] = /* Extra bits for distance codes */ -{ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, -10, 11, 11, 12, 12, 13, 13}; - -/* And'ing with Zipmask[n] masks the lower n bits */ -static const uint16_t Zipmask[17] = { - 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -#define ZIPNEEDBITS(n) {while(k<(n)){int32_t c=*(ZIP(inpos)++);\ - b|=((uint32_t)c)<>=(n);k-=(n);} - -static void Ziphuft_free(struct Ziphuft *t) -{ - register struct Ziphuft *p, *q; - - /* Go through linked list, freeing from the allocated (t[-1]) address. */ - p = t; - while (p != (struct Ziphuft *)NULL) - { - q = (--p)->v.t; - free(p); - p = q; - } -} - -static int32_t Ziphuft_build(struct decomp_state *decomp_state, - uint32_t *b, uint32_t n, uint32_t s, const uint16_t *d, const uint16_t *e, - struct Ziphuft **t, int32_t *m) -{ - uint32_t a; /* counter for codes of length k */ - uint32_t el; /* length of EOB code (value 256) */ - uint32_t f; /* i repeats in table every f entries */ - int32_t g; /* maximum code length */ - int32_t h; /* table level */ - register uint32_t i; /* counter, current code */ - register uint32_t j; /* counter */ - register int32_t k; /* number of bits in current code */ - int32_t *l; /* stack of bits per table */ - register uint32_t *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */ - register struct Ziphuft *q; /* points to current table */ - struct Ziphuft r; /* table entry for structure assignment */ - register int32_t w; /* bits before this table == (l * h) */ - uint32_t *xp; /* pointer into x */ - int32_t y; /* number of dummy codes added */ - uint32_t z; /* number of entries in current table */ - - l = ZIP(lx)+1; - - /* Generate counts for each bit length */ - el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */ - - for(i = 0; i < ZIPBMAX+1; ++i) - ZIP(c)[i] = 0; - p = b; i = n; - do - { - ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */ - } while (--i); - if (ZIP(c)[0] == n) /* null input--all zero length codes */ - { - *t = (struct Ziphuft *)NULL; - *m = 0; - return 0; - } - - /* Find minimum and maximum length, bound *m by those */ - for (j = 1; j <= ZIPBMAX; j++) - if (ZIP(c)[j]) - break; - k = j; /* minimum code length */ - if ((uint32_t)*m < j) - *m = j; - for (i = ZIPBMAX; i; i--) - if (ZIP(c)[i]) - break; - g = i; /* maximum code length */ - if ((uint32_t)*m > i) - *m = i; - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= ZIP(c)[j]) < 0) - return 2; /* bad input: more codes than bits */ - if ((y -= ZIP(c)[i]) < 0) - return 2; - ZIP(c)[i] += y; - - /* Generate starting offsets int32_to the value table for each length */ - ZIP(x)[1] = j = 0; - p = ZIP(c) + 1; xp = ZIP(x) + 2; - while (--i) - { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do{ - if ((j = *p++) != 0) - ZIP(v)[ZIP(x)[j]++] = i; - } while (++i < n); - - - /* Generate the Huffman codes and for each, make the table entries */ - ZIP(x)[0] = i = 0; /* first Huffman code is zero */ - p = ZIP(v); /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = l[-1] = 0; /* no bits decoded yet */ - ZIP(u)[0] = (struct Ziphuft *)NULL; /* just to keep compilers happy */ - q = (struct Ziphuft *)NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = ZIP(c)[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l[h]) - { - w += l[h++]; /* add bits already decoded */ - - /* compute minimum size table less than or equal to *m bits */ - z = (z = g - w) > (uint32_t)*m ? *m : z; /* upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = ZIP(c) + k; - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - if ((uint32_t)w + j > el && (uint32_t)w < el) - j = el - w; /* make EOB code end at table */ - z = 1 << j; /* table entries for j-bit table */ - l[h] = j; /* set table size in stack */ - - /* allocate and link in new table */ - if (!(q = (struct Ziphuft *)SMB_MALLOC((z + 1)*sizeof(struct Ziphuft)))) - { - if(h) - Ziphuft_free(ZIP(u)[0]); - return 3; /* not enough memory */ - } - *t = q + 1; /* link to list for Ziphuft_free() */ - *(t = &(q->v.t)) = (struct Ziphuft *)NULL; - ZIP(u)[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - ZIP(x)[h] = i; /* save pattern for backing up */ - r.b = (uint8_t)l[h-1]; /* bits to dump before this table */ - r.e = (uint8_t)(16 + j); /* bits in this table */ - r.v.t = q; /* pointer to this table */ - j = (i & ((1 << w) - 1)) >> (w - l[h-1]); - ZIP(u)[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.b = (uint8_t)(k - w); - if (p >= ZIP(v) + n) - r.e = 99; /* out of values--invalid code */ - else if (*p < s) - { - r.e = (uint8_t)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ - r.v.n = *p++; /* simple code is just the value */ - } - else - { - r.e = (uint8_t)e[*p - s]; /* non-simple--look up in lists */ - r.v.n = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != ZIP(x)[h]) - w -= l[--h]; /* don't need to update q */ - } - } - - /* return actual size of base table */ - *m = l[0]; - - /* Return true (1) if we were given an incomplete table */ - return y != 0 && g != 1; -} - -static int32_t Zipinflate_codes(struct decomp_state *decomp_state, - struct Ziphuft *tl, struct Ziphuft *td, - int32_t bl, int32_t bd) -{ - register uint32_t e; /* table entry flag/number of extra bits */ - uint32_t n, d; /* length and index for copy */ - uint32_t w; /* current window position */ - struct Ziphuft *t; /* pointer to table entry */ - uint32_t ml, md; /* masks for bl and bd bits */ - register uint32_t b; /* bit buffer */ - register uint32_t k; /* number of bits in bit buffer */ - - DEBUG(10,("Zipinflate_codes\n")); - - /* make local copies of globals */ - b = ZIP(bb); /* initialize bit buffer */ - k = ZIP(bk); - w = ZIP(window_posn); /* initialize window position */ - - /* inflate the coded data */ - ml = Zipmask[bl]; /* precompute masks for speed */ - md = Zipmask[bd]; - - for(;;) - { - ZIPNEEDBITS((uint32_t)bl) - if((e = (t = tl + ((uint32_t)b & ml))->e) > 16) - do - { - if (e == 99) - return 1; - ZIPDUMPBITS(t->b) - e -= 16; - ZIPNEEDBITS(e) - } while ((e = (t = t->v.t + ((uint32_t)b & Zipmask[e]))->e) > 16); - ZIPDUMPBITS(t->b) - if (w >= CAB_BLOCKMAX) break; - if (e == 16) /* then it's a literal */ - CAB(outbuf)[w++] = (uint8_t)t->v.n; - else /* it's an EOB or a length */ - { - /* exit if end of block */ - if(e == 15) - break; - - /* get length of block to copy */ - ZIPNEEDBITS(e) - n = t->v.n + ((uint32_t)b & Zipmask[e]); - ZIPDUMPBITS(e); - - /* decode distance of block to copy */ - ZIPNEEDBITS((uint32_t)bd) - if ((e = (t = td + ((uint32_t)b & md))->e) > 16) - do { - if (e == 99) - return 1; - ZIPDUMPBITS(t->b) - e -= 16; - ZIPNEEDBITS(e) - } while ((e = (t = t->v.t + ((uint32_t)b & Zipmask[e]))->e) > 16); - ZIPDUMPBITS(t->b) - ZIPNEEDBITS(e) - d = w - t->v.n - ((uint32_t)b & Zipmask[e]); - ZIPDUMPBITS(e) - do - { - n -= (e = (e = ZIPWSIZE - ((d &= ZIPWSIZE-1) > w ? d : w)) > n ?n:e); - do - { - CAB(outbuf)[w++] = CAB(outbuf)[d++]; - } while (--e); - } while (n); - } - } - - /* restore the globals from the locals */ - ZIP(window_posn) = w; /* restore global window pointer */ - ZIP(bb) = b; /* restore global bit buffer */ - ZIP(bk) = k; - - /* done */ - return 0; -} - -/* "decompress" an inflated type 0 (stored) block. */ -static int32_t Zipinflate_stored(struct decomp_state *decomp_state) -{ - uint32_t n; /* number of bytes in block */ - uint32_t w; /* current window position */ - register uint32_t b; /* bit buffer */ - register uint32_t k; /* number of bits in bit buffer */ - - /* make local copies of globals */ - b = ZIP(bb); /* initialize bit buffer */ - k = ZIP(bk); - w = ZIP(window_posn); /* initialize window position */ - - /* go to byte boundary */ - n = k & 7; - ZIPDUMPBITS(n); - - /* get the length and its complement */ - ZIPNEEDBITS(16) - n = ((uint32_t)b & 0xffff); - ZIPDUMPBITS(16) - ZIPNEEDBITS(16) - if (n != (uint32_t)((~b) & 0xffff)) - return 1; /* error in compressed data */ - ZIPDUMPBITS(16) - - /* read and output the compressed data */ - while(n--) - { - ZIPNEEDBITS(8) - CAB(outbuf)[w++] = (uint8_t)b; - ZIPDUMPBITS(8) - } - - /* restore the globals from the locals */ - ZIP(window_posn) = w; /* restore global window pointer */ - ZIP(bb) = b; /* restore global bit buffer */ - ZIP(bk) = k; - return 0; -} - -static int32_t Zipinflate_fixed(struct decomp_state *decomp_state) -{ - struct Ziphuft *fixed_tl; - struct Ziphuft *fixed_td; - int32_t fixed_bl, fixed_bd; - int32_t i; /* temporary variable */ - uint32_t *l; - - l = ZIP(ll); - - /* literal table */ - for(i = 0; i < 144; i++) - l[i] = 8; - for(; i < 256; i++) - l[i] = 9; - for(; i < 280; i++) - l[i] = 7; - for(; i < 288; i++) /* make a complete, but wrong code set */ - l[i] = 8; - fixed_bl = 7; - if((i = Ziphuft_build(decomp_state, l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl))) - return i; - - /* distance table */ - for(i = 0; i < 30; i++) /* make an incomplete code set */ - l[i] = 5; - fixed_bd = 5; - if((i = Ziphuft_build(decomp_state, l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd)) > 1) - { - Ziphuft_free(fixed_tl); - return i; - } - - /* decompress until an end-of-block code */ - i = Zipinflate_codes(decomp_state, fixed_tl, fixed_td, fixed_bl, fixed_bd); - - Ziphuft_free(fixed_td); - Ziphuft_free(fixed_tl); - return i; -} - -/* decompress an inflated type 2 (dynamic Huffman codes) block. */ -static int32_t Zipinflate_dynamic(struct decomp_state *decomp_state) -{ - int32_t i; /* temporary variables */ - uint32_t j; - uint32_t *ll; - uint32_t l; /* last length */ - uint32_t m; /* mask for bit lengths table */ - uint32_t n; /* number of lengths to get */ - struct Ziphuft *tl; /* literal/length code table */ - struct Ziphuft *td; /* distance code table */ - int32_t bl; /* lookup bits for tl */ - int32_t bd; /* lookup bits for td */ - uint32_t nb; /* number of bit length codes */ - uint32_t nl; /* number of literal/length codes */ - uint32_t nd; /* number of distance codes */ - register uint32_t b; /* bit buffer */ - register uint32_t k; /* number of bits in bit buffer */ - - /* make local bit buffer */ - b = ZIP(bb); - k = ZIP(bk); - ll = ZIP(ll); - - /* read in table lengths */ - ZIPNEEDBITS(5) - nl = 257 + ((uint32_t)b & 0x1f); /* number of literal/length codes */ - ZIPDUMPBITS(5) - ZIPNEEDBITS(5) - nd = 1 + ((uint32_t)b & 0x1f); /* number of distance codes */ - ZIPDUMPBITS(5) - ZIPNEEDBITS(4) - nb = 4 + ((uint32_t)b & 0xf); /* number of bit length codes */ - ZIPDUMPBITS(4) - if(nl > 288 || nd > 32) - return 1; /* bad lengths */ - - /* read in bit-length-code lengths */ - for(j = 0; j < nb; j++) - { - ZIPNEEDBITS(3) - ll[Zipborder[j]] = (uint32_t)b & 7; - ZIPDUMPBITS(3) - } - for(; j < 19; j++) - ll[Zipborder[j]] = 0; - - /* build decoding table for trees--single level, 7 bit lookup */ - bl = 7; - if((i = Ziphuft_build(decomp_state, ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) - { - if(i == 1) - Ziphuft_free(tl); - return i; /* incomplete code set */ - } - - /* read in literal and distance code lengths */ - n = nl + nd; - m = Zipmask[bl]; - i = l = 0; - while((uint32_t)i < n) - { - ZIPNEEDBITS((uint32_t)bl) - j = (td = tl + ((uint32_t)b & m))->b; - ZIPDUMPBITS(j) - j = td->v.n; - if (j < 16) /* length of code in bits (0..15) */ - ll[i++] = l = j; /* save last length in l */ - else if (j == 16) /* repeat last length 3 to 6 times */ - { - ZIPNEEDBITS(2) - j = 3 + ((uint32_t)b & 3); - ZIPDUMPBITS(2) - if((uint32_t)i + j > n) - return 1; - while (j--) - ll[i++] = l; - } - else if (j == 17) /* 3 to 10 zero length codes */ - { - ZIPNEEDBITS(3) - j = 3 + ((uint32_t)b & 7); - ZIPDUMPBITS(3) - if ((uint32_t)i + j > n) - return 1; - while (j--) - ll[i++] = 0; - l = 0; - } - else /* j == 18: 11 to 138 zero length codes */ - { - ZIPNEEDBITS(7) - j = 11 + ((uint32_t)b & 0x7f); - ZIPDUMPBITS(7) - if ((uint32_t)i + j > n) - return 1; - while (j--) - ll[i++] = 0; - l = 0; - } - } - - /* free decoding table for trees */ - Ziphuft_free(tl); - - /* restore the global bit buffer */ - ZIP(bb) = b; - ZIP(bk) = k; - - /* build the decoding tables for literal/length and distance codes */ - bl = ZIPLBITS; - if((i = Ziphuft_build(decomp_state, ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl)) != 0) - { - if(i == 1) - Ziphuft_free(tl); - return i; /* incomplete code set */ - } - bd = ZIPDBITS; - Ziphuft_build(decomp_state, ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd); - - /* decompress until an end-of-block code */ - if(Zipinflate_codes(decomp_state, tl, td, bl, bd)) - return 1; - - /* free the decoding tables, return */ - Ziphuft_free(tl); - Ziphuft_free(td); - return 0; -} - -/* e == last block flag */ -static int32_t Zipinflate_block(struct decomp_state *decomp_state, int32_t *e) -{ /* decompress an inflated block */ - uint32_t t; /* block type */ - register uint32_t b; /* bit buffer */ - register uint32_t k; /* number of bits in bit buffer */ - - DEBUG(10,("Zipinflate_block\n")); - - /* make local bit buffer */ - b = ZIP(bb); - k = ZIP(bk); - - /* read in last block bit */ - ZIPNEEDBITS(1) - *e = (int32_t)b & 1; - ZIPDUMPBITS(1) - - /* read in block type */ - ZIPNEEDBITS(2) - t = (uint32_t)b & 3; - ZIPDUMPBITS(2) - - /* restore the global bit buffer */ - ZIP(bb) = b; - ZIP(bk) = k; - - DEBUG(10,("inflate type %d\n", t)); - - /* inflate that block type */ - if(t == 2) - return Zipinflate_dynamic(decomp_state); - if(t == 0) - return Zipinflate_stored(decomp_state); - if(t == 1) - return Zipinflate_fixed(decomp_state); - /* bad block type */ - return 2; -} - -_PUBLIC_ struct decomp_state *ZIPdecomp_state(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct decomp_state); -} - -int ZIPdecompress(struct decomp_state *decomp_state, DATA_BLOB *inbuf, DATA_BLOB *outbuf) -{ - int32_t e = 0;/* last block flag */ - - ZIP(inpos) = CAB(inbuf); - ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0; - - if (inbuf->length > sizeof(decomp_state->inbuf)) return DECR_INPUT; - - if (outbuf->length > sizeof(decomp_state->outbuf)) return DECR_OUTPUT; - - if (outbuf->length > ZIPWSIZE) return DECR_DATAFORMAT; - - memcpy(decomp_state->inbuf, inbuf->data, inbuf->length); - - /* CK = Chris Kirmse, official Microsoft purloiner */ - if (ZIP(inpos)[0] != 'C' || ZIP(inpos)[1] != 'K') return DECR_ILLEGALDATA; - ZIP(inpos) += 2; - - while (!e) { - if (Zipinflate_block(decomp_state, &e)) { - return DECR_ILLEGALDATA; - } - } - - memcpy(outbuf->data, decomp_state->outbuf, outbuf->length); - - return DECR_OK; -} diff --git a/compression/mszip.h b/compression/mszip.h deleted file mode 100644 index bb835f2595..0000000000 --- a/compression/mszip.h +++ /dev/null @@ -1,33 +0,0 @@ -/* mszip decompression - based on cabextract.c code from - * Stuart Caie - * - * adapted for Samba by Andrew Tridgell and Stefan Metzmacher 2005 - * - * (C) 2000-2001 Stuart Caie - * reaktivate-specifics by Malte Starostik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -struct decomp_state; -struct decomp_state *ZIPdecomp_state(TALLOC_CTX *mem_ctx); - -#define DECR_OK (0) -#define DECR_DATAFORMAT (1) -#define DECR_ILLEGALDATA (2) -#define DECR_NOMEMORY (3) -#define DECR_CHECKSUM (4) -#define DECR_INPUT (5) -#define DECR_OUTPUT (6) -int ZIPdecompress(struct decomp_state *decomp_state, DATA_BLOB *inbuf, DATA_BLOB *outbuf); diff --git a/compression/testsuite.c b/compression/testsuite.c deleted file mode 100644 index b9cebb2e8d..0000000000 --- a/compression/testsuite.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - Unix SMB/CIFS implementation. - test suite for the compression functions - - Copyright (C) Jelmer Vernooij 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "torture/torture.h" -#include "../compression/mszip.h" - -struct torture_suite *torture_local_compression(TALLOC_CTX *mem_ctx) -{ - struct torture_suite *suite = torture_suite_create(mem_ctx, "COMPRESSION"); - - return suite; -} diff --git a/lib/compression/lzxpress.c b/lib/compression/lzxpress.c new file mode 100644 index 0000000000..0abbfc4d3d --- /dev/null +++ b/lib/compression/lzxpress.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) Matthieu Suiche 2008 + * + * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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 "replace.h" +#include "lzxpress.h" + + +#define __BUF_POS_CONST(buf,ofs)(((const uint8_t *)buf)+(ofs)) +#define __PULL_BYTE(buf,ofs) \ + ((uint8_t)((*__BUF_POS_CONST(buf,ofs)) & 0xFF)) + +#ifndef PULL_LE_UINT16 +#define PULL_LE_UINT16(buf,ofs) ((uint16_t)( \ + ((uint16_t)(((uint16_t)(__PULL_BYTE(buf,(ofs)+0))) << 0)) | \ + ((uint16_t)(((uint16_t)(__PULL_BYTE(buf,(ofs)+1))) << 8)) \ +)) +#endif + +#ifndef PULL_LE_UINT32 +#define PULL_LE_UINT32(buf,ofs) ((uint32_t)( \ + ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+0))) << 0)) | \ + ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+1))) << 8)) | \ + ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+2))) << 16)) | \ + ((uint32_t)(((uint32_t)(__PULL_BYTE(buf,(ofs)+3))) << 24)) \ +)) +#endif + +ssize_t lzxpress_compress(const uint8_t *uncompressed, + uint32_t uncompressed_size, + uint8_t *compressed, + uint32_t max_compressed_size) +{ + uint32_t uncompressed_pos, compressed_pos, byte_left; + uint32_t max_offset, best_offset; + int32_t offset; + uint32_t max_len, len, best_len; + const uint8_t *str1, *str2; + uint32_t indic; + uint8_t *indic_pos; + uint32_t indic_bit, nibble_index; + + uint32_t metadata_size; + uint16_t metadata; + uint16_t *dest; + + if (!uncompressed_size) { + return 0; + } + + uncompressed_pos = 0; + indic = 0; + compressed_pos = sizeof(uint32_t); + indic_pos = &compressed[0]; + + byte_left = uncompressed_size; + indic_bit = 0; + nibble_index = 0; + + if (uncompressed_pos > XPRESS_BLOCK_SIZE) + return 0; + + do { + bool found = false; + + max_offset = uncompressed_pos; + + str1 = &uncompressed[uncompressed_pos]; + + best_len = 2; + best_offset = 0; + + max_offset = MIN(0x1FFF, max_offset); + + /* search for the longest match in the window for the lookahead buffer */ + for (offset = 1; (uint32_t)offset <= max_offset; offset++) { + str2 = &str1[-offset]; + + /* maximum len we can encode into metadata */ + max_len = MIN((255 + 15 + 7 + 3), byte_left); + + for (len = 0; (len < max_len) && (str1[len] == str2[len]); len++); + + /* + * We check if len is better than the value found before, including the + * sequence of identical bytes + */ + if (len > best_len) { + found = true; + best_len = len; + best_offset = offset; + } + } + + if (found) { + metadata_size = 0; + dest = (uint16_t *)&compressed[compressed_pos]; + + if (best_len < 10) { + /* Classical meta-data */ + metadata = (uint16_t)(((best_offset - 1) << 3) | (best_len - 3)); + dest[metadata_size / sizeof(uint16_t)] = metadata; + metadata_size += sizeof(uint16_t); + } else { + metadata = (uint16_t)(((best_offset - 1) << 3) | 7); + dest[metadata_size / sizeof(uint16_t)] = metadata; + metadata_size = sizeof(uint16_t); + + if (best_len < (15 + 7 + 3)) { + /* Shared byte */ + if (!nibble_index) { + compressed[compressed_pos + metadata_size] = (best_len - (3 + 7)) & 0xF; + metadata_size += sizeof(uint8_t); + } else { + compressed[nibble_index] &= 0xF; + compressed[nibble_index] |= (best_len - (3 + 7)) * 16; + } + } else if (best_len < (3 + 7 + 15 + 255)) { + /* Shared byte */ + if (!nibble_index) { + compressed[compressed_pos + metadata_size] = 15; + metadata_size += sizeof(uint8_t); + } else { + compressed[nibble_index] &= 0xF; + compressed[nibble_index] |= (15 * 16); + } + + /* Additionnal best_len */ + compressed[compressed_pos + metadata_size] = (best_len - (3 + 7 + 15)) & 0xFF; + metadata_size += sizeof(uint8_t); + } else { + /* Shared byte */ + if (!nibble_index) { + compressed[compressed_pos + metadata_size] |= 15; + metadata_size += sizeof(uint8_t); + } else { + compressed[nibble_index] |= 15 << 4; + } + + /* Additionnal best_len */ + compressed[compressed_pos + metadata_size] = 255; + + metadata_size += sizeof(uint8_t); + + compressed[compressed_pos + metadata_size] = (best_len - 3) & 0xFF; + compressed[compressed_pos + metadata_size + 1] = ((best_len - 3) >> 8) & 0xFF; + metadata_size += sizeof(uint16_t); + } + } + + indic |= 1 << (32 - ((indic_bit % 32) + 1)); + + if (best_len > 9) { + if (nibble_index == 0) { + nibble_index = compressed_pos + sizeof(uint16_t); + } else { + nibble_index = 0; + } + } + + compressed_pos += metadata_size; + uncompressed_pos += best_len; + byte_left -= best_len; + } else { + compressed[compressed_pos++] = uncompressed[uncompressed_pos++]; + byte_left--; + } + indic_bit++; + + if ((indic_bit - 1) % 32 > (indic_bit % 32)) { + *(uint32_t *)indic_pos = indic; + indic = 0; + indic_pos = &compressed[compressed_pos]; + compressed_pos += sizeof(uint32_t); + } + } while (byte_left > 3); + + do { + compressed[compressed_pos] = uncompressed[uncompressed_pos]; + indic_bit++; + + uncompressed_pos++; + compressed_pos++; + if (((indic_bit - 1) % 32) > (indic_bit % 32)){ + *(uint32_t *)indic_pos = indic; + indic = 0; + indic_pos = &compressed[compressed_pos]; + compressed_pos += sizeof(uint32_t); + } + } while (uncompressed_pos < uncompressed_size); + + if ((indic_bit % 32) > 0) { + for (; (indic_bit % 32) != 0; indic_bit++) + indic |= 0 << (32 - ((indic_bit % 32) + 1)); + + *(uint32_t *)indic_pos = indic; + compressed_pos += sizeof(uint32_t); + } + + return compressed_pos; +} + +ssize_t lzxpress_decompress(const uint8_t *input, + uint32_t input_size, + uint8_t *output, + uint32_t max_output_size) +{ + uint32_t output_index, input_index; + uint32_t indicator, indicator_bit; + uint32_t length; + uint32_t offset; + uint32_t nibble_index; + + output_index = 0; + input_index = 0; + indicator = 0; + indicator_bit = 0; + length = 0; + offset = 0; + nibble_index = 0; + + do { + if (indicator_bit == 0) { + indicator = PULL_LE_UINT32(input, input_index); + input_index += sizeof(uint32_t); + indicator_bit = 32; + } + indicator_bit--; + + /* + * check whether the bit specified by indicator_bit is set or not + * set in indicator. For example, if indicator_bit has value 4 + * check whether the 4th bit of the value in indicator is set + */ + if (((indicator >> indicator_bit) & 1) == 0) { + output[output_index] = input[input_index]; + input_index += sizeof(uint8_t); + output_index += sizeof(uint8_t); + } else { + length = PULL_LE_UINT16(input, input_index); + input_index += sizeof(uint16_t); + offset = length / 8; + length = length % 8; + + if (length == 7) { + if (nibble_index == 0) { + nibble_index = input_index; + length = input[input_index] % 16; + input_index += sizeof(uint8_t); + } else { + length = input[nibble_index] / 16; + nibble_index = 0; + } + + if (length == 15) { + length = input[input_index]; + input_index += sizeof(uint8_t); + if (length == 255) { + length = PULL_LE_UINT16(input, input_index); + input_index += sizeof(uint16_t); + length -= (15 + 7); + } + length += 15; + } + length += 7; + } + + length += 3; + + do { + if ((output_index >= max_output_size) || ((offset + 1) > output_index)) break; + + output[output_index] = output[output_index - offset - 1]; + + output_index += sizeof(uint8_t); + length -= sizeof(uint8_t); + } while (length != 0); + } + } while ((output_index < max_output_size) && (input_index < (input_size))); + + return output_index; +} diff --git a/lib/compression/lzxpress.h b/lib/compression/lzxpress.h new file mode 100644 index 0000000000..df0ee59a0e --- /dev/null +++ b/lib/compression/lzxpress.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) Matthieu Suiche 2008 + * + * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _LZXPRESS_H +#define _LZXPRESS_H + +#define XPRESS_BLOCK_SIZE 0x10000 + +ssize_t lzxpress_compress(const uint8_t *uncompressed, + uint32_t uncompressed_size, + uint8_t *compressed, + uint32_t max_compressed_size); + +ssize_t lzxpress_decompress(const uint8_t *input, + uint32_t input_size, + uint8_t *output, + uint32_t max_output_size); + +#endif /* _LZXPRESS_H */ diff --git a/lib/compression/mszip.c b/lib/compression/mszip.c new file mode 100644 index 0000000000..9aa1772414 --- /dev/null +++ b/lib/compression/mszip.c @@ -0,0 +1,676 @@ +/* mszip decompression - based on cabextract.c code from + * Stuart Caie + * + * adapted for Samba by Andrew Tridgell and Stefan Metzmacher 2005 + * + * (C) 2000-2001 Stuart Caie + * reaktivate-specifics by Malte Starostik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "../compression/mszip.h" + +/*--------------------------------------------------------------------------*/ +/* our archiver information / state */ + +/* MSZIP stuff */ +#define ZIPWSIZE 0x8000 /* window size */ +#define ZIPLBITS 9 /* bits in base literal/length lookup table */ +#define ZIPDBITS 6 /* bits in base distance lookup table */ +#define ZIPBMAX 16 /* maximum bit length of any code */ +#define ZIPN_MAX 288 /* maximum number of codes in any set */ + +struct Ziphuft { + uint8_t e; /* number of extra bits or operation */ + uint8_t b; /* number of bits in this code or subcode */ + union { + uint16_t n; /* literal, length base, or distance base */ + struct Ziphuft *t; /* pointer to next level of table */ + } v; +}; + +struct ZIPstate { + uint32_t window_posn; /* current offset within the window */ + uint32_t bb; /* bit buffer */ + uint32_t bk; /* bits in bit buffer */ + uint32_t ll[288+32]; /* literal/length and distance code lengths */ + uint32_t c[ZIPBMAX+1]; /* bit length count table */ + int32_t lx[ZIPBMAX+1]; /* memory for l[-1..ZIPBMAX-1] */ + struct Ziphuft *u[ZIPBMAX]; /* table stack */ + uint32_t v[ZIPN_MAX]; /* values in order of bit length */ + uint32_t x[ZIPBMAX+1]; /* bit offsets, then code stack */ + uint8_t *inpos; +}; + +/* generic stuff */ +#define CAB(x) (decomp_state->x) +#define ZIP(x) (decomp_state->methods.zip.x) + +/* CAB data blocks are <= 32768 bytes in uncompressed form. Uncompressed + * blocks have zero growth. MSZIP guarantees that it won't grow above + * uncompressed size by more than 12 bytes. LZX guarantees it won't grow + * more than 6144 bytes. + */ +#define CAB_BLOCKMAX (32768) +#define CAB_INPUTMAX (CAB_BLOCKMAX+6144) + +struct decomp_state { + struct folder *current; /* current folder we're extracting from */ + uint32_t offset; /* uncompressed offset within folder */ + uint8_t *outpos; /* (high level) start of data to use up */ + uint16_t outlen; /* (high level) amount of data to use up */ + uint16_t split; /* at which split in current folder? */ + int (*decompress)(int, int); /* the chosen compression func */ + uint8_t inbuf[CAB_INPUTMAX+2]; /* +2 for lzx bitbuffer overflows! */ + uint8_t outbuf[CAB_BLOCKMAX]; + union { + struct ZIPstate zip; + } methods; +}; + + +/* MSZIP decruncher */ + +/* Dirk Stoecker wrote the ZIP decoder, based on the InfoZip deflate code */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +static const uint8_t Zipborder[] = /* Order of the bit length code lengths */ +{ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +static const uint16_t Zipcplens[] = /* Copy lengths for literal codes 257..285 */ +{ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, + 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; +static const uint16_t Zipcplext[] = /* Extra bits for literal codes 257..285 */ +{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, + 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ +static const uint16_t Zipcpdist[] = /* Copy offsets for distance codes 0..29 */ +{ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, +513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; +static const uint16_t Zipcpdext[] = /* Extra bits for distance codes */ +{ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, +10, 11, 11, 12, 12, 13, 13}; + +/* And'ing with Zipmask[n] masks the lower n bits */ +static const uint16_t Zipmask[17] = { + 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +#define ZIPNEEDBITS(n) {while(k<(n)){int32_t c=*(ZIP(inpos)++);\ + b|=((uint32_t)c)<>=(n);k-=(n);} + +static void Ziphuft_free(struct Ziphuft *t) +{ + register struct Ziphuft *p, *q; + + /* Go through linked list, freeing from the allocated (t[-1]) address. */ + p = t; + while (p != (struct Ziphuft *)NULL) + { + q = (--p)->v.t; + free(p); + p = q; + } +} + +static int32_t Ziphuft_build(struct decomp_state *decomp_state, + uint32_t *b, uint32_t n, uint32_t s, const uint16_t *d, const uint16_t *e, + struct Ziphuft **t, int32_t *m) +{ + uint32_t a; /* counter for codes of length k */ + uint32_t el; /* length of EOB code (value 256) */ + uint32_t f; /* i repeats in table every f entries */ + int32_t g; /* maximum code length */ + int32_t h; /* table level */ + register uint32_t i; /* counter, current code */ + register uint32_t j; /* counter */ + register int32_t k; /* number of bits in current code */ + int32_t *l; /* stack of bits per table */ + register uint32_t *p; /* pointer into ZIP(c)[],ZIP(b)[],ZIP(v)[] */ + register struct Ziphuft *q; /* points to current table */ + struct Ziphuft r; /* table entry for structure assignment */ + register int32_t w; /* bits before this table == (l * h) */ + uint32_t *xp; /* pointer into x */ + int32_t y; /* number of dummy codes added */ + uint32_t z; /* number of entries in current table */ + + l = ZIP(lx)+1; + + /* Generate counts for each bit length */ + el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */ + + for(i = 0; i < ZIPBMAX+1; ++i) + ZIP(c)[i] = 0; + p = b; i = n; + do + { + ZIP(c)[*p]++; p++; /* assume all entries <= ZIPBMAX */ + } while (--i); + if (ZIP(c)[0] == n) /* null input--all zero length codes */ + { + *t = (struct Ziphuft *)NULL; + *m = 0; + return 0; + } + + /* Find minimum and maximum length, bound *m by those */ + for (j = 1; j <= ZIPBMAX; j++) + if (ZIP(c)[j]) + break; + k = j; /* minimum code length */ + if ((uint32_t)*m < j) + *m = j; + for (i = ZIPBMAX; i; i--) + if (ZIP(c)[i]) + break; + g = i; /* maximum code length */ + if ((uint32_t)*m > i) + *m = i; + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= ZIP(c)[j]) < 0) + return 2; /* bad input: more codes than bits */ + if ((y -= ZIP(c)[i]) < 0) + return 2; + ZIP(c)[i] += y; + + /* Generate starting offsets int32_to the value table for each length */ + ZIP(x)[1] = j = 0; + p = ZIP(c) + 1; xp = ZIP(x) + 2; + while (--i) + { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do{ + if ((j = *p++) != 0) + ZIP(v)[ZIP(x)[j]++] = i; + } while (++i < n); + + + /* Generate the Huffman codes and for each, make the table entries */ + ZIP(x)[0] = i = 0; /* first Huffman code is zero */ + p = ZIP(v); /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = l[-1] = 0; /* no bits decoded yet */ + ZIP(u)[0] = (struct Ziphuft *)NULL; /* just to keep compilers happy */ + q = (struct Ziphuft *)NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = ZIP(c)[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l[h]) + { + w += l[h++]; /* add bits already decoded */ + + /* compute minimum size table less than or equal to *m bits */ + z = (z = g - w) > (uint32_t)*m ? *m : z; /* upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = ZIP(c) + k; + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + if ((uint32_t)w + j > el && (uint32_t)w < el) + j = el - w; /* make EOB code end at table */ + z = 1 << j; /* table entries for j-bit table */ + l[h] = j; /* set table size in stack */ + + /* allocate and link in new table */ + if (!(q = (struct Ziphuft *)SMB_MALLOC((z + 1)*sizeof(struct Ziphuft)))) + { + if(h) + Ziphuft_free(ZIP(u)[0]); + return 3; /* not enough memory */ + } + *t = q + 1; /* link to list for Ziphuft_free() */ + *(t = &(q->v.t)) = (struct Ziphuft *)NULL; + ZIP(u)[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + ZIP(x)[h] = i; /* save pattern for backing up */ + r.b = (uint8_t)l[h-1]; /* bits to dump before this table */ + r.e = (uint8_t)(16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = (i & ((1 << w) - 1)) >> (w - l[h-1]); + ZIP(u)[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.b = (uint8_t)(k - w); + if (p >= ZIP(v) + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { + r.e = (uint8_t)(*p < 256 ? 16 : 15); /* 256 is end-of-block code */ + r.v.n = *p++; /* simple code is just the value */ + } + else + { + r.e = (uint8_t)e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != ZIP(x)[h]) + w -= l[--h]; /* don't need to update q */ + } + } + + /* return actual size of base table */ + *m = l[0]; + + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; +} + +static int32_t Zipinflate_codes(struct decomp_state *decomp_state, + struct Ziphuft *tl, struct Ziphuft *td, + int32_t bl, int32_t bd) +{ + register uint32_t e; /* table entry flag/number of extra bits */ + uint32_t n, d; /* length and index for copy */ + uint32_t w; /* current window position */ + struct Ziphuft *t; /* pointer to table entry */ + uint32_t ml, md; /* masks for bl and bd bits */ + register uint32_t b; /* bit buffer */ + register uint32_t k; /* number of bits in bit buffer */ + + DEBUG(10,("Zipinflate_codes\n")); + + /* make local copies of globals */ + b = ZIP(bb); /* initialize bit buffer */ + k = ZIP(bk); + w = ZIP(window_posn); /* initialize window position */ + + /* inflate the coded data */ + ml = Zipmask[bl]; /* precompute masks for speed */ + md = Zipmask[bd]; + + for(;;) + { + ZIPNEEDBITS((uint32_t)bl) + if((e = (t = tl + ((uint32_t)b & ml))->e) > 16) + do + { + if (e == 99) + return 1; + ZIPDUMPBITS(t->b) + e -= 16; + ZIPNEEDBITS(e) + } while ((e = (t = t->v.t + ((uint32_t)b & Zipmask[e]))->e) > 16); + ZIPDUMPBITS(t->b) + if (w >= CAB_BLOCKMAX) break; + if (e == 16) /* then it's a literal */ + CAB(outbuf)[w++] = (uint8_t)t->v.n; + else /* it's an EOB or a length */ + { + /* exit if end of block */ + if(e == 15) + break; + + /* get length of block to copy */ + ZIPNEEDBITS(e) + n = t->v.n + ((uint32_t)b & Zipmask[e]); + ZIPDUMPBITS(e); + + /* decode distance of block to copy */ + ZIPNEEDBITS((uint32_t)bd) + if ((e = (t = td + ((uint32_t)b & md))->e) > 16) + do { + if (e == 99) + return 1; + ZIPDUMPBITS(t->b) + e -= 16; + ZIPNEEDBITS(e) + } while ((e = (t = t->v.t + ((uint32_t)b & Zipmask[e]))->e) > 16); + ZIPDUMPBITS(t->b) + ZIPNEEDBITS(e) + d = w - t->v.n - ((uint32_t)b & Zipmask[e]); + ZIPDUMPBITS(e) + do + { + n -= (e = (e = ZIPWSIZE - ((d &= ZIPWSIZE-1) > w ? d : w)) > n ?n:e); + do + { + CAB(outbuf)[w++] = CAB(outbuf)[d++]; + } while (--e); + } while (n); + } + } + + /* restore the globals from the locals */ + ZIP(window_posn) = w; /* restore global window pointer */ + ZIP(bb) = b; /* restore global bit buffer */ + ZIP(bk) = k; + + /* done */ + return 0; +} + +/* "decompress" an inflated type 0 (stored) block. */ +static int32_t Zipinflate_stored(struct decomp_state *decomp_state) +{ + uint32_t n; /* number of bytes in block */ + uint32_t w; /* current window position */ + register uint32_t b; /* bit buffer */ + register uint32_t k; /* number of bits in bit buffer */ + + /* make local copies of globals */ + b = ZIP(bb); /* initialize bit buffer */ + k = ZIP(bk); + w = ZIP(window_posn); /* initialize window position */ + + /* go to byte boundary */ + n = k & 7; + ZIPDUMPBITS(n); + + /* get the length and its complement */ + ZIPNEEDBITS(16) + n = ((uint32_t)b & 0xffff); + ZIPDUMPBITS(16) + ZIPNEEDBITS(16) + if (n != (uint32_t)((~b) & 0xffff)) + return 1; /* error in compressed data */ + ZIPDUMPBITS(16) + + /* read and output the compressed data */ + while(n--) + { + ZIPNEEDBITS(8) + CAB(outbuf)[w++] = (uint8_t)b; + ZIPDUMPBITS(8) + } + + /* restore the globals from the locals */ + ZIP(window_posn) = w; /* restore global window pointer */ + ZIP(bb) = b; /* restore global bit buffer */ + ZIP(bk) = k; + return 0; +} + +static int32_t Zipinflate_fixed(struct decomp_state *decomp_state) +{ + struct Ziphuft *fixed_tl; + struct Ziphuft *fixed_td; + int32_t fixed_bl, fixed_bd; + int32_t i; /* temporary variable */ + uint32_t *l; + + l = ZIP(ll); + + /* literal table */ + for(i = 0; i < 144; i++) + l[i] = 8; + for(; i < 256; i++) + l[i] = 9; + for(; i < 280; i++) + l[i] = 7; + for(; i < 288; i++) /* make a complete, but wrong code set */ + l[i] = 8; + fixed_bl = 7; + if((i = Ziphuft_build(decomp_state, l, 288, 257, Zipcplens, Zipcplext, &fixed_tl, &fixed_bl))) + return i; + + /* distance table */ + for(i = 0; i < 30; i++) /* make an incomplete code set */ + l[i] = 5; + fixed_bd = 5; + if((i = Ziphuft_build(decomp_state, l, 30, 0, Zipcpdist, Zipcpdext, &fixed_td, &fixed_bd)) > 1) + { + Ziphuft_free(fixed_tl); + return i; + } + + /* decompress until an end-of-block code */ + i = Zipinflate_codes(decomp_state, fixed_tl, fixed_td, fixed_bl, fixed_bd); + + Ziphuft_free(fixed_td); + Ziphuft_free(fixed_tl); + return i; +} + +/* decompress an inflated type 2 (dynamic Huffman codes) block. */ +static int32_t Zipinflate_dynamic(struct decomp_state *decomp_state) +{ + int32_t i; /* temporary variables */ + uint32_t j; + uint32_t *ll; + uint32_t l; /* last length */ + uint32_t m; /* mask for bit lengths table */ + uint32_t n; /* number of lengths to get */ + struct Ziphuft *tl; /* literal/length code table */ + struct Ziphuft *td; /* distance code table */ + int32_t bl; /* lookup bits for tl */ + int32_t bd; /* lookup bits for td */ + uint32_t nb; /* number of bit length codes */ + uint32_t nl; /* number of literal/length codes */ + uint32_t nd; /* number of distance codes */ + register uint32_t b; /* bit buffer */ + register uint32_t k; /* number of bits in bit buffer */ + + /* make local bit buffer */ + b = ZIP(bb); + k = ZIP(bk); + ll = ZIP(ll); + + /* read in table lengths */ + ZIPNEEDBITS(5) + nl = 257 + ((uint32_t)b & 0x1f); /* number of literal/length codes */ + ZIPDUMPBITS(5) + ZIPNEEDBITS(5) + nd = 1 + ((uint32_t)b & 0x1f); /* number of distance codes */ + ZIPDUMPBITS(5) + ZIPNEEDBITS(4) + nb = 4 + ((uint32_t)b & 0xf); /* number of bit length codes */ + ZIPDUMPBITS(4) + if(nl > 288 || nd > 32) + return 1; /* bad lengths */ + + /* read in bit-length-code lengths */ + for(j = 0; j < nb; j++) + { + ZIPNEEDBITS(3) + ll[Zipborder[j]] = (uint32_t)b & 7; + ZIPDUMPBITS(3) + } + for(; j < 19; j++) + ll[Zipborder[j]] = 0; + + /* build decoding table for trees--single level, 7 bit lookup */ + bl = 7; + if((i = Ziphuft_build(decomp_state, ll, 19, 19, NULL, NULL, &tl, &bl)) != 0) + { + if(i == 1) + Ziphuft_free(tl); + return i; /* incomplete code set */ + } + + /* read in literal and distance code lengths */ + n = nl + nd; + m = Zipmask[bl]; + i = l = 0; + while((uint32_t)i < n) + { + ZIPNEEDBITS((uint32_t)bl) + j = (td = tl + ((uint32_t)b & m))->b; + ZIPDUMPBITS(j) + j = td->v.n; + if (j < 16) /* length of code in bits (0..15) */ + ll[i++] = l = j; /* save last length in l */ + else if (j == 16) /* repeat last length 3 to 6 times */ + { + ZIPNEEDBITS(2) + j = 3 + ((uint32_t)b & 3); + ZIPDUMPBITS(2) + if((uint32_t)i + j > n) + return 1; + while (j--) + ll[i++] = l; + } + else if (j == 17) /* 3 to 10 zero length codes */ + { + ZIPNEEDBITS(3) + j = 3 + ((uint32_t)b & 7); + ZIPDUMPBITS(3) + if ((uint32_t)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + else /* j == 18: 11 to 138 zero length codes */ + { + ZIPNEEDBITS(7) + j = 11 + ((uint32_t)b & 0x7f); + ZIPDUMPBITS(7) + if ((uint32_t)i + j > n) + return 1; + while (j--) + ll[i++] = 0; + l = 0; + } + } + + /* free decoding table for trees */ + Ziphuft_free(tl); + + /* restore the global bit buffer */ + ZIP(bb) = b; + ZIP(bk) = k; + + /* build the decoding tables for literal/length and distance codes */ + bl = ZIPLBITS; + if((i = Ziphuft_build(decomp_state, ll, nl, 257, Zipcplens, Zipcplext, &tl, &bl)) != 0) + { + if(i == 1) + Ziphuft_free(tl); + return i; /* incomplete code set */ + } + bd = ZIPDBITS; + Ziphuft_build(decomp_state, ll + nl, nd, 0, Zipcpdist, Zipcpdext, &td, &bd); + + /* decompress until an end-of-block code */ + if(Zipinflate_codes(decomp_state, tl, td, bl, bd)) + return 1; + + /* free the decoding tables, return */ + Ziphuft_free(tl); + Ziphuft_free(td); + return 0; +} + +/* e == last block flag */ +static int32_t Zipinflate_block(struct decomp_state *decomp_state, int32_t *e) +{ /* decompress an inflated block */ + uint32_t t; /* block type */ + register uint32_t b; /* bit buffer */ + register uint32_t k; /* number of bits in bit buffer */ + + DEBUG(10,("Zipinflate_block\n")); + + /* make local bit buffer */ + b = ZIP(bb); + k = ZIP(bk); + + /* read in last block bit */ + ZIPNEEDBITS(1) + *e = (int32_t)b & 1; + ZIPDUMPBITS(1) + + /* read in block type */ + ZIPNEEDBITS(2) + t = (uint32_t)b & 3; + ZIPDUMPBITS(2) + + /* restore the global bit buffer */ + ZIP(bb) = b; + ZIP(bk) = k; + + DEBUG(10,("inflate type %d\n", t)); + + /* inflate that block type */ + if(t == 2) + return Zipinflate_dynamic(decomp_state); + if(t == 0) + return Zipinflate_stored(decomp_state); + if(t == 1) + return Zipinflate_fixed(decomp_state); + /* bad block type */ + return 2; +} + +_PUBLIC_ struct decomp_state *ZIPdecomp_state(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct decomp_state); +} + +int ZIPdecompress(struct decomp_state *decomp_state, DATA_BLOB *inbuf, DATA_BLOB *outbuf) +{ + int32_t e = 0;/* last block flag */ + + ZIP(inpos) = CAB(inbuf); + ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0; + + if (inbuf->length > sizeof(decomp_state->inbuf)) return DECR_INPUT; + + if (outbuf->length > sizeof(decomp_state->outbuf)) return DECR_OUTPUT; + + if (outbuf->length > ZIPWSIZE) return DECR_DATAFORMAT; + + memcpy(decomp_state->inbuf, inbuf->data, inbuf->length); + + /* CK = Chris Kirmse, official Microsoft purloiner */ + if (ZIP(inpos)[0] != 'C' || ZIP(inpos)[1] != 'K') return DECR_ILLEGALDATA; + ZIP(inpos) += 2; + + while (!e) { + if (Zipinflate_block(decomp_state, &e)) { + return DECR_ILLEGALDATA; + } + } + + memcpy(outbuf->data, decomp_state->outbuf, outbuf->length); + + return DECR_OK; +} diff --git a/lib/compression/mszip.h b/lib/compression/mszip.h new file mode 100644 index 0000000000..bb835f2595 --- /dev/null +++ b/lib/compression/mszip.h @@ -0,0 +1,33 @@ +/* mszip decompression - based on cabextract.c code from + * Stuart Caie + * + * adapted for Samba by Andrew Tridgell and Stefan Metzmacher 2005 + * + * (C) 2000-2001 Stuart Caie + * reaktivate-specifics by Malte Starostik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +struct decomp_state; +struct decomp_state *ZIPdecomp_state(TALLOC_CTX *mem_ctx); + +#define DECR_OK (0) +#define DECR_DATAFORMAT (1) +#define DECR_ILLEGALDATA (2) +#define DECR_NOMEMORY (3) +#define DECR_CHECKSUM (4) +#define DECR_INPUT (5) +#define DECR_OUTPUT (6) +int ZIPdecompress(struct decomp_state *decomp_state, DATA_BLOB *inbuf, DATA_BLOB *outbuf); diff --git a/lib/compression/testsuite.c b/lib/compression/testsuite.c new file mode 100644 index 0000000000..b9cebb2e8d --- /dev/null +++ b/lib/compression/testsuite.c @@ -0,0 +1,30 @@ +/* + Unix SMB/CIFS implementation. + test suite for the compression functions + + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "torture/torture.h" +#include "../compression/mszip.h" + +struct torture_suite *torture_local_compression(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "COMPRESSION"); + + return suite; +} diff --git a/lib/nss_wrapper/config.m4 b/lib/nss_wrapper/config.m4 new file mode 100644 index 0000000000..45423788d1 --- /dev/null +++ b/lib/nss_wrapper/config.m4 @@ -0,0 +1,19 @@ +AC_ARG_ENABLE(nss-wrapper, +[ --enable-nss-wrapper Turn on nss wrapper library (default=no)]) + +HAVE_NSS_WRAPPER=no + +if eval "test x$developer = xyes"; then + enable_nss_wrapper=yes +fi + +if eval "test x$enable_nss_wrapper = xyes"; then + AC_DEFINE(NSS_WRAPPER,1,[Use nss wrapper library]) + HAVE_NSS_WRAPPER=yes + + # this is only used for samba3 + NSS_WRAPPER_OBJS="../lib/nss_wrapper/nss_wrapper.o" +fi + +AC_SUBST(HAVE_NSS_WRAPPER) +AC_SUBST(NSS_WRAPPER_OBJS) diff --git a/lib/nss_wrapper/config.mk b/lib/nss_wrapper/config.mk new file mode 100644 index 0000000000..015fbe511c --- /dev/null +++ b/lib/nss_wrapper/config.mk @@ -0,0 +1,7 @@ +############################## +# Start SUBSYSTEM NSS_WRAPPER +[SUBSYSTEM::NSS_WRAPPER] +# End SUBSYSTEM NSS_WRAPPER +############################## + +NSS_WRAPPER_OBJ_FILES = $(nsswrappersrcdir)/nss_wrapper.o diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c new file mode 100644 index 0000000000..da090832b0 --- /dev/null +++ b/lib/nss_wrapper/nss_wrapper.c @@ -0,0 +1,1130 @@ +/* + * Copyright (C) Stefan Metzmacher 2007 + * + * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. + */ + +#ifdef _SAMBA_BUILD_ + +#define NSS_WRAPPER_NOT_REPLACE +#include "../replace/replace.h" +#include "system/passwd.h" +#include "system/filesys.h" + +#else /* _SAMBA_BUILD_ */ + +#error nss_wrapper_only_supported_in_samba_yet + +#endif + +#ifndef _PUBLIC_ +#define _PUBLIC_ +#endif + +/* not all systems have _r functions... */ +#ifndef HAVE_GETPWNAM_R +#define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS +#endif +#ifndef HAVE_GETPWUID_R +#define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS +#endif +#ifndef HAVE_GETPWENT_R +#define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS +#endif +#ifndef HAVE_GETGRNAM_R +#define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS +#endif +#ifndef HAVE_GETGRUID_R +#define getgrgid_r(uid, grdst, buf, buflen, grdstp) ENOSYS +#endif +#ifndef HAVE_GETGRENT_R +#define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS +#endif + +/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support + * for now */ +#define REWRITE_CALLS + +#ifdef REWRITE_CALLS + +#define real_getpwnam getpwnam +#define real_getpwnam_r getpwnam_r +#define real_getpwuid getpwuid +#define real_getpwuid_r getpwuid_r + +#define real_setpwent setpwent +#define real_getpwent getpwent +#define real_getpwent_r getpwent_r +#define real_endpwent endpwent + +/* +#define real_getgrlst getgrlst +#define real_getgrlst_r getgrlst_r +#define real_initgroups_dyn initgroups_dyn +*/ +#define real_initgroups initgroups + +#define real_getgrnam getgrnam +#define real_getgrnam_r getgrnam_r +#define real_getgrgid getgrgid +#define real_getgrgid_r getgrgid_r + +#define real_setgrent setgrent +#define real_getgrent getgrent +#define real_getgrent_r getgrent_r +#define real_endgrent endgrent + +#endif + +#if 0 +# ifdef DEBUG +# define NWRAP_ERROR(args) DEBUG(0, args) +# else +# define NWRAP_ERROR(args) printf args +# endif +#else +#define NWRAP_ERROR(args) +#endif + +#if 0 +# ifdef DEBUG +# define NWRAP_DEBUG(args) DEBUG(0, args) +# else +# define NWRAP_DEBUG(args) printf args +# endif +#else +#define NWRAP_DEBUG(args) +#endif + +#if 0 +# ifdef DEBUG +# define NWRAP_VERBOSE(args) DEBUG(0, args) +# else +# define NWRAP_VERBOSE(args) printf args +# endif +#else +#define NWRAP_VERBOSE(args) +#endif + +struct nwrap_cache { + const char *path; + int fd; + struct stat st; + uint8_t *buf; + void *private_data; + bool (*parse_line)(struct nwrap_cache *, char *line); + void (*unload)(struct nwrap_cache *); +}; + +struct nwrap_pw { + struct nwrap_cache *cache; + + struct passwd *list; + int num; + int idx; +}; + +struct nwrap_cache __nwrap_cache_pw; +struct nwrap_pw nwrap_pw_global; + +static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line); +static void nwrap_pw_unload(struct nwrap_cache *nwrap); + +struct nwrap_gr { + struct nwrap_cache *cache; + + struct group *list; + int num; + int idx; +}; + +struct nwrap_cache __nwrap_cache_gr; +struct nwrap_gr nwrap_gr_global; + +static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line); +static void nwrap_gr_unload(struct nwrap_cache *nwrap); + +static void nwrap_init(void) +{ + static bool initialized; + + if (initialized) return; + initialized = true; + + nwrap_pw_global.cache = &__nwrap_cache_pw; + + nwrap_pw_global.cache->path = getenv("NSS_WRAPPER_PASSWD"); + nwrap_pw_global.cache->fd = -1; + nwrap_pw_global.cache->private_data = &nwrap_pw_global; + nwrap_pw_global.cache->parse_line = nwrap_pw_parse_line; + nwrap_pw_global.cache->unload = nwrap_pw_unload; + + nwrap_gr_global.cache = &__nwrap_cache_gr; + + nwrap_gr_global.cache->path = getenv("NSS_WRAPPER_GROUP"); + nwrap_gr_global.cache->fd = -1; + nwrap_gr_global.cache->private_data = &nwrap_gr_global; + nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line; + nwrap_gr_global.cache->unload = nwrap_gr_unload; +} + +static bool nwrap_enabled(void) +{ + nwrap_init(); + + if (!nwrap_pw_global.cache->path) { + return false; + } + if (nwrap_pw_global.cache->path[0] == '\0') { + return false; + } + if (!nwrap_gr_global.cache->path) { + return false; + } + if (nwrap_gr_global.cache->path[0] == '\0') { + return false; + } + + return true; +} + +static bool nwrap_parse_file(struct nwrap_cache *nwrap) +{ + int ret; + uint8_t *buf = NULL; + char *nline; + + if (nwrap->st.st_size == 0) { + NWRAP_DEBUG(("%s: size == 0\n", + __location__)); + goto done; + } + + if (nwrap->st.st_size > INT32_MAX) { + NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n", + __location__, (unsigned)nwrap->st.st_size)); + goto failed; + } + + ret = lseek(nwrap->fd, 0, SEEK_SET); + if (ret != 0) { + NWRAP_ERROR(("%s: lseek - %d\n",__location__,ret)); + goto failed; + } + + buf = (uint8_t *)malloc(nwrap->st.st_size + 1); + if (!buf) { + NWRAP_ERROR(("%s: malloc failed\n",__location__)); + goto failed; + } + + ret = read(nwrap->fd, buf, nwrap->st.st_size); + if (ret != nwrap->st.st_size) { + NWRAP_ERROR(("%s: read(%u) gave %d\n", + __location__, (unsigned)nwrap->st.st_size, ret)); + goto failed; + } + + buf[nwrap->st.st_size] = '\0'; + + nline = (char *)buf; + while (nline && nline[0]) { + char *line; + char *e; + bool ok; + + line = nline; + nline = NULL; + + e = strchr(line, '\n'); + if (e) { + e[0] = '\0'; + e++; + if (e[0] == '\r') { + e[0] = '\0'; + e++; + } + nline = e; + } + + NWRAP_VERBOSE(("%s:'%s'\n",__location__, line)); + + if (strlen(line) == 0) { + continue; + } + + ok = nwrap->parse_line(nwrap, line); + if (!ok) { + goto failed; + } + } + +done: + nwrap->buf = buf; + return true; + +failed: + if (buf) free(buf); + return false; +} + +static void nwrap_cache_unload(struct nwrap_cache *nwrap) +{ + nwrap->unload(nwrap); + + if (nwrap->buf) free(nwrap->buf); + + nwrap->buf = NULL; +} + +static void nwrap_cache_reload(struct nwrap_cache *nwrap) +{ + struct stat st; + int ret; + bool ok; + bool retried = false; + +reopen: + if (nwrap->fd < 0) { + nwrap->fd = open(nwrap->path, O_RDONLY); + if (nwrap->fd < 0) { + NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n", + __location__, + nwrap->path, nwrap->fd, + strerror(errno))); + return; + } + NWRAP_VERBOSE(("%s: open '%s'\n", __location__, nwrap->path)); + } + + ret = fstat(nwrap->fd, &st); + if (ret != 0) { + NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n", + __location__, + nwrap->path, + ret, strerror(errno))); + return; + } + + if (retried == false && st.st_nlink == 0) { + /* maybe someone has replaced the file... */ + NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n", + __location__, nwrap->path)); + retried = true; + memset(&nwrap->st, 0, sizeof(nwrap->st)); + close(nwrap->fd); + nwrap->fd = -1; + goto reopen; + } + + if (st.st_mtime == nwrap->st.st_mtime) { + NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n", + __location__, (unsigned)st.st_mtime)); + return; + } + NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n", + __location__, (unsigned)st.st_mtime, + (unsigned)nwrap->st.st_mtime)); + + nwrap->st = st; + + nwrap_cache_unload(nwrap); + + ok = nwrap_parse_file(nwrap); + if (!ok) { + NWRAP_ERROR(("%s: failed to reload %s\n", + __location__, nwrap->path)); + nwrap_cache_unload(nwrap); + } + NWRAP_DEBUG(("%s: reloaded %s\n", + __location__, nwrap->path)); +} + +/* + * the caller has to call nwrap_unload() on failure + */ +static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line) +{ + struct nwrap_pw *nwrap_pw; + char *c; + char *p; + char *e; + struct passwd *pw; + size_t list_size; + + nwrap_pw = (struct nwrap_pw *)nwrap->private_data; + + list_size = sizeof(*nwrap_pw->list) * (nwrap_pw->num+1); + pw = (struct passwd *)realloc(nwrap_pw->list, list_size); + if (!pw) { + NWRAP_ERROR(("%s:realloc(%u) failed\n", + __location__, list_size)); + return false; + } + nwrap_pw->list = pw; + + pw = &nwrap_pw->list[nwrap_pw->num]; + + c = line; + + /* name */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + pw->pw_name = c; + c = p; + + NWRAP_VERBOSE(("name[%s]\n", pw->pw_name)); + + /* password */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + pw->pw_passwd = c; + c = p; + + NWRAP_VERBOSE(("password[%s]\n", pw->pw_passwd)); + + /* uid */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + e = NULL; + pw->pw_uid = (uid_t)strtoul(c, &e, 10); + if (c == e) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + if (e == NULL) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + if (e[0] != '\0') { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + c = p; + + NWRAP_VERBOSE(("uid[%u]\n", pw->pw_uid)); + + /* gid */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + e = NULL; + pw->pw_gid = (gid_t)strtoul(c, &e, 10); + if (c == e) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + if (e == NULL) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + if (e[0] != '\0') { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + c = p; + + NWRAP_VERBOSE(("gid[%u]\n", pw->pw_gid)); + + /* gecos */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + pw->pw_gecos = c; + c = p; + + NWRAP_VERBOSE(("gecos[%s]\n", pw->pw_gecos)); + + /* dir */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:'%s'\n",__location__,c)); + return false; + } + *p = '\0'; + p++; + pw->pw_dir = c; + c = p; + + NWRAP_VERBOSE(("dir[%s]\n", pw->pw_dir)); + + /* shell */ + pw->pw_shell = c; + NWRAP_VERBOSE(("shell[%s]\n", pw->pw_shell)); + + NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n", + pw->pw_name, pw->pw_passwd, + pw->pw_uid, pw->pw_gid, + pw->pw_gecos, pw->pw_dir, pw->pw_shell)); + + nwrap_pw->num++; + return true; +} + +static void nwrap_pw_unload(struct nwrap_cache *nwrap) +{ + struct nwrap_pw *nwrap_pw; + nwrap_pw = (struct nwrap_pw *)nwrap->private_data; + + if (nwrap_pw->list) free(nwrap_pw->list); + + nwrap_pw->list = NULL; + nwrap_pw->num = 0; + nwrap_pw->idx = 0; +} + +static int nwrap_pw_copy_r(const struct passwd *src, struct passwd *dst, + char *buf, size_t buflen, struct passwd **dstp) +{ + char *first; + char *last; + off_t ofs; + + first = src->pw_name; + + last = src->pw_shell; + while (*last) last++; + + ofs = PTR_DIFF(last + 1, first); + + if (ofs > buflen) { + return ERANGE; + } + + memcpy(buf, first, ofs); + + ofs = PTR_DIFF(src->pw_name, first); + dst->pw_name = buf + ofs; + ofs = PTR_DIFF(src->pw_passwd, first); + dst->pw_passwd = buf + ofs; + dst->pw_uid = src->pw_uid; + dst->pw_gid = src->pw_gid; + ofs = PTR_DIFF(src->pw_gecos, first); + dst->pw_gecos = buf + ofs; + ofs = PTR_DIFF(src->pw_dir, first); + dst->pw_dir = buf + ofs; + ofs = PTR_DIFF(src->pw_shell, first); + dst->pw_shell = buf + ofs; + + if (dstp) { + *dstp = dst; + } + + return 0; +} + +/* + * the caller has to call nwrap_unload() on failure + */ +static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line) +{ + struct nwrap_gr *nwrap_gr; + char *c; + char *p; + char *e; + struct group *gr; + size_t list_size; + unsigned nummem; + + nwrap_gr = (struct nwrap_gr *)nwrap->private_data; + + list_size = sizeof(*nwrap_gr->list) * (nwrap_gr->num+1); + gr = (struct group *)realloc(nwrap_gr->list, list_size); + if (!gr) { + NWRAP_ERROR(("%s:realloc failed\n",__location__)); + return false; + } + nwrap_gr->list = gr; + + gr = &nwrap_gr->list[nwrap_gr->num]; + + c = line; + + /* name */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + gr->gr_name = c; + c = p; + + NWRAP_VERBOSE(("name[%s]\n", gr->gr_name)); + + /* password */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + gr->gr_passwd = c; + c = p; + + NWRAP_VERBOSE(("password[%s]\n", gr->gr_passwd)); + + /* gid */ + p = strchr(c, ':'); + if (!p) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", + __location__, line, c)); + return false; + } + *p = '\0'; + p++; + e = NULL; + gr->gr_gid = (gid_t)strtoul(c, &e, 10); + if (c == e) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + if (e == NULL) { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + if (e[0] != '\0') { + NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", + __location__, line, c, strerror(errno))); + return false; + } + c = p; + + NWRAP_VERBOSE(("gid[%u]\n", gr->gr_gid)); + + /* members */ + gr->gr_mem = (char **)malloc(sizeof(char *)); + if (!gr->gr_mem) { + NWRAP_ERROR(("%s:calloc failed\n",__location__)); + return false; + } + gr->gr_mem[0] = NULL; + + for(nummem=0; p; nummem++) { + char **m; + size_t m_size; + c = p; + p = strchr(c, ','); + if (p) { + *p = '\0'; + p++; + } + + if (strlen(c) == 0) { + break; + } + + m_size = sizeof(char *) * (nummem+2); + m = (char **)realloc(gr->gr_mem, m_size); + if (!m) { + NWRAP_ERROR(("%s:realloc(%u) failed\n", + __location__, m_size)); + return false; + } + gr->gr_mem = m; + gr->gr_mem[nummem] = c; + gr->gr_mem[nummem+1] = NULL; + + NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem, gr->gr_mem[nummem])); + } + + NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n", + gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem)); + + nwrap_gr->num++; + return true; +} + +static void nwrap_gr_unload(struct nwrap_cache *nwrap) +{ + int i; + struct nwrap_gr *nwrap_gr; + nwrap_gr = (struct nwrap_gr *)nwrap->private_data; + + if (nwrap_gr->list) { + for (i=0; i < nwrap_gr->num; i++) { + if (nwrap_gr->list[i].gr_mem) { + free(nwrap_gr->list[i].gr_mem); + } + } + free(nwrap_gr->list); + } + + nwrap_gr->list = NULL; + nwrap_gr->num = 0; + nwrap_gr->idx = 0; +} + +static int nwrap_gr_copy_r(const struct group *src, struct group *dst, + char *buf, size_t buflen, struct group **dstp) +{ + char *first; + char **lastm; + char *last; + off_t ofsb; + off_t ofsm; + off_t ofs; + unsigned i; + + first = src->gr_name; + + lastm = src->gr_mem; + while (*lastm) lastm++; + + last = *lastm; + while (*last) last++; + + ofsb = PTR_DIFF(last + 1, first); + ofsm = PTR_DIFF(lastm + 1, src->gr_mem); + + if ((ofsb + ofsm) > buflen) { + return ERANGE; + } + + memcpy(buf, first, ofsb); + memcpy(buf + ofsb, src->gr_mem, ofsm); + + ofs = PTR_DIFF(src->gr_name, first); + dst->gr_name = buf + ofs; + ofs = PTR_DIFF(src->gr_passwd, first); + dst->gr_passwd = buf + ofs; + dst->gr_gid = src->gr_gid; + + dst->gr_mem = (char **)(buf + ofsb); + for (i=0; src->gr_mem[i]; i++) { + ofs = PTR_DIFF(src->gr_mem[i], first); + dst->gr_mem[i] = buf + ofs; + } + + if (dstp) { + *dstp = dst; + } + + return 0; +} + +/* user functions */ +_PUBLIC_ struct passwd *nwrap_getpwnam(const char *name) +{ + int i; + + if (!nwrap_enabled()) { + return real_getpwnam(name); + } + + nwrap_cache_reload(nwrap_pw_global.cache); + + for (i=0; i= nwrap_pw_global.num) { + errno = ENOENT; + return NULL; + } + + pw = &nwrap_pw_global.list[nwrap_pw_global.idx++]; + + NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n", + __location__, pw->pw_name, pw->pw_uid)); + + return pw; +} + +_PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf, + size_t buflen, struct passwd **pwdstp) +{ + struct passwd *pw; + + if (!nwrap_enabled()) { +#ifdef SOLARIS_GETPWENT_R + pw = real_getpwent_r(pwdst, buf, buflen); + if (!pw) { + if (errno == 0) { + return ENOENT; + } + return errno; + } + if (pwdstp) { + *pwdstp = pw; + } + return 0; +#else + return real_getpwent_r(pwdst, buf, buflen, pwdstp); +#endif + } + + pw = nwrap_getpwent(); + if (!pw) { + if (errno == 0) { + return ENOENT; + } + return errno; + } + + return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp); +} + +_PUBLIC_ void nwrap_endpwent(void) +{ + if (!nwrap_enabled()) { + real_endpwent(); + } + + nwrap_pw_global.idx = 0; +} + +/* misc functions */ +_PUBLIC_ int nwrap_initgroups(const char *user, gid_t group) +{ + if (!nwrap_enabled()) { + return real_initgroups(user, group); + } + + /* TODO: maybe we should also fake this... */ + return EPERM; +} + +/* group functions */ +_PUBLIC_ struct group *nwrap_getgrnam(const char *name) +{ + int i; + + if (!nwrap_enabled()) { + return real_getgrnam(name); + } + + nwrap_cache_reload(nwrap_gr_global.cache); + + for (i=0; i= nwrap_gr_global.num) { + errno = ENOENT; + return NULL; + } + + gr = &nwrap_gr_global.list[nwrap_gr_global.idx++]; + + NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n", + __location__, gr->gr_name, gr->gr_gid)); + + return gr; +} + +_PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf, + size_t buflen, struct group **grdstp) +{ + struct group *gr; + + if (!nwrap_enabled()) { +#ifdef SOLARIS_GETGRENT_R + gr = real_getgrent_r(grdst, buf, buflen); + if (!gr) { + if (errno == 0) { + return ENOENT; + } + return errno; + } + if (grdstp) { + *grdstp = gr; + } + return 0; +#else + return real_getgrent_r(grdst, buf, buflen, grdstp); +#endif + } + + gr = nwrap_getgrent(); + if (!gr) { + if (errno == 0) { + return ENOENT; + } + return errno; + } + + return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp); +} + +_PUBLIC_ void nwrap_endgrent(void) +{ + if (!nwrap_enabled()) { + real_endgrent(); + } + + nwrap_gr_global.idx = 0; +} diff --git a/lib/nss_wrapper/nss_wrapper.h b/lib/nss_wrapper/nss_wrapper.h new file mode 100644 index 0000000000..35a47348a8 --- /dev/null +++ b/lib/nss_wrapper/nss_wrapper.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) Stefan Metzmacher 2007 + * + * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. + */ + +#ifndef __NSS_WRAPPER_H__ +#define __NSS_WRAPPER_H__ + +struct passwd *nwrap_getpwnam(const char *name); +int nwrap_getpwnam_r(const char *name, struct passwd *pwbuf, + char *buf, size_t buflen, struct passwd **pwbufp); +struct passwd *nwrap_getpwuid(uid_t uid); +int nwrap_getpwuid_r(uid_t uid, struct passwd *pwbuf, + char *buf, size_t buflen, struct passwd **pwbufp); +void nwrap_setpwent(void); +struct passwd *nwrap_getpwent(void); +int nwrap_getpwent_r(struct passwd *pwbuf, char *buf, + size_t buflen, struct passwd **pwbufp); +void nwrap_endpwent(void); +int nwrap_initgroups(const char *user, gid_t group); +struct group *nwrap_getgrnam(const char *name); +int nwrap_getgrnam_r(const char *name, struct group *gbuf, + char *buf, size_t buflen, struct group **gbufp); +struct group *nwrap_getgrgid(gid_t gid); +int nwrap_getgrgid_r(gid_t gid, struct group *gbuf, + char *buf, size_t buflen, struct group **gbufp); +void nwrap_setgrent(void); +struct group *nwrap_getgrent(void); +int nwrap_getgrent_r(struct group *gbuf, char *buf, + size_t buflen, struct group **gbufp); +void nwrap_endgrent(void); + +#ifdef NSS_WRAPPER_REPLACE + +#ifdef getpwnam +#undef getpwnam +#endif +#define getpwnam nwrap_getpwnam + +#ifdef getpwnam_r +#undef getpwnam_r +#endif +#define getpwnam_r nwrap_getpwnam_r + +#ifdef getpwuid +#undef getpwuid +#endif +#define getpwuid nwrap_getpwuid + +#ifdef getpwuid_r +#undef getpwuid_r +#endif +#define getpwuid_r nwrap_getpwuid_r + +#ifdef setpwent +#undef setpwent +#endif +#define setpwent nwrap_setpwent + +#ifdef getpwent +#undef getpwent +#endif +#define getpwent nwrap_getpwent + +#ifdef getpwent_r +#undef getpwent_r +#endif +#define getpwent_r nwrap_getpwent_r + +#ifdef endpwent +#undef endpwent +#endif +#define endpwent nwrap_endpwent + +#ifdef getgrlst +#undef getgrlst +#endif +#define getgrlst __none_nwrap_getgrlst + +#ifdef getgrlst_r +#undef getgrlst_r +#endif +#define getgrlst_r __none_nwrap_getgrlst_r + +#ifdef initgroups_dyn +#undef initgroups_dyn +#endif +#define initgroups_dyn __none_nwrap_initgroups_dyn + +#ifdef initgroups +#undef initgroups +#endif +#define initgroups nwrap_initgroups + +#ifdef getgrnam +#undef getgrnam +#endif +#define getgrnam nwrap_getgrnam + +#ifdef getgrnam_r +#undef getgrnam_r +#endif +#define getgrnam_r nwrap_getgrnam_r + +#ifdef getgrgid +#undef getgrgid +#endif +#define getgrgid nwrap_getgrgid + +#ifdef getgrgid_r +#undef getgrgid_r +#endif +#define getgrgid_r nwrap_getgrgid_r + +#ifdef setgrent +#undef setgrent +#endif +#define setgrent nwrap_setgrent + +#ifdef getgrent +#undef getgrent +#endif +#define getgrent nwrap_getgrent + +#ifdef getgrent_r +#undef getgrent_r +#endif +#define getgrent_r nwrap_getgrent_r + +#ifdef endgrent +#undef endgrent +#endif +#define endgrent nwrap_endgrent + +#endif /* NSS_WRAPPER_REPLACE */ + +#endif /* __NSS_WRAPPER_H__ */ diff --git a/lib/nss_wrapper/nss_wrapper.pl b/lib/nss_wrapper/nss_wrapper.pl new file mode 100644 index 0000000000..b1c9be5365 --- /dev/null +++ b/lib/nss_wrapper/nss_wrapper.pl @@ -0,0 +1,265 @@ +#!/usr/bin/perl +# + +use strict; + +use Getopt::Long; +use Cwd qw(abs_path); + +my $opt_help = 0; +my $opt_path = undef; +my $opt_action = undef; +my $opt_type = undef; +my $opt_name = undef; + +my $passwdfn = undef; +my $groupfn = undef; +my $actionfn = undef; + +sub passwd_add($$); +sub passwd_delete($$); +sub group_add($$); +sub group_delete($$); + +my $result = GetOptions( + 'help|h|?' => \$opt_help, + 'path=s' => \$opt_path, + 'action=s' => \$opt_action, + 'type=s' => \$opt_type, + 'name=s' => \$opt_name +); + +sub usage($;$) +{ + my ($ret, $msg) = @_; + + print $msg."\n\n" if defined($msg); + + print "usage: + + --help|-h|-? Show this help. + + --path Path of the 'passwd' or 'group' file. + + --type Only 'passwd' is supported yet, + but 'group' and maybe 'member' will be added + in future. + + --action 'add' or 'delete'. + + --name The name of the object. +"; + exit($ret); +} + +usage(1) if (not $result); + +usage(0) if ($opt_help); + +if (not defined($opt_path)) { + usage(1, "missing: --path "); +} +if ($opt_path eq "" or $opt_path eq "/") { + usage(1, "invalid: --path : '$opt_path'"); +} +my $opt_fullpath = abs_path($opt_path); +if (not defined($opt_fullpath)) { + usage(1, "invalid: --path : '$opt_path'"); +} + + +if (not defined($opt_action)) { + usage(1, "missing: --action [add|delete]"); +} +if ($opt_action eq "add") { + $passwdfn = \&passwd_add; + $groupfn = \&group_add; +} elsif ($opt_action eq "delete") { + $passwdfn = \&passwd_delete; + $groupfn = \&group_delete; +} else { + usage(1, "invalid: --action [add|delete]: '$opt_action'"); +} + +if (not defined($opt_type)) { + usage(1, "missing: --type [passwd|group]"); +} +if ($opt_type eq "passwd") { + $actionfn = $passwdfn; +} elsif ($opt_type eq "group") { + $actionfn = $groupfn; +} else { + usage(1, "invalid: --type [passwd|group]: '$opt_type'") +} + +if (not defined($opt_name)) { + usage(1, "missing: --name "); +} +if ($opt_name eq "") { + usage(1, "invalid: --name "); +} + +exit $actionfn->($opt_fullpath, $opt_name); + +sub passwd_add_entry($$); + +sub passwd_load($) +{ + my ($path) = @_; + my @lines; + my $passwd = undef; + + open(PWD, "<$path") or die("Unable to open '$path' for read"); + @lines = ; + close(PWD); + + $passwd->{array} = (); + $passwd->{name} = {}; + $passwd->{uid} = {}; + $passwd->{path} = $path; + + foreach my $line (@lines) { + passwd_add_entry($passwd, $line); + } + + return $passwd; +} + +sub passwd_lookup_name($$) +{ + my ($passwd, $name) = @_; + + return undef unless defined($passwd->{name}{$name}); + + return $passwd->{name}{$name}; +} + +sub passwd_lookup_uid($$) +{ + my ($passwd, $uid) = @_; + + return undef unless defined($passwd->{uid}{$uid}); + + return $passwd->{uid}{$uid}; +} + +sub passwd_get_free_uid($) +{ + my ($passwd) = @_; + my $uid = 1000; + + while (passwd_lookup_uid($passwd, $uid)) { + $uid++; + } + + return $uid; +} + +sub passwd_add_entry($$) +{ + my ($passwd, $str) = @_; + + chomp $str; + my @e = split(':', $str); + + push(@{$passwd->{array}}, \@e); + $passwd->{name}{$e[0]} = \@e; + $passwd->{uid}{$e[2]} = \@e; +} + +sub passwd_remove_entry($$) +{ + my ($passwd, $eref) = @_; + + for(my $i; defined($passwd->{array}[$i]); $i++) { + if ($eref == $passwd->{array}[$i]) { + $passwd->{array}[$i] = undef; + } + } + + delete $passwd->{name}{${$eref}[0]}; + delete $passwd->{uid}{${$eref}[2]}; +} + +sub passwd_save($) +{ + my ($passwd) = @_; + my @lines = (); + my $path = $passwd->{path}; + my $tmppath = $path.$$; + + foreach my $eref (@{$passwd->{array}}) { + next unless defined($eref); + + my $line = join(':', @{$eref}); + push(@lines, $line); + } + + open(PWD, ">$tmppath") or die("Unable to open '$tmppath' for write"); + print PWD join("\n", @lines)."\n"; + close(PWD); + rename($tmppath, $path) or die("Unable to rename $tmppath => $path"); +} + +sub passwd_add($$) +{ + my ($path, $name) = @_; + + #print "passwd_add: '$name' in '$path'\n"; + + my $passwd = passwd_load($path); + + my $e = passwd_lookup_name($passwd, $name); + die("account[$name] already exists in '$path'") if defined($e); + + my $uid = passwd_get_free_uid($passwd); + my $gid = 65534;# nogroup gid + + my $pwent = $name.":x:".$uid.":".$gid.":".$name." gecos:/nodir:/bin/false"; + + passwd_add_entry($passwd, $pwent); + + passwd_save($passwd); + + return 0; +} + +sub passwd_delete($$) +{ + my ($path, $name) = @_; + + #print "passwd_delete: '$name' in '$path'\n"; + + my $passwd = passwd_load($path); + + my $e = passwd_lookup_name($passwd, $name); + die("account[$name] does not exists in '$path'") unless defined($e); + + passwd_remove_entry($passwd, $e); + + passwd_save($passwd); + + return 0; +} + +sub group_add($$) +{ + my ($path, $name) = @_; + + #print "group_add: '$name' in '$path'\n"; + + die("group_add: not implemented yet!"); + + return 0; +} + +sub group_delete($$) +{ + my ($path, $name) = @_; + + #print "group_delete: '$name' in '$path'\n"; + + die("group_delete: not implemented yet!"); + + return 0; +} diff --git a/lib/popt/CHANGES b/lib/popt/CHANGES new file mode 100644 index 0000000000..db16a5fdd0 --- /dev/null +++ b/lib/popt/CHANGES @@ -0,0 +1,46 @@ +1.5 -> 1.6 + - add ability to perform callbacks for every, not just first, match. + +1.3 -> 1.5 + - heavy dose of const's + - poptParseArgvString() now NULL terminates the list + +1.2.3 -> 1.3 + - added support for single - + - misc bug fixes + - portability improvements + +1.2.2 -> 1.2.3 + - fixed memset() in help message generation (Dale Hawkins) + - added extern "C" stuff to popt.h for C++ compilers (Dale Hawkins) + - const'ified poptParseArgvString (Jeff Garzik) + +1.2.1 -> 1.2.2 + - fixed bug in chaind alias happens which seems to have only + affected --triggers in rpm + - added POPT_ARG_VAL + - popt.3 installed by default + +1.2 -> 1.2.1 + - added POPT_ARG_INTL_DOMAIN (Elliot Lee) + - updated Makefile's to be more GNUish (Elliot Lee) + +1.1 -> 1.2 + - added popt.3 man page (Robert Lynch) + - don't use mmap anymore (its lack of portability isn't worth the + trouble) + - added test script + - added support for exec + - removed support for *_POPT_ALIASES env variable -- it was a bad + idea + - reorganized into multiple source files + - added automatic help generation, POPT_AUTOHELP + - added table callbacks + - added table inclusion + - updated man page for new features + - added test scripts + +1.0 -> 1.1 + - moved to autoconf (Fred Fish) + - added STRERROR replacement (Norbert Warmuth) + - added const keywords (Bruce Perens) diff --git a/lib/popt/COPYING b/lib/popt/COPYING new file mode 100644 index 0000000000..b4c7ca876c --- /dev/null +++ b/lib/popt/COPYING @@ -0,0 +1,22 @@ +Copyright (c) 1998 Red Hat Software + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in 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: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +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 +X CONSORTIUM 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. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. diff --git a/lib/popt/README b/lib/popt/README new file mode 100644 index 0000000000..0b5205bfdd --- /dev/null +++ b/lib/popt/README @@ -0,0 +1,18 @@ +This is the popt command line option parsing library. While it is similiar +to getopt(3), it contains a number of enhancements, including: + + 1) popt is fully reentrant + 2) popt can parse arbitrary argv[] style arrays while + getopt(2) makes this quite difficult + 3) popt allows users to alias command line arguments + 4) popt provides convience functions for parsing strings + into argv[] style arrays + +popt is used by rpm, the Red Hat install program, and many other Red Hat +utilities, all of which provide excellent examples of how to use popt. +Complete documentation on popt is available in popt.ps (included in this +tarball), which is excerpted with permission from the book "Linux +Application Development" by Michael K. Johnson and Erik Troan (availble +from Addison Wesley in May, 1998). + +Comments on popt should be addressed to ewt@redhat.com. diff --git a/lib/popt/config.mk b/lib/popt/config.mk new file mode 100644 index 0000000000..04cc2c7ea5 --- /dev/null +++ b/lib/popt/config.mk @@ -0,0 +1,5 @@ +[SUBSYSTEM::LIBPOPT] +CFLAGS = -I$(poptsrcdir) + +LIBPOPT_OBJ_FILES = $(addprefix $(poptsrcdir)/, findme.o popt.o poptconfig.o popthelp.o poptparse.o) + diff --git a/lib/popt/dummy.in b/lib/popt/dummy.in new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/popt/findme.c b/lib/popt/findme.c new file mode 100644 index 0000000000..b28981ba1f --- /dev/null +++ b/lib/popt/findme.c @@ -0,0 +1,50 @@ +/** \ingroup popt + * \file popt/findme.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#include "system.h" +#include "findme.h" + +const char * findProgramPath(const char * argv0) { + char * path = getenv("PATH"); + char * pathbuf; + char * start, * chptr; + char * buf; + + if (argv0 == NULL) return NULL; /* XXX can't happen */ + /* If there is a / in the argv[0], it has to be an absolute path */ + if (strchr(argv0, '/')) + return xstrdup(argv0); + + if (path == NULL) return NULL; + + start = pathbuf = (char *)alloca(strlen(path) + 1); + buf = (char *)malloc(strlen(path) + strlen(argv0) + sizeof("/")); + if (buf == NULL) return NULL; /* XXX can't happen */ + strcpy(pathbuf, path); + + chptr = NULL; + /*@-branchstate@*/ + do { + if ((chptr = strchr(start, ':'))) + *chptr = '\0'; + sprintf(buf, "%s/%s", start, argv0); + + if (!access(buf, X_OK)) + return buf; + + if (chptr) + start = chptr + 1; + else + start = NULL; + } while (start && *start); + /*@=branchstate@*/ + + free(buf); + + return NULL; +} diff --git a/lib/popt/findme.h b/lib/popt/findme.h new file mode 100644 index 0000000000..a016b867ea --- /dev/null +++ b/lib/popt/findme.h @@ -0,0 +1,20 @@ +/** \ingroup popt + * \file popt/findme.h + */ + +/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#ifndef H_FINDME +#define H_FINDME + +/** + * Return absolute path to executable by searching PATH. + * @param argv0 name of executable + * @return (malloc'd) absolute path to executable (or NULL) + */ +/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0) + /*@*/; + +#endif diff --git a/lib/popt/libpopt.m4 b/lib/popt/libpopt.m4 new file mode 100644 index 0000000000..79980d1d6b --- /dev/null +++ b/lib/popt/libpopt.m4 @@ -0,0 +1,43 @@ +dnl Check to see if we should use the included popt + +INCLUDED_POPT=auto +AC_ARG_WITH(included-popt, +[ --with-included-popt use bundled popt library, not from system], +[ INCLUDED_POPT=$withval ]) + +AC_SUBST(POPT_LIBS) +AC_SUBST(POPT_CFLAGS) + +if test x"$INCLUDED_POPT" != x"yes"; then + AC_CHECK_HEADERS(popt.h) + AC_CHECK_LIB(popt, poptGetContext, [ POPT_LIBS="-lpopt" ]) + if test x"$ac_cv_header_popt_h" = x"no" -o x"$ac_cv_lib_popt_poptGetContext" = x"no"; then + INCLUDED_POPT=yes + POPT_CFLAGS="" + else + INCLUDED_POPT=no + fi +fi + +AC_MSG_CHECKING(whether to use included popt) +AC_MSG_RESULT($INCLUDED_POPT) +if test x"$INCLUDED_POPT" != x"no"; then + dnl find the popt sources. This is meant to work both for + dnl popt standalone builds, and builds of packages using popt + poptdir="" + poptpaths="$srcdir $srcdir/lib/popt $srcdir/popt $srcdir/../popt" + for d in $poptpaths; do + if test -f "$d/popt.c"; then + poptdir="$d" + POPT_CFLAGS="-I$d" + AC_SUBST(poptdir) + break + fi + done + if test x"$poptdir" = "x"; then + AC_MSG_ERROR([cannot find popt source in $poptpaths]) + fi + POPT_OBJ="popt.o findme.o poptconfig.o popthelp.o poptparse.o" + AC_SUBST(POPT_OBJ) + AC_CHECK_HEADERS([float.h alloca.h]) +fi diff --git a/lib/popt/popt.c b/lib/popt/popt.c new file mode 100644 index 0000000000..d9e8411b9f --- /dev/null +++ b/lib/popt/popt.c @@ -0,0 +1,1249 @@ +/** \ingroup popt + * \file popt/popt.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist */ + +#undef MYDEBUG + +#include "system.h" + +#if HAVE_FLOAT_H +#include +#endif +#include + +#include "findme.h" +#include "poptint.h" + +#ifdef MYDEBUG +/*@unchecked@*/ +int _popt_debug = 0; +#endif + +#ifndef HAVE_STRERROR +static char * strerror(int errno) { + extern int sys_nerr; + extern char * sys_errlist[]; + + if ((0 <= errno) && (errno < sys_nerr)) + return sys_errlist[errno]; + else + return POPT_("unknown errno"); +} +#endif + +#ifdef MYDEBUG +/*@unused@*/ static void prtcon(const char *msg, poptContext con) +{ + if (msg) fprintf(stderr, "%s", msg); + fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n", + con, con->os, + (con->os->nextCharArg ? con->os->nextCharArg : ""), + (con->os->nextArg ? con->os->nextArg : ""), + con->os->next, + (con->os->argv && con->os->argv[con->os->next] + ? con->os->argv[con->os->next] : "")); +} +#endif + +void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) +{ + con->execPath = (const char *)_free(con->execPath); + con->execPath = xstrdup(path); + con->execAbsolute = allowAbsolute; + /*@-nullstate@*/ /* LCL: con->execPath can be NULL? */ + return; + /*@=nullstate@*/ +} + +static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt) + /*@globals internalState@*/ + /*@modifies internalState@*/ +{ + if (opt != NULL) + for (; opt->longName || opt->shortName || opt->arg; opt++) { + if (opt->arg == NULL) continue; /* XXX program error. */ + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { + /* Recurse on included sub-tables. */ + invokeCallbacksPRE(con, (const struct poptOption *)opt->arg); + } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && + (opt->argInfo & POPT_CBFLAG_PRE)) + { /*@-castfcnptr@*/ + poptCallbackType cb = (poptCallbackType)opt->arg; + /*@=castfcnptr@*/ + /* Perform callback. */ + /*@-moduncon -noeffectuncon @*/ + cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip); + /*@=moduncon =noeffectuncon @*/ + } + } +} + +static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt) + /*@globals internalState@*/ + /*@modifies internalState@*/ +{ + if (opt != NULL) + for (; opt->longName || opt->shortName || opt->arg; opt++) { + if (opt->arg == NULL) continue; /* XXX program error. */ + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { + /* Recurse on included sub-tables. */ + invokeCallbacksPOST(con, (const struct poptOption *)opt->arg); + } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && + (opt->argInfo & POPT_CBFLAG_POST)) + { /*@-castfcnptr@*/ + poptCallbackType cb = (poptCallbackType)opt->arg; + /*@=castfcnptr@*/ + /* Perform callback. */ + /*@-moduncon -noeffectuncon @*/ + cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip); + /*@=moduncon =noeffectuncon @*/ + } + } +} + +static void invokeCallbacksOPTION(poptContext con, + const struct poptOption * opt, + const struct poptOption * myOpt, + /*@null@*/ const void * myData, int shorty) + /*@globals internalState@*/ + /*@modifies internalState@*/ +{ + const struct poptOption * cbopt = NULL; + + if (opt != NULL) + for (; opt->longName || opt->shortName || opt->arg; opt++) { + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { + /* Recurse on included sub-tables. */ + if (opt->arg != NULL) /* XXX program error */ + invokeCallbacksOPTION(con, (const struct poptOption *)opt->arg, + myOpt, myData, shorty); + } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && + !(opt->argInfo & POPT_CBFLAG_SKIPOPTION)) { + /* Save callback info. */ + cbopt = opt; + } else if (cbopt != NULL && + ((myOpt->shortName && opt->shortName && shorty && + myOpt->shortName == opt->shortName) || + (myOpt->longName && opt->longName && + /*@-nullpass@*/ /* LCL: opt->longName != NULL */ + !strcmp(myOpt->longName, opt->longName))) + /*@=nullpass@*/ + ) + { /*@-castfcnptr@*/ + poptCallbackType cb = (poptCallbackType)cbopt->arg; + /*@=castfcnptr@*/ + const void * cbData = (cbopt->descrip ? cbopt->descrip : myData); + /* Perform callback. */ + if (cb != NULL) { /* XXX program error */ + /*@-moduncon -noeffectuncon @*/ + cb(con, POPT_CALLBACK_REASON_OPTION, myOpt, + con->os->nextArg, cbData); + /*@=moduncon =noeffectuncon @*/ + } + /* Terminate (unless explcitly continuing). */ + if (!(cbopt->argInfo & POPT_CBFLAG_CONTINUE)) + return; + } + } +} + +poptContext poptGetContext(const char * name, int argc, const char ** argv, + const struct poptOption * options, int flags) +{ + poptContext con = (poptContext)malloc(sizeof(*con)); + + if (con == NULL) return NULL; /* XXX can't happen */ + memset(con, 0, sizeof(*con)); + + con->os = con->optionStack; + con->os->argc = argc; + /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ + con->os->argv = argv; + /*@=dependenttrans =assignexpose@*/ + con->os->argb = NULL; + + if (!(flags & POPT_CONTEXT_KEEP_FIRST)) + con->os->next = 1; /* skip argv[0] */ + + con->leftovers = (const char **)calloc( (argc + 1), + sizeof(*con->leftovers) ); + /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ + con->options = options; + /*@=dependenttrans =assignexpose@*/ + con->aliases = NULL; + con->numAliases = 0; + con->flags = flags; + con->execs = NULL; + con->numExecs = 0; + con->finalArgvAlloced = argc * 2; + con->finalArgv = (const char **)calloc( con->finalArgvAlloced, + sizeof(*con->finalArgv) ); + con->execAbsolute = 1; + con->arg_strip = NULL; + + if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) + con->flags |= POPT_CONTEXT_POSIXMEHARDER; + + if (name) { + char * t = (char *)malloc(strlen(name) + 1); + if (t) con->appName = strcpy(t, name); + } + + /*@-internalglobs@*/ + invokeCallbacksPRE(con, con->options); + /*@=internalglobs@*/ + + return con; +} + +static void cleanOSE(/*@special@*/ struct optionStackEntry *os) + /*@uses os @*/ + /*@releases os->nextArg, os->argv, os->argb @*/ + /*@modifies os @*/ +{ + os->nextArg = (const char *)_free(os->nextArg); + os->argv = (const char **)_free(os->argv); + os->argb = (pbm_set *)PBM_FREE(os->argb); +} + +/*@-boundswrite@*/ +void poptResetContext(poptContext con) +{ + int i; + + if (con == NULL) return; + while (con->os > con->optionStack) { + cleanOSE(con->os--); + } + con->os->argb = (pbm_set *)PBM_FREE(con->os->argb); + con->os->currAlias = NULL; + con->os->nextCharArg = NULL; + con->os->nextArg = NULL; + con->os->next = 1; /* skip argv[0] */ + + con->numLeftovers = 0; + con->nextLeftover = 0; + con->restLeftover = 0; + con->doExec = NULL; + + if (con->finalArgv != NULL) + for (i = 0; i < con->finalArgvCount; i++) { + /*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */ + con->finalArgv[i] = (const char *)_free(con->finalArgv[i]); + /*@=unqualifiedtrans@*/ + } + + con->finalArgvCount = 0; + con->arg_strip = ( pbm_set *)PBM_FREE(con->arg_strip); + /*@-nullstate@*/ /* FIX: con->finalArgv != NULL */ + return; + /*@=nullstate@*/ +} +/*@=boundswrite@*/ + +/* Only one of longName, shortName should be set, not both. */ +/*@-boundswrite@*/ +static int handleExec(/*@special@*/ poptContext con, + /*@null@*/ const char * longName, char shortName) + /*@uses con->execs, con->numExecs, con->flags, con->doExec, + con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/ + /*@modifies con @*/ +{ + poptItem item; + int i; + + if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */ + return 0; + + for (i = con->numExecs - 1; i >= 0; i--) { + item = con->execs + i; + if (longName && !(item->option.longName && + !strcmp(longName, item->option.longName))) + continue; + else if (shortName != item->option.shortName) + continue; + break; + } + if (i < 0) return 0; + + + if (con->flags & POPT_CONTEXT_NO_EXEC) + return 1; + + if (con->doExec == NULL) { + con->doExec = con->execs + i; + return 1; + } + + /* We already have an exec to do; remember this option for next + time 'round */ + if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { + con->finalArgvAlloced += 10; + con->finalArgv = (const char **)realloc(con->finalArgv, + sizeof(*con->finalArgv) * con->finalArgvAlloced); + } + + i = con->finalArgvCount++; + if (con->finalArgv != NULL) /* XXX can't happen */ + { char *s = (char *)malloc((longName ? strlen(longName) : 0) + 3); + if (s != NULL) { /* XXX can't happen */ + if (longName) + sprintf(s, "--%s", longName); + else + sprintf(s, "-%c", shortName); + con->finalArgv[i] = s; + } else + con->finalArgv[i] = NULL; + } + + /*@-nullstate@*/ /* FIX: con->finalArgv[] == NULL */ + return 1; + /*@=nullstate@*/ +} +/*@=boundswrite@*/ + +/* Only one of longName, shortName may be set at a time */ +static int handleAlias(/*@special@*/ poptContext con, + /*@null@*/ const char * longName, char shortName, + /*@exposed@*/ /*@null@*/ const char * nextCharArg) + /*@uses con->aliases, con->numAliases, con->optionStack, con->os, + con->os->currAlias, con->os->currAlias->option.longName @*/ + /*@modifies con @*/ +{ + poptItem item = con->os->currAlias; + int rc; + int i; + + if (item) { + if (longName && (item->option.longName && + !strcmp(longName, item->option.longName))) + return 0; + if (shortName && shortName == item->option.shortName) + return 0; + } + + if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */ + return 0; + + for (i = con->numAliases - 1; i >= 0; i--) { + item = con->aliases + i; + if (longName && !(item->option.longName && + !strcmp(longName, item->option.longName))) + continue; + else if (shortName != item->option.shortName) + continue; + break; + } + if (i < 0) return 0; + + if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) + return POPT_ERROR_OPTSTOODEEP; + +/*@-boundsread@*/ + if (nextCharArg && *nextCharArg) + con->os->nextCharArg = nextCharArg; +/*@=boundsread@*/ + + con->os++; + con->os->next = 0; + con->os->stuffed = 0; + con->os->nextArg = NULL; + con->os->nextCharArg = NULL; + con->os->currAlias = con->aliases + i; + rc = poptDupArgv(con->os->currAlias->argc, con->os->currAlias->argv, + &con->os->argc, &con->os->argv); + con->os->argb = NULL; + + return (rc ? rc : 1); +} + +/*@-bounds -boundswrite @*/ +static int execCommand(poptContext con) + /*@globals internalState @*/ + /*@modifies internalState @*/ +{ + poptItem item = con->doExec; + const char ** argv; + int argc = 0; + int rc; + + if (item == NULL) /*XXX can't happen*/ + return POPT_ERROR_NOARG; + + if (item->argv == NULL || item->argc < 1 || + (!con->execAbsolute && strchr(item->argv[0], '/'))) + return POPT_ERROR_NOARG; + + argv = (const char **)malloc( + sizeof(*argv) * (6 + item->argc + con->numLeftovers + con->finalArgvCount)); + if (argv == NULL) return POPT_ERROR_MALLOC; /* XXX can't happen */ + + if (!strchr(item->argv[0], '/') && con->execPath) { + char *s = (char *)alloca( + strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/")); + sprintf(s, "%s/%s", con->execPath, item->argv[0]); + argv[argc] = s; + } else { + argv[argc] = findProgramPath(item->argv[0]); + } + if (argv[argc++] == NULL) return POPT_ERROR_NOARG; + + if (item->argc > 1) { + memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); + argc += (item->argc - 1); + } + + if (con->finalArgv != NULL && con->finalArgvCount > 0) { + memcpy(argv + argc, con->finalArgv, + sizeof(*argv) * con->finalArgvCount); + argc += con->finalArgvCount; + } + + if (con->leftovers != NULL && con->numLeftovers > 0) { +#if 0 + argv[argc++] = "--"; +#endif + memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers); + argc += con->numLeftovers; + } + + argv[argc] = NULL; + +#ifdef __hpux + rc = setresuid(getuid(), getuid(),-1); + if (rc) return POPT_ERROR_ERRNO; +#else +/* + * XXX " ... on BSD systems setuid() should be preferred over setreuid()" + * XXX sez' Timur Bakeyev + * XXX from Norbert Warmuth + */ +#if defined(HAVE_SETUID) + rc = setuid(getuid()); + if (rc) return POPT_ERROR_ERRNO; +#elif defined (HAVE_SETREUID) + rc = setreuid(getuid(), getuid()); /*hlauer: not portable to hpux9.01 */ + if (rc) return POPT_ERROR_ERRNO; +#else + ; /* Can't drop privileges */ +#endif +#endif + + if (argv[0] == NULL) + return POPT_ERROR_NOARG; + +#ifdef MYDEBUG +if (_popt_debug) + { const char ** avp; + fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc); + for (avp = argv; *avp; avp++) + fprintf(stderr, " '%s'", *avp); + fprintf(stderr, "\n"); + } +#endif + + rc = execvp(argv[0], (char *const *)argv); + /* notreached */ + if (rc) { + return POPT_ERROR_ERRNO; + } + + return 0; +} +/*@=bounds =boundswrite @*/ + +/*@-boundswrite@*/ +/*@observer@*/ /*@null@*/ static const struct poptOption * +findOption(const struct poptOption * opt, /*@null@*/ const char * longName, + char shortName, + /*@null@*/ /*@out@*/ poptCallbackType * callback, + /*@null@*/ /*@out@*/ const void ** callbackData, + int singleDash) + /*@modifies *callback, *callbackData */ +{ + const struct poptOption * cb = NULL; + + /* This happens when a single - is given */ + if (singleDash && !shortName && (longName && *longName == '\0')) + shortName = '-'; + + for (; opt->longName || opt->shortName || opt->arg; opt++) { + + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { + const struct poptOption * opt2; + + /* Recurse on included sub-tables. */ + if (opt->arg == NULL) continue; /* XXX program error */ + opt2 = findOption((const struct poptOption *)opt->arg, longName, + shortName, callback, + callbackData, singleDash); + if (opt2 == NULL) continue; + /* Sub-table data will be inheirited if no data yet. */ + if (!(callback && *callback)) return opt2; + if (!(callbackData && *callbackData == NULL)) return opt2; + /*@-observertrans -dependenttrans @*/ + *callbackData = opt->descrip; + /*@=observertrans =dependenttrans @*/ + return opt2; + } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) { + cb = opt; + } else if (longName && opt->longName && + (!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) && + /*@-nullpass@*/ /* LCL: opt->longName != NULL */ + !strcmp(longName, opt->longName)) + /*@=nullpass@*/ + { + break; + } else if (shortName && shortName == opt->shortName) { + break; + } + } + + if (!opt->longName && !opt->shortName) + return NULL; + /*@-modobserver -mods @*/ + if (callback) *callback = NULL; + if (callbackData) *callbackData = NULL; + if (cb) { + if (callback) + /*@-castfcnptr@*/ + *callback = (poptCallbackType)cb->arg; + /*@=castfcnptr@*/ + if (!(cb->argInfo & POPT_CBFLAG_INC_DATA)) { + if (callbackData) + /*@-observertrans@*/ /* FIX: typedef double indirection. */ + *callbackData = cb->descrip; + /*@=observertrans@*/ + } + } + /*@=modobserver =mods @*/ + + return opt; +} +/*@=boundswrite@*/ + +static const char * findNextArg(/*@special@*/ poptContext con, + unsigned argx, int delete_arg) + /*@uses con->optionStack, con->os, + con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ + /*@modifies con @*/ +{ + struct optionStackEntry * os = con->os; + const char * arg; + + do { + int i; + arg = NULL; + while (os->next == os->argc && os > con->optionStack) os--; + if (os->next == os->argc && os == con->optionStack) break; + if (os->argv != NULL) + for (i = os->next; i < os->argc; i++) { + /*@-sizeoftype@*/ + if (os->argb && PBM_ISSET(i, os->argb)) + /*@innercontinue@*/ continue; + if (*os->argv[i] == '-') + /*@innercontinue@*/ continue; + if (--argx > 0) + /*@innercontinue@*/ continue; + arg = os->argv[i]; + if (delete_arg) { + if (os->argb == NULL) os->argb = (pbm_set *)PBM_ALLOC(os->argc); + if (os->argb != NULL) /* XXX can't happen */ + PBM_SET(i, os->argb); + } + /*@innerbreak@*/ break; + /*@=sizeoftype@*/ + } + if (os > con->optionStack) os--; + } while (arg == NULL); + return arg; +} + +/*@-boundswrite@*/ +static /*@only@*/ /*@null@*/ const char * +expandNextArg(/*@special@*/ poptContext con, const char * s) + /*@uses con->optionStack, con->os, + con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ + /*@modifies con @*/ +{ + const char * a = NULL; + size_t alen; + char *t, *te; + size_t tn = strlen(s) + 1; + char c; + + te = t = (char *)malloc(tn);; + if (t == NULL) return NULL; /* XXX can't happen */ + while ((c = *s++) != '\0') { + switch (c) { +#if 0 /* XXX can't do this */ + case '\\': /* escape */ + c = *s++; + /*@switchbreak@*/ break; +#endif + case '!': + if (!(s[0] == '#' && s[1] == ':' && s[2] == '+')) + /*@switchbreak@*/ break; + /* XXX Make sure that findNextArg deletes only next arg. */ + if (a == NULL) { + if ((a = findNextArg(con, 1, 1)) == NULL) + /*@switchbreak@*/ break; + } + s += 3; + + alen = strlen(a); + tn += alen; + *te = '\0'; + t = (char *)realloc(t, tn); + te = t + strlen(t); + strncpy(te, a, alen); te += alen; + continue; + /*@notreached@*/ /*@switchbreak@*/ break; + default: + /*@switchbreak@*/ break; + } + *te++ = c; + } + *te = '\0'; + t = (char *)realloc(t, strlen(t) + 1); /* XXX memory leak, hard to plug */ + return t; +} +/*@=boundswrite@*/ + +static void poptStripArg(/*@special@*/ poptContext con, int which) + /*@uses con->arg_strip, con->optionStack @*/ + /*@defines con->arg_strip @*/ + /*@modifies con @*/ +{ + /*@-sizeoftype@*/ + if (con->arg_strip == NULL) + con->arg_strip = (pbm_set *)PBM_ALLOC(con->optionStack[0].argc); + if (con->arg_strip != NULL) /* XXX can't happen */ + PBM_SET(which, con->arg_strip); + /*@=sizeoftype@*/ + /*@-compdef@*/ /* LCL: con->arg_strip udefined? */ + return; + /*@=compdef@*/ +} + +int poptSaveLong(long * arg, int argInfo, long aLong) +{ + /* XXX Check alignment, may fail on funky platforms. */ + if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) + return POPT_ERROR_NULLARG; + + if (argInfo & POPT_ARGFLAG_NOT) + aLong = ~aLong; + switch (argInfo & POPT_ARGFLAG_LOGICALOPS) { + case 0: + *arg = aLong; + break; + case POPT_ARGFLAG_OR: + *arg |= aLong; + break; + case POPT_ARGFLAG_AND: + *arg &= aLong; + break; + case POPT_ARGFLAG_XOR: + *arg ^= aLong; + break; + default: + return POPT_ERROR_BADOPERATION; + /*@notreached@*/ break; + } + return 0; +} + +int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) +{ + /* XXX Check alignment, may fail on funky platforms. */ + if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) + return POPT_ERROR_NULLARG; + + if (argInfo & POPT_ARGFLAG_NOT) + aLong = ~aLong; + switch (argInfo & POPT_ARGFLAG_LOGICALOPS) { + case 0: + *arg = aLong; + break; + case POPT_ARGFLAG_OR: + *arg |= aLong; + break; + case POPT_ARGFLAG_AND: + *arg &= aLong; + break; + case POPT_ARGFLAG_XOR: + *arg ^= aLong; + break; + default: + return POPT_ERROR_BADOPERATION; + /*@notreached@*/ break; + } + return 0; +} + +/*@-boundswrite@*/ +/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ +int poptGetNextOpt(poptContext con) +{ + const struct poptOption * opt = NULL; + int done = 0; + + if (con == NULL) + return -1; + while (!done) { + const char * origOptString = NULL; + poptCallbackType cb = NULL; + const void * cbData = NULL; + const char * longArg = NULL; + int canstrip = 0; + int shorty = 0; + + while (!con->os->nextCharArg && con->os->next == con->os->argc + && con->os > con->optionStack) { + cleanOSE(con->os--); + } + if (!con->os->nextCharArg && con->os->next == con->os->argc) { + /*@-internalglobs@*/ + invokeCallbacksPOST(con, con->options); + /*@=internalglobs@*/ + if (con->doExec) return execCommand(con); + return -1; + } + + /* Process next long option */ + if (!con->os->nextCharArg) { + char * localOptString, * optString; + int thisopt; + + /*@-sizeoftype@*/ + if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { + con->os->next++; + continue; + } + /*@=sizeoftype@*/ + thisopt = con->os->next; + if (con->os->argv != NULL) /* XXX can't happen */ + origOptString = con->os->argv[con->os->next++]; + + if (origOptString == NULL) /* XXX can't happen */ + return POPT_ERROR_BADOPT; + + if (con->restLeftover || *origOptString != '-') { + if (con->flags & POPT_CONTEXT_POSIXMEHARDER) + con->restLeftover = 1; + if (con->flags & POPT_CONTEXT_ARG_OPTS) { + con->os->nextArg = xstrdup(origOptString); + return 0; + } + if (con->leftovers != NULL) /* XXX can't happen */ + con->leftovers[con->numLeftovers++] = origOptString; + continue; + } + + /* Make a copy we can hack at */ + localOptString = optString = + strcpy((char *)alloca(strlen(origOptString) + 1), + origOptString); + + if (optString[0] == '\0') + return POPT_ERROR_BADOPT; + + if (optString[1] == '-' && !optString[2]) { + con->restLeftover = 1; + continue; + } else { + char *oe; + int singleDash; + + optString++; + if (*optString == '-') + singleDash = 0, optString++; + else + singleDash = 1; + + /* XXX aliases with arg substitution need "--alias=arg" */ + if (handleAlias(con, optString, '\0', NULL)) + continue; + + if (handleExec(con, optString, '\0')) + continue; + + /* Check for "--long=arg" option. */ + for (oe = optString; *oe && *oe != '='; oe++) + {}; + if (*oe == '=') { + *oe++ = '\0'; + /* XXX longArg is mapped back to persistent storage. */ + longArg = origOptString + (oe - localOptString); + } + + opt = findOption(con->options, optString, '\0', &cb, &cbData, + singleDash); + if (!opt && !singleDash) + return POPT_ERROR_BADOPT; + } + + if (!opt) { + con->os->nextCharArg = origOptString + 1; + } else { + if (con->os == con->optionStack && + opt->argInfo & POPT_ARGFLAG_STRIP) + { + canstrip = 1; + poptStripArg(con, thisopt); + } + shorty = 0; + } + } + + /* Process next short option */ + /*@-branchstate@*/ /* FIX: W2DO? */ + if (con->os->nextCharArg) { + origOptString = con->os->nextCharArg; + + con->os->nextCharArg = NULL; + + if (handleAlias(con, NULL, *origOptString, origOptString + 1)) + continue; + + if (handleExec(con, NULL, *origOptString)) { + /* Restore rest of short options for further processing */ + origOptString++; + if (*origOptString != '\0') + con->os->nextCharArg = origOptString; + continue; + } + + opt = findOption(con->options, NULL, *origOptString, &cb, + &cbData, 0); + if (!opt) + return POPT_ERROR_BADOPT; + shorty = 1; + + origOptString++; + if (*origOptString != '\0') + con->os->nextCharArg = origOptString; + } + /*@=branchstate@*/ + + if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */ + if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) { + if (poptSaveInt((int *)opt->arg, opt->argInfo, 1L)) + return POPT_ERROR_BADOPERATION; + } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) { + if (opt->arg) { + if (poptSaveInt((int *)opt->arg, opt->argInfo, (long)opt->val)) + return POPT_ERROR_BADOPERATION; + } + } else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { + con->os->nextArg = (const char *)_free(con->os->nextArg); + /*@-usedef@*/ /* FIX: W2DO? */ + if (longArg) { + /*@=usedef@*/ + longArg = expandNextArg(con, longArg); + con->os->nextArg = longArg; + } else if (con->os->nextCharArg) { + longArg = expandNextArg(con, con->os->nextCharArg); + con->os->nextArg = longArg; + con->os->nextCharArg = NULL; + } else { + while (con->os->next == con->os->argc && + con->os > con->optionStack) { + cleanOSE(con->os--); + } + if (con->os->next == con->os->argc) { + if (!(opt->argInfo & POPT_ARGFLAG_OPTIONAL)) + /*@-compdef@*/ /* FIX: con->os->argv not defined */ + return POPT_ERROR_NOARG; + /*@=compdef@*/ + con->os->nextArg = NULL; + } else { + + /* + * Make sure this isn't part of a short arg or the + * result of an alias expansion. + */ + if (con->os == con->optionStack && + (opt->argInfo & POPT_ARGFLAG_STRIP) && + canstrip) { + poptStripArg(con, con->os->next); + } + + if (con->os->argv != NULL) { /* XXX can't happen */ + /* XXX watchout: subtle side-effects live here. */ + longArg = con->os->argv[con->os->next++]; + longArg = expandNextArg(con, longArg); + con->os->nextArg = longArg; + } + } + } + longArg = NULL; + + if (opt->arg) { + switch (opt->argInfo & POPT_ARG_MASK) { + case POPT_ARG_STRING: + /* XXX memory leak, hard to plug */ + *((const char **) opt->arg) = (con->os->nextArg) + ? xstrdup(con->os->nextArg) : NULL; + /*@switchbreak@*/ break; + + case POPT_ARG_INT: + case POPT_ARG_LONG: + { long aLong = 0; + char *end; + + if (con->os->nextArg) { + aLong = strtol(con->os->nextArg, &end, 0); + if (!(end && *end == '\0')) + return POPT_ERROR_BADNUMBER; + } + + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { + if (aLong == LONG_MIN || aLong == LONG_MAX) + return POPT_ERROR_OVERFLOW; + if (poptSaveLong((long *)opt->arg, opt->argInfo, aLong)) + return POPT_ERROR_BADOPERATION; + } else { + if (aLong > INT_MAX || aLong < INT_MIN) + return POPT_ERROR_OVERFLOW; + if (poptSaveInt((int *)opt->arg, opt->argInfo, aLong)) + return POPT_ERROR_BADOPERATION; + } + } /*@switchbreak@*/ break; + + case POPT_ARG_FLOAT: + case POPT_ARG_DOUBLE: + { double aDouble = 0.0; + char *end; + + if (con->os->nextArg) { + /*@-mods@*/ + int saveerrno = errno; + errno = 0; + aDouble = strtod(con->os->nextArg, &end); + if (errno == ERANGE) + return POPT_ERROR_OVERFLOW; + errno = saveerrno; + /*@=mods@*/ + if (*end != '\0') + return POPT_ERROR_BADNUMBER; + } + + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_DOUBLE) { + *((double *) opt->arg) = aDouble; + } else { +#ifndef _ABS +#define _ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a)) +#endif + if ((_ABS(aDouble) - FLT_MAX) > DBL_EPSILON) + return POPT_ERROR_OVERFLOW; + if ((FLT_MIN - _ABS(aDouble)) > DBL_EPSILON) + return POPT_ERROR_OVERFLOW; + *((float *) opt->arg) = aDouble; + } + } /*@switchbreak@*/ break; + default: + fprintf(stdout, + POPT_("option type (%d) not implemented in popt\n"), + (opt->argInfo & POPT_ARG_MASK)); + exit(EXIT_FAILURE); + /*@notreached@*/ /*@switchbreak@*/ break; + } + } + } + + if (cb) { + /*@-internalglobs@*/ + invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); + /*@=internalglobs@*/ + } else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)) + done = 1; + + if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { + con->finalArgvAlloced += 10; + con->finalArgv = (const char **)realloc(con->finalArgv, + sizeof(*con->finalArgv) * con->finalArgvAlloced); + } + + if (con->finalArgv != NULL) + { char *s = (char *)malloc( + (opt->longName ? strlen(opt->longName) : 0) + 3); + if (s != NULL) { /* XXX can't happen */ + if (opt->longName) + sprintf(s, "%s%s", + ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), + opt->longName); + else + sprintf(s, "-%c", opt->shortName); + con->finalArgv[con->finalArgvCount++] = s; + } else + con->finalArgv[con->finalArgvCount++] = NULL; + } + + if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) + /*@-ifempty@*/ ; /*@=ifempty@*/ + else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) + /*@-ifempty@*/ ; /*@=ifempty@*/ + else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { + if (con->finalArgv != NULL && con->os->nextArg) + con->finalArgv[con->finalArgvCount++] = + /*@-nullpass@*/ /* LCL: con->os->nextArg != NULL */ + xstrdup(con->os->nextArg); + /*@=nullpass@*/ + } + } + + return (opt ? opt->val : -1); /* XXX can't happen */ +} +/*@=boundswrite@*/ + +const char * poptGetOptArg(poptContext con) +{ + const char * ret = NULL; + /*@-branchstate@*/ + if (con) { + ret = con->os->nextArg; + con->os->nextArg = NULL; + } + /*@=branchstate@*/ + return ret; +} + +const char * poptGetArg(poptContext con) +{ + const char * ret = NULL; + if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) + ret = con->leftovers[con->nextLeftover++]; + return ret; +} + +const char * poptPeekArg(poptContext con) +{ + const char * ret = NULL; + if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) + ret = con->leftovers[con->nextLeftover]; + return ret; +} + +/*@-boundswrite@*/ +const char ** poptGetArgs(poptContext con) +{ + if (con == NULL || + con->leftovers == NULL || con->numLeftovers == con->nextLeftover) + return NULL; + + /* some apps like [like RPM ;-) ] need this NULL terminated */ + con->leftovers[con->numLeftovers] = NULL; + + /*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */ + return (con->leftovers + con->nextLeftover); + /*@=nullret =nullstate @*/ +} +/*@=boundswrite@*/ + +poptContext poptFreeContext(poptContext con) +{ + poptItem item; + int i; + + if (con == NULL) return con; + poptResetContext(con); + con->os->argb = (pbm_set *)_free(con->os->argb); + + if (con->aliases != NULL) + for (i = 0; i < con->numAliases; i++) { + item = con->aliases + i; + /*@-modobserver -observertrans -dependenttrans@*/ + item->option.longName = (const char *)_free(item->option.longName); + item->option.descrip = (const char *)_free(item->option.descrip); + item->option.argDescrip = (const char *)_free(item->option.argDescrip); + /*@=modobserver =observertrans =dependenttrans@*/ + item->argv = (const char **)_free(item->argv); + } + con->aliases = (poptItem)_free(con->aliases); + + if (con->execs != NULL) + for (i = 0; i < con->numExecs; i++) { + item = con->execs + i; + /*@-modobserver -observertrans -dependenttrans@*/ + item->option.longName = (const char *)_free(item->option.longName); + item->option.descrip = (const char *)_free(item->option.descrip); + item->option.argDescrip = (const char *)_free(item->option.argDescrip); + /*@=modobserver =observertrans =dependenttrans@*/ + item->argv = (const char **)_free(item->argv); + } + con->execs = (poptItem)_free(con->execs); + + con->leftovers = (const char **)_free(con->leftovers); + con->finalArgv = (const char **)_free(con->finalArgv); + con->appName = (const char *)_free(con->appName); + con->otherHelp = (const char *)_free(con->otherHelp); + con->execPath = (const char *)_free(con->execPath); + con->arg_strip = (pbm_set *)PBM_FREE(con->arg_strip); + + con = (poptContext)_free(con); + return con; +} + +int poptAddAlias(poptContext con, struct poptAlias alias, + /*@unused@*/ int flags) +{ + poptItem item = (poptItem)alloca(sizeof(*item)); + memset(item, 0, sizeof(*item)); + item->option.longName = alias.longName; + item->option.shortName = alias.shortName; + item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; + item->option.arg = 0; + item->option.val = 0; + item->option.descrip = NULL; + item->option.argDescrip = NULL; + item->argc = alias.argc; + item->argv = alias.argv; + return poptAddItem(con, item, 0); +} + +/*@-boundswrite@*/ +/*@-mustmod@*/ /* LCL: con not modified? */ +int poptAddItem(poptContext con, poptItem newItem, int flags) +{ + poptItem * items, item; + int * nitems; + + switch (flags) { + case 1: + items = &con->execs; + nitems = &con->numExecs; + break; + case 0: + items = &con->aliases; + nitems = &con->numAliases; + break; + default: + return 1; + /*@notreached@*/ break; + } + + *items = (poptItem)realloc((*items), ((*nitems) + 1) * sizeof(**items)); + if ((*items) == NULL) + return 1; + + item = (*items) + (*nitems); + + item->option.longName = + (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL); + item->option.shortName = newItem->option.shortName; + item->option.argInfo = newItem->option.argInfo; + item->option.arg = newItem->option.arg; + item->option.val = newItem->option.val; + item->option.descrip = + (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL); + item->option.argDescrip = + (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL); + item->argc = newItem->argc; + item->argv = newItem->argv; + + (*nitems)++; + + return 0; +} +/*@=mustmod@*/ +/*@=boundswrite@*/ + +const char * poptBadOption(poptContext con, int flags) +{ + struct optionStackEntry * os = NULL; + + if (con != NULL) + os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os; + + /*@-nullderef@*/ /* LCL: os->argv != NULL */ + return (os && os->argv ? os->argv[os->next - 1] : NULL); + /*@=nullderef@*/ +} + +const char *poptStrerror(const int error) +{ + switch (error) { + case POPT_ERROR_NOARG: + return POPT_("missing argument"); + case POPT_ERROR_BADOPT: + return POPT_("unknown option"); + case POPT_ERROR_BADOPERATION: + return POPT_("mutually exclusive logical operations requested"); + case POPT_ERROR_NULLARG: + return POPT_("opt->arg should not be NULL"); + case POPT_ERROR_OPTSTOODEEP: + return POPT_("aliases nested too deeply"); + case POPT_ERROR_BADQUOTE: + return POPT_("error in parameter quoting"); + case POPT_ERROR_BADNUMBER: + return POPT_("invalid numeric value"); + case POPT_ERROR_OVERFLOW: + return POPT_("number too large or too small"); + case POPT_ERROR_MALLOC: + return POPT_("memory allocation failed"); + case POPT_ERROR_ERRNO: + return strerror(errno); + default: + return POPT_("unknown error"); + } +} + +int poptStuffArgs(poptContext con, const char ** argv) +{ + int argc; + int rc; + + if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) + return POPT_ERROR_OPTSTOODEEP; + + for (argc = 0; argv[argc]; argc++) + {}; + + con->os++; + con->os->next = 0; + con->os->nextArg = NULL; + con->os->nextCharArg = NULL; + con->os->currAlias = NULL; + rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv); + con->os->argb = NULL; + con->os->stuffed = 1; + + return rc; +} + +const char * poptGetInvocationName(poptContext con) +{ + return (con->os->argv ? con->os->argv[0] : ""); +} + +/*@-boundswrite@*/ +int poptStrippedArgv(poptContext con, int argc, char ** argv) +{ + int numargs = argc; + int j = 1; + int i; + + /*@-sizeoftype@*/ + if (con->arg_strip) + for (i = 1; i < argc; i++) { + if (PBM_ISSET(i, con->arg_strip)) + numargs--; + } + + for (i = 1; i < argc; i++) { + if (con->arg_strip && PBM_ISSET(i, con->arg_strip)) + continue; + argv[j] = (j < numargs) ? argv[i] : NULL; + j++; + } + /*@=sizeoftype@*/ + + return numargs; +} +/*@=boundswrite@*/ diff --git a/lib/popt/popt.h b/lib/popt/popt.h new file mode 100644 index 0000000000..08701d73b5 --- /dev/null +++ b/lib/popt/popt.h @@ -0,0 +1,545 @@ +/** \file popt/popt.h + * \ingroup popt + */ + +/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#ifndef H_POPT +#define H_POPT + +#include /* for FILE * */ + +#define POPT_OPTION_DEPTH 10 + +/** \ingroup popt + * \name Arg type identifiers + */ +/*@{*/ +#define POPT_ARG_NONE 0 /*!< no arg */ +#define POPT_ARG_STRING 1 /*!< arg will be saved as string */ +#define POPT_ARG_INT 2 /*!< arg will be converted to int */ +#define POPT_ARG_LONG 3 /*!< arg will be converted to long */ +#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */ +#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be + set first in table; arg points + to callback, descrip points to + callback data to pass */ +#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain + for this table and any + included tables; arg points + to the domain string */ +#define POPT_ARG_VAL 7 /*!< arg should take value val */ +#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */ +#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */ + +#define POPT_ARG_MASK 0x0000FFFF +/*@}*/ + +/** \ingroup popt + * \name Arg modifiers + */ +/*@{*/ +#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */ +#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */ +#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */ +#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */ + +#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */ +#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */ +#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */ +#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */ +#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */ +#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */ +#define POPT_ARGFLAG_LOGICALOPS \ + (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) + +#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) + /*!< set arg bit(s) */ +#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND) + /*!< clear arg bit(s) */ + +#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */ + +/*@}*/ + +/** \ingroup popt + * \name Callback modifiers + */ +/*@{*/ +#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */ +#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */ +#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line, + not the subtable */ +#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */ +#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */ +/*@}*/ + +/** \ingroup popt + * \name Error return values + */ +/*@{*/ +#define POPT_ERROR_NOARG -10 /*!< missing argument */ +#define POPT_ERROR_BADOPT -11 /*!< unknown option */ +#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */ +#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */ +#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */ +#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */ +#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */ +#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */ +#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */ +#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */ +/*@}*/ + +/** \ingroup popt + * \name poptBadOption() flags + */ +/*@{*/ +#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */ +/*@}*/ + +/** \ingroup popt + * \name poptGetContext() flags + */ +/*@{*/ +#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */ +#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */ +#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */ +#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */ +/*@}*/ + +/** \ingroup popt + */ +struct poptOption { +/*@observer@*/ /*@null@*/ + const char * longName; /*!< may be NULL */ + char shortName; /*!< may be '\0' */ + int argInfo; +/*@shared@*/ /*@null@*/ + void * arg; /*!< depends on argInfo */ + int val; /*!< 0 means don't return, just update flag */ +/*@observer@*/ /*@null@*/ + const char * descrip; /*!< description for autohelp -- may be NULL */ +/*@observer@*/ /*@null@*/ + const char * argDescrip; /*!< argument description for autohelp */ +}; + +/** \ingroup popt + * A popt alias argument for poptAddAlias(). + */ +struct poptAlias { +/*@owned@*/ /*@null@*/ + const char * longName; /*!< may be NULL */ + char shortName; /*!< may be '\0' */ + int argc; +/*@owned@*/ + const char ** argv; /*!< must be free()able */ +}; + +/** \ingroup popt + * A popt alias or exec argument for poptAddItem(). + */ +/*@-exporttype@*/ +typedef struct poptItem_s { + struct poptOption option; /*!< alias/exec name(s) and description. */ + int argc; /*!< (alias) no. of args. */ +/*@owned@*/ + const char ** argv; /*!< (alias) args, must be free()able. */ +} * poptItem; +/*@=exporttype@*/ + +/** \ingroup popt + * \name Auto-generated help/usage + */ +/*@{*/ + +/** + * Empty table marker to enable displaying popt alias/exec options. + */ +/*@-exportvar@*/ +/*@unchecked@*/ /*@observer@*/ +extern struct poptOption poptAliasOptions[]; +/*@=exportvar@*/ +#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ + 0, "Options implemented via popt alias/exec:", NULL }, + +/** + * Auto help table options. + */ +/*@-exportvar@*/ +/*@unchecked@*/ /*@observer@*/ +extern struct poptOption poptHelpOptions[]; +/*@=exportvar@*/ +#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ + 0, "Help options:", NULL }, + +#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } +/*@}*/ + +/** \ingroup popt + */ +/*@-exporttype@*/ +typedef /*@abstract@*/ struct poptContext_s * poptContext; +/*@=exporttype@*/ + +/** \ingroup popt + */ +#ifndef __cplusplus +/*@-exporttype -typeuse@*/ +typedef struct poptOption * poptOption; +/*@=exporttype =typeuse@*/ +#endif + +/*@-exportconst@*/ +enum poptCallbackReason { + POPT_CALLBACK_REASON_PRE = 0, + POPT_CALLBACK_REASON_POST = 1, + POPT_CALLBACK_REASON_OPTION = 2 +}; +/*@=exportconst@*/ + +#ifdef __cplusplus +extern "C" { +#endif +/*@-type@*/ + +/** \ingroup popt + * Table callback prototype. + * @param con context + * @param reason reason for callback + * @param opt option that triggered callback + * @param arg @todo Document. + * @param data @todo Document. + */ +typedef void (*poptCallbackType) (poptContext con, + enum poptCallbackReason reason, + /*@null@*/ const struct poptOption * opt, + /*@null@*/ const char * arg, + /*@null@*/ const void * data) + /*@*/; + +/** \ingroup popt + * Initialize popt context. + * @param name context name (usually argv[0] program name) + * @param argc no. of arguments + * @param argv argument array + * @param options address of popt option table + * @param flags or'd POPT_CONTEXT_* bits + * @return initialized popt context + */ +/*@only@*/ /*@null@*/ poptContext poptGetContext( + /*@dependent@*/ /*@keep@*/ const char * name, + int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, + /*@dependent@*/ /*@keep@*/ const struct poptOption * options, + int flags) + /*@*/; + +/** \ingroup popt + * Reinitialize popt context. + * @param con context + */ +/*@unused@*/ +void poptResetContext(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return value of next option found. + * @param con context + * @return next option val, -1 on last item, POPT_ERROR_* on error + */ +int poptGetNextOpt(/*@null@*/poptContext con) + /*@globals fileSystem, internalState @*/ + /*@modifies con, fileSystem, internalState @*/; + +/** \ingroup popt + * Return next option argument (if any). + * @param con context + * @return option argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return next argument. + * @param con context + * @return next argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Peek at current argument. + * @param con context + * @return current argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con) + /*@*/; + +/** \ingroup popt + * Return remaining arguments. + * @param con context + * @return argument array, NULL terminated + */ +/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return the option which caused the most recent error. + * @param con context + * @param flags + * @return offending option + */ +/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags) + /*@*/; + +/** \ingroup popt + * Destroy context. + * @param con context + * @return NULL always + */ +/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Add arguments to context. + * @param con context + * @param argv argument array, NULL terminated + * @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure + */ +int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv) + /*@modifies con @*/; + +/** \ingroup popt + * Add alias to context. + * @todo Pass alias by reference, not value. + * @deprecated Use poptAddItem instead. + * @param con context + * @param alias alias to add + * @param flags (unused) + * @return 0 on success + */ +/*@unused@*/ +int poptAddAlias(poptContext con, struct poptAlias alias, int flags) + /*@modifies con @*/; + +/** \ingroup popt + * Add alias/exec item to context. + * @param con context + * @param newItem alias/exec item to add + * @param flags 0 for alias, 1 for exec + * @return 0 on success + */ +int poptAddItem(poptContext con, poptItem newItem, int flags) + /*@modifies con @*/; + +/** \ingroup popt + * Read configuration file. + * @param con context + * @param fn file name to read + * @return 0 on success, POPT_ERROR_ERRNO on failure + */ +int poptReadConfigFile(poptContext con, const char * fn) + /*@globals fileSystem, internalState @*/ + /*@modifies con->execs, con->numExecs, + fileSystem, internalState @*/; + +/** \ingroup popt + * Read default configuration from /etc/popt and $HOME/.popt. + * @param con context + * @param useEnv (unused) + * @return 0 on success, POPT_ERROR_ERRNO on failure + */ +int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) + /*@globals fileSystem, internalState @*/ + /*@modifies con->execs, con->numExecs, + fileSystem, internalState @*/; + +/** \ingroup popt + * Duplicate an argument array. + * @note: The argument array is malloc'd as a single area, so only argv must + * be free'd. + * + * @param argc no. of arguments + * @param argv argument array + * @retval argcPtr address of returned no. of arguments + * @retval argvPtr address of returned argument array + * @return 0 on success, POPT_ERROR_NOARG on failure + */ +int poptDupArgv(int argc, /*@null@*/ const char **argv, + /*@null@*/ /*@out@*/ int * argcPtr, + /*@null@*/ /*@out@*/ const char *** argvPtr) + /*@modifies *argcPtr, *argvPtr @*/; + +/** \ingroup popt + * Parse a string into an argument array. + * The parse allows ', ", and \ quoting, but ' is treated the same as " and + * both may include \ quotes. + * @note: The argument array is malloc'd as a single area, so only argv must + * be free'd. + * + * @param s string to parse + * @retval argcPtr address of returned no. of arguments + * @retval argvPtr address of returned argument array + */ +int poptParseArgvString(const char * s, + /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) + /*@modifies *argcPtr, *argvPtr @*/; + +/** \ingroup popt + * Parses an input configuration file and returns an string that is a + * command line. For use with popt. You must free the return value when done. + * + * Given the file: +\verbatim +# this line is ignored + # this one too +aaa + bbb + ccc +bla=bla + +this_is = fdsafdas + bad_line= + reall bad line + reall bad line = again +5555= 55555 + test = with lots of spaces +\endverbatim +* +* The result is: +\verbatim +--aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" +\endverbatim +* +* Passing this to poptParseArgvString() yields an argv of: +\verbatim +'--aaa' +'--bbb' +'--ccc' +'--bla=bla' +'--this_is=fdsafdas' +'--5555=55555' +'--test=with lots of spaces' +\endverbatim + * + * @bug NULL is returned if file line is too long. + * @bug Silently ignores invalid lines. + * + * @param fp file handle to read + * @param *argstrp return string of options (malloc'd) + * @param flags unused + * @return 0 on success + * @see poptParseArgvString + */ +/*@-fcnuse@*/ +int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) + /*@globals fileSystem @*/ + /*@modifies *fp, *argstrp, fileSystem @*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Return formatted error string for popt failure. + * @param error popt error + * @return error string + */ +/*@observer@*/ const char* poptStrerror(const int error) + /*@*/; + +/** \ingroup popt + * Limit search for executables. + * @param con context + * @param path single path to search for executables + * @param allowAbsolute absolute paths only? + */ +void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) + /*@modifies con @*/; + +/** \ingroup popt + * Print detailed description of options. + * @param con context + * @param fp ouput file handle + * @param flags (unused) + */ +void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/; + +/** \ingroup popt + * Print terse description of options. + * @param con context + * @param fp ouput file handle + * @param flags (unused) + */ +void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/; + +/** \ingroup popt + * Provide text to replace default "[OPTION...]" in help/usage output. + * @param con context + * @param text replacement text + */ +/*@-fcnuse@*/ +void poptSetOtherOptionHelp(poptContext con, const char * text) + /*@modifies con @*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Return argv[0] from context. + * @param con context + * @return argv[0] + */ +/*@-fcnuse@*/ +/*@observer@*/ const char * poptGetInvocationName(poptContext con) + /*@*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Shuffle argv pointers to remove stripped args, returns new argc. + * @param con context + * @param argc no. of args + * @param argv arg vector + * @return new argc + */ +/*@-fcnuse@*/ +int poptStrippedArgv(poptContext con, int argc, char ** argv) + /*@modifies *argv @*/; +/*@=fcnuse@*/ + +/** + * Save a long, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg integer pointer, aligned on int boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveLong(/*@null@*/ long * arg, int argInfo, long aLong) + /*@modifies *arg @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/** + * Save an integer, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg integer pointer, aligned on int boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) + /*@modifies *arg @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/*@=type@*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/popt/poptconfig.c b/lib/popt/poptconfig.c new file mode 100644 index 0000000000..837828ccf9 --- /dev/null +++ b/lib/popt/poptconfig.c @@ -0,0 +1,190 @@ +/** \ingroup popt + * \file popt/poptconfig.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#include "system.h" +#include "poptint.h" + +/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ +static void configLine(poptContext con, char * line) + /*@modifies con @*/ +{ + /*@-type@*/ + int nameLength = strlen(con->appName); + /*@=type@*/ + const char * entryType; + const char * opt; + poptItem item = (poptItem)alloca(sizeof(*item)); + int i, j; + +/*@-boundswrite@*/ + memset(item, 0, sizeof(*item)); + + /*@-type@*/ + if (strncmp(line, con->appName, nameLength)) return; + /*@=type@*/ + + line += nameLength; + if (*line == '\0' || !isspace(*line)) return; + + while (*line != '\0' && isspace(*line)) line++; + entryType = line; + while (*line == '\0' || !isspace(*line)) line++; + *line++ = '\0'; + + while (*line != '\0' && isspace(*line)) line++; + if (*line == '\0') return; + opt = line; + while (*line == '\0' || !isspace(*line)) line++; + *line++ = '\0'; + + while (*line != '\0' && isspace(*line)) line++; + if (*line == '\0') return; + + /*@-temptrans@*/ /* FIX: line alias is saved */ + if (opt[0] == '-' && opt[1] == '-') + item->option.longName = opt + 2; + else if (opt[0] == '-' && opt[2] == '\0') + item->option.shortName = opt[1]; + /*@=temptrans@*/ + + if (poptParseArgvString(line, &item->argc, &item->argv)) return; + + /*@-modobserver@*/ + item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; + for (i = 0, j = 0; i < item->argc; i++, j++) { + const char * f; + if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { + f = item->argv[i] + sizeof("--POPTdesc="); + if (f[0] == '$' && f[1] == '"') f++; + item->option.descrip = f; + item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; + j--; + } else + if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { + f = item->argv[i] + sizeof("--POPTargs="); + if (f[0] == '$' && f[1] == '"') f++; + item->option.argDescrip = f; + item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; + item->option.argInfo |= POPT_ARG_STRING; + j--; + } else + if (j != i) + item->argv[j] = item->argv[i]; + } + if (j != i) { + item->argv[j] = NULL; + item->argc = j; + } + /*@=modobserver@*/ +/*@=boundswrite@*/ + + /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ + if (!strcmp(entryType, "alias")) + (void) poptAddItem(con, item, 0); + else if (!strcmp(entryType, "exec")) + (void) poptAddItem(con, item, 1); + /*@=nullstate@*/ +} +/*@=compmempass@*/ + +int poptReadConfigFile(poptContext con, const char * fn) +{ + const char * file, * chptr, * end; + char * buf; +/*@dependent@*/ char * dst; + int fd, rc; + off_t fileLength; + + fd = open(fn, O_RDONLY); + if (fd < 0) + return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO); + + fileLength = lseek(fd, 0, SEEK_END); + if (fileLength == -1 || lseek(fd, 0, 0) == -1) { + rc = errno; + (void) close(fd); + /*@-mods@*/ + errno = rc; + /*@=mods@*/ + return POPT_ERROR_ERRNO; + } + + file = (const char *)alloca(fileLength + 1); + if (read(fd, (char *)file, fileLength) != fileLength) { + rc = errno; + (void) close(fd); + /*@-mods@*/ + errno = rc; + /*@=mods@*/ + return POPT_ERROR_ERRNO; + } + if (close(fd) == -1) + return POPT_ERROR_ERRNO; + +/*@-boundswrite@*/ + dst = buf = (char *)alloca(fileLength + 1); + + chptr = file; + end = (file + fileLength); + /*@-infloops@*/ /* LCL: can't detect chptr++ */ + while (chptr < end) { + switch (*chptr) { + case '\n': + *dst = '\0'; + dst = buf; + while (*dst && isspace(*dst)) dst++; + if (*dst && *dst != '#') + configLine(con, dst); + chptr++; + /*@switchbreak@*/ break; + case '\\': + *dst++ = *chptr++; + if (chptr < end) { + if (*chptr == '\n') + dst--, chptr++; + /* \ at the end of a line does not insert a \n */ + else + *dst++ = *chptr++; + } + /*@switchbreak@*/ break; + default: + *dst++ = *chptr++; + /*@switchbreak@*/ break; + } + } + /*@=infloops@*/ +/*@=boundswrite@*/ + + return 0; +} + +int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) +{ + char * fn, * home; + int rc; + + /*@-type@*/ + if (!con->appName) return 0; + /*@=type@*/ + + rc = poptReadConfigFile(con, "/etc/popt"); + if (rc) return rc; +#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) + if (getuid() != geteuid()) return 0; +#endif + + if ((home = getenv("HOME"))) { + fn = (char *)alloca(strlen(home) + 20); + strcpy(fn, home); + strcat(fn, "/.popt"); + rc = poptReadConfigFile(con, fn); + if (rc) return rc; + } + + return 0; +} diff --git a/lib/popt/popthelp.c b/lib/popt/popthelp.c new file mode 100644 index 0000000000..e965ff6168 --- /dev/null +++ b/lib/popt/popthelp.c @@ -0,0 +1,740 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/*@-type@*/ +/** \ingroup popt + * \file popt/popthelp.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#include "system.h" +#include "poptint.h" + +/** + * Display arguments. + * @param con context + * @param foo (unused) + * @param key option(s) + * @param arg (unused) + * @param data (unused) + */ +static void displayArgs(poptContext con, + /*@unused@*/ enum poptCallbackReason foo, + struct poptOption * key, + /*@unused@*/ const char * arg, /*@unused@*/ void * data) + /*@globals fileSystem@*/ + /*@modifies fileSystem@*/ +{ + if (key->shortName == '?') + poptPrintHelp(con, stdout, 0); + else + poptPrintUsage(con, stdout, 0); + exit(0); +} + +#ifdef NOTYET +/*@unchecked@*/ +static int show_option_defaults = 0; +#endif + +/** + * Empty table marker to enable displaying popt alias/exec options. + */ +/*@observer@*/ /*@unchecked@*/ +struct poptOption poptAliasOptions[] = { + POPT_TABLEEND +}; + +/** + * Auto help table options. + */ +/*@-castfcnptr@*/ +/*@observer@*/ /*@unchecked@*/ +struct poptOption poptHelpOptions[] = { + { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL }, + { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL }, + { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL }, +#ifdef NOTYET + { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0, + N_("Display option defaults in message"), NULL }, +#endif + POPT_TABLEEND +} ; +/*@=castfcnptr@*/ + +/** + * @param table option(s) + */ +/*@observer@*/ /*@null@*/ static const char * +getTableTranslationDomain(/*@null@*/ const struct poptOption *table) + /*@*/ +{ + const struct poptOption *opt; + + if (table != NULL) + for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { + if (opt->argInfo == POPT_ARG_INTL_DOMAIN) + return (char *)opt->arg; + } + return NULL; +} + +/** + * @param opt option(s) + * @param translation_domain translation domain + */ +/*@observer@*/ /*@null@*/ static const char * +getArgDescrip(const struct poptOption * opt, + /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ + /*@null@*/ const char * translation_domain) + /*@=paramuse@*/ + /*@*/ +{ + if (!(opt->argInfo & POPT_ARG_MASK)) return NULL; + + if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2)) + if (opt->argDescrip) return POPT_(opt->argDescrip); + + if (opt->argDescrip) return D_(translation_domain, opt->argDescrip); + + switch (opt->argInfo & POPT_ARG_MASK) { + case POPT_ARG_NONE: return POPT_("NONE"); +#ifdef DYING + case POPT_ARG_VAL: return POPT_("VAL"); +#else + case POPT_ARG_VAL: return NULL; +#endif + case POPT_ARG_INT: return POPT_("INT"); + case POPT_ARG_LONG: return POPT_("LONG"); + case POPT_ARG_STRING: return POPT_("STRING"); + case POPT_ARG_FLOAT: return POPT_("FLOAT"); + case POPT_ARG_DOUBLE: return POPT_("DOUBLE"); + default: return POPT_("ARG"); + } +} + +/** + * Display default value for an option. + * @param lineLength + * @param opt option(s) + * @param translation_domain translation domain + * @return + */ +static /*@only@*/ /*@null@*/ char * +singleOptionDefaultValue(int lineLength, + const struct poptOption * opt, + /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ + /*@null@*/ const char * translation_domain) + /*@=paramuse@*/ + /*@*/ +{ + const char * defstr = D_(translation_domain, "default"); + char * le = (char *)malloc(4*lineLength + 1); + char * l = le; + + if (le == NULL) return NULL; /* XXX can't happen */ +/*@-boundswrite@*/ + *le = '\0'; + *le++ = '('; + strcpy(le, defstr); le += strlen(le); + *le++ = ':'; + *le++ = ' '; + if (opt->arg) /* XXX programmer error */ + switch (opt->argInfo & POPT_ARG_MASK) { + case POPT_ARG_VAL: + case POPT_ARG_INT: + { long aLong = *((int *)opt->arg); + le += sprintf(le, "%ld", aLong); + } break; + case POPT_ARG_LONG: + { long aLong = *((long *)opt->arg); + le += sprintf(le, "%ld", aLong); + } break; + case POPT_ARG_FLOAT: + { double aDouble = *((float *)opt->arg); + le += sprintf(le, "%g", aDouble); + } break; + case POPT_ARG_DOUBLE: + { double aDouble = *((double *)opt->arg); + le += sprintf(le, "%g", aDouble); + } break; + case POPT_ARG_STRING: + { const char * s = *(const char **)opt->arg; + if (s == NULL) { + strcpy(le, "null"); le += strlen(le); + } else { + size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")"); + *le++ = '"'; + strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le); + if (slen < strlen(s)) { + strcpy(le, "..."); le += strlen(le); + } + *le++ = '"'; + } + } break; + case POPT_ARG_NONE: + default: + l = (char *)_free(l); + return NULL; + /*@notreached@*/ break; + } + *le++ = ')'; + *le = '\0'; +/*@=boundswrite@*/ + + return l; +} + +/** + * Display help text for an option. + * @param fp output file handle + * @param maxLeftCol + * @param opt option(s) + * @param translation_domain translation domain + */ +static void singleOptionHelp(FILE * fp, int maxLeftCol, + const struct poptOption * opt, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/ +{ + int indentLength = maxLeftCol + 5; + int lineLength = 79 - indentLength; + const char * help = D_(translation_domain, opt->descrip); + const char * argDescrip = getArgDescrip(opt, translation_domain); + int helpLength; + char * defs = NULL; + char * left; + int nb = maxLeftCol + 1; + + /* Make sure there's more than enough room in target buffer. */ + if (opt->longName) nb += strlen(opt->longName); + if (argDescrip) nb += strlen(argDescrip); + +/*@-boundswrite@*/ + left = (char *)malloc(nb); + if (left == NULL) return; /* XXX can't happen */ + left[0] = '\0'; + left[maxLeftCol] = '\0'; + + if (opt->longName && opt->shortName) + sprintf(left, "-%c, %s%s", opt->shortName, + ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), + opt->longName); + else if (opt->shortName != '\0') + sprintf(left, "-%c", opt->shortName); + else if (opt->longName) + sprintf(left, "%s%s", + ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), + opt->longName); + if (!*left) goto out; + + if (argDescrip) { + char * le = left + strlen(left); + + if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) + *le++ = '['; + + /* Choose type of output */ + /*@-branchstate@*/ + if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) { + defs = singleOptionDefaultValue(lineLength, opt, translation_domain); + if (defs) { + char * t = (char *)malloc((help ? strlen(help) : 0) + + strlen(defs) + sizeof(" ")); + if (t) { + char * te = t; + *te = '\0'; + if (help) { + strcpy(te, help); te += strlen(te); + } + *te++ = ' '; + strcpy(te, defs); + defs = (char *)_free(defs); + } + defs = t; + } + } + /*@=branchstate@*/ + + if (opt->argDescrip == NULL) { + switch (opt->argInfo & POPT_ARG_MASK) { + case POPT_ARG_NONE: + break; + case POPT_ARG_VAL: +#ifdef NOTNOW /* XXX pug ugly nerdy output */ + { long aLong = opt->val; + int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS); + int negate = (opt->argInfo & POPT_ARGFLAG_NOT); + + /* Don't bother displaying typical values */ + if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L)) + break; + *le++ = '['; + switch (ops) { + case POPT_ARGFLAG_OR: + *le++ = '|'; + /*@innerbreak@*/ break; + case POPT_ARGFLAG_AND: + *le++ = '&'; + /*@innerbreak@*/ break; + case POPT_ARGFLAG_XOR: + *le++ = '^'; + /*@innerbreak@*/ break; + default: + /*@innerbreak@*/ break; + } + *le++ = '='; + if (negate) *le++ = '~'; + /*@-formatconst@*/ + le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong); + /*@=formatconst@*/ + *le++ = ']'; + } +#endif + break; + case POPT_ARG_INT: + case POPT_ARG_LONG: + case POPT_ARG_FLOAT: + case POPT_ARG_DOUBLE: + case POPT_ARG_STRING: + *le++ = '='; + strcpy(le, argDescrip); le += strlen(le); + break; + default: + break; + } + } else { + *le++ = '='; + strcpy(le, argDescrip); le += strlen(le); + } + if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) + *le++ = ']'; + *le = '\0'; + } +/*@=boundswrite@*/ + + if (help) + fprintf(fp," %-*s ", maxLeftCol, left); + else { + fprintf(fp," %s\n", left); + goto out; + } + + left = (char *)_free(left); + if (defs) { + help = defs; defs = NULL; + } + + helpLength = strlen(help); +/*@-boundsread@*/ + while (helpLength > lineLength) { + const char * ch; + char format[16]; + + ch = help + lineLength - 1; + while (ch > help && !isspace(*ch)) ch--; + if (ch == help) break; /* give up */ + while (ch > (help + 1) && isspace(*ch)) ch--; + ch++; + + sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength); + /*@-formatconst@*/ + fprintf(fp, format, help, " "); + /*@=formatconst@*/ + help = ch; + while (isspace(*help) && *help) help++; + helpLength = strlen(help); + } +/*@=boundsread@*/ + + if (helpLength) fprintf(fp, "%s\n", help); + +out: + /*@-dependenttrans@*/ + defs = (char *)_free(defs); + /*@=dependenttrans@*/ + left = (char *)_free(left); +} + +/** + * @param opt option(s) + * @param translation_domain translation domain + */ +static int maxArgWidth(const struct poptOption * opt, + /*@null@*/ const char * translation_domain) + /*@*/ +{ + int max = 0; + int len = 0; + const char * s; + + if (opt != NULL) + while (opt->longName || opt->shortName || opt->arg) { + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { + if (opt->arg) /* XXX program error */ + len = maxArgWidth((const struct poptOption *)opt->arg, translation_domain); + if (len > max) max = len; + } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { + len = sizeof(" ")-1; + if (opt->shortName != '\0') len += sizeof("-X")-1; + if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1; + if (opt->longName) { + len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH) + ? sizeof("-")-1 : sizeof("--")-1); + len += strlen(opt->longName); + } + + s = getArgDescrip(opt, translation_domain); + if (s) + len += sizeof("=")-1 + strlen(s); + if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1; + if (len > max) max = len; + } + + opt++; + } + + return max; +} + +/** + * Display popt alias and exec help. + * @param fp output file handle + * @param items alias/exec array + * @param nitems no. of alias/exec entries + * @param left + * @param translation_domain translation domain + */ +static void itemHelp(FILE * fp, + /*@null@*/ poptItem items, int nitems, int left, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/ +{ + poptItem item; + int i; + + if (items != NULL) + for (i = 0, item = items; i < nitems; i++, item++) { + const struct poptOption * opt; + opt = &item->option; + if ((opt->longName || opt->shortName) && + !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) + singleOptionHelp(fp, left, opt, translation_domain); + } +} + +/** + * Display help text for a table of options. + * @param con context + * @param fp output file handle + * @param table option(s) + * @param left + * @param translation_domain translation domain + */ +static void singleTableHelp(poptContext con, FILE * fp, + /*@null@*/ const struct poptOption * table, int left, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/ +{ + const struct poptOption * opt; + const char *sub_transdom; + + if (table == poptAliasOptions) { + itemHelp(fp, con->aliases, con->numAliases, left, NULL); + itemHelp(fp, con->execs, con->numExecs, left, NULL); + return; + } + + if (table != NULL) + for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { + if ((opt->longName || opt->shortName) && + !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) + singleOptionHelp(fp, left, opt, translation_domain); + } + + if (table != NULL) + for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { + if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE) + continue; + sub_transdom = getTableTranslationDomain( + (const struct poptOption *)opt->arg); + if (sub_transdom == NULL) + sub_transdom = translation_domain; + + if (opt->descrip) + fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip)); + + singleTableHelp(con, fp, (const struct poptOption *)opt->arg, left, sub_transdom); + } +} + +/** + * @param con context + * @param fp output file handle + */ +static int showHelpIntro(poptContext con, FILE * fp) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/ +{ + int len = 6; + const char * fn; + + fprintf(fp, POPT_("Usage:")); + if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) { +/*@-boundsread@*/ + /*@-nullderef@*/ /* LCL: wazzup? */ + fn = con->optionStack->argv[0]; + /*@=nullderef@*/ +/*@=boundsread@*/ + if (fn == NULL) return len; + if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1; + fprintf(fp, " %s", fn); + len += strlen(fn) + 1; + } + + return len; +} + +void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) +{ + int leftColWidth; + + (void) showHelpIntro(con, fp); + if (con->otherHelp) + fprintf(fp, " %s\n", con->otherHelp); + else + fprintf(fp, " %s\n", POPT_("[OPTION...]")); + + leftColWidth = maxArgWidth(con->options, NULL); + singleTableHelp(con, fp, con->options, leftColWidth, NULL); +} + +/** + * @param fp output file handle + * @param cursor + * @param opt option(s) + * @param translation_domain translation domain + */ +static int singleOptionUsage(FILE * fp, int cursor, + const struct poptOption * opt, + /*@null@*/ const char *translation_domain) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/ +{ + int len = 4; + char shortStr[2] = { '\0', '\0' }; + const char * item = shortStr; + const char * argDescrip = getArgDescrip(opt, translation_domain); + + if (opt->shortName != '\0' && opt->longName != NULL) { + len += 2; + if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; + len += strlen(opt->longName); + } else if (opt->shortName != '\0') { + len++; + shortStr[0] = opt->shortName; + shortStr[1] = '\0'; + } else if (opt->longName) { + len += strlen(opt->longName); + if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; + item = opt->longName; + } + + if (len == 4) return cursor; + + if (argDescrip) + len += strlen(argDescrip) + 1; + + if ((cursor + len) > 79) { + fprintf(fp, "\n "); + cursor = 7; + } + + if (opt->longName && opt->shortName) { + fprintf(fp, " [-%c|-%s%s%s%s]", + opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"), + opt->longName, + (argDescrip ? " " : ""), + (argDescrip ? argDescrip : "")); + } else { + fprintf(fp, " [-%s%s%s%s]", + ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"), + item, + (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""), + (argDescrip ? argDescrip : "")); + } + + return cursor + len + 1; +} + +/** + * Display popt alias and exec usage. + * @param fp output file handle + * @param cursor + * @param item alias/exec array + * @param nitems no. of ara/exec entries + * @param translation_domain translation domain + */ +static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies *fp, fileSystem @*/ +{ + int i; + + /*@-branchstate@*/ /* FIX: W2DO? */ + if (item != NULL) + for (i = 0; i < nitems; i++, item++) { + const struct poptOption * opt; + opt = &item->option; + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { + translation_domain = (const char *)opt->arg; + } else if ((opt->longName || opt->shortName) && + !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { + cursor = singleOptionUsage(fp, cursor, opt, translation_domain); + } + } + /*@=branchstate@*/ + + return cursor; +} + +/** + * Keep track of option tables already processed. + */ +typedef struct poptDone_s { + int nopts; + int maxopts; + const void ** opts; +} * poptDone; + +/** + * Display usage text for a table of options. + * @param con context + * @param fp output file handle + * @param cursor + * @param opt option(s) + * @param translation_domain translation domain + * @param done tables already processed + * @return + */ +static int singleTableUsage(poptContext con, FILE * fp, int cursor, + /*@null@*/ const struct poptOption * opt, + /*@null@*/ const char * translation_domain, + /*@null@*/ poptDone done) + /*@globals fileSystem @*/ + /*@modifies *fp, done, fileSystem @*/ +{ + /*@-branchstate@*/ /* FIX: W2DO? */ + if (opt != NULL) + for (; (opt->longName || opt->shortName || opt->arg) ; opt++) { + if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { + translation_domain = (const char *)opt->arg; + } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { + if (done) { + int i = 0; + for (i = 0; i < done->nopts; i++) { +/*@-boundsread@*/ + const void * that = done->opts[i]; +/*@=boundsread@*/ + if (that == NULL || that != opt->arg) + /*@innercontinue@*/ continue; + /*@innerbreak@*/ break; + } + /* Skip if this table has already been processed. */ + if (opt->arg == NULL || i < done->nopts) + continue; +/*@-boundswrite@*/ + if (done->nopts < done->maxopts) + done->opts[done->nopts++] = (const void *) opt->arg; +/*@=boundswrite@*/ + } + cursor = singleTableUsage(con, fp, cursor, (const struct poptOption *)opt->arg, + translation_domain, done); + } else if ((opt->longName || opt->shortName) && + !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { + cursor = singleOptionUsage(fp, cursor, opt, translation_domain); + } + } + /*@=branchstate@*/ + + return cursor; +} + +/** + * Return concatenated short options for display. + * @todo Sub-tables should be recursed. + * @param opt option(s) + * @param fp output file handle + * @retval str concatenation of short options + * @return length of display string + */ +static int showShortOptions(const struct poptOption * opt, FILE * fp, + /*@null@*/ char * str) + /*@globals fileSystem @*/ + /*@modifies *str, *fp, fileSystem @*/ + /*@requires maxRead(str) >= 0 @*/ +{ + /* bufsize larger then the ascii set, lazy alloca on top level call. */ + char * s = (str != NULL ? str : (char *)memset(alloca(300), 0, 300)); + int len = 0; + +/*@-boundswrite@*/ + if (opt != NULL) + for (; (opt->longName || opt->shortName || opt->arg); opt++) { + if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK)) + s[strlen(s)] = opt->shortName; + else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) + if (opt->arg) /* XXX program error */ + len = showShortOptions( + (const struct poptOption *)opt->arg, fp, s); + } +/*@=boundswrite@*/ + + /* On return to top level, print the short options, return print length. */ + if (s == str && *s != '\0') { + fprintf(fp, " [-%s]", s); + len = strlen(s) + sizeof(" [-]")-1; + } + return len; +} + +void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) +{ + poptDone done = (poptDone)memset(alloca(sizeof(*done)), 0, sizeof(*done)); + int cursor; + + done->nopts = 0; + done->maxopts = 64; + cursor = done->maxopts * sizeof(*done->opts); +/*@-boundswrite@*/ + done->opts = (const void **)memset(alloca(cursor), 0, cursor); + done->opts[done->nopts++] = (const void *) con->options; +/*@=boundswrite@*/ + + cursor = showHelpIntro(con, fp); + cursor += showShortOptions(con->options, fp, NULL); + cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done); + cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL); + cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL); + + if (con->otherHelp) { + cursor += strlen(con->otherHelp) + 1; + if (cursor > 79) fprintf(fp, "\n "); + fprintf(fp, " %s", con->otherHelp); + } + + fprintf(fp, "\n"); +} + +void poptSetOtherOptionHelp(poptContext con, const char * text) +{ + con->otherHelp = (const char *)_free(con->otherHelp); + con->otherHelp = xstrdup(text); +} +/*@=type@*/ diff --git a/lib/popt/poptint.h b/lib/popt/poptint.h new file mode 100644 index 0000000000..5d308efe96 --- /dev/null +++ b/lib/popt/poptint.h @@ -0,0 +1,116 @@ +/** \ingroup popt + * \file popt/poptint.h + */ + +/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#ifndef H_POPTINT +#define H_POPTINT + +/** + * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL. + * @param p memory to free + * @retval NULL always + */ +/*@unused@*/ static inline /*@null@*/ void * +_free(/*@only@*/ /*@null@*/ const void * p) + /*@modifies p @*/ +{ + if (p != NULL) free((void *)p); + return NULL; +} + +/* Bit mask macros. */ +/*@-exporttype -redef @*/ +typedef unsigned int __pbm_bits; +/*@=exporttype =redef @*/ +#define __PBM_NBITS (8 * sizeof (__pbm_bits)) +#define __PBM_IX(d) ((d) / __PBM_NBITS) +#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS)) +/*@-exporttype -redef @*/ +typedef struct { + __pbm_bits bits[1]; +} pbm_set; +/*@=exporttype =redef @*/ +#define __PBM_BITS(set) ((set)->bits) + +#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits)) +#define PBM_FREE(s) _free(s); +#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d)) +#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d)) +#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0) + +struct optionStackEntry { + int argc; +/*@only@*/ /*@null@*/ + const char ** argv; +/*@only@*/ /*@null@*/ + pbm_set * argb; + int next; +/*@only@*/ /*@null@*/ + const char * nextArg; +/*@observer@*/ /*@null@*/ + const char * nextCharArg; +/*@dependent@*/ /*@null@*/ + poptItem currAlias; + int stuffed; +}; + +struct poptContext_s { + struct optionStackEntry optionStack[POPT_OPTION_DEPTH]; +/*@dependent@*/ + struct optionStackEntry * os; +/*@owned@*/ /*@null@*/ + const char ** leftovers; + int numLeftovers; + int nextLeftover; +/*@keep@*/ + const struct poptOption * options; + int restLeftover; +/*@only@*/ /*@null@*/ + const char * appName; +/*@only@*/ /*@null@*/ + poptItem aliases; + int numAliases; + int flags; +/*@owned@*/ /*@null@*/ + poptItem execs; + int numExecs; +/*@only@*/ /*@null@*/ + const char ** finalArgv; + int finalArgvCount; + int finalArgvAlloced; +/*@dependent@*/ /*@null@*/ + poptItem doExec; +/*@only@*/ + const char * execPath; + int execAbsolute; +/*@only@*/ + const char * otherHelp; +/*@null@*/ + pbm_set * arg_strip; +}; + +#ifdef HAVE_LIBINTL_H +#include +#endif + +#if defined(HAVE_GETTEXT) && !defined(__LCLINT__) +#define _(foo) gettext(foo) +#else +#define _(foo) foo +#endif + +#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) +#define D_(dom, str) dgettext(dom, str) +#define POPT_(foo) D_("popt", foo) +#else +#define D_(dom, str) str +#define POPT_(foo) foo +#endif + +#define N_(foo) foo + +#endif diff --git a/lib/popt/poptparse.c b/lib/popt/poptparse.c new file mode 100644 index 0000000000..b03deef085 --- /dev/null +++ b/lib/popt/poptparse.c @@ -0,0 +1,227 @@ +/** \ingroup popt + * \file popt/poptparse.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#include "system.h" + +#define POPT_ARGV_ARRAY_GROW_DELTA 5 + +/*@-boundswrite@*/ +int poptDupArgv(int argc, const char **argv, + int * argcPtr, const char *** argvPtr) +{ + size_t nb = (argc + 1) * sizeof(*argv); + const char ** argv2; + char * dst; + int i; + + if (argc <= 0 || argv == NULL) /* XXX can't happen */ + return POPT_ERROR_NOARG; + for (i = 0; i < argc; i++) { + if (argv[i] == NULL) + return POPT_ERROR_NOARG; + nb += strlen(argv[i]) + 1; + } + + dst = (char *)malloc(nb); + if (dst == NULL) /* XXX can't happen */ + return POPT_ERROR_MALLOC; + argv2 = (const char **) dst; + dst += (argc + 1) * sizeof(*argv); + + /*@-branchstate@*/ + for (i = 0; i < argc; i++) { + argv2[i] = dst; + dst += strlen(strcpy(dst, argv[i])) + 1; + } + /*@=branchstate@*/ + argv2[argc] = NULL; + + if (argvPtr) { + *argvPtr = argv2; + } else { + free(argv2); + argv2 = NULL; + } + if (argcPtr) + *argcPtr = argc; + return 0; +} +/*@=boundswrite@*/ + +/*@-bounds@*/ +int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) +{ + const char * src; + char quote = '\0'; + int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; + const char ** argv = (const char **)malloc(sizeof(*argv) * argvAlloced); + int argc = 0; + int buflen = strlen(s) + 1; + char * buf = (char*)memset(alloca(buflen), 0, buflen); + int rc = POPT_ERROR_MALLOC; + + if (argv == NULL) return rc; + argv[argc] = buf; + + for (src = s; *src != '\0'; src++) { + if (quote == *src) { + quote = '\0'; + } else if (quote != '\0') { + if (*src == '\\') { + src++; + if (!*src) { + rc = POPT_ERROR_BADQUOTE; + goto exit; + } + if (*src != quote) *buf++ = '\\'; + } + *buf++ = *src; + } else if (isspace(*src)) { + if (*argv[argc] != '\0') { + buf++, argc++; + if (argc == argvAlloced) { + argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; + argv = (const char **)realloc(argv, sizeof(*argv) * argvAlloced); + if (argv == NULL) goto exit; + } + argv[argc] = buf; + } + } else switch (*src) { + case '"': + case '\'': + quote = *src; + /*@switchbreak@*/ break; + case '\\': + src++; + if (!*src) { + rc = POPT_ERROR_BADQUOTE; + goto exit; + } + /*@fallthrough@*/ + default: + *buf++ = *src; + /*@switchbreak@*/ break; + } + } + + if (strlen(argv[argc])) { + argc++, buf++; + } + + rc = poptDupArgv(argc, argv, argcPtr, argvPtr); + +exit: + if (argv) free(argv); + return rc; +} +/*@=bounds@*/ + +/* still in the dev stage. + * return values, perhaps 1== file erro + * 2== line to long + * 3== umm.... more? + */ +int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags) +{ + char line[999]; + char * argstr; + char * p; + char * q; + char * x; + int t; + int argvlen = 0; + size_t maxlinelen = sizeof(line); + size_t linelen; + int maxargvlen = 480; + int linenum = 0; + + *argstrp = NULL; + + /* | this_is = our_line + * p q x + */ + + if (fp == NULL) + return POPT_ERROR_NULLARG; + + argstr = (char *)calloc(maxargvlen, sizeof(*argstr)); + if (argstr == NULL) return POPT_ERROR_MALLOC; + + while (fgets(line, (int)maxlinelen, fp) != NULL) { + linenum++; + p = line; + + /* loop until first non-space char or EOL */ + while( *p != '\0' && isspace(*p) ) + p++; + + linelen = strlen(p); + if (linelen >= maxlinelen-1) + return POPT_ERROR_OVERFLOW; /* XXX line too long */ + + if (*p == '\0' || *p == '\n') continue; /* line is empty */ + if (*p == '#') continue; /* comment line */ + + q = p; + + while (*q != '\0' && (!isspace(*q)) && *q != '=') + q++; + + if (isspace(*q)) { + /* a space after the name, find next non space */ + *q++='\0'; + while( *q != '\0' && isspace((int)*q) ) q++; + } + if (*q == '\0') { + /* single command line option (ie, no name=val, just name) */ + q[-1] = '\0'; /* kill off newline from fgets() call */ + argvlen += (t = q - p) + (sizeof(" --")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = (char *)realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strcat(argstr, " --"); + strcat(argstr, p); + continue; + } + if (*q != '=') + continue; /* XXX for now, silently ignore bogus line */ + + /* *q is an equal sign. */ + *q++ = '\0'; + + /* find next non-space letter of value */ + while (*q != '\0' && isspace(*q)) + q++; + if (*q == '\0') + continue; /* XXX silently ignore missing value */ + + /* now, loop and strip all ending whitespace */ + x = p + linelen; + while (isspace(*--x)) + *x = 0; /* null out last char if space (including fgets() NL) */ + + /* rest of line accept */ + t = x - p; + argvlen += t + (sizeof("' --='")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = (char *)realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strcat(argstr, " --"); + strcat(argstr, p); + strcat(argstr, "=\""); + strcat(argstr, q); + strcat(argstr, "\""); + } + + *argstrp = argstr; + return 0; +} diff --git a/lib/popt/samba.m4 b/lib/popt/samba.m4 new file mode 100644 index 0000000000..627dd854b2 --- /dev/null +++ b/lib/popt/samba.m4 @@ -0,0 +1,8 @@ +m4_include(../lib/popt/libpopt.m4) + +if test x"$POPT_OBJ" = "x"; then + SMB_EXT_LIB(LIBPOPT, [${POPT_LIBS}]) +else + SMB_INCLUDE_MK(../lib/popt/config.mk) +fi + diff --git a/lib/popt/system.h b/lib/popt/system.h new file mode 100644 index 0000000000..1d1b9dae88 --- /dev/null +++ b/lib/popt/system.h @@ -0,0 +1,76 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined (__GLIBC__) && defined(__LCLINT__) +/*@-declundef@*/ +/*@unchecked@*/ +extern __const __int32_t *__ctype_tolower; +/*@unchecked@*/ +extern __const __int32_t *__ctype_toupper; +/*@=declundef@*/ +#endif + +#include + +#include +#include +#include + +#if HAVE_MCHECK_H +#include +#endif + +#include +#include +#include + +#if HAVE_UNISTD_H +#include +#endif + +#ifdef __NeXT +/* access macros are not declared in non posix mode in unistd.h - + don't try to use posix on NeXTstep 3.3 ! */ +#include +#endif + +#if defined(__LCLINT__) +/*@-declundef -incondefs -redecl@*/ /* LCL: missing annotation */ +/*@only@*/ void * alloca (size_t __size) + /*@ensures MaxSet(result) == (__size - 1) @*/ + /*@*/; +/*@=declundef =incondefs =redecl@*/ +#endif + +/* AIX requires this to be the first thing in the file. */ +#ifndef __GNUC__ +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX +#pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +#elif defined(__GNUC__) && defined(__STRICT_ANSI__) +#define alloca __builtin_alloca +#endif + +/*@-redecl -redef@*/ +/*@mayexit@*/ /*@only@*/ char * xstrdup (const char *str) + /*@*/; +/*@=redecl =redef@*/ + +#if HAVE_MCHECK_H && defined(__GNUC__) +#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL) +#define xstrdup(_str) (strcpy((malloc(strlen(_str)+1) ? : vmefail()), (_str))) +#else +#define xstrdup(_str) strdup(_str) +#endif /* HAVE_MCHECK_H && defined(__GNUC__) */ + + +#include "popt.h" diff --git a/lib/replace/.checker_innocent b/lib/replace/.checker_innocent new file mode 100644 index 0000000000..e619176540 --- /dev/null +++ b/lib/replace/.checker_innocent @@ -0,0 +1,4 @@ +>>>MISTAKE21_create_files_6a9e68ada99a97cb +>>>MISTAKE21_os2_delete_9b2bfa7f38711d09 +>>>MISTAKE21_os2_delete_2fcc29aaa99a97cb +>>>SECURITY2_os2_delete_9b2bfa7f1c9396ca diff --git a/lib/replace/Makefile.in b/lib/replace/Makefile.in new file mode 100644 index 0000000000..c989835a8d --- /dev/null +++ b/lib/replace/Makefile.in @@ -0,0 +1,63 @@ +#!gmake +# +CC = @CC@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +includedir = @includedir@ +libdir = @libdir@ +VPATH = @libreplacedir@ +srcdir = @srcdir@ +builddir = @builddir@ +INSTALL = @INSTALL@ +LIBS = @LIBS@ + +.PHONY: test all showflags install installcheck clean distclean realdistclean + +CFLAGS=-I. @CFLAGS@ +LDFLAGS=@LDFLAGS@ + +OBJS = @LIBREPLACEOBJ@ + +all: showflags libreplace.a testsuite + +showflags: + @echo 'libreplace will be compiled with flags:' + @echo ' CC = $(CC)' + @echo ' CFLAGS = $(CFLAGS)' + @echo ' LDFLAGS= $(LDFLAGS)' + @echo ' LIBS = $(LIBS)' + +install: all + mkdir -p $(libdir) + $(INSTALL) libreplace.a $(libdir) + +libreplace.a: $(OBJS) + ar -rcsv $@ $(OBJS) + +test: all + ./testsuite + +installcheck: install test + +TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o test/getifaddrs.o + +testsuite: libreplace.a $(TEST_OBJS) + $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) $(LIBS) + +.c.o: + @echo Compiling $*.c + @mkdir -p `dirname $@` + @$(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f *.o test/*.o *.a testsuite + rm -f testfile.dat + +distclean: clean + rm -f *~ */*~ + rm -f config.log config.status config.h config.cache + rm -f Makefile + +realdistclean: distclean + rm -f configure config.h.in diff --git a/lib/replace/README b/lib/replace/README new file mode 100644 index 0000000000..4d94317c4b --- /dev/null +++ b/lib/replace/README @@ -0,0 +1,113 @@ +This subsystem ensures that we can always use a certain core set of +functions and types, that are either provided by the OS or by replacement +functions / definitions in this subsystem. The aim is to try to stick +to POSIX functions in here as much as possible. Convenience functions +that are available on no platform at all belong in other subsystems +(such as LIBUTIL). + +The following functions are guaranteed: + +ftruncate +strlcpy +strlcat +mktime +rename +initgroups +memmove +strdup +setlinebuf +vsyslog +timegm +setenv +unsetenv +strndup +strnlen +waitpid +seteuid +setegid +asprintf +snprintf +vasprintf +vsnprintf +opendir +readdir +telldir +seekdir +closedir +dlopen +dlclose +dlsym +dlerror +chroot +bzero +strerror +errno +mkdtemp +mkstemp (a secure one!) +pread +pwrite +getpass +readline (the library) +inet_ntoa +inet_ntop +inet_pton +inet_aton +strtoll +strtoull +socketpair +strptime +getaddrinfo +freeaddrinfo +getnameinfo +gai_strerror +getifaddrs +freeifaddrs +utime +utimes + +Types: +bool +socklen_t +uint_t +uint{8,16,32,64}_t +int{8,16,32,64}_t +intptr_t + +Constants: +PATH_NAME_MAX +UINT{16,32,64}_MAX +INT32_MAX +RTLD_LAZY +HOST_NAME_MAX +UINT16_MAX +UINT32_MAX +UINT64_MAX +CHAR_BIT + +Macros: +va_copy +__FUNCTION__ +__FILE__ +__LINE__ +__LINESTR__ +__location__ +__STRING +__STRINGSTRING +MIN +MAX +QSORT_CAST +ZERO_STRUCT +ZERO_STRUCTP +ZERO_STRUCTPN +ZERO_ARRAY +ARRAY_SIZE +PTR_DIFF + +Headers: +stdint.h +stdbool.h + +Prerequisites: +memset (for bzero) +syslog (for vsyslog) +mktemp (for mkstemp and mkdtemp) diff --git a/lib/replace/aclocal.m4 b/lib/replace/aclocal.m4 new file mode 100644 index 0000000000..5605e476ba --- /dev/null +++ b/lib/replace/aclocal.m4 @@ -0,0 +1 @@ +m4_include(libreplace.m4) diff --git a/lib/replace/autoconf-2.60.m4 b/lib/replace/autoconf-2.60.m4 new file mode 100644 index 0000000000..acdcd38efe --- /dev/null +++ b/lib/replace/autoconf-2.60.m4 @@ -0,0 +1,210 @@ +# AC_GNU_SOURCE +# -------------- +AC_DEFUN([AC_GNU_SOURCE], +[AH_VERBATIM([_GNU_SOURCE], +[/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif])dnl +AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_RUN_IFELSE])dnl +AC_DEFINE([_GNU_SOURCE]) +]) + +# _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, +# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) +# -------------------------------------------------------------- +# Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99') +# by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails, +# try again with each compiler option in the space-separated OPTION-LIST; if one +# helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE, +# else ACTION-IF-UNAVAILABLE. +AC_DEFUN([_AC_C_STD_TRY], +[AC_MSG_CHECKING([for $CC option to accept ISO ]m4_translit($1, [c], [C])) +AC_CACHE_VAL(ac_cv_prog_cc_$1, +[ac_cv_prog_cc_$1=no +ac_save_CC=$CC +AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) +for ac_arg in '' $4 +do + CC="$ac_save_CC $ac_arg" + _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg]) + test "x$ac_cv_prog_cc_$1" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +])# AC_CACHE_VAL +case "x$ac_cv_prog_cc_$1" in + x) + AC_MSG_RESULT([none needed]) ;; + xno) + AC_MSG_RESULT([unsupported]) ;; + *) + CC="$CC $ac_cv_prog_cc_$1" + AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;; +esac +AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6]) +])# _AC_C_STD_TRY + +# _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) +# ---------------------------------------------------------------- +# If the C compiler is not in ISO C99 mode by default, try to add an +# option to output variable CC to make it so. This macro tries +# various options that select ISO C99 on some system or another. It +# considers the compiler to be in ISO C99 mode if it handles mixed +# code and declarations, _Bool, inline and restrict. +AC_DEFUN([_AC_PROG_CC_C99], +[_AC_C_STD_TRY([c99], +[[#include +#include +#include +#include +#include + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict(ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy work. +static void +test_varargs(const char *format, ...) +{ + va_list args; + va_start(args, format); + va_list args_copy; + va_copy(args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg(args_copy, const char *); + break; + case 'd': // int + number = va_arg(args_copy, int); + break; + case 'f': // float + fnumber = (float) va_arg(args_copy, double); + break; + default: + break; + } + } + va_end(args_copy); + va_end(args); +} +]], +[[ + // Check bool and long long datatypes. + _Bool success = false; + long long int bignum = -1234567890LL; + unsigned long long int ubignum = 1234567890uLL; + + // Check restrict. + if (test_restrict("String literal") != 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs("s, d' f .", "string", 65, 34.234); + + // Check incomplete arrays work. + struct incomplete_array *ia = + malloc(sizeof(struct incomplete_array) + (sizeof(double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = (double) i * 1.234; + + // Check named initialisers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[43] = 543; + + // work around unused variable warnings + return bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'; +]], +dnl Try +dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999) +dnl AIX -qlanglvl=extc99 (unused restrictive mode: -qlanglvl=stdc99) +dnl Intel ICC -c99 +dnl IRIX -c99 +dnl Solaris (unused because it causes the compiler to assume C99 semantics for +dnl library functions, and this is invalid before Solaris 10: -xc99) +dnl Tru64 -c99 +dnl with extended modes being tried first. +[[-std=gnu99 -c99 -qlanglvl=extc99]], [$1], [$2])[]dnl +])# _AC_PROG_CC_C99 + +# AC_PROG_CC_C99 +# -------------- +AC_DEFUN([AC_PROG_CC_C99], +[ AC_REQUIRE([AC_PROG_CC])dnl + _AC_PROG_CC_C99 +]) + +# AC_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS], +[ + AC_BEFORE([$0], [AC_COMPILE_IFELSE]) + AC_BEFORE([$0], [AC_RUN_IFELSE]) + + AC_REQUIRE([AC_GNU_SOURCE]) + AC_REQUIRE([AC_AIX]) + AC_REQUIRE([AC_MINIX]) + + AH_VERBATIM([__EXTENSIONS__], +[/* Enable extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif]) + AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], + [ac_cv_safe_to_define___extensions__], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([ +# define __EXTENSIONS__ 1 + AC_INCLUDES_DEFAULT])], + [ac_cv_safe_to_define___extensions__=yes], + [ac_cv_safe_to_define___extensions__=no])]) + test $ac_cv_safe_to_define___extensions__ = yes && + AC_DEFINE([__EXTENSIONS__]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) +]) diff --git a/lib/replace/autogen.sh b/lib/replace/autogen.sh new file mode 100755 index 0000000000..d46a4279f3 --- /dev/null +++ b/lib/replace/autogen.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +rm -rf autom4te.cache +rm -f configure config.h.in + +autoheader || exit 1 +autoconf || exit 1 + +rm -rf autom4te.cache + +echo "Now run ./configure and then make." +exit 0 + diff --git a/lib/replace/config.guess b/lib/replace/config.guess new file mode 100755 index 0000000000..354dbe175a --- /dev/null +++ b/lib/replace/config.guess @@ -0,0 +1,1464 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-08-03' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/replace/config.sub b/lib/replace/config.sub new file mode 100755 index 0000000000..23cd6fd75c --- /dev/null +++ b/lib/replace/config.sub @@ -0,0 +1,1577 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ms1 \ + | msp430 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | ms1-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/replace/configure.ac b/lib/replace/configure.ac new file mode 100644 index 0000000000..81997e09b7 --- /dev/null +++ b/lib/replace/configure.ac @@ -0,0 +1,30 @@ +AC_PREREQ(2.50) +AC_INIT(replace.c) +AC_CONFIG_SRCDIR([replace.c]) +AC_CONFIG_HEADER(config.h) + +CFLAGS="$CFLAGS -I$srcdir" + +AC_LIBREPLACE_ALL_CHECKS +AC_LIBREPLACE_NETWORK_CHECKS + +if test "$ac_cv_prog_gcc" = yes; then + CFLAGS="$CFLAGS -Wall" + CFLAGS="$CFLAGS -W" + CFLAGS="$CFLAGS -Wshadow" + CFLAGS="$CFLAGS -Wstrict-prototypes" + CFLAGS="$CFLAGS -Wpointer-arith" + CFLAGS="$CFLAGS -Wcast-qual" + CFLAGS="$CFLAGS -Wcast-align" + CFLAGS="$CFLAGS -Wwrite-strings" + CFLAGS="$CFLAGS -Werror-implicit-function-declaration" + CFLAGS="$CFLAGS -Wformat=2" + CFLAGS="$CFLAGS -Wno-format-y2k" +fi + +LIBS="${LIBREPLACE_NETWORK_LIBS}" +AC_SUBST(LIBS) + +AC_SUBST(LDFLAGS) + +AC_OUTPUT(Makefile) diff --git a/lib/replace/dlfcn.c b/lib/replace/dlfcn.c new file mode 100644 index 0000000000..3b109d7e40 --- /dev/null +++ b/lib/replace/dlfcn.c @@ -0,0 +1,75 @@ +/* + Unix SMB/CIFS implementation. + Samba system utilities + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 1998-2002 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#ifdef HAVE_DL_H +#include +#endif + +#ifndef HAVE_DLOPEN +#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS +void *rep_dlopen(const char *name, unsigned int flags) +#else +void *rep_dlopen(const char *name, int flags) +#endif +{ +#ifdef HAVE_SHL_LOAD + if (name == NULL) + return PROG_HANDLE; + return (void *)shl_load(name, flags, 0); +#else + return NULL; +#endif +} +#endif + +#ifndef HAVE_DLSYM +void *rep_dlsym(void *handle, const char *symbol) +{ +#ifdef HAVE_SHL_FINDSYM + void *sym_addr; + if (!shl_findsym((shl_t *)&handle, symbol, TYPE_UNDEFINED, &sym_addr)) + return sym_addr; +#endif + return NULL; +} +#endif + +#ifndef HAVE_DLERROR +char *rep_dlerror(void) +{ + return "dynamic loading of objects not supported on this platform"; +} +#endif + +#ifndef HAVE_DLCLOSE +int rep_dlclose(void *handle) +{ +#ifdef HAVE_SHL_CLOSE + return shl_unload((shl_t)handle); +#else + return 0; +#endif +} +#endif diff --git a/lib/replace/dlfcn.m4 b/lib/replace/dlfcn.m4 new file mode 100644 index 0000000000..42f56f26be --- /dev/null +++ b/lib/replace/dlfcn.m4 @@ -0,0 +1,31 @@ +dnl dummies provided by dlfcn.c if not available +save_LIBS="$LIBS" +LIBS="" + +libreplace_cv_dlfcn=no +AC_SEARCH_LIBS(dlopen, dl) + +AC_CHECK_HEADERS(dlfcn.h) +AC_CHECK_FUNCS([dlopen dlsym dlerror dlclose],[],[libreplace_cv_dlfcn=yes]) + +libreplace_cv_shl=no +AC_SEARCH_LIBS(shl_load, sl) +AC_CHECK_HEADERS(dl.h) +AC_CHECK_FUNCS([shl_load shl_unload shl_findsym],[],[libreplace_cv_shl=yes]) + +AC_VERIFY_C_PROTOTYPE([void *dlopen(const char* filename, unsigned int flags)], + [ + return 0; + ],[ + AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsigned int flags]) + ],[],[ + #include + ]) + +if test x"${libreplace_cv_dlfcn}" = x"yes";then + LIBREPLACEOBJ="${LIBREPLACEOBJ} dlfcn.o" +fi + +LIBDL="$LIBS" +AC_SUBST(LIBDL) +LIBS="$save_LIBS" diff --git a/lib/replace/getaddrinfo.c b/lib/replace/getaddrinfo.c new file mode 100644 index 0000000000..c5cd52be93 --- /dev/null +++ b/lib/replace/getaddrinfo.c @@ -0,0 +1,497 @@ +/* +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this paragraph +and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +*/ + +/*------------------------------------------------------------------------- + * + * getaddrinfo.c + * Support getaddrinfo() on platforms that don't have it. + * + * We also supply getnameinfo() here, assuming that the platform will have + * it if and only if it has getaddrinfo(). If this proves false on some + * platform, we'll need to split this file and provide a separate configure + * test for getnameinfo(). + * + * Copyright (c) 2003-2007, PostgreSQL Global Development Group + * + * Copyright (C) 2007 Jeremy Allison. + * Modified to return multiple IPv4 addresses for Samba. + * + *------------------------------------------------------------------------- + */ + +#include "replace.h" +#include "system/network.h" + +#ifndef SMB_MALLOC +#define SMB_MALLOC(s) malloc(s) +#endif + +#ifndef SMB_STRDUP +#define SMB_STRDUP(s) strdup(s) +#endif + +static int check_hostent_err(struct hostent *hp) +{ + if (!hp) { + switch (h_errno) { + case HOST_NOT_FOUND: + case NO_DATA: + return EAI_NONAME; + case TRY_AGAIN: + return EAI_AGAIN; + case NO_RECOVERY: + default: + return EAI_FAIL; + } + } + if (!hp->h_name || hp->h_addrtype != AF_INET) { + return EAI_FAIL; + } + return 0; +} + +static char *canon_name_from_hostent(struct hostent *hp, + int *perr) +{ + char *ret = NULL; + + *perr = check_hostent_err(hp); + if (*perr) { + return NULL; + } + ret = SMB_STRDUP(hp->h_name); + if (!ret) { + *perr = EAI_MEMORY; + } + return ret; +} + +static char *get_my_canon_name(int *perr) +{ + char name[HOST_NAME_MAX+1]; + + if (gethostname(name, HOST_NAME_MAX) == -1) { + *perr = EAI_FAIL; + return NULL; + } + /* Ensure null termination. */ + name[HOST_NAME_MAX] = '\0'; + return canon_name_from_hostent(gethostbyname(name), perr); +} + +static char *get_canon_name_from_addr(struct in_addr ip, + int *perr) +{ + return canon_name_from_hostent( + gethostbyaddr(&ip, sizeof(ip), AF_INET), + perr); +} + +static struct addrinfo *alloc_entry(const struct addrinfo *hints, + struct in_addr ip, + unsigned short port) +{ + struct sockaddr_in *psin = NULL; + struct addrinfo *ai = SMB_MALLOC(sizeof(*ai)); + + if (!ai) { + return NULL; + } + memset(ai, '\0', sizeof(*ai)); + + psin = SMB_MALLOC(sizeof(*psin)); + if (!psin) { + free(ai); + return NULL; + } + + memset(psin, '\0', sizeof(*psin)); + + psin->sin_family = AF_INET; + psin->sin_port = htons(port); + psin->sin_addr = ip; + + ai->ai_flags = 0; + ai->ai_family = AF_INET; + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + ai->ai_addrlen = sizeof(*psin); + ai->ai_addr = (struct sockaddr *) psin; + ai->ai_canonname = NULL; + ai->ai_next = NULL; + + return ai; +} + +/* + * get address info for a single ipv4 address. + * + * Bugs: - servname can only be a number, not text. + */ + +static int getaddr_info_single_addr(const char *service, + uint32_t addr, + const struct addrinfo *hints, + struct addrinfo **res) +{ + + struct addrinfo *ai = NULL; + struct in_addr ip; + unsigned short port = 0; + + if (service) { + port = (unsigned short)atoi(service); + } + ip.s_addr = htonl(addr); + + ai = alloc_entry(hints, ip, port); + if (!ai) { + return EAI_MEMORY; + } + + /* If we're asked for the canonical name, + * make sure it returns correctly. */ + if (!(hints->ai_flags & AI_NUMERICSERV) && + hints->ai_flags & AI_CANONNAME) { + int err; + if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) { + ai->ai_canonname = get_my_canon_name(&err); + } else { + ai->ai_canonname = + get_canon_name_from_addr(ip,&err); + } + if (ai->ai_canonname == NULL) { + freeaddrinfo(ai); + return err; + } + } + + *res = ai; + return 0; +} + +/* + * get address info for multiple ipv4 addresses. + * + * Bugs: - servname can only be a number, not text. + */ + +static int getaddr_info_name(const char *node, + const char *service, + const struct addrinfo *hints, + struct addrinfo **res) +{ + struct addrinfo *listp = NULL, *prevp = NULL; + char **pptr = NULL; + int err; + struct hostent *hp = NULL; + unsigned short port = 0; + + if (service) { + port = (unsigned short)atoi(service); + } + + hp = gethostbyname(node); + err = check_hostent_err(hp); + if (err) { + return err; + } + + for(pptr = hp->h_addr_list; *pptr; pptr++) { + struct in_addr ip = *(struct in_addr *)*pptr; + struct addrinfo *ai = alloc_entry(hints, ip, port); + + if (!ai) { + freeaddrinfo(listp); + return EAI_MEMORY; + } + + if (!listp) { + listp = ai; + prevp = ai; + ai->ai_canonname = SMB_STRDUP(hp->h_name); + if (!ai->ai_canonname) { + freeaddrinfo(listp); + return EAI_MEMORY; + } + } else { + prevp->ai_next = ai; + prevp = ai; + } + } + *res = listp; + return 0; +} + +/* + * get address info for ipv4 sockets. + * + * Bugs: - servname can only be a number, not text. + */ + +int rep_getaddrinfo(const char *node, + const char *service, + const struct addrinfo * hintp, + struct addrinfo ** res) +{ + struct addrinfo hints; + + /* Setup the hints struct. */ + if (hintp == NULL) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + } else { + memcpy(&hints, hintp, sizeof(hints)); + } + + if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) { + return EAI_FAMILY; + } + + if (hints.ai_socktype == 0) { + hints.ai_socktype = SOCK_STREAM; + } + + if (!node && !service) { + return EAI_NONAME; + } + + if (node) { + if (node[0] == '\0') { + return getaddr_info_single_addr(service, + INADDR_ANY, + &hints, + res); + } else if (hints.ai_flags & AI_NUMERICHOST) { + struct in_addr ip; + if (!inet_aton(node, &ip)) { + return EAI_FAIL; + } + return getaddr_info_single_addr(service, + ntohl(ip.s_addr), + &hints, + res); + } else { + return getaddr_info_name(node, + service, + &hints, + res); + } + } else if (hints.ai_flags & AI_PASSIVE) { + return getaddr_info_single_addr(service, + INADDR_ANY, + &hints, + res); + } + return getaddr_info_single_addr(service, + INADDR_LOOPBACK, + &hints, + res); +} + + +void rep_freeaddrinfo(struct addrinfo *res) +{ + struct addrinfo *next = NULL; + + for (;res; res = next) { + next = res->ai_next; + if (res->ai_canonname) { + free(res->ai_canonname); + } + if (res->ai_addr) { + free(res->ai_addr); + } + free(res); + } +} + + +const char *rep_gai_strerror(int errcode) +{ +#ifdef HAVE_HSTRERROR + int hcode; + + switch (errcode) + { + case EAI_NONAME: + hcode = HOST_NOT_FOUND; + break; + case EAI_AGAIN: + hcode = TRY_AGAIN; + break; + case EAI_FAIL: + default: + hcode = NO_RECOVERY; + break; + } + + return hstrerror(hcode); +#else /* !HAVE_HSTRERROR */ + + switch (errcode) + { + case EAI_NONAME: + return "Unknown host"; + case EAI_AGAIN: + return "Host name lookup failure"; +#ifdef EAI_BADFLAGS + case EAI_BADFLAGS: + return "Invalid argument"; +#endif +#ifdef EAI_FAMILY + case EAI_FAMILY: + return "Address family not supported"; +#endif +#ifdef EAI_MEMORY + case EAI_MEMORY: + return "Not enough memory"; +#endif +#ifdef EAI_NODATA + case EAI_NODATA: + return "No host data of that type was found"; +#endif +#ifdef EAI_SERVICE + case EAI_SERVICE: + return "Class type not found"; +#endif +#ifdef EAI_SOCKTYPE + case EAI_SOCKTYPE: + return "Socket type not supported"; +#endif + default: + return "Unknown server error"; + } +#endif /* HAVE_HSTRERROR */ +} + +static int gethostnameinfo(const struct sockaddr *sa, + char *node, + size_t nodelen, + int flags) +{ + int ret = -1; + char *p = NULL; + + if (!(flags & NI_NUMERICHOST)) { + struct hostent *hp = gethostbyaddr( + &((struct sockaddr_in *)sa)->sin_addr, + sizeof(struct in_addr), + sa->sa_family); + ret = check_hostent_err(hp); + if (ret == 0) { + /* Name looked up successfully. */ + ret = snprintf(node, nodelen, "%s", hp->h_name); + if (ret < 0 || (size_t)ret >= nodelen) { + return EAI_MEMORY; + } + if (flags & NI_NOFQDN) { + p = strchr(node,'.'); + if (p) { + *p = '\0'; + } + } + return 0; + } + + if (flags & NI_NAMEREQD) { + /* If we require a name and didn't get one, + * automatically fail. */ + return ret; + } + /* Otherwise just fall into the numeric host code... */ + } + p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); + ret = snprintf(node, nodelen, "%s", p); + if (ret < 0 || (size_t)ret >= nodelen) { + return EAI_MEMORY; + } + return 0; +} + +static int getservicenameinfo(const struct sockaddr *sa, + char *service, + size_t servicelen, + int flags) +{ + int ret = -1; + int port = ntohs(((struct sockaddr_in *)sa)->sin_port); + + if (!(flags & NI_NUMERICSERV)) { + struct servent *se = getservbyport( + port, + (flags & NI_DGRAM) ? "udp" : "tcp"); + if (se && se->s_name) { + /* Service name looked up successfully. */ + ret = snprintf(service, servicelen, "%s", se->s_name); + if (ret < 0 || (size_t)ret >= servicelen) { + return EAI_MEMORY; + } + return 0; + } + /* Otherwise just fall into the numeric service code... */ + } + ret = snprintf(service, servicelen, "%d", port); + if (ret < 0 || (size_t)ret >= servicelen) { + return EAI_MEMORY; + } + return 0; +} + +/* + * Convert an ipv4 address to a hostname. + * + * Bugs: - No IPv6 support. + */ +int rep_getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *node, size_t nodelen, + char *service, size_t servicelen, int flags) +{ + + /* Invalid arguments. */ + if (sa == NULL || (node == NULL && service == NULL)) { + return EAI_FAIL; + } + + if (sa->sa_family != AF_INET) { + return EAI_FAIL; + } + + if (salen < sizeof(struct sockaddr_in)) { + return EAI_FAIL; + } + + if (node) { + return gethostnameinfo(sa, node, nodelen, flags); + } + + if (service) { + return getservicenameinfo(sa, service, servicelen, flags); + } + return 0; +} diff --git a/lib/replace/getaddrinfo.h b/lib/replace/getaddrinfo.h new file mode 100644 index 0000000000..dddd699b62 --- /dev/null +++ b/lib/replace/getaddrinfo.h @@ -0,0 +1,89 @@ +/* +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this paragraph +and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +*/ + +/*------------------------------------------------------------------------- + * + * getaddrinfo.h + * Support getaddrinfo() on platforms that don't have it. + * + * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, + * whether or not the library routine getaddrinfo() can be found. This + * policy is needed because on some platforms a manually installed libbind.a + * may provide getaddrinfo(), yet the system headers may not provide the + * struct definitions needed to call it. To avoid conflict with the libbind + * definition in such cases, we rename our routines to pg_xxx() via macros. + * + +in lib/replace we use rep_xxx() + + * This code will also work on platforms where struct addrinfo is defined + * in the system headers but no getaddrinfo() can be located. + * + * Copyright (c) 2003-2007, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef GETADDRINFO_H +#define GETADDRINFO_H + +#ifndef HAVE_GETADDRINFO + +/* Rename private copies per comments above */ +#ifdef getaddrinfo +#undef getaddrinfo +#endif +#define getaddrinfo rep_getaddrinfo +#define HAVE_GETADDRINFO + +#ifdef freeaddrinfo +#undef freeaddrinfo +#endif +#define freeaddrinfo rep_freeaddrinfo +#define HAVE_FREEADDRINFO + +#ifdef gai_strerror +#undef gai_strerror +#endif +#define gai_strerror rep_gai_strerror +#define HAVE_GAI_STRERROR + +#ifdef getnameinfo +#undef getnameinfo +#endif +#define getnameinfo rep_getnameinfo +#define HAVE_GETNAMEINFO + +extern int rep_getaddrinfo(const char *node, const char *service, + const struct addrinfo * hints, struct addrinfo ** res); +extern void rep_freeaddrinfo(struct addrinfo * res); +extern const char *rep_gai_strerror(int errcode); +extern int rep_getnameinfo(const struct sockaddr * sa, socklen_t salen, + char *node, size_t nodelen, + char *service, size_t servicelen, int flags); +#endif /* HAVE_GETADDRINFO */ + +#endif /* GETADDRINFO_H */ diff --git a/lib/replace/getifaddrs.c b/lib/replace/getifaddrs.c new file mode 100644 index 0000000000..f6f0ec080c --- /dev/null +++ b/lib/replace/getifaddrs.c @@ -0,0 +1,361 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Jeremy Allison 2007 + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define SOCKET_WRAPPER_NOT_REPLACE + +#include "replace.h" +#include "system/network.h" + +#include +#include +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifndef SIOCGIFCONF +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#endif + +#ifdef HAVE_IFACE_GETIFADDRS +#define _FOUND_IFACE_ANY +#else + +void rep_freeifaddrs(struct ifaddrs *ifp) +{ + if (ifp != NULL) { + free(ifp->ifa_name); + free(ifp->ifa_addr); + free(ifp->ifa_netmask); + free(ifp->ifa_dstaddr); + freeifaddrs(ifp->ifa_next); + free(ifp); + } +} + +static struct sockaddr *sockaddr_dup(struct sockaddr *sa) +{ + struct sockaddr *ret; + socklen_t socklen; +#ifdef HAVE_SOCKADDR_SA_LEN + socklen = sa->sa_len; +#else + socklen = sizeof(struct sockaddr_storage); +#endif + ret = calloc(1, socklen); + if (ret == NULL) + return NULL; + memcpy(ret, sa, socklen); + return ret; +} +#endif + +#if HAVE_IFACE_IFCONF + +/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 + V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. + + It probably also works on any BSD style system. */ + +int rep_getifaddrs(struct ifaddrs **ifap) +{ + struct ifconf ifc; + char buff[8192]; + int fd, i, n; + struct ifreq *ifr=NULL; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + + if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + close(fd); + return -1; + } + + ifr = ifc.ifc_req; + + n = ifc.ifc_len / sizeof(struct ifreq); + + /* Loop through interfaces, looking for given IP address */ + for (i=n-1; i>=0; i--) { + if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) == -1) { + freeifaddrs(*ifap); + return -1; + } + + curif = calloc(1, sizeof(struct ifaddrs)); + curif->ifa_name = strdup(ifr[i].ifr_name); + curif->ifa_flags = ifr[i].ifr_flags; + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_next = NULL; + + curif->ifa_addr = NULL; + if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != -1) { + curif->ifa_addr = sockaddr_dup(&ifr[i].ifr_addr); + } + + curif->ifa_netmask = NULL; + if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != -1) { + curif->ifa_netmask = sockaddr_dup(&ifr[i].ifr_addr); + } + + if (lastif == NULL) { + *ifap = curif; + } else { + lastif->ifa_next = curif; + } + lastif = curif; + } + + close(fd); + + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFCONF */ +#ifdef HAVE_IFACE_IFREQ + +#ifndef I_STR +#include +#endif + +/**************************************************************************** +this should cover most of the streams based systems +Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code +****************************************************************************/ +int rep_getifaddrs(struct ifaddrs **ifap) +{ + struct ifreq ifreq; + struct strioctl strioctl; + char buff[8192]; + int fd, i, n; + struct ifreq *ifr=NULL; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + strioctl.ic_cmd = SIOCGIFCONF; + strioctl.ic_dp = buff; + strioctl.ic_len = sizeof(buff); + if (ioctl(fd, I_STR, &strioctl) < 0) { + close(fd); + return -1; + } + + /* we can ignore the possible sizeof(int) here as the resulting + number of interface structures won't change */ + n = strioctl.ic_len / sizeof(struct ifreq); + + /* we will assume that the kernel returns the length as an int + at the start of the buffer if the offered size is a + multiple of the structure size plus an int */ + if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { + ifr = (struct ifreq *)(buff + sizeof(int)); + } else { + ifr = (struct ifreq *)buff; + } + + /* Loop through interfaces */ + + for (i = 0; iifa_next = curif; + } + + strioctl.ic_cmd = SIOCGIFFLAGS; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_flags = ifreq.ifr_flags; + + strioctl.ic_cmd = SIOCGIFADDR; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_name = strdup(ifreq.ifr_name); + curif->ifa_addr = sockaddr_dup(&ifreq.ifr_addr); + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_next = NULL; + curif->ifa_netmask = NULL; + + strioctl.ic_cmd = SIOCGIFNETMASK; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_netmask = sockaddr_dup(&ifreq.ifr_addr); + + lastif = curif; + } + + close(fd); + + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFREQ */ +#ifdef HAVE_IFACE_AIX + +/**************************************************************************** +this one is for AIX (tested on 4.2) +****************************************************************************/ +int rep_getifaddrs(struct ifaddrs **ifap) +{ + char buff[8192]; + int fd, i; + struct ifconf ifc; + struct ifreq *ifr=NULL; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + + if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + close(fd); + return -1; + } + + ifr = ifc.ifc_req; + + /* Loop through interfaces */ + i = ifc.ifc_len; + + while (i > 0) { + uint_t inc; + + inc = ifr->ifr_addr.sa_len; + + if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif = calloc(1, sizeof(struct ifaddrs)); + if (lastif == NULL) { + *ifap = curif; + } else { + lastif->ifa_next = curif; + } + + curif->ifa_name = strdup(ifr->ifr_name); + curif->ifa_addr = sockaddr_dup(&ifr->ifr_addr); + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_netmask = NULL; + curif->ifa_next = NULL; + + if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif->ifa_flags = ifr->ifr_flags; + + if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif->ifa_netmask = sockaddr_dup(&ifr->ifr_addr); + + lastif = curif; + + next: + /* + * Patch from Archie Cobbs (archie@whistle.com). The + * addresses in the SIOCGIFCONF interface list have a + * minimum size. Usually this doesn't matter, but if + * your machine has tunnel interfaces, etc. that have + * a zero length "link address", this does matter. */ + + if (inc < sizeof(ifr->ifr_addr)) + inc = sizeof(ifr->ifr_addr); + inc += IFNAMSIZ; + + ifr = (struct ifreq*) (((char*) ifr) + inc); + i -= inc; + } + + close(fd); + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_AIX */ +#ifndef _FOUND_IFACE_ANY +int rep_getifaddrs(struct ifaddrs **ifap) +{ + errno = ENOSYS; + return -1; +} +#endif diff --git a/lib/replace/getpass.c b/lib/replace/getpass.c new file mode 100644 index 0000000000..0be618fc91 --- /dev/null +++ b/lib/replace/getpass.c @@ -0,0 +1,222 @@ +/* Copyright (C) 1992-1998 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation; either version 3 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, see . */ + +/* Modified to use with samba by Jeremy Allison, 8th July 1995. */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "system/terminal.h" +#include "system/passwd.h" + +/* + * Define additional missing types + */ +#ifndef HAVE_SIG_ATOMIC_T_TYPE +typedef int sig_atomic_t; +#endif + +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif + +#ifndef SIGNAL_CAST +#define SIGNAL_CAST (RETSIGTYPE (*)(int)) +#endif + +#ifdef SYSV_TERMIO + +/* SYSTEM V TERMIO HANDLING */ + +static struct termio t; + +#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) +#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) +#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) + +#ifndef TCSAFLUSH +#define TCSAFLUSH 1 +#endif + +#ifndef TCSANOW +#define TCSANOW 0 +#endif + +static int tcgetattr(int fd, struct termio *_t) +{ + return ioctl(fd, TCGETA, _t); +} + +static int tcsetattr(int fd, int flags, struct termio *_t) +{ + if(flags & TCSAFLUSH) + ioctl(fd, TCFLSH, TCIOFLUSH); + return ioctl(fd, TCSETS, _t); +} + +#elif !defined(TCSAFLUSH) + +/* BSD TERMIO HANDLING */ + +static struct sgttyb t; + +#define ECHO_IS_ON(t) ((t).sg_flags & ECHO) +#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO) +#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO) + +#define TCSAFLUSH 1 +#define TCSANOW 0 + +static int tcgetattr(int fd, struct sgttyb *_t) +{ + return ioctl(fd, TIOCGETP, (char *)_t); +} + +static int tcsetattr(int fd, int flags, struct sgttyb *_t) +{ + return ioctl(fd, TIOCSETP, (char *)_t); +} + +#else /* POSIX TERMIO HANDLING */ +#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) +#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) +#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) + +static struct termios t; +#endif /* SYSV_TERMIO */ + +static void catch_signal(int signum,void (*handler)(int )) +{ +#ifdef HAVE_SIGACTION + struct sigaction act; + struct sigaction oldact; + + memset(&act, 0, sizeof(act)); + + act.sa_handler = handler; +#ifdef SA_RESTART + /* + * We *want* SIGALRM to interrupt a system call. + */ + if(signum != SIGALRM) + act.sa_flags = SA_RESTART; +#endif + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask,signum); + sigaction(signum,&act,&oldact); +#else /* !HAVE_SIGACTION */ + /* FIXME: need to handle sigvec and systems with broken signal() */ + signal(signum, handler); +#endif +} + +static sig_atomic_t gotintr; +static int in_fd = -1; + +/*************************************************************** + Signal function to tell us were ^C'ed. +****************************************************************/ + +static void gotintr_sig(void) +{ + gotintr = 1; + if (in_fd != -1) + close(in_fd); /* Safe way to force a return. */ + in_fd = -1; +} + +char *rep_getpass(const char *prompt) +{ + FILE *in, *out; + int echo_off; + static char buf[256]; + static size_t bufsize = sizeof(buf); + size_t nread; + + /* Catch problematic signals */ + catch_signal(SIGINT, SIGNAL_CAST gotintr_sig); + + /* Try to write to and read from the terminal if we can. + If we can't open the terminal, use stderr and stdin. */ + + in = fopen ("/dev/tty", "w+"); + if (in == NULL) { + in = stdin; + out = stderr; + } else { + out = in; + } + + setvbuf(in, NULL, _IONBF, 0); + + /* Turn echoing off if it is on now. */ + + if (tcgetattr (fileno (in), &t) == 0) { + if (ECHO_IS_ON(t)) { + TURN_ECHO_OFF(t); + echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0; + TURN_ECHO_ON(t); + } else { + echo_off = 0; + } + } else { + echo_off = 0; + } + + /* Write the prompt. */ + fputs(prompt, out); + fflush(out); + + /* Read the password. */ + buf[0] = 0; + if (!gotintr) { + in_fd = fileno(in); + if (fgets(buf, bufsize, in) == NULL) { + buf[0] = 0; + } + } + nread = strlen(buf); + if (nread) { + if (buf[nread - 1] == '\n') + buf[nread - 1] = '\0'; + } + + /* Restore echoing. */ + if (echo_off) { + if (gotintr && in_fd == -1) { + in = fopen ("/dev/tty", "w+"); + } + if (in != NULL) + tcsetattr (fileno (in), TCSANOW, &t); + } + + fprintf(out, "\n"); + fflush(out); + + if (in && in != stdin) /* We opened the terminal; now close it. */ + fclose(in); + + /* Catch problematic signals */ + catch_signal(SIGINT, SIGNAL_CAST SIG_DFL); + + if (gotintr) { + printf("Interupted by signal.\n"); + fflush(stdout); + exit(1); + } + return buf; +} diff --git a/lib/replace/getpass.m4 b/lib/replace/getpass.m4 new file mode 100644 index 0000000000..b93817f9d3 --- /dev/null +++ b/lib/replace/getpass.m4 @@ -0,0 +1,24 @@ +AC_CHECK_FUNC(getpass, libreplace_cv_HAVE_GETPASS=yes) +AC_CHECK_FUNC(getpassphrase, libreplace_cv_HAVE_GETPASSPHRASE=yes) +if test x"$libreplace_cv_HAVE_GETPASS" = x"yes" -a x"$libreplace_cv_HAVE_GETPASSPHRASE" = x"yes"; then + AC_DEFINE(REPLACE_GETPASS_BY_GETPASSPHRASE, 1, [getpass returns <9 chars where getpassphrase returns <265 chars]) + AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) + LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" +else + +AC_CACHE_CHECK([whether getpass should be replaced],libreplace_cv_REPLACE_GETPASS,[ +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -I$libreplacedir/" +AC_TRY_COMPILE([ +#include "confdefs.h" +#define NO_CONFIG_H +#include "$libreplacedir/getpass.c" +],[],libreplace_cv_REPLACE_GETPASS=yes,libreplace_cv_REPLACE_GETPASS=no) +CPPFLAGS="$SAVE_CPPFLAGS" +]) +if test x"$libreplace_cv_REPLACE_GETPASS" = x"yes"; then + AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) + LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" +fi + +fi diff --git a/lib/replace/inet_aton.c b/lib/replace/inet_aton.c new file mode 100644 index 0000000000..c6b3bb11a7 --- /dev/null +++ b/lib/replace/inet_aton.c @@ -0,0 +1,33 @@ +/* + * Unix SMB/CIFS implementation. + * replacement functions + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/network.h" + +/** + * We know that we have inet_pton from earlier libreplace checks. + */ +int rep_inet_aton(const char *src, struct in_addr *dst) +{ + return (inet_pton(AF_INET, src, dst) > 0) ? 1 : 0; +} diff --git a/lib/replace/inet_ntoa.c b/lib/replace/inet_ntoa.c new file mode 100644 index 0000000000..e3b80ebef8 --- /dev/null +++ b/lib/replace/inet_ntoa.c @@ -0,0 +1,39 @@ +/* + * Unix SMB/CIFS implementation. + * replacement routines for broken systems + * Copyright (C) Andrew Tridgell 2003 + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/network.h" + +/** + * NOTE: this is not thread safe, but it can't be, either + * since it returns a pointer to static memory. + */ +char *rep_inet_ntoa(struct in_addr ip) +{ + uint8_t *p = (uint8_t *)&ip.s_addr; + static char buf[18]; + slprintf(buf, 17, "%d.%d.%d.%d", + (int)p[0], (int)p[1], (int)p[2], (int)p[3]); + return buf; +} diff --git a/lib/replace/inet_ntop.c b/lib/replace/inet_ntop.c new file mode 100644 index 0000000000..fb3d8e90c8 --- /dev/null +++ b/lib/replace/inet_ntop.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 1996-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include "replace.h" +#include "system/network.h" + +#define NS_INT16SZ 2 +#define NS_IN6ADDRSZ 16 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const unsigned char *src, char *dst, + socklen_t size); + +#ifdef AF_INET6 +static const char *inet_ntop6(const unsigned char *src, char *dst, + socklen_t size); +#endif + +/* char * + * isc_net_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +rep_inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); +#ifdef AF_INET6 + case AF_INET6: + return (inet_ntop6(src, dst, size)); +#endif + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a unsigned char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(const unsigned char *src, char *dst, socklen_t size) +{ + static const char *fmt = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + size_t len; + + len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); + if (len >= size) { + errno = ENOSPC; + return (NULL); + } + memcpy(dst, tmp, len + 1); + + return (dst); +} + +/* const char * + * isc_inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +#ifdef AF_INET6 +static const char * +inet_ntop6(const unsigned char *src, char *dst, socklen_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i, inc; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + inc = snprintf(tp, 5, "%x", words[i]); + if (inc >= 5) { + abort(); + } + tp += inc; + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + memcpy(dst, tmp, tp - tmp); + return (dst); +} +#endif /* AF_INET6 */ diff --git a/lib/replace/inet_pton.c b/lib/replace/inet_pton.c new file mode 100644 index 0000000000..80e4865ef4 --- /dev/null +++ b/lib/replace/inet_pton.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 1996-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "replace.h" +#include "system/network.h" + +#define NS_INT16SZ 2 +#define NS_INADDRSZ 4 +#define NS_IN6ADDRSZ 16 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4(const char *src, unsigned char *dst); +#ifdef AF_INET6 +static int inet_pton6(const char *src, unsigned char *dst); +#endif + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +rep_inet_pton(int af, + const char *src, + void *dst) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); +#ifdef AF_INET6 + case AF_INET6: + return (inet_pton6(src, dst)); +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(src, dst) + const char *src; + unsigned char *dst; +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[NS_INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + unsigned int new = *tp * 10 + (pch - digits); + + if (new > 255) + return (0); + *tp = new; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + memcpy(dst, tmp, NS_INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +#ifdef AF_INET6 +static int +inet_pton6(src, dst) + const char *src; + unsigned char *dst; +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + unsigned int val; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_IN6ADDRSZ); + return (1); +} +#endif diff --git a/lib/replace/install-sh b/lib/replace/install-sh new file mode 100755 index 0000000000..58719246f0 --- /dev/null +++ b/lib/replace/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +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=: + 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 diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4 new file mode 100644 index 0000000000..dc7d88e6e1 --- /dev/null +++ b/lib/replace/libreplace.m4 @@ -0,0 +1,308 @@ +AC_DEFUN_ONCE(AC_LIBREPLACE_LOCATION_CHECKS, +[ +echo "LIBREPLACE_LOCATION_CHECKS: START" + +dnl find the libreplace sources. This is meant to work both for +dnl libreplace standalone builds, and builds of packages using libreplace +libreplacedir="" +libreplacepaths="$srcdir $srcdir/lib/replace $srcdir/libreplace $srcdir/../libreplace $srcdir/../replace $srcdir/../lib/replace" +for d in $libreplacepaths; do + if test -f "$d/replace.c"; then + libreplacedir="$d" + AC_SUBST(libreplacedir) + break; + fi +done +if test x"$libreplacedir" = "x"; then + AC_MSG_ERROR([cannot find libreplace in $libreplacepaths]) +fi +LIBREPLACEOBJ="replace.o" +AC_SUBST(LIBREPLACEOBJ) + +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +echo "LIBREPLACE_LOCATION_CHECKS: END" +]) dnl end AC_LIBREPLACE_LOCATION_CHECKS + + +AC_DEFUN_ONCE(AC_LIBREPLACE_BROKEN_CHECKS, +[ +echo "LIBREPLACE_BROKEN_CHECKS: START" + +dnl find the libreplace sources. This is meant to work both for +dnl libreplace standalone builds, and builds of packages using libreplace +libreplacedir="" +libreplacepaths="$srcdir $srcdir/lib/replace $srcdir/libreplace $srcdir/../libreplace $srcdir/../replace $srcdir/../lib/replace" +for d in $libreplacepaths; do + if test -f "$d/replace.c"; then + libreplacedir="$d" + AC_SUBST(libreplacedir) + break; + fi +done +if test x"$libreplacedir" = "x"; then + AC_MSG_ERROR([cannot find libreplace in $libreplacepaths]) +fi + +LIBREPLACEOBJ="replace.o" +AC_SUBST(LIBREPLACEOBJ) + +LIBREPLACEOBJ="${LIBREPLACEOBJ} snprintf.o" + +AC_TYPE_SIGNAL +AC_TYPE_UID_T +AC_TYPE_MODE_T +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_TYPE_PID_T +AC_STRUCT_ST_RDEV +AC_CHECK_TYPE(ino_t,unsigned) +AC_CHECK_TYPE(loff_t,off_t) +AC_CHECK_TYPE(offset_t,loff_t) + +AC_FUNC_MEMCMP + +AC_CHECK_FUNCS(pipe strftime srandom random srand rand usleep setbuffer lstat getpgrp) + +AC_CHECK_HEADERS(stdbool.h stdint.h sys/select.h) +AC_CHECK_HEADERS(setjmp.h) + +LIBREPLACE_PROVIDE_HEADER([stdint.h]) +LIBREPLACE_PROVIDE_HEADER([stdbool.h]) + +AC_CHECK_TYPE(bool, +[AC_DEFINE(HAVE_BOOL, 1, [Whether the bool type is available])],, +[ +AC_INCLUDES_DEFAULT +#ifdef HAVE_STDBOOL_H +#include +#endif] +) + +AC_CHECK_TYPE(_Bool, +[AC_DEFINE(HAVE__Bool, 1, [Whether the _Bool type is available])],, +[ +AC_INCLUDES_DEFAULT +#ifdef HAVE_STDBOOL_H +#include +#endif] +) + +AC_CACHE_CHECK([for working mmap],libreplace_cv_HAVE_MMAP,[ +AC_TRY_RUN([#include "$libreplacedir/test/shared_mmap.c"], + libreplace_cv_HAVE_MMAP=yes,libreplace_cv_HAVE_MMAP=no,libreplace_cv_HAVE_MMAP=cross)]) +if test x"$libreplace_cv_HAVE_MMAP" = x"yes"; then + AC_DEFINE(HAVE_MMAP,1,[Whether mmap works]) +fi + + +AC_CHECK_HEADERS(sys/syslog.h syslog.h) +AC_CHECK_HEADERS(sys/time.h time.h) +AC_CHECK_HEADERS(stdarg.h vararg.h) +AC_CHECK_HEADERS(sys/mount.h mntent.h) +AC_CHECK_HEADERS(stropts.h) + +AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) +AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) +AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup) +AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp) +AC_CHECK_FUNCS(isatty) +AC_HAVE_DECL(setresuid, [#include ]) +AC_HAVE_DECL(setresgid, [#include ]) +AC_HAVE_DECL(errno, [#include ]) + +AC_CACHE_CHECK([for secure mkstemp],libreplace_cv_HAVE_SECURE_MKSTEMP,[ +AC_TRY_RUN([#include +#include +#include +#include +main() { + struct stat st; + char tpl[20]="/tmp/test.XXXXXX"; + int fd = mkstemp(tpl); + if (fd == -1) exit(1); + unlink(tpl); + if (fstat(fd, &st) != 0) exit(1); + if ((st.st_mode & 0777) != 0600) exit(1); + exit(0); +}], +libreplace_cv_HAVE_SECURE_MKSTEMP=yes, +libreplace_cv_HAVE_SECURE_MKSTEMP=no, +libreplace_cv_HAVE_SECURE_MKSTEMP=cross)]) +if test x"$libreplace_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then + AC_DEFINE(HAVE_SECURE_MKSTEMP,1,[Whether mkstemp is secure]) +fi + +dnl Provided by snprintf.c: +AC_CHECK_HEADERS(stdio.h strings.h) +AC_CHECK_DECLS([snprintf, vsnprintf, asprintf, vasprintf]) +AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf) + +AC_CACHE_CHECK([for C99 vsnprintf],libreplace_cv_HAVE_C99_VSNPRINTF,[ +AC_TRY_RUN([ +#include +#include +#include +#include +void foo(const char *format, ...) { + va_list ap; + int len; + char buf[20]; + long long l = 1234567890; + l *= 100; + + va_start(ap, format); + len = vsnprintf(buf, 0, format, ap); + va_end(ap); + if (len != 5) exit(1); + + va_start(ap, format); + len = vsnprintf(0, 0, format, ap); + va_end(ap); + if (len != 5) exit(2); + + if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(3); + + if (snprintf(buf, 20, "%lld", l) != 12 || strcmp(buf, "123456789000") != 0) exit(4); + if (snprintf(buf, 20, "%zu", 123456789) != 9 || strcmp(buf, "123456789") != 0) exit(5); + if (snprintf(buf, 20, "%2\$d %1\$d", 3, 4) != 3 || strcmp(buf, "4 3") != 0) exit(6); + if (snprintf(buf, 20, "%s", 0) < 3) exit(7); + + exit(0); +} +main() { foo("hello"); } +], +libreplace_cv_HAVE_C99_VSNPRINTF=yes,libreplace_cv_HAVE_C99_VSNPRINTF=no,libreplace_cv_HAVE_C99_VSNPRINTF=cross)]) +if test x"$libreplace_cv_HAVE_C99_VSNPRINTF" = x"yes"; then + AC_DEFINE(HAVE_C99_VSNPRINTF,1,[Whether there is a C99 compliant vsnprintf]) +fi + + +dnl VA_COPY +AC_CACHE_CHECK([for va_copy],libreplace_cv_HAVE_VA_COPY,[ +AC_TRY_LINK([#include +va_list ap1,ap2;], [va_copy(ap1,ap2);], +libreplace_cv_HAVE_VA_COPY=yes,libreplace_cv_HAVE_VA_COPY=no)]) +if test x"$libreplace_cv_HAVE_VA_COPY" = x"yes"; then + AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available]) +fi + +if test x"$libreplace_cv_HAVE_VA_COPY" != x"yes"; then +AC_CACHE_CHECK([for __va_copy],libreplace_cv_HAVE___VA_COPY,[ +AC_TRY_LINK([#include +va_list ap1,ap2;], [__va_copy(ap1,ap2);], +libreplace_cv_HAVE___VA_COPY=yes,libreplace_cv_HAVE___VA_COPY=no)]) +if test x"$libreplace_cv_HAVE___VA_COPY" = x"yes"; then + AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available]) +fi +fi + +dnl __FUNCTION__ macro +AC_CACHE_CHECK([for __FUNCTION__ macro],libreplace_cv_HAVE_FUNCTION_MACRO,[ +AC_TRY_COMPILE([#include ], [printf("%s\n", __FUNCTION__);], +libreplace_cv_HAVE_FUNCTION_MACRO=yes,libreplace_cv_HAVE_FUNCTION_MACRO=no)]) +if test x"$libreplace_cv_HAVE_FUNCTION_MACRO" = x"yes"; then + AC_DEFINE(HAVE_FUNCTION_MACRO,1,[Whether there is a __FUNCTION__ macro]) +else + dnl __func__ macro + AC_CACHE_CHECK([for __func__ macro],libreplace_cv_HAVE_func_MACRO,[ + AC_TRY_COMPILE([#include ], [printf("%s\n", __func__);], + libreplace_cv_HAVE_func_MACRO=yes,libreplace_cv_HAVE_func_MACRO=no)]) + if test x"$libreplace_cv_HAVE_func_MACRO" = x"yes"; then + AC_DEFINE(HAVE_func_MACRO,1,[Whether there is a __func__ macro]) + fi +fi + +AC_CHECK_HEADERS([sys/param.h limits.h]) + +AC_CHECK_TYPE(comparison_fn_t, +[AC_DEFINE(HAVE_COMPARISON_FN_T, 1,[Whether or not we have comparison_fn_t])]) + +AC_HAVE_DECL(setenv, [#include ]) +AC_CHECK_FUNCS(setenv unsetenv) + +AC_CHECK_FUNCS(strnlen) +AC_CHECK_FUNCS(strtoull __strtoull strtouq strtoll __strtoll strtoq) + +# this test disabled as we don't actually need __VA_ARGS__ yet +AC_TRY_CPP([ +#define eprintf(...) fprintf(stderr, __VA_ARGS__) +eprintf("bla", "bar"); +], AC_DEFINE(HAVE__VA_ARGS__MACRO, 1, [Whether the __VA_ARGS__ macro is available])) + + +AC_CACHE_CHECK([for sig_atomic_t type],libreplace_cv_sig_atomic_t, [ + AC_TRY_COMPILE([ +#include +#if STDC_HEADERS +#include +#include +#endif +#include ],[sig_atomic_t i = 0], + libreplace_cv_sig_atomic_t=yes,libreplace_cv_sig_atomic_t=no)]) +if test x"$libreplace_cv_sig_atomic_t" = x"yes"; then + AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE,1,[Whether we have the atomic_t variable type]) +fi + + +AC_CACHE_CHECK([for O_DIRECT flag to open(2)],libreplace_cv_HAVE_OPEN_O_DIRECT,[ +AC_TRY_COMPILE([ +#include +#ifdef HAVE_FCNTL_H +#include +#endif], +[int fd = open("/dev/null", O_DIRECT);], +libreplace_cv_HAVE_OPEN_O_DIRECT=yes,libreplace_cv_HAVE_OPEN_O_DIRECT=no)]) +if test x"$libreplace_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then + AC_DEFINE(HAVE_OPEN_O_DIRECT,1,[Whether the open(2) accepts O_DIRECT]) +fi + + +dnl Check if the C compiler understands volatile (it should, being ANSI). +AC_CACHE_CHECK([that the C compiler understands volatile],libreplace_cv_volatile, [ + AC_TRY_COMPILE([#include ],[volatile int i = 0], + libreplace_cv_volatile=yes,libreplace_cv_volatile=no)]) +if test x"$libreplace_cv_volatile" = x"yes"; then + AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile]) +fi + +m4_include(system/config.m4) + +m4_include(dlfcn.m4) +m4_include(getpass.m4) +m4_include(strptime.m4) +m4_include(win32.m4) +m4_include(timegm.m4) +m4_include(repdir.m4) + +AC_CHECK_FUNCS([syslog printf memset memcpy],,[AC_MSG_ERROR([Required function not found])]) + +echo "LIBREPLACE_BROKEN_CHECKS: END" +]) dnl end AC_LIBREPLACE_BROKEN_CHECKS + +AC_DEFUN_ONCE(AC__LIBREPLACE_ALL_CHECKS_START, +[ +#LIBREPLACE_ALL_CHECKS: START" +]) +AC_DEFUN_ONCE(AC__LIBREPLACE_ALL_CHECKS_END, +[ +#LIBREPLACE_ALL_CHECKS: END" +]) +m4_define(AC_LIBREPLACE_ALL_CHECKS, +[ +AC__LIBREPLACE_ALL_CHECKS_START +AC_LIBREPLACE_LOCATION_CHECKS +AC_LIBREPLACE_CC_CHECKS +AC_LIBREPLACE_BROKEN_CHECKS +AC__LIBREPLACE_ALL_CHECKS_END +CFLAGS="$CFLAGS -I$libreplacedir" +]) + +m4_include(libreplace_cc.m4) +m4_include(libreplace_ld.m4) +m4_include(libreplace_network.m4) +m4_include(libreplace_macros.m4) + +m4_ifndef([AC_USE_SYSTEM_EXTENSIONS],[m4_include(autoconf-2.60.m4)]) diff --git a/lib/replace/libreplace_cc.m4 b/lib/replace/libreplace_cc.m4 new file mode 100644 index 0000000000..30c63f2f05 --- /dev/null +++ b/lib/replace/libreplace_cc.m4 @@ -0,0 +1,182 @@ + +AC_DEFUN_ONCE(AC__LIBREPLACE_ONLY_CC_CHECKS_START, +[ +echo "LIBREPLACE_CC_CHECKS: START" +]) + +AC_DEFUN_ONCE(AC__LIBREPLACE_ONLY_CC_CHECKS_END, +[ +echo "LIBREPLACE_CC_CHECKS: END" +]) + +dnl +dnl +dnl AC_LIBREPLACE_CC_CHECKS +dnl +dnl Note: we need to use m4_define instead of AC_DEFUN because +dnl of the ordering of tests +dnl +dnl +m4_define(AC_LIBREPLACE_CC_CHECKS, +[ +AC__LIBREPLACE_ONLY_CC_CHECKS_START + +dnl stop the C89 attempt by autoconf - if autoconf detects -Ae it will enable it +dnl which conflicts with C99 on HPUX +ac_cv_prog_cc_Ae=no + +savedCFLAGS=$CFLAGS +AC_PROG_CC +CFLAGS=$savedCFLAGS + +dnl don't try for C99 if we are using gcc, as otherwise we +dnl lose immediate structure constants +if test x"$GCC" != x"yes" ; then +AC_PROG_CC_C99 +fi + +if test x"$GCC" = x"yes" ; then + AC_MSG_CHECKING([for version of gcc]) + GCC_VERSION=`$CC -dumpversion` + AC_MSG_RESULT(${GCC_VERSION}) +fi +AC_USE_SYSTEM_EXTENSIONS +AC_C_BIGENDIAN +AC_C_INLINE +LIBREPLACE_C99_STRUCT_INIT([],[AC_MSG_WARN([c99 structure initializer are not supported])]) + +AC_PROG_INSTALL + +AC_ISC_POSIX +AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) + +AC_SYS_LARGEFILE + +dnl Add #include for broken IRIX header files +case "$host_os" in + *irix6*) AC_ADD_INCLUDE() + ;; + *hpux*) + # mmap on HPUX is completely broken... + AC_DEFINE(MMAP_BLACKLIST, 1, [Whether MMAP is broken]) + if test "`uname -r`" = "B.11.00" -o "`uname -r`" = "B.11.11"; then + AC_MSG_WARN([Enabling HPUX 11.00/11.11 header bug workaround]) + CFLAGS="$CFLAGS -Dpread=pread64 -Dpwrite=pwrite64" + fi + if test "`uname -r`" = "B.11.23"; then + AC_MSG_WARN([Enabling HPUX 11.23 machine/sys/getppdp.h bug workaround]) + CFLAGS="$CFLAGS -D_MACHINE_SYS_GETPPDP_INCLUDED" + fi + ;; + *aix*) + AC_DEFINE(BROKEN_STRNDUP, 1, [Whether strndup is broken]) + AC_DEFINE(BROKEN_STRNLEN, 1, [Whether strnlen is broken]) + if test "${GCC}" != "yes"; then + ## for funky AIX compiler using strncpy() + CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" + fi + ;; + *osf*) + # this brings in socklen_t + AC_N_DEFINE(_XOPEN_SOURCE,600) + AC_N_DEFINE(_OSF_SOURCE) + ;; + # + # VOS may need to have POSIX support and System V compatibility enabled. + # + *vos*) + case "$CFLAGS" in + *-D_POSIX_C_SOURCE*);; + *) + CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112L" + AC_DEFINE(_POSIX_C_SOURCE, 200112L, [Whether to enable POSIX support]) + ;; + esac + case "$CFLAGS" in + *-D_SYSV*|*-D_SVID_SOURCE*);; + *) + CFLAGS="$CFLAGS -D_SYSV" + AC_DEFINE(_SYSV, 1, [Whether to enable System V compatibility]) + ;; + esac + ;; +esac + + + +AC_CHECK_HEADERS([standards.h]) + +# Solaris needs HAVE_LONG_LONG defined +AC_CHECK_TYPES(long long) + +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(char) +AC_CHECK_SIZEOF(short) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(long long) + +AC_CHECK_TYPE(uint_t, unsigned int) +AC_CHECK_TYPE(int8_t, char) +AC_CHECK_TYPE(uint8_t, unsigned char) +AC_CHECK_TYPE(int16_t, short) +AC_CHECK_TYPE(uint16_t, unsigned short) + +if test $ac_cv_sizeof_int -eq 4 ; then +AC_CHECK_TYPE(int32_t, int) +AC_CHECK_TYPE(uint32_t, unsigned int) +elif test $ac_cv_size_long -eq 4 ; then +AC_CHECK_TYPE(int32_t, long) +AC_CHECK_TYPE(uint32_t, unsigned long) +else +AC_MSG_ERROR([LIBREPLACE no 32-bit type found]) +fi + +AC_CHECK_TYPE(int64_t, long long) +AC_CHECK_TYPE(uint64_t, unsigned long long) + +AC_CHECK_TYPE(size_t, unsigned int) +AC_CHECK_TYPE(ssize_t, int) + +AC_CHECK_SIZEOF(off_t) +AC_CHECK_SIZEOF(size_t) +AC_CHECK_SIZEOF(ssize_t) + +AC_CHECK_TYPE(intptr_t, long long) +AC_CHECK_TYPE(uintptr_t, unsigned long long) +AC_CHECK_TYPE(ptrdiff_t, unsigned long long) + +if test x"$ac_cv_type_long_long" != x"yes";then + AC_MSG_ERROR([LIBREPLACE needs type 'long long']) +fi +if test $ac_cv_sizeof_long_long -lt 8;then + AC_MSG_ERROR([LIBREPLACE needs sizeof(long long) >= 8]) +fi + +############################################ +# check if the compiler can do immediate structures +AC_SUBST(libreplace_cv_immediate_structures) +AC_CACHE_CHECK([for immediate structures],libreplace_cv_immediate_structures,[ + AC_TRY_COMPILE([ + #include + ],[ + typedef struct {unsigned x;} FOOBAR; + #define X_FOOBAR(x) ((FOOBAR) { x }) + #define FOO_ONE X_FOOBAR(1) + FOOBAR f = FOO_ONE; + static const struct { + FOOBAR y; + } f2[] = { + {FOO_ONE} + }; + static const FOOBAR f3[] = {FOO_ONE}; + ], + libreplace_cv_immediate_structures=yes, + libreplace_cv_immediate_structures=no, + libreplace_cv_immediate_structures=cross) +]) +if test x"$libreplace_cv_immediate_structures" = x"yes"; then + AC_DEFINE(HAVE_IMMEDIATE_STRUCTURES,1,[Whether the compiler supports immediate structures]) +fi + +AC__LIBREPLACE_ONLY_CC_CHECKS_END +]) dnl end AC_LIBREPLACE_CC_CHECKS diff --git a/lib/replace/libreplace_ld.m4 b/lib/replace/libreplace_ld.m4 new file mode 100644 index 0000000000..81bde46219 --- /dev/null +++ b/lib/replace/libreplace_ld.m4 @@ -0,0 +1,319 @@ +# +# This offers a nice overview how to build shared libraries on all platforms +# http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html +# + +AC_DEFUN([AC_LIBREPLACE_STLD], +[ + AC_PATH_PROG(PROG_AR, ar) + + STLD=${PROG_AR} + + AC_SUBST(STLD) +]) + +AC_DEFUN([AC_LIBREPLACE_STLD_FLAGS], +[ + STLD_FLAGS="-rcs" + AC_SUBST(STLD_FLAGS) +]) + +AC_DEFUN([AC_LD_EXPORT_DYNAMIC], +[ +saved_LDFLAGS="$LDFLAGS" +if AC_TRY_COMMAND([${CC-cc} $CFLAGS -Wl,--version 2>&1 | grep "GNU ld" >/dev/null]); then + LD_EXPORT_DYNAMIC="-Wl,-export-dynamic" +else + case "$host_os" in + hpux* ) + LD_EXPORT_DYNAMIC="-Wl,-E" + ;; + *) + LD_EXPORT_DYNAMIC="" + ;; + esac +fi +AC_SUBST(LD_EXPORT_DYNAMIC) +LDFLAGS="$saved_LDFLAGS" +]) + +AC_DEFUN([AC_LD_PICFLAG], +[ +case "$host_os" in + *linux*) + PICFLAG="-fPIC" + ;; + *solaris*) + if test "${GCC}" = "yes"; then + PICFLAG="-fPIC" + else + PICFLAG="-KPIC" + fi + ;; + *sunos*) + PICFLAG="-KPIC" # Is this correct for SunOS + ;; + *netbsd* | *freebsd* | *dragonfly* ) + PICFLAG="-fPIC -DPIC" + ;; + *openbsd*) + PICFLAG="-fPIC" + ;; + *irix*) + if test "${GCC}" = "yes"; then + PICFLAG="-fPIC" + else + PICFLAG="-KPIC" + fi + ;; + *aix*) + # as AIX code is always position independent... + PICFLAG="-O2" + ;; + *hpux*) + if test $ac_cv_prog_cc_Ae = yes; then + PICFLAG="+z +ESnolit" + elif test "${GCC}" = "yes"; then + PICFLAG="-fPIC" + fi + if test "$host_cpu" = "ia64"; then + PICFLAG="+z" + fi + ;; + *osf*) + PICFLAG="-fPIC" + ;; + *unixware*) + PICFLAG="-KPIC" + ;; + *darwin*) + PICFLAG="-fno-common" + ;; +esac +AC_SUBST(PICFLAG) +]) + +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_LINKER], +[ + LD_SHLIB_LINKER="${CC}" + + case "$host_os" in + *irix*) + LD_SHLIB_LINKER="${PROG_LD}" + ;; + esac + + AC_SUBST(LD_SHLIB_LINKER) +]) + +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_FLAGS], +[ + LD_SHLIB_FLAGS="-shared" + + case "$host_os" in + *linux*) + LD_SHLIB_FLAGS="-shared -Wl,-Bsymbolic" + ;; + *solaris*) + LD_SHLIB_FLAGS="-G" + if test "${GCC}" = "no"; then + ## ${CFLAGS} added for building 64-bit shared + ## libs using Sun's Compiler + LD_SHLIB_FLAGS="-G \${CFLAGS}" + fi + ;; + *sunos*) + LD_SHLIB_FLAGS="-G" + ;; + *irix*) + LD_SHLIB_FLAGS="-shared" + ;; + *aix*) + LD_SHLIB_FLAGS="-Wl,-G,-bexpall,-bbigtoc" + ;; + *hpux*) + if test "${GCC}" = "yes"; then + LD_SHLIB_FLAGS="-shared" + else + LD_SHLIB_FLAGS="-b" + fi + ;; + *osf*) + LD_SHLIB_FLAGS="-shared" + ;; + *darwin*) + LD_SHLIB_FLAGS="-dynamiclib -Wl,-search_paths_first" + ;; + esac + + AC_SUBST(LD_SHLIB_FLAGS) +]) + +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_DISALLOW_UNDEF_FLAG], +[ + LD_SHLIB_DISALLOW_UNDEF_FLAG="" + + # + # TODO: enforce error not only warnings + # + # NOTE: -Wl,--no-allow-shlib-undefined isn't what we want... + # as it bails out on broken system libraries + # + case "$host_os" in + *osf*) + LD_SHLIB_DISALLOW_UNDEF_FLAG="-warning_unresolved" + ;; + *darwin*) + LD_SHLIB_DISALLOW_UNDEF_FLAG="-undefined error" + ;; + esac + + AC_SUBST(LD_SHLIB_DISALLOW_UNDEF_FLAG) +]) + +AC_DEFUN([AC_LIBREPLACE_SHLD], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_LINKER]) + SHLD="$LD_SHLIB_LINKER" + AC_SUBST(SHLD) +]) + +AC_DEFUN([AC_LIBREPLACE_SHLD_FLAGS], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_FLAGS]) + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_DISALLOW_UNDEF_FLAG]) + SHLD_FLAGS="$LD_SHLIB_FLAGS $LD_SHLIB_DISALLOW_UNDEF_FLAG" + AC_SUBST(SHLD_FLAGS) +]) + +AC_DEFUN([AC_LD_SHLIBEXT], +[ + SHLIBEXT="so" + case "$host_os" in + *hpux*) + if test "$host_cpu" = "ia64"; then + SHLIBEXT="so" + else + SHLIBEXT="sl" + fi + ;; + *darwin*) + SHLIBEXT="dylib" + ;; + esac + AC_SUBST(SHLIBEXT) +]) + +AC_DEFUN([AC_LD_SONAMEFLAG], +[ + AC_SUBST(SONAMEFLAG) + SONAMEFLAG="" + case "$host_os" in + *linux*) + SONAMEFLAG="-Wl,-soname=" + ;; + *solaris*) + SONAMEFLAG="-h " + if test "${GCC}" = "yes"; then + SONAMEFLAG="-Wl,-soname=" + fi + ;; + *sunos*) + SONAMEFLAG="-Wl,-h," + ;; + *netbsd* | *freebsd* | *dragonfly* ) + SONAMEFLAG="-Wl,-soname," + ;; + *openbsd*) + SONAMEFLAG="-Wl,-soname," + ;; + *irix*) + SONAMEFLAG="-Wl,-soname," + ;; + *hpux*) + SONAMEFLAG="-Wl,+h," + ;; + *osf*) + SONAMEFLAG="-Wl,-soname," + ;; + *unixware*) + SONAMEFLAG="-Wl,-soname," + ;; + *darwin*) + SONAMEFLAG="#" + ;; + *aix*) + # Not supported + SONAMEFLAG="#" + ;; + esac +]) + +AC_DEFUN([AC_LIBREPLACE_MDLD], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_LINKER]) + MDLD="$LD_SHLIB_LINKER" + AC_SUBST(MDLD) +]) + +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], +[ + LD_ALLOW_SHLIB_UNDEF_FLAG="" + + case "$host_os" in + *linux*) + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" + ;; + *osf*) + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,\"*\"" + ;; + *darwin*) + LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" + ;; + *aix*) + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-bnoentry" + ;; + esac + + AC_SUBST(LD_SHLIB_ALLOW_UNDEF_FLAG) +]) + +AC_DEFUN([AC_LIBREPLACE_MDLD_FLAGS], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_FLAGS]) + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG]) + MDLD_FLAGS="$LD_SHLIB_FLAGS $LD_SHLIB_ALLOW_UNDEF_FLAG" + AC_SUBST(MDLD_FLAGS) +]) + +AC_DEFUN([AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR], +[ + case "$host_os" in + *linux*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *netbsd*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *solaris*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *hpux*) + LIB_PATH_VAR=SHLIB_PATH + ;; + *osf*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *aix*) + LIB_PATH_VAR=LIB_PATH + ;; + *irix*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *darwin*) + LIB_PATH_VAR=DYLD_LIBRARY_PATH + ;; + esac + + AC_SUBST(LIB_PATH_VAR) +]) diff --git a/lib/replace/libreplace_macros.m4 b/lib/replace/libreplace_macros.m4 new file mode 100644 index 0000000000..1856eacf66 --- /dev/null +++ b/lib/replace/libreplace_macros.m4 @@ -0,0 +1,332 @@ +# +# This is a collection of useful autoconf macros +# + +############################################ +# Check if the compiler handles c99 struct initialization, and if not try -AC99 and -c99 flags +# Usage: LIBREPLACE_C99_STRUCT_INIT(success-action,failure-action) +# changes CFLAGS to add -AC99 or -c99 if needed +AC_DEFUN([LIBREPLACE_C99_STRUCT_INIT], +[ +saved_CFLAGS="$CFLAGS"; +c99_init=no +if test x"$c99_init" = x"no"; then + AC_MSG_CHECKING(for C99 designated initializers) + CFLAGS="$saved_CFLAGS"; + AC_TRY_COMPILE([#include ], + [ struct foo {int x;char y;}; + struct foo bar = { .y = 'X', .x = 1 }; + ], + [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) +fi +if test x"$c99_init" = x"no"; then + AC_MSG_CHECKING(for C99 designated initializers with -AC99) + CFLAGS="$saved_CFLAGS -AC99"; + AC_TRY_COMPILE([#include ], + [ struct foo {int x;char y;}; + struct foo bar = { .y = 'X', .x = 1 }; + ], + [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) +fi +if test x"$c99_init" = x"no"; then + AC_MSG_CHECKING(for C99 designated initializers with -qlanglvl=extc99) + CFLAGS="$saved_CFLAGS -qlanglvl=extc99"; + AC_TRY_COMPILE([#include ], + [ struct foo {int x;char y;}; + struct foo bar = { .y = 'X', .x = 1 }; + ], + [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) +fi +if test x"$c99_init" = x"no"; then + AC_MSG_CHECKING(for C99 designated initializers with -qlanglvl=stdc99) + CFLAGS="$saved_CFLAGS -qlanglvl=stdc99"; + AC_TRY_COMPILE([#include ], + [ struct foo {int x;char y;}; + struct foo bar = { .y = 'X', .x = 1 }; + ], + [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) +fi +if test x"$c99_init" = x"no"; then + AC_MSG_CHECKING(for C99 designated initializers with -c99) + CFLAGS="$saved_CFLAGS -c99" + AC_TRY_COMPILE([#include ], + [ struct foo {int x;char y;}; + struct foo bar = { .y = 'X', .x = 1 }; + ], + [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) +fi + +if test "`uname`" = "HP-UX"; then + if test "$ac_cv_c_compiler_gnu" = no; then + # special override for broken HP-UX compiler - I can't find a way to test + # this properly (its a compiler bug) + CFLAGS="$CFLAGS -AC99"; + c99_init=yes; + fi +fi + +if test x"$c99_init" = x"yes"; then + saved_CFLAGS="" + $1 +else + CFLAGS="$saved_CFLAGS" + saved_CFLAGS="" + $2 +fi +]) + +dnl AC_PROG_CC_FLAG(flag) +AC_DEFUN(AC_PROG_CC_FLAG, +[AC_CACHE_CHECK(whether ${CC-cc} accepts -$1, ac_cv_prog_cc_$1, +[echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -$1 -c conftest.c 2>&1`"; then + ac_cv_prog_cc_$1=yes +else + ac_cv_prog_cc_$1=no +fi +rm -f conftest* +])]) + +dnl see if a declaration exists for a function or variable +dnl defines HAVE_function_DECL if it exists +dnl AC_HAVE_DECL(var, includes) +AC_DEFUN(AC_HAVE_DECL, +[ + AC_CACHE_CHECK([for $1 declaration],ac_cv_have_$1_decl,[ + AC_TRY_COMPILE([$2],[int i = (int)$1], + ac_cv_have_$1_decl=yes,ac_cv_have_$1_decl=no)]) + if test x"$ac_cv_have_$1_decl" = x"yes"; then + AC_DEFINE([HAVE_]translit([$1], [a-z], [A-Z])[_DECL],1,[Whether $1() is available]) + fi +]) + + +# AC_CHECK_LIB_EXT(LIBRARY, [EXT_LIBS], [FUNCTION], +# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], +# [ADD-ACTION-IF-FOUND],[OTHER-LIBRARIES]) +# ------------------------------------------------------ +# +# Use a cache variable name containing both the library and function name, +# because the test really is for library $1 defining function $3, not +# just for library $1. Separate tests with the same $1 and different $3s +# may have different results. +# +# Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3]) +# is asking for trouble, since AC_CHECK_LIB($lib, fun) would give +# ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence +# the AS_LITERAL_IF indirection. +# +# FIXME: This macro is extremely suspicious. It DEFINEs unconditionally, +# whatever the FUNCTION, in addition to not being a *S macro. Note +# that the cache does depend upon the function we are looking for. +# +# It is on purpose we used `ac_check_lib_ext_save_LIBS' and not just +# `ac_save_LIBS': there are many macros which don't want to see `LIBS' +# changed but still want to use AC_CHECK_LIB_EXT, so they save `LIBS'. +# And ``ac_save_LIBS' is too tempting a name, so let's leave them some +# freedom. +AC_DEFUN([AC_CHECK_LIB_EXT], +[ +AH_CHECK_LIB_EXT([$1]) +ac_check_lib_ext_save_LIBS=$LIBS +LIBS="-l$1 $$2 $7 $LIBS" +AS_LITERAL_IF([$1], + [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1])], + [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1''])])dnl + +m4_ifval([$3], + [ + AH_CHECK_FUNC_EXT([$3]) + AS_LITERAL_IF([$1], + [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1_$3])], + [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1''_$3])])dnl + AC_CACHE_CHECK([for $3 in -l$1], ac_Lib_func, + [AC_TRY_LINK_FUNC($3, + [AS_VAR_SET(ac_Lib_func, yes); + AS_VAR_SET(ac_Lib_ext, yes)], + [AS_VAR_SET(ac_Lib_func, no); + AS_VAR_SET(ac_Lib_ext, no)]) + ]) + AS_IF([test AS_VAR_GET(ac_Lib_func) = yes], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$3))])dnl + AS_VAR_POPDEF([ac_Lib_func])dnl + ],[ + AC_CACHE_CHECK([for -l$1], ac_Lib_ext, + [AC_TRY_LINK_FUNC([main], + [AS_VAR_SET(ac_Lib_ext, yes)], + [AS_VAR_SET(ac_Lib_ext, no)]) + ]) + ]) +LIBS=$ac_check_lib_ext_save_LIBS + +AS_IF([test AS_VAR_GET(ac_Lib_ext) = yes], + [m4_default([$4], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1)) + case "$$2" in + *-l$1*) + ;; + *) + $2="-l$1 $$2" + ;; + esac]) + [$6] + ], + [$5])dnl +AS_VAR_POPDEF([ac_Lib_ext])dnl +])# AC_CHECK_LIB_EXT + +# AH_CHECK_LIB_EXT(LIBNAME) +# --------------------- +m4_define([AH_CHECK_LIB_EXT], +[AH_TEMPLATE(AS_TR_CPP(HAVE_LIB$1), + [Define to 1 if you have the `]$1[' library (-l]$1[).])]) + +dnl AC_SEARCH_LIBS_EXT(FUNCTION, SEARCH-LIBS, EXT_LIBS, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], +dnl [OTHER-LIBRARIES]) +dnl -------------------------------------------------------- +dnl Search for a library defining FUNC, if it's not already available. +AC_DEFUN([AC_SEARCH_LIBS_EXT], +[AC_CACHE_CHECK([for library containing $1], [ac_cv_search_ext_$1], +[ +ac_func_search_ext_save_LIBS=$LIBS +ac_cv_search_ext_$1=no +AC_LINK_IFELSE([AC_LANG_CALL([], [$1])], + [ac_cv_search_ext_$1="none required"]) +if test "$ac_cv_search_ext_$1" = no; then + for ac_lib in $2; do + LIBS="-l$ac_lib $$3 $6 $ac_func_search_save_ext_LIBS" + AC_LINK_IFELSE([AC_LANG_CALL([], [$1])], + [ac_cv_search_ext_$1="-l$ac_lib" +break]) + done +fi +LIBS=$ac_func_search_ext_save_LIBS]) +AS_IF([test "$ac_cv_search_ext_$1" != no], + [test "$ac_cv_search_ext_$1" = "none required" || $3="$ac_cv_search_ext_$1 $$3" + $4], + [$5])dnl +]) + +dnl check for a function in a $LIBS and $OTHER_LIBS libraries variable. +dnl AC_CHECK_FUNC_EXT(func,OTHER_LIBS,IF-TRUE,IF-FALSE) +AC_DEFUN([AC_CHECK_FUNC_EXT], +[ + AH_CHECK_FUNC_EXT($1) + ac_check_func_ext_save_LIBS=$LIBS + LIBS="$2 $LIBS" + AS_VAR_PUSHDEF([ac_var], [ac_cv_func_ext_$1])dnl + AC_CACHE_CHECK([for $1], ac_var, + [AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([$1])], + [AS_VAR_SET(ac_var, yes)], + [AS_VAR_SET(ac_var, no)])]) + LIBS=$ac_check_func_ext_save_LIBS + AS_IF([test AS_VAR_GET(ac_var) = yes], + [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) $3], + [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +])# AC_CHECK_FUNC + +# AH_CHECK_FUNC_EXT(FUNCNAME) +# --------------------- +m4_define([AH_CHECK_FUNC_EXT], +[AH_TEMPLATE(AS_TR_CPP(HAVE_$1), + [Define to 1 if you have the `]$1[' function.])]) + +dnl Define an AC_DEFINE with ifndef guard. +dnl AC_N_DEFINE(VARIABLE [, VALUE]) +AC_DEFUN([AC_N_DEFINE], +[ +AH_VERBATIM([$1], [ +#ifndef $1 +# undef $1 +#endif +]) + + cat >>confdefs.h <<\EOF +#ifndef $1 +[#define] $1 m4_if($#, 1, 1, [$2]) +#endif +EOF +]) + +dnl Add an #include +dnl AC_ADD_INCLUDE(VARIABLE) +define(AC_ADD_INCLUDE, +[cat >> confdefs.h <<\EOF +[#include] $1 +EOF +]) + +dnl remove an #include +dnl AC_REMOVE_INCLUDE(VARIABLE) +define(AC_REMOVE_INCLUDE, +[ +grep -v '[#include] $1' confdefs.h >confdefs.h.tmp +cat confdefs.h.tmp > confdefs.h +rm confdefs.h.tmp +]) + +dnl remove an #define +dnl AC_REMOVE_DEFINE(VARIABLE) +define(AC_REMOVE_DEFINE, +[ +grep -v '[#define] $1 ' confdefs.h |grep -v '[#define] $1[$]'>confdefs.h.tmp +cat confdefs.h.tmp > confdefs.h +rm confdefs.h.tmp +]) + +dnl AS_HELP_STRING is not available in autoconf 2.57, and AC_HELP_STRING is deprecated +dnl in autoconf 2.59, so define AS_HELP_STRING to be AC_HELP_STRING unless it is already +dnl defined. +m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))]) + +dnl check if the prototype in the header matches the given one +dnl AC_VERIFY_C_PROTOTYPE(prototype,functionbody,[IF-TRUE].[IF-FALSE],[extraheaders]) +AC_DEFUN(AC_VERIFY_C_PROTOTYPE, +[AC_CACHE_CHECK([for prototype $1], AS_TR_SH([ac_cv_c_prototype_$1]), + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + AC_INCLUDES_DEFAULT + $5 + $1 + { + $2 + } + ])],[ + AS_TR_SH([ac_cv_c_prototype_$1])=yes + ],[ + AS_TR_SH([ac_cv_c_prototype_$1])=no + ]) +) +AS_IF([test $AS_TR_SH([ac_cv_c_prototype_$1]) = yes],[$3],[$4]) +]) + +AC_DEFUN(LIBREPLACE_PROVIDE_HEADER, +[AC_CHECK_HEADER([$1], + [ AC_CONFIG_COMMANDS(rm-$1, [rm -f $libreplacedir/$1], [libreplacedir=$libreplacedir]) ], + [ AC_CONFIG_COMMANDS(mk-$1, [echo "#include \"replace.h\"" > $libreplacedir/$1], [libreplacedir=$libreplacedir]) ] + ) +]) + +dnl AC_HAVE_TYPE(TYPE,INCLUDES) +AC_DEFUN([AC_HAVE_TYPE], [ +AC_REQUIRE([AC_HEADER_STDC]) +cv=`echo "$1" | sed 'y%./+- %__p__%'` +AC_MSG_CHECKING(for $1) +AC_CACHE_VAL([ac_cv_type_$cv], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +AC_INCLUDES_DEFAULT +$2]], +[[$1 foo;]])], +[eval "ac_cv_type_$cv=yes"], +[eval "ac_cv_type_$cv=no"]))dnl +ac_foo=`eval echo \\$ac_cv_type_$cv` +AC_MSG_RESULT($ac_foo) +if test "$ac_foo" = yes; then + ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'` +if false; then + AC_CHECK_TYPES($1) +fi + AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1']) +fi +]) diff --git a/lib/replace/libreplace_network.m4 b/lib/replace/libreplace_network.m4 new file mode 100644 index 0000000000..4edb55c03a --- /dev/null +++ b/lib/replace/libreplace_network.m4 @@ -0,0 +1,377 @@ +AC_DEFUN_ONCE(AC_LIBREPLACE_NETWORK_CHECKS, +[ +echo "LIBREPLACE_NETWORK_CHECKS: START" + +AC_DEFINE(LIBREPLACE_NETWORK_CHECKS, 1, [LIBREPLACE_NETWORK_CHECKS were used]) +LIBREPLACE_NETWORK_OBJS="" +LIBREPLACE_NETWORK_LIBS="" + +AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h) +AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) +AC_CHECK_HEADERS(sys/sockio.h sys/un.h) + +dnl we need to check that net/if.h really can be used, to cope with hpux +dnl where including it always fails +AC_CACHE_CHECK([for usable net/if.h],libreplace_cv_USABLE_NET_IF_H,[ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + AC_INCLUDES_DEFAULT + #if HAVE_SYS_SOCKET_H + # include + #endif + #include + int main(void) {return 0;}])], + [libreplace_cv_USABLE_NET_IF_H=yes], + [libreplace_cv_USABLE_NET_IF_H=no] + ) +]) +if test x"$libreplace_cv_USABLE_NET_IF_H" = x"yes";then + AC_DEFINE(HAVE_NET_IF_H, 1, usability of net/if.h) +fi + +AC_HAVE_TYPE([socklen_t],[#include ]) +AC_HAVE_TYPE([sa_family_t],[#include ]) +AC_HAVE_TYPE([struct addrinfo], [#include ]) +AC_HAVE_TYPE([struct sockaddr], [#include ]) +AC_HAVE_TYPE([struct sockaddr_storage], [ +#include +#include +#include +]) +AC_HAVE_TYPE([struct sockaddr_in6], [ +#include +#include +#include +]) + +if test x"$ac_cv_type_struct_sockaddr_storage" = x"yes"; then +AC_CHECK_MEMBER(struct sockaddr_storage.ss_family, + AC_DEFINE(HAVE_SS_FAMILY, 1, [Defined if struct sockaddr_storage has ss_family field]),, + [ +#include +#include +#include + ]) + +if test x"$ac_cv_member_struct_sockaddr_storage_ss_family" != x"yes"; then +AC_CHECK_MEMBER(struct sockaddr_storage.__ss_family, + AC_DEFINE(HAVE___SS_FAMILY, 1, [Defined if struct sockaddr_storage has __ss_family field]),, + [ +#include +#include +#include + ]) +fi +fi + +AC_CACHE_CHECK([for sin_len in sock],libreplace_cv_HAVE_SOCK_SIN_LEN,[ + AC_TRY_COMPILE( + [ +#include +#include +#include + ],[ +struct sockaddr_in sock; sock.sin_len = sizeof(sock); + ],[ + libreplace_cv_HAVE_SOCK_SIN_LEN=yes + ],[ + libreplace_cv_HAVE_SOCK_SIN_LEN=no + ]) +]) +if test x"$libreplace_cv_HAVE_SOCK_SIN_LEN" = x"yes"; then + AC_DEFINE(HAVE_SOCK_SIN_LEN,1,[Whether the sockaddr_in struct has a sin_len property]) +fi + +############################################ +# check for unix domain sockets +AC_CACHE_CHECK([for unix domain sockets],libreplace_cv_HAVE_UNIXSOCKET,[ + AC_TRY_COMPILE([ +#include +#include +#include +#include +#include + ],[ +struct sockaddr_un sunaddr; +sunaddr.sun_family = AF_UNIX; + ],[ + libreplace_cv_HAVE_UNIXSOCKET=yes + ],[ + libreplace_cv_HAVE_UNIXSOCKET=no + ]) +]) +if test x"$libreplace_cv_HAVE_UNIXSOCKET" = x"yes"; then + AC_DEFINE(HAVE_UNIXSOCKET,1,[If we need to build with unixscoket support]) +fi + +dnl The following test is roughl taken from the cvs sources. +dnl +dnl If we can't find connect, try looking in -lsocket, -lnsl, and -linet. +dnl The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has +dnl libsocket.so which has a bad implementation of gethostbyname (it +dnl only looks in /etc/hosts), so we only look for -lsocket if we need +dnl it. +AC_CHECK_FUNCS(connect) +if test x"$ac_cv_func_connect" = x"no"; then + AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, connect) + AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, connect) + AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, connect) + AC_CHECK_LIB_EXT(inet, LIBREPLACE_NETWORK_LIBS, connect) + dnl We can't just call AC_CHECK_FUNCS(connect) here, + dnl because the value has been cached. + if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" || + test x"$ac_cv_lib_ext_nsl_connect" = x"yes" || + test x"$ac_cv_lib_ext_socket_connect" = x"yes" || + test x"$ac_cv_lib_ext_inet_connect" = x"yes" + then + AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()]) + fi +fi + +AC_CHECK_FUNCS(gethostbyname) +if test x"$ac_cv_func_gethostbyname" = x"no"; then + AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, gethostbyname) + AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, gethostbyname) + AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, gethostbyname) + dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here, + dnl because the value has been cached. + if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" = x"yes" || + test x"$ac_cv_lib_ext_nsl_gethostbyname" = x"yes" || + test x"$ac_cv_lib_ext_socket_gethostbyname" = x"yes" + then + AC_DEFINE(HAVE_GETHOSTBYNAME,1, + [Whether the system has gethostbyname()]) + fi +fi + +dnl HP-UX has if_nametoindex in -lipv6 +AC_CHECK_FUNCS(if_nametoindex) +if test x"$ac_cv_func_if_nametoindex" = x"no"; then + AC_CHECK_LIB_EXT(ipv6, LIBREPLACE_NETWORK_LIBS, if_nametoindex) + dnl We can't just call AC_CHECK_FUNCS(if_nametoindex) here, + dnl because the value has been cached. + if test x"$ac_cv_lib_ext_ipv6_if_nametoindex" = x"yes" + then + AC_DEFINE(HAVE_IF_NAMETOINDEX, 1, + [Whether the system has if_nametoindex()]) + fi +fi + +# The following tests need LIBS="${LIBREPLACE_NETWORK_LIBS}" +old_LIBS=$LIBS +LIBS="${LIBREPLACE_NETWORK_LIBS}" +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS -I$libreplacedir" + +AC_CHECK_FUNCS(socketpair,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} socketpair.o"]) + +AC_CACHE_CHECK([for broken inet_ntoa],libreplace_cv_REPLACE_INET_NTOA,[ +AC_TRY_RUN([ +#include +#include +#include +#include +#ifdef HAVE_ARPA_INET_H +#include +#endif +main() { struct in_addr ip; ip.s_addr = 0x12345678; +if (strcmp(inet_ntoa(ip),"18.52.86.120") && + strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } +exit(1);}], + libreplace_cv_REPLACE_INET_NTOA=yes,libreplace_cv_REPLACE_INET_NTOA=no,libreplace_cv_REPLACE_INET_NTOA=cross)]) + +AC_CHECK_FUNCS(inet_ntoa,[],[libreplace_cv_REPLACE_INET_NTOA=yes]) +if test x"$libreplace_cv_REPLACE_INET_NTOA" = x"yes"; then + AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced]) + LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_ntoa.o" +fi + +AC_CHECK_FUNCS(inet_aton,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_aton.o"]) + +AC_CHECK_FUNCS(inet_ntop,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_ntop.o"]) + +AC_CHECK_FUNCS(inet_pton,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_pton.o"]) + +dnl test for getaddrinfo/getnameinfo +AC_CACHE_CHECK([for getaddrinfo],libreplace_cv_HAVE_GETADDRINFO,[ +AC_TRY_LINK([ +#include +#if STDC_HEADERS +#include +#include +#endif +#include +#include ], +[ +struct sockaddr sa; +struct addrinfo *ai = NULL; +int ret = getaddrinfo(NULL, NULL, NULL, &ai); +if (ret != 0) { + const char *es = gai_strerror(ret); +} +freeaddrinfo(ai); +ret = getnameinfo(&sa, sizeof(sa), + NULL, 0, + NULL, 0, 0); + +], +libreplace_cv_HAVE_GETADDRINFO=yes,libreplace_cv_HAVE_GETADDRINFO=no)]) +if test x"$libreplace_cv_HAVE_GETADDRINFO" = x"yes"; then + AC_DEFINE(HAVE_GETADDRINFO,1,[Whether the system has getaddrinfo]) + AC_DEFINE(HAVE_GETNAMEINFO,1,[Whether the system has getnameinfo]) + AC_DEFINE(HAVE_FREEADDRINFO,1,[Whether the system has freeaddrinfo]) + AC_DEFINE(HAVE_GAI_STRERROR,1,[Whether the system has gai_strerror]) +else + LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} getaddrinfo.o" +fi + +AC_CHECK_HEADERS([ifaddrs.h]) + +dnl Used when getifaddrs is not available +AC_CHECK_MEMBERS([struct sockaddr.sa_len], + [AC_DEFINE(HAVE_SOCKADDR_SA_LEN, 1, [Whether struct sockaddr has a sa_len member])], + [], + [#include ]) + +dnl test for getifaddrs and freeifaddrs +AC_CACHE_CHECK([for getifaddrs and freeifaddrs],libreplace_cv_HAVE_GETIFADDRS,[ +AC_TRY_COMPILE([ +#include +#if STDC_HEADERS +#include +#include +#endif +#include +#include +#include +#include +#include ], +[ +struct ifaddrs *ifp = NULL; +int ret = getifaddrs (&ifp); +freeifaddrs(ifp); +], +libreplace_cv_HAVE_GETIFADDRS=yes,libreplace_cv_HAVE_GETIFADDRS=no)]) +if test x"$libreplace_cv_HAVE_GETIFADDRS" = x"yes"; then + AC_DEFINE(HAVE_GETIFADDRS,1,[Whether the system has getifaddrs]) + AC_DEFINE(HAVE_FREEIFADDRS,1,[Whether the system has freeifaddrs]) + AC_DEFINE(HAVE_STRUCT_IFADDRS,1,[Whether struct ifaddrs is available]) +fi + +################## +# look for a method of finding the list of network interfaces +iface=no; +AC_CACHE_CHECK([for iface getifaddrs],libreplace_cv_HAVE_IFACE_GETIFADDRS,[ +AC_TRY_RUN([ +#define HAVE_IFACE_GETIFADDRS 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_GETIFADDRS=yes,libreplace_cv_HAVE_IFACE_GETIFADDRS=no,libreplace_cv_HAVE_IFACE_GETIFADDRS=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_GETIFADDRS" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_GETIFADDRS,1,[Whether iface getifaddrs is available]) +else + LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} getifaddrs.o" +fi + + +if test $iface = no; then +AC_CACHE_CHECK([for iface AIX],libreplace_cv_HAVE_IFACE_AIX,[ +AC_TRY_RUN([ +#define HAVE_IFACE_AIX 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#undef _XOPEN_SOURCE_EXTENDED +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available]) +fi +fi + + +if test $iface = no; then +AC_CACHE_CHECK([for iface ifconf],libreplace_cv_HAVE_IFACE_IFCONF,[ +AC_TRY_RUN([ +#define HAVE_IFACE_IFCONF 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available]) +fi +fi + +if test $iface = no; then +AC_CACHE_CHECK([for iface ifreq],libreplace_cv_HAVE_IFACE_IFREQ,[ +AC_TRY_RUN([ +#define HAVE_IFACE_IFREQ 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available]) +fi +fi + +dnl test for ipv6 +AC_CACHE_CHECK([for ipv6 support],libreplace_cv_HAVE_IPV6,[ + AC_TRY_LINK([ +#include /* for NULL */ +#include +#include +#include + ], + [ +struct sockaddr_storage sa_store; +struct addrinfo *ai = NULL; +struct in6_addr in6addr; +int idx = if_nametoindex("iface1"); +int s = socket(AF_INET6, SOCK_STREAM, 0); +int ret = getaddrinfo(NULL, NULL, NULL, &ai); +if (ret != 0) { + const char *es = gai_strerror(ret); +} +freeaddrinfo(ai); + ],[ + libreplace_cv_HAVE_IPV6=yes + ],[ + libreplace_cv_HAVE_IPV6=no + ]) +]) +if test x"$libreplace_cv_HAVE_IPV6" = x"yes"; then + AC_DEFINE(HAVE_IPV6,1,[Whether the system has IPv6 support]) +fi + +LIBS=$old_LIBS +CPPFLAGS="$SAVE_CPPFLAGS" + +LIBREPLACEOBJ="${LIBREPLACEOBJ} ${LIBREPLACE_NETWORK_OBJS}" + +echo "LIBREPLACE_NETWORK_CHECKS: END" +]) dnl end AC_LIBREPLACE_NETWORK_CHECKS diff --git a/lib/replace/repdir.m4 b/lib/replace/repdir.m4 new file mode 100644 index 0000000000..f53a4c2974 --- /dev/null +++ b/lib/replace/repdir.m4 @@ -0,0 +1,78 @@ +AC_CACHE_CHECK([for broken readdir],libreplace_cv_READDIR_NEEDED,[ + AC_TRY_RUN([ +#define test_readdir_os2_delete main +#include "$libreplacedir/test/os2_delete.c"], + [libreplace_cv_READDIR_NEEDED=no], + [libreplace_cv_READDIR_NEEDED=yes], + [libreplace_cv_READDIR_NEEDED="assuming not"]) +]) + +# +# try to replace with getdirentries() if needed +# +if test x"$libreplace_cv_READDIR_NEEDED" = x"yes"; then +AC_CHECK_FUNCS(getdirentries) +AC_VERIFY_C_PROTOTYPE([long telldir(const DIR *dir)], + [ + return 0; + ],[ + AC_DEFINE(TELLDIR_TAKES_CONST_DIR, 1, [Whether telldir takes a const pointer]) + ],[],[ + #include + ]) + +AC_VERIFY_C_PROTOTYPE([int seekdir(DIR *dir, long ofs)], + [ + return 0; + ],[ + AC_DEFINE(SEEKDIR_RETURNS_INT, 1, [Whether seekdir returns an int]) + ],[],[ + #include + ]) +AC_CACHE_CHECK([for replacing readdir using getdirentries()],libreplace_cv_READDIR_GETDIRENTRIES,[ + AC_TRY_RUN([ +#define _LIBREPLACE_REPLACE_H +#include "$libreplacedir/repdir_getdirentries.c" +#define test_readdir_os2_delete main +#include "$libreplacedir/test/os2_delete.c"], + [libreplace_cv_READDIR_GETDIRENTRIES=yes], + [libreplace_cv_READDIR_GETDIRENTRIES=no]) +]) +fi +if test x"$libreplace_cv_READDIR_GETDIRENTRIES" = x"yes"; then + AC_DEFINE(REPLACE_READDIR,1,[replace readdir]) + AC_DEFINE(REPLACE_READDIR_GETDIRENTRIES,1,[replace readdir using getdirentries()]) + LIBREPLACEOBJ="${LIBREPLACEOBJ} repdir_getdirentries.o" + libreplace_cv_READDIR_NEEDED=no +fi + +# +# try to replace with getdents() if needed +# +if test x"$libreplace_cv_READDIR_NEEDED" = x"yes"; then +AC_CHECK_FUNCS(getdents) +AC_CACHE_CHECK([for replacing readdir using getdents()],libreplace_cv_READDIR_GETDENTS,[ + AC_TRY_RUN([ +#define _LIBREPLACE_REPLACE_H +#error _donot_use_getdents_replacement_anymore +#include "$libreplacedir/repdir_getdents.c" +#define test_readdir_os2_delete main +#include "$libreplacedir/test/os2_delete.c"], + [libreplace_cv_READDIR_GETDENTS=yes], + [libreplace_cv_READDIR_GETDENTS=no]) +]) +fi +if test x"$libreplace_cv_READDIR_GETDENTS" = x"yes"; then + AC_DEFINE(REPLACE_READDIR,1,[replace readdir]) + AC_DEFINE(REPLACE_READDIR_GETDENTS,1,[replace readdir using getdents()]) + LIBREPLACEOBJ="${LIBREPLACEOBJ} repdir_getdents.o" + libreplace_cv_READDIR_NEEDED=no +fi + +AC_MSG_CHECKING([a usable readdir()]) +if test x"$libreplace_cv_READDIR_NEEDED" = x"yes"; then + AC_MSG_RESULT(no) + AC_MSG_WARN([the provided readdir() is broken]) +else + AC_MSG_RESULT(yes) +fi diff --git a/lib/replace/repdir_getdents.c b/lib/replace/repdir_getdents.c new file mode 100644 index 0000000000..afc634a796 --- /dev/null +++ b/lib/replace/repdir_getdents.c @@ -0,0 +1,166 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +/* + a replacement for opendir/readdir/telldir/seekdir/closedir for BSD systems + + This is needed because the existing directory handling in FreeBSD + and OpenBSD (and possibly NetBSD) doesn't correctly handle unlink() + on files in a directory where telldir() has been used. On a block + boundary it will occasionally miss a file when seekdir() is used to + return to a position previously recorded with telldir(). + + This also fixes a severe performance and memory usage problem with + telldir() on BSD systems. Each call to telldir() in BSD adds an + entry to a linked list, and those entries are cleaned up on + closedir(). This means with a large directory closedir() can take an + arbitrary amount of time, causing network timeouts as millions of + telldir() entries are freed + + Note! This replacement code is not portable. It relies on getdents() + always leaving the file descriptor at a seek offset that is a + multiple of DIR_BUF_SIZE. If the code detects that this doesn't + happen then it will abort(). It also does not handle directories + with offsets larger than can be stored in a long, + + This code is available under other free software licenses as + well. Contact the author. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define DIR_BUF_BITS 9 +#define DIR_BUF_SIZE (1<fd = open(dname, O_RDONLY); + if (d->fd == -1) { + free(d); + return NULL; + } + if (fstat(d->fd, &sb) < 0) { + close(d->fd); + free(d); + return NULL; + } + if (!S_ISDIR(sb.st_mode)) { + close(d->fd); + free(d); + errno = ENOTDIR; + return NULL; + } + d->ofs = 0; + d->seekpos = 0; + d->nbytes = 0; + return (DIR *)d; +} + +struct dirent *readdir(DIR *dir) +{ + struct dir_buf *d = (struct dir_buf *)dir; + struct dirent *de; + + if (d->ofs >= d->nbytes) { + d->seekpos = lseek(d->fd, 0, SEEK_CUR); + d->nbytes = getdents(d->fd, d->buf, DIR_BUF_SIZE); + d->ofs = 0; + } + if (d->ofs >= d->nbytes) { + return NULL; + } + de = (struct dirent *)&d->buf[d->ofs]; + d->ofs += de->d_reclen; + return de; +} + +long telldir(DIR *dir) +{ + struct dir_buf *d = (struct dir_buf *)dir; + if (d->ofs >= d->nbytes) { + d->seekpos = lseek(d->fd, 0, SEEK_CUR); + d->ofs = 0; + d->nbytes = 0; + } + /* this relies on seekpos always being a multiple of + DIR_BUF_SIZE. Is that always true on BSD systems? */ + if (d->seekpos & (DIR_BUF_SIZE-1)) { + abort(); + } + return d->seekpos + d->ofs; +} + +void seekdir(DIR *dir, long ofs) +{ + struct dir_buf *d = (struct dir_buf *)dir; + d->seekpos = lseek(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET); + d->nbytes = getdents(d->fd, d->buf, DIR_BUF_SIZE); + d->ofs = 0; + while (d->ofs < (ofs & (DIR_BUF_SIZE-1))) { + if (readdir(dir) == NULL) break; + } +} + +void rewinddir(DIR *dir) +{ + seekdir(dir, 0); +} + +int closedir(DIR *dir) +{ + struct dir_buf *d = (struct dir_buf *)dir; + int r = close(d->fd); + if (r != 0) { + return r; + } + free(d); + return 0; +} + +#ifndef dirfd +/* darn, this is a macro on some systems. */ +int dirfd(DIR *dir) +{ + struct dir_buf *d = (struct dir_buf *)dir; + return d->fd; +} +#endif diff --git a/lib/replace/repdir_getdirentries.c b/lib/replace/repdir_getdirentries.c new file mode 100644 index 0000000000..197e5931fc --- /dev/null +++ b/lib/replace/repdir_getdirentries.c @@ -0,0 +1,183 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +/* + a replacement for opendir/readdir/telldir/seekdir/closedir for BSD + systems using getdirentries + + This is needed because the existing directory handling in FreeBSD + and OpenBSD (and possibly NetBSD) doesn't correctly handle unlink() + on files in a directory where telldir() has been used. On a block + boundary it will occasionally miss a file when seekdir() is used to + return to a position previously recorded with telldir(). + + This also fixes a severe performance and memory usage problem with + telldir() on BSD systems. Each call to telldir() in BSD adds an + entry to a linked list, and those entries are cleaned up on + closedir(). This means with a large directory closedir() can take an + arbitrary amount of time, causing network timeouts as millions of + telldir() entries are freed + + Note! This replacement code is not portable. It relies on + getdirentries() always leaving the file descriptor at a seek offset + that is a multiple of DIR_BUF_SIZE. If the code detects that this + doesn't happen then it will abort(). It also does not handle + directories with offsets larger than can be stored in a long, + + This code is available under other free software licenses as + well. Contact the author. +*/ + +#include "replace.h" +#include +#include +#include +#include +#include +#include +#include + +#define DIR_BUF_BITS 9 +#define DIR_BUF_SIZE (1<fd = open(dname, O_RDONLY); + if (d->fd == -1) { + free(d); + return NULL; + } + if (fstat(d->fd, &sb) < 0) { + close(d->fd); + free(d); + return NULL; + } + if (!S_ISDIR(sb.st_mode)) { + close(d->fd); + free(d); + errno = ENOTDIR; + return NULL; + } + d->ofs = 0; + d->seekpos = 0; + d->nbytes = 0; + return (DIR *)d; +} + +struct dirent *readdir(DIR *dir) +{ + struct dir_buf *d = (struct dir_buf *)dir; + struct dirent *de; + + if (d->ofs >= d->nbytes) { + long pos; + d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos); + d->seekpos = pos; + d->ofs = 0; + } + if (d->ofs >= d->nbytes) { + return NULL; + } + de = (struct dirent *)&d->buf[d->ofs]; + d->ofs += de->d_reclen; + return de; +} + +#ifdef TELLDIR_TAKES_CONST_DIR +long telldir(const DIR *dir) +#else +long telldir(DIR *dir) +#endif +{ + struct dir_buf *d = (struct dir_buf *)dir; + if (d->ofs >= d->nbytes) { + d->seekpos = lseek(d->fd, 0, SEEK_CUR); + d->ofs = 0; + d->nbytes = 0; + } + /* this relies on seekpos always being a multiple of + DIR_BUF_SIZE. Is that always true on BSD systems? */ + if (d->seekpos & (DIR_BUF_SIZE-1)) { + abort(); + } + return d->seekpos + d->ofs; +} + +#ifdef SEEKDIR_RETURNS_INT +int seekdir(DIR *dir, long ofs) +#else +void seekdir(DIR *dir, long ofs) +#endif +{ + struct dir_buf *d = (struct dir_buf *)dir; + long pos; + d->seekpos = lseek(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET); + d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos); + d->ofs = 0; + while (d->ofs < (ofs & (DIR_BUF_SIZE-1))) { + if (readdir(dir) == NULL) break; + } +#ifdef SEEKDIR_RETURNS_INT + return -1; +#endif +} + +void rewinddir(DIR *dir) +{ + seekdir(dir, 0); +} + +int closedir(DIR *dir) +{ + struct dir_buf *d = (struct dir_buf *)dir; + int r = close(d->fd); + if (r != 0) { + return r; + } + free(d); + return 0; +} + +#ifndef dirfd +/* darn, this is a macro on some systems. */ +int dirfd(DIR *dir) +{ + struct dir_buf *d = (struct dir_buf *)dir; + return d->fd; +} +#endif + + diff --git a/lib/replace/replace.c b/lib/replace/replace.c new file mode 100644 index 0000000000..98d799b07e --- /dev/null +++ b/lib/replace/replace.c @@ -0,0 +1,616 @@ +/* + Unix SMB/CIFS implementation. + replacement routines for broken systems + Copyright (C) Andrew Tridgell 1992-1998 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" + +#include "system/filesys.h" +#include "system/time.h" +#include "system/passwd.h" +#include "system/syslog.h" +#include "system/locale.h" +#include "system/wait.h" + +void replace_dummy(void); +void replace_dummy(void) {} + +#ifndef HAVE_FTRUNCATE + /******************************************************************* +ftruncate for operating systems that don't have it +********************************************************************/ +int rep_ftruncate(int f, off_t l) +{ +#ifdef HAVE_CHSIZE + return chsize(f,l); +#elif defined(F_FREESP) + struct flock fl; + + fl.l_whence = 0; + fl.l_len = 0; + fl.l_start = l; + fl.l_type = F_WRLCK; + return fcntl(f, F_FREESP, &fl); +#else +#error "you must have a ftruncate function" +#endif +} +#endif /* HAVE_FTRUNCATE */ + + +#ifndef HAVE_STRLCPY +/* like strncpy but does not 0 fill the buffer and always null + terminates. bufsize is the size of the destination buffer */ +size_t rep_strlcpy(char *d, const char *s, size_t bufsize) +{ + size_t len = strlen(s); + size_t ret = len; + if (bufsize <= 0) return 0; + if (len >= bufsize) len = bufsize-1; + memcpy(d, s, len); + d[len] = 0; + return ret; +} +#endif + +#ifndef HAVE_STRLCAT +/* like strncat but does not 0 fill the buffer and always null + terminates. bufsize is the length of the buffer, which should + be one more than the maximum resulting string length */ +size_t rep_strlcat(char *d, const char *s, size_t bufsize) +{ + size_t len1 = strlen(d); + size_t len2 = strlen(s); + size_t ret = len1 + len2; + + if (len1+len2 >= bufsize) { + if (bufsize < (len1+1)) { + return ret; + } + len2 = bufsize - (len1+1); + } + if (len2 > 0) { + memcpy(d+len1, s, len2); + d[len1+len2] = 0; + } + return ret; +} +#endif + +#ifndef HAVE_MKTIME +/******************************************************************* +a mktime() replacement for those who don't have it - contributed by +C.A. Lademann +Corrections by richard.kettlewell@kewill.com +********************************************************************/ + +#define MINUTE 60 +#define HOUR 60*MINUTE +#define DAY 24*HOUR +#define YEAR 365*DAY +time_t rep_mktime(struct tm *t) +{ + struct tm *u; + time_t epoch = 0; + int n; + int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + y, m, i; + + if(t->tm_year < 70) + return((time_t)-1); + + n = t->tm_year + 1900 - 1; + epoch = (t->tm_year - 70) * YEAR + + ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY; + + y = t->tm_year + 1900; + m = 0; + + for(i = 0; i < t->tm_mon; i++) { + epoch += mon [m] * DAY; + if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) + epoch += DAY; + + if(++m > 11) { + m = 0; + y++; + } + } + + epoch += (t->tm_mday - 1) * DAY; + epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; + + if((u = localtime(&epoch)) != NULL) { + t->tm_sec = u->tm_sec; + t->tm_min = u->tm_min; + t->tm_hour = u->tm_hour; + t->tm_mday = u->tm_mday; + t->tm_mon = u->tm_mon; + t->tm_year = u->tm_year; + t->tm_wday = u->tm_wday; + t->tm_yday = u->tm_yday; + t->tm_isdst = u->tm_isdst; + } + + return(epoch); +} +#endif /* !HAVE_MKTIME */ + + +#ifndef HAVE_INITGROUPS +/**************************************************************************** + some systems don't have an initgroups call +****************************************************************************/ +int rep_initgroups(char *name, gid_t id) +{ +#ifndef HAVE_SETGROUPS + /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ + errno = ENOSYS; + return -1; +#else /* HAVE_SETGROUPS */ + +#include + + gid_t *grouplst = NULL; + int max_gr = NGROUPS_MAX; + int ret; + int i,j; + struct group *g; + char *gr; + + if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) { + errno = ENOMEM; + return -1; + } + + grouplst[0] = id; + i = 1; + while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) { + if (g->gr_gid == id) + continue; + j = 0; + gr = g->gr_mem[0]; + while (gr && (*gr != (char)NULL)) { + if (strcmp(name,gr) == 0) { + grouplst[i] = g->gr_gid; + i++; + gr = (char *)NULL; + break; + } + gr = g->gr_mem[++j]; + } + } + endgrent(); + ret = setgroups(i, grouplst); + free(grouplst); + return ret; +#endif /* HAVE_SETGROUPS */ +} +#endif /* HAVE_INITGROUPS */ + + +#if (defined(SecureWare) && defined(SCO)) +/* This is needed due to needing the nap() function but we don't want + to include the Xenix libraries since that will break other things... + BTW: system call # 0x0c28 is the same as calling nap() */ +long nap(long milliseconds) { + return syscall(0x0c28, milliseconds); + } +#endif + + +#ifndef HAVE_MEMMOVE +/******************************************************************* +safely copies memory, ensuring no overlap problems. +this is only used if the machine does not have its own memmove(). +this is not the fastest algorithm in town, but it will do for our +needs. +********************************************************************/ +void *rep_memmove(void *dest,const void *src,int size) +{ + unsigned long d,s; + int i; + if (dest==src || !size) return(dest); + + d = (unsigned long)dest; + s = (unsigned long)src; + + if ((d >= (s+size)) || (s >= (d+size))) { + /* no overlap */ + memcpy(dest,src,size); + return(dest); + } + + if (d < s) { + /* we can forward copy */ + if (s-d >= sizeof(int) && + !(s%sizeof(int)) && + !(d%sizeof(int)) && + !(size%sizeof(int))) { + /* do it all as words */ + int *idest = (int *)dest; + int *isrc = (int *)src; + size /= sizeof(int); + for (i=0;i= sizeof(int) && + !(s%sizeof(int)) && + !(d%sizeof(int)) && + !(size%sizeof(int))) { + /* do it all as words */ + int *idest = (int *)dest; + int *isrc = (int *)src; + size /= sizeof(int); + for (i=size-1;i>=0;i--) idest[i] = isrc[i]; + } else { + /* simplest */ + char *cdest = (char *)dest; + char *csrc = (char *)src; + for (i=size-1;i>=0;i--) cdest[i] = csrc[i]; + } + } + return(dest); +} +#endif /* HAVE_MEMMOVE */ + +#ifndef HAVE_STRDUP +/**************************************************************************** +duplicate a string +****************************************************************************/ +char *rep_strdup(const char *s) +{ + size_t len; + char *ret; + + if (!s) return(NULL); + + len = strlen(s)+1; + ret = (char *)malloc(len); + if (!ret) return(NULL); + memcpy(ret,s,len); + return(ret); +} +#endif /* HAVE_STRDUP */ + +#ifndef HAVE_SETLINEBUF +void rep_setlinebuf(FILE *stream) +{ + setvbuf(stream, (char *)NULL, _IOLBF, 0); +} +#endif /* HAVE_SETLINEBUF */ + +#ifndef HAVE_VSYSLOG +#ifdef HAVE_SYSLOG +void rep_vsyslog (int facility_priority, const char *format, va_list arglist) +{ + char *msg = NULL; + vasprintf(&msg, format, arglist); + if (!msg) + return; + syslog(facility_priority, "%s", msg); + free(msg); +} +#endif /* HAVE_SYSLOG */ +#endif /* HAVE_VSYSLOG */ + +#ifndef HAVE_STRNLEN +/** + Some platforms don't have strnlen +**/ + size_t rep_strnlen(const char *s, size_t max) +{ + size_t len; + + for (len = 0; len < max; len++) { + if (s[len] == '\0') { + break; + } + } + return len; +} +#endif + +#ifndef HAVE_STRNDUP +/** + Some platforms don't have strndup. +**/ +char *rep_strndup(const char *s, size_t n) +{ + char *ret; + + n = strnlen(s, n); + ret = malloc(n+1); + if (!ret) + return NULL; + memcpy(ret, s, n); + ret[n] = 0; + + return ret; +} +#endif + +#ifndef HAVE_WAITPID +int rep_waitpid(pid_t pid,int *status,int options) +{ + return wait4(pid, status, options, NULL); +} +#endif + +#ifndef HAVE_SETEUID +int rep_seteuid(uid_t euid) +{ +#ifdef HAVE_SETRESUID + return setresuid(-1, euid, -1); +#else +# error "You need a seteuid function" +#endif +} +#endif + +#ifndef HAVE_SETEGID +int rep_setegid(gid_t egid) +{ +#ifdef HAVE_SETRESGID + return setresgid(-1, egid, -1); +#else +# error "You need a setegid function" +#endif +} +#endif + +/******************************************************************* +os/2 also doesn't have chroot +********************************************************************/ +#ifndef HAVE_CHROOT +int rep_chroot(const char *dname) +{ + errno = ENOSYS; + return -1; +} +#endif + +/***************************************************************** + Possibly replace mkstemp if it is broken. +*****************************************************************/ + +#ifndef HAVE_SECURE_MKSTEMP +int rep_mkstemp(char *template) +{ + /* have a reasonable go at emulating it. Hope that + the system mktemp() isn't completly hopeless */ + char *p = mktemp(template); + if (!p) + return -1; + return open(p, O_CREAT|O_EXCL|O_RDWR, 0600); +} +#endif + +#ifndef HAVE_MKDTEMP +char *rep_mkdtemp(char *template) +{ + char *dname; + + if ((dname = mktemp(template))) { + if (mkdir(dname, 0700) >= 0) { + return dname; + } + } + + return NULL; +} +#endif + +/***************************************************************** + Watch out: this is not thread safe. +*****************************************************************/ + +#ifndef HAVE_PREAD +ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) +{ + if (lseek(__fd, __offset, SEEK_SET) != __offset) { + return -1; + } + return read(__fd, __buf, __nbytes); +} +#endif + +/***************************************************************** + Watch out: this is not thread safe. +*****************************************************************/ + +#ifndef HAVE_PWRITE +ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) +{ + if (lseek(__fd, __offset, SEEK_SET) != __offset) { + return -1; + } + return write(__fd, __buf, __nbytes); +} +#endif + +#ifndef HAVE_STRCASESTR +char *rep_strcasestr(const char *haystack, const char *needle) +{ + const char *s; + size_t nlen = strlen(needle); + for (s=haystack;*s;s++) { + if (toupper(*needle) == toupper(*s) && + strncasecmp(s, needle, nlen) == 0) { + return (char *)((uintptr_t)s); + } + } + return NULL; +} +#endif + +#ifndef HAVE_STRTOK_R +/* based on GLIBC version, copyright Free Software Foundation */ +char *rep_strtok_r(char *s, const char *delim, char **save_ptr) +{ + char *token; + + if (s == NULL) s = *save_ptr; + + s += strspn(s, delim); + if (*s == '\0') { + *save_ptr = s; + return NULL; + } + + token = s; + s = strpbrk(token, delim); + if (s == NULL) { + *save_ptr = token + strlen(token); + } else { + *s = '\0'; + *save_ptr = s + 1; + } + + return token; +} +#endif + +#ifndef HAVE_STRTOLL +long long int rep_strtoll(const char *str, char **endptr, int base) +{ +#ifdef HAVE_STRTOQ + return strtoq(str, endptr, base); +#elif defined(HAVE___STRTOLL) + return __strtoll(str, endptr, base); +#elif SIZEOF_LONG == SIZEOF_LONG_LONG + return (long long int) strtol(str, endptr, base); +#else +# error "You need a strtoll function" +#endif +} +#endif + + +#ifndef HAVE_STRTOULL +unsigned long long int rep_strtoull(const char *str, char **endptr, int base) +{ +#ifdef HAVE_STRTOUQ + return strtouq(str, endptr, base); +#elif defined(HAVE___STRTOULL) + return __strtoull(str, endptr, base); +#elif SIZEOF_LONG == SIZEOF_LONG_LONG + return (unsigned long long int) strtoul(str, endptr, base); +#else +# error "You need a strtoull function" +#endif +} +#endif + +#ifndef HAVE_SETENV +int rep_setenv(const char *name, const char *value, int overwrite) +{ + char *p; + size_t l1, l2; + int ret; + + if (!overwrite && getenv(name)) { + return 0; + } + + l1 = strlen(name); + l2 = strlen(value); + + p = malloc(l1+l2+2); + if (p == NULL) { + return -1; + } + memcpy(p, name, l1); + p[l1] = '='; + memcpy(p+l1+1, value, l2); + p[l1+l2+1] = 0; + + ret = putenv(p); + if (ret != 0) { + free(p); + } + + return ret; +} +#endif + +#ifndef HAVE_UNSETENV +int rep_unsetenv(const char *name) +{ + extern char **environ; + size_t len = strlen(name); + size_t i, count; + + if (environ == NULL || getenv(name) == NULL) { + return 0; + } + + for (i=0;environ[i];i++) /* noop */ ; + + count=i; + + for (i=0;i +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#if STDC_HEADERS +#include +#include +#endif + +#ifndef HAVE_STRERROR +extern char *sys_errlist[]; +#define strerror(i) sys_errlist[i] +#endif + +#ifndef HAVE_ERRNO_DECL +extern int errno; +#endif + +#ifndef HAVE_STRDUP +#define strdup rep_strdup +char *rep_strdup(const char *s); +#endif + +#ifndef HAVE_MEMMOVE +#define memmove rep_memmove +void *rep_memmove(void *dest,const void *src,int size); +#endif + +#ifndef HAVE_MKTIME +#define mktime rep_mktime +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_TIMEGM +#define timegm rep_timegm +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_UTIME +#define utime rep_utime +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_UTIMES +#define utimes rep_utimes +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_STRLCPY +#define strlcpy rep_strlcpy +size_t rep_strlcpy(char *d, const char *s, size_t bufsize); +#endif + +#ifndef HAVE_STRLCAT +#define strlcat rep_strlcat +size_t rep_strlcat(char *d, const char *s, size_t bufsize); +#endif + +#if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP)) +#undef HAVE_STRNDUP +#define strndup rep_strndup +char *rep_strndup(const char *s, size_t n); +#endif + +#if (defined(BROKEN_STRNLEN) || !defined(HAVE_STRNLEN)) +#undef HAVE_STRNLEN +#define strnlen rep_strnlen +size_t rep_strnlen(const char *s, size_t n); +#endif + +#ifndef HAVE_SETENV +#define setenv rep_setenv +int rep_setenv(const char *name, const char *value, int overwrite); +#else +#ifndef HAVE_SETENV_DECL +int setenv(const char *name, const char *value, int overwrite); +#endif +#endif + +#ifndef HAVE_UNSETENV +#define unsetenv rep_unsetenv +int rep_unsetenv(const char *name); +#endif + +#ifndef HAVE_SETEUID +#define seteuid rep_seteuid +int rep_seteuid(uid_t); +#endif + +#ifndef HAVE_SETEGID +#define setegid rep_setegid +int rep_setegid(gid_t); +#endif + +#ifndef HAVE_SETLINEBUF +#define setlinebuf rep_setlinebuf +void rep_setlinebuf(FILE *); +#endif + +#ifndef HAVE_STRCASESTR +#define strcasestr rep_strcasestr +char *rep_strcasestr(const char *haystack, const char *needle); +#endif + +#ifndef HAVE_STRTOK_R +#define strtok_r rep_strtok_r +char *rep_strtok_r(char *s, const char *delim, char **save_ptr); +#endif + +#ifndef HAVE_STRTOLL +#define strtoll rep_strtoll +long long int rep_strtoll(const char *str, char **endptr, int base); +#endif + +#ifndef HAVE_STRTOULL +#define strtoull rep_strtoull +unsigned long long int rep_strtoull(const char *str, char **endptr, int base); +#endif + +#ifndef HAVE_FTRUNCATE +#define ftruncate rep_ftruncate +int rep_ftruncate(int,off_t); +#endif + +#ifndef HAVE_INITGROUPS +#define initgroups rep_initgroups +int rep_initgroups(char *name, gid_t id); +#endif + +#if !defined(HAVE_BZERO) && defined(HAVE_MEMSET) +#define bzero(a,b) memset((a),'\0',(b)) +#endif + +#ifndef HAVE_DLERROR +#define dlerror rep_dlerror +char *rep_dlerror(void); +#endif + +#ifndef HAVE_DLOPEN +#define dlopen rep_dlopen +#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS +void *rep_dlopen(const char *name, unsigned int flags); +#else +void *rep_dlopen(const char *name, int flags); +#endif +#endif + +#ifndef HAVE_DLSYM +#define dlsym rep_dlsym +void *rep_dlsym(void *handle, const char *symbol); +#endif + +#ifndef HAVE_DLCLOSE +#define dlclose rep_dlclose +int rep_dlclose(void *handle); +#endif + +#ifndef HAVE_SOCKETPAIR +#define socketpair rep_socketpair +/* prototype is in system/network.h */ +#endif + +#ifndef PRINTF_ATTRIBUTE +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +#ifndef _DEPRECATED_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif + +#ifndef HAVE_VASPRINTF +#define vasprintf rep_vasprintf +int rep_vasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); +#endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define snprintf rep_snprintf +int rep_snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4); +#endif + +#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define vsnprintf rep_vsnprintf +int rep_vsnprintf(char *,size_t ,const char *, va_list ap) PRINTF_ATTRIBUTE(3,0); +#endif + +#ifndef HAVE_ASPRINTF +#define asprintf rep_asprintf +int rep_asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); +#endif + +#ifndef HAVE_VSYSLOG +#ifdef HAVE_SYSLOG +#define vsyslog rep_vsyslog +void rep_vsyslog (int facility_priority, const char *format, va_list arglist) PRINTF_ATTRIBUTE(2,0); +#endif +#endif + +/* we used to use these fns, but now we have good replacements + for snprintf and vsnprintf */ +#define slprintf snprintf + + +#ifndef HAVE_VA_COPY +#undef va_copy +#ifdef HAVE___VA_COPY +#define va_copy(dest, src) __va_copy(dest, src) +#else +#define va_copy(dest, src) (dest) = (src) +#endif +#endif + +#ifndef HAVE_VOLATILE +#define volatile +#endif + +#ifndef HAVE_COMPARISON_FN_T +typedef int (*comparison_fn_t)(const void *, const void *); +#endif + +#ifdef REPLACE_STRPTIME +#define strptime rep_strptime +struct tm; +char *rep_strptime(const char *buf, const char *format, struct tm *tm); +#endif + +/* Load header file for dynamic linking stuff */ +#ifdef HAVE_DLFCN_H +#include +#endif + +#ifndef RTLD_LAZY +#define RTLD_LAZY 0 +#endif +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + +#ifndef HAVE_SECURE_MKSTEMP +#define mkstemp(path) rep_mkstemp(path) +int rep_mkstemp(char *temp); +#endif + +#ifndef HAVE_MKDTEMP +#define mkdtemp rep_mkdtemp +char *rep_mkdtemp(char *template); +#endif + +#ifndef HAVE_PREAD +#define pread rep_pread +ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); +#endif + +#ifndef HAVE_PWRITE +#define pwrite rep_pwrite +ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); +#endif + +#if !defined(HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) +#define inet_ntoa rep_inet_ntoa +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_INET_PTON +#define inet_pton rep_inet_pton +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_INET_NTOP +#define inet_ntop rep_inet_ntop +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_INET_ATON +#define inet_aton rep_inet_aton +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_CONNECT +#define connect rep_connect +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETHOSTBYNAME +#define gethostbyname rep_gethostbyname +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETIFADDRS +#define getifaddrs rep_getifaddrs +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_FREEIFADDRS +#define freeifaddrs rep_freeifaddrs +/* prototype is in "system/network.h" */ +#endif + +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +/* The extra casts work around common compiler bugs. */ +#define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +/* The outer cast is needed to work around a bug in Cray C 5.0.3.0. + It is necessary at least when t == time_t. */ +#define _TYPE_MINIMUM(t) ((t) (_TYPE_SIGNED (t) \ + ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) +#define _TYPE_MAXIMUM(t) ((t) (~ (t) 0 - _TYPE_MINIMUM (t))) + +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + +/* + * Some older systems seem not to have MAXHOSTNAMELEN + * defined. + */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN HOST_NAME_MAX +#endif + +#ifndef UINT16_MAX +#define UINT16_MAX 65535 +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef UINT64_MAX +#define UINT64_MAX ((uint64_t)-1) +#endif + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#ifndef INT32_MAX +#define INT32_MAX _TYPE_MAXIMUM(int32_t) +#endif + +#ifdef HAVE_STDBOOL_H +#include +#endif + +#if !defined(HAVE_BOOL) +#ifdef HAVE__Bool +#define bool _Bool +#else +typedef int bool; +#endif +#endif + +/* + * to prevent from doing a redefine of 'bool' + * + * IRIX, HPUX, MacOS 10 and Solaris need BOOL_DEFINED + * Tru64 needs _BOOL_EXISTS + * AIX needs _BOOL,_TRUE,_FALSE + */ +#ifndef BOOL_DEFINED +#define BOOL_DEFINED +#endif +#ifndef _BOOL_EXISTS +#define _BOOL_EXISTS +#endif +#ifndef _BOOL +#define _BOOL +#endif + +#ifndef __bool_true_false_are_defined +#define __bool_true_false_are_defined +#endif + +#ifndef true +#define true (1) +#endif +#ifndef false +#define false (0) +#endif + +#ifndef _TRUE +#define _TRUE true +#endif +#ifndef _FALSE +#define _FALSE false +#endif + +#ifndef HAVE_FUNCTION_MACRO +#ifdef HAVE_func_MACRO +#define __FUNCTION__ __func__ +#else +#define __FUNCTION__ ("") +#endif +#endif + + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +#if !defined(HAVE_VOLATILE) +#define volatile +#endif + +/** + this is a warning hack. The idea is to use this everywhere that we + get the "discarding const" warning from gcc. That doesn't actually + fix the problem of course, but it means that when we do get to + cleaning them up we can do it by searching the code for + discard_const. + + It also means that other error types aren't as swamped by the noise + of hundreds of const warnings, so we are more likely to notice when + we get new errors. + + Please only add more uses of this macro when you find it + _really_ hard to fix const warnings. Our aim is to eventually use + this function in only a very few places. + + Also, please call this via the discard_const_p() macro interface, as that + makes the return type safe. +*/ +#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) + +/** Type-safe version of discard_const */ +#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) + +#ifndef __STRING +#define __STRING(x) #x +#endif + +#ifndef __STRINGSTRING +#define __STRINGSTRING(x) __STRING(x) +#endif + +#ifndef __LINESTR__ +#define __LINESTR__ __STRINGSTRING(__LINE__) +#endif + +#ifndef __location__ +#define __location__ __FILE__ ":" __LINESTR__ +#endif + +/** + * zero a structure + */ +#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) + +/** + * zero a structure given a pointer to the structure + */ +#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) + +/** + * zero a structure given a pointer to the structure - no zero check + */ +#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x))) + +/* zero an array - note that sizeof(array) must work - ie. it must not be a + pointer */ +#define ZERO_ARRAY(x) memset((char *)(x), 0, sizeof(x)) + +/** + * work out how many elements there are in a static array + */ +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/** + * pointer difference macro + */ +#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) + +#if MMAP_BLACKLIST +#undef HAVE_MMAP +#endif + +#ifdef __COMPAR_FN_T +#define QSORT_CAST (__compar_fn_t) +#endif + +#ifndef QSORT_CAST +#define QSORT_CAST (int (*)(const void *, const void *)) +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#ifndef MAX_DNS_NAME_LENGTH +#define MAX_DNS_NAME_LENGTH 256 /* Actually 255 but +1 for terminating null. */ +#endif + +#endif /* _LIBREPLACE_REPLACE_H */ diff --git a/lib/replace/samba.m4 b/lib/replace/samba.m4 new file mode 100644 index 0000000000..07c4d38887 --- /dev/null +++ b/lib/replace/samba.m4 @@ -0,0 +1,35 @@ +AC_LIBREPLACE_BROKEN_CHECKS +AC_LIBREPLACE_NETWORK_CHECKS + +SMB_EXT_LIB(LIBREPLACE_EXT, [${LIBDL}]) +SMB_ENABLE(LIBREPLACE_EXT) + +SMB_EXT_LIB(LIBREPLACE_NETWORK, [${LIBREPLACE_NETWORK_LIBS}]) +SMB_ENABLE(LIBREPLACE_NETWORK) + +# remove leading ./ +LIBREPLACE_DIR=`echo ${libreplacedir} |sed -e 's/^\.\///g'` + +# remove leading srcdir .. we are looking for the relative +# path within the samba source tree or wherever libreplace is. +# We need to make sure the object is not forced to end up in +# the source directory because we might be using a separate +# build directory. +LIBREPLACE_DIR=`echo ${LIBREPLACE_DIR} | sed -e "s|^$srcdir/||g"` + +LIBREPLACE_OBJS="" +for obj in ${LIBREPLACEOBJ}; do + LIBREPLACE_OBJS="${LIBREPLACE_OBJS} ${LIBREPLACE_DIR}/${obj}" +done + +SMB_SUBSYSTEM(LIBREPLACE, + [${LIBREPLACE_OBJS}], + [LIBREPLACE_EXT LIBREPLACE_NETWORK], + [-Ilib/replace]) + +LIBREPLACE_HOSTCC_OBJS=`echo ${LIBREPLACE_OBJS} |sed -e 's/\.o/\.ho/g'` + +SMB_SUBSYSTEM(LIBREPLACE_HOSTCC, + [${LIBREPLACE_HOSTCC_OBJS}], + [], + [-Ilib/replace]) diff --git a/lib/replace/snprintf.c b/lib/replace/snprintf.c new file mode 100644 index 0000000000..c54d721ce5 --- /dev/null +++ b/lib/replace/snprintf.c @@ -0,0 +1,1530 @@ +/* + * NOTE: If you change this file, please merge it into rsync, samba, etc. + */ + +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell (papowell@astart.com) + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions + */ + +/************************************************************** + * 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 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 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 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 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. + * + * Andrew Tridgell (tridge@samba.org) Oct 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE + * + * tridge@samba.org, idra@samba.org, April 2001 + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * + * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 + * actually print args for %g and %e + * + * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 + * Since includes.h isn't included here, VA_COPY has to be defined here. I don't + * see any include file that is guaranteed to be here, so I'm defining it + * locally. Fixes AIX and Solaris builds. + * + * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 + * put the ifdef for HAVE_VA_COPY in one place rather than in lots of + * functions + * + * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 + * Fix usage of va_list passed as an arg. Use __va_copy before using it + * when it exists. + * + * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 + * Fix incorrect zpadlen handling in fmtfp. + * Thanks to Ollie Oldham for spotting it. + * few mods to make it easier to compile the tests. + * addedd the "Ollie" test to the floating point ones. + * + * Martin Pool (mbp@samba.org) April 2003 + * Remove NO_CONFIG_H so that the test case can be built within a source + * tree with less trouble. + * Remove unnecessary SAFE_FREE() definition. + * + * Martin Pool (mbp@samba.org) May 2003 + * Put in a prototype for dummy_snprintf() to quiet compiler warnings. + * + * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even + * if the C library has some snprintf functions already. + * + * Darren Tucker (dtucker@zip.com.au) 2005 + * Fix bug allowing read overruns of the source string with "%.*s" + * Usually harmless unless the read runs outside the process' allocation + * (eg if your malloc does guard pages) in which case it will segfault. + * From OpenSSH. Also added test for same. + * + * Simo Sorce (idra@samba.org) Jan 2006 + * + * Add support for position independent parameters + * fix fmtstr now it conforms to sprintf wrt min.max + * + **************************************************************/ + +#include "replace.h" +#include "system/locale.h" + +#ifdef TEST_SNPRINTF /* need math library headers for testing */ + +/* In test mode, we pretend that this system doesn't have any snprintf + * functions, regardless of what config.h says. */ +# undef HAVE_SNPRINTF +# undef HAVE_VSNPRINTF +# undef HAVE_C99_VSNPRINTF +# undef HAVE_ASPRINTF +# undef HAVE_VASPRINTF +# include +#endif /* TEST_SNPRINTF */ + +#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) +/* only include stdio.h if we are not re-defining snprintf or vsnprintf */ +#include + /* make the compiler happy with an empty file */ + void dummy_snprintf(void); + void dummy_snprintf(void) {} +#endif /* HAVE_SNPRINTF, etc */ + +/* yes this really must be a ||. Don't muck with this (tridge) */ +#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) + +#ifdef HAVE_LONG_DOUBLE +#define LDOUBLE long double +#else +#define LDOUBLE double +#endif + +#ifdef HAVE_LONG_LONG +#define LLONG long long +#else +#define LLONG long +#endif + +#ifndef VA_COPY +#ifdef HAVE_VA_COPY +#define VA_COPY(dest, src) va_copy(dest, src) +#else +#ifdef HAVE___VA_COPY +#define VA_COPY(dest, src) __va_copy(dest, src) +#else +#define VA_COPY(dest, src) (dest) = (src) +#endif +#endif + +/* + * 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_CHAR 1 +#define DP_C_SHORT 2 +#define DP_C_LONG 3 +#define DP_C_LDOUBLE 4 +#define DP_C_LLONG 5 +#define DP_C_SIZET 6 + +/* Chunk types */ +#define CNK_FMT_STR 0 +#define CNK_INT 1 +#define CNK_OCTAL 2 +#define CNK_UINT 3 +#define CNK_HEX 4 +#define CNK_FLOAT 5 +#define CNK_CHAR 6 +#define CNK_STRING 7 +#define CNK_PTR 8 +#define CNK_NUM 9 +#define CNK_PRCNT 10 + +#define char_to_int(p) ((p)- '0') +#ifndef MAX +#define MAX(p,q) (((p) >= (q)) ? (p) : (q)) +#endif + +struct pr_chunk { + int type; /* chunk type */ + int num; /* parameter number */ + int min; + int max; + int flags; + int cflags; + int start; + int len; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + void *pnum; + struct pr_chunk *min_star; + struct pr_chunk *max_star; + struct pr_chunk *next; +}; + +struct pr_chunk_x { + struct pr_chunk **chunks; + int num; +}; + +static int dopr(char *buffer, size_t maxlen, const char *format, + va_list args_in); +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, + LLONG value, int base, int min, int max, int flags); +static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags); +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); +static struct pr_chunk *new_chunk(void); +static int add_cnk_list_entry(struct pr_chunk_x **list, + int max_num, struct pr_chunk *chunk); + +static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) +{ + char ch; + int state; + int pflag; + int pnum; + int pfirst; + size_t currlen; + va_list args; + const char *base; + struct pr_chunk *chunks = NULL; + struct pr_chunk *cnk = NULL; + struct pr_chunk_x *clist = NULL; + int max_pos; + int ret = -1; + + VA_COPY(args, args_in); + + state = DP_S_DEFAULT; + pfirst = 1; + pflag = 0; + pnum = 0; + + max_pos = 0; + base = format; + ch = *format++; + + /* retrieve the string structure as chunks */ + while (state != DP_S_DONE) { + if (ch == '\0') + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + + if (cnk) { + cnk->next = new_chunk(); + cnk = cnk->next; + } else { + cnk = new_chunk(); + } + if (!cnk) goto done; + if (!chunks) chunks = cnk; + + if (ch == '%') { + state = DP_S_FLAGS; + ch = *format++; + } else { + cnk->type = CNK_FMT_STR; + cnk->start = format - base -1; + while ((ch != '\0') && (ch != '%')) ch = *format++; + cnk->len = format - base - cnk->start -1; + } + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + cnk->flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + cnk->flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + cnk->flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + cnk->flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + cnk->flags |= DP_F_ZERO; + ch = *format++; + break; + case 'I': + /* internationalization not supported yet */ + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + cnk->min = 10 * cnk->min + char_to_int (ch); + ch = *format++; + } else if (ch == '$') { + if (!pfirst && !pflag) { + /* parameters must be all positioned or none */ + goto done; + } + if (pfirst) { + pfirst = 0; + pflag = 1; + } + if (cnk->min == 0) /* what ?? */ + goto done; + cnk->num = cnk->min; + cnk->min = 0; + ch = *format++; + } else if (ch == '*') { + if (pfirst) pfirst = 0; + cnk->min_star = new_chunk(); + if (!cnk->min_star) /* out of memory :-( */ + goto done; + cnk->min_star->type = CNK_INT; + if (pflag) { + int num; + ch = *format++; + if (!isdigit((unsigned char)ch)) { + /* parameters must be all positioned or none */ + goto done; + } + for (num = 0; isdigit((unsigned char)ch); ch = *format++) { + num = 10 * num + char_to_int(ch); + } + cnk->min_star->num = num; + if (ch != '$') /* what ?? */ + goto done; + } else { + cnk->min_star->num = ++pnum; + } + max_pos = add_cnk_list_entry(&clist, max_pos, cnk->min_star); + if (max_pos == 0) /* out of memory :-( */ + goto done; + ch = *format++; + state = DP_S_DOT; + } else { + if (pfirst) pfirst = 0; + 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 (cnk->max < 0) + cnk->max = 0; + cnk->max = 10 * cnk->max + char_to_int (ch); + ch = *format++; + } else if (ch == '$') { + if (!pfirst && !pflag) { + /* parameters must be all positioned or none */ + goto done; + } + if (cnk->max <= 0) /* what ?? */ + goto done; + cnk->num = cnk->max; + cnk->max = -1; + ch = *format++; + } else if (ch == '*') { + cnk->max_star = new_chunk(); + if (!cnk->max_star) /* out of memory :-( */ + goto done; + cnk->max_star->type = CNK_INT; + if (pflag) { + int num; + ch = *format++; + if (!isdigit((unsigned char)ch)) { + /* parameters must be all positioned or none */ + goto done; + } + for (num = 0; isdigit((unsigned char)ch); ch = *format++) { + num = 10 * num + char_to_int(ch); + } + cnk->max_star->num = num; + if (ch != '$') /* what ?? */ + goto done; + } else { + cnk->max_star->num = ++pnum; + } + max_pos = add_cnk_list_entry(&clist, max_pos, cnk->max_star); + if (max_pos == 0) /* out of memory :-( */ + goto done; + + ch = *format++; + state = DP_S_MOD; + } else { + state = DP_S_MOD; + } + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cnk->cflags = DP_C_SHORT; + ch = *format++; + if (ch == 'h') { + cnk->cflags = DP_C_CHAR; + ch = *format++; + } + break; + case 'l': + cnk->cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { /* It's a long long */ + cnk->cflags = DP_C_LLONG; + ch = *format++; + } + break; + case 'L': + cnk->cflags = DP_C_LDOUBLE; + ch = *format++; + break; + case 'z': + cnk->cflags = DP_C_SIZET; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + if (cnk->num == 0) cnk->num = ++pnum; + max_pos = add_cnk_list_entry(&clist, max_pos, cnk); + if (max_pos == 0) /* out of memory :-( */ + goto done; + + switch (ch) { + case 'd': + case 'i': + cnk->type = CNK_INT; + break; + case 'o': + cnk->type = CNK_OCTAL; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'u': + cnk->type = CNK_UINT; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'X': + cnk->flags |= DP_F_UP; + case 'x': + cnk->type = CNK_HEX; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'A': + /* hex float not supported yet */ + case 'E': + case 'G': + case 'F': + cnk->flags |= DP_F_UP; + case 'a': + /* hex float not supported yet */ + case 'e': + case 'f': + case 'g': + cnk->type = CNK_FLOAT; + break; + case 'c': + cnk->type = CNK_CHAR; + break; + case 's': + cnk->type = CNK_STRING; + break; + case 'p': + cnk->type = CNK_PTR; + break; + case 'n': + cnk->type = CNK_NUM; + break; + case '%': + cnk->type = CNK_PRCNT; + break; + default: + /* Unknown, bail out*/ + goto done; + } + ch = *format++; + state = DP_S_DEFAULT; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + + /* retrieve the format arguments */ + for (pnum = 0; pnum < max_pos; pnum++) { + int i; + + if (clist[pnum].num == 0) { + /* ignoring a parameter should not be permitted + * all parameters must be matched at least once + * BUT seem some system ignore this rule ... + * at least my glibc based system does --SSS + */ +#ifdef DEBUG_SNPRINTF + printf("parameter at position %d not used\n", pnum+1); +#endif + /* eat the parameter */ + va_arg (args, int); + continue; + } + for (i = 1; i < clist[pnum].num; i++) { + if (clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) { + /* nooo noo no! + * all the references to a parameter + * must be of the same type + */ + goto done; + } + } + cnk = clist[pnum].chunks[0]; + switch (cnk->type) { + case CNK_INT: + if (cnk->cflags == DP_C_SHORT) + cnk->value = va_arg (args, int); + else if (cnk->cflags == DP_C_LONG) + cnk->value = va_arg (args, long int); + else if (cnk->cflags == DP_C_LLONG) + cnk->value = va_arg (args, LLONG); + else if (cnk->cflags == DP_C_SIZET) + cnk->value = va_arg (args, ssize_t); + else + cnk->value = va_arg (args, int); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_OCTAL: + case CNK_UINT: + case CNK_HEX: + if (cnk->cflags == DP_C_SHORT) + cnk->value = va_arg (args, unsigned int); + else if (cnk->cflags == DP_C_LONG) + cnk->value = (unsigned long int)va_arg (args, unsigned long int); + else if (cnk->cflags == DP_C_LLONG) + cnk->value = (LLONG)va_arg (args, unsigned LLONG); + else if (cnk->cflags == DP_C_SIZET) + cnk->value = (size_t)va_arg (args, size_t); + else + cnk->value = (unsigned int)va_arg (args, unsigned int); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_FLOAT: + if (cnk->cflags == DP_C_LDOUBLE) + cnk->fvalue = va_arg (args, LDOUBLE); + else + cnk->fvalue = va_arg (args, double); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->fvalue = cnk->fvalue; + } + break; + + case CNK_CHAR: + cnk->value = va_arg (args, int); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_STRING: + cnk->strvalue = va_arg (args, char *); + if (!cnk->strvalue) cnk->strvalue = "(NULL)"; + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->strvalue = cnk->strvalue; + } + break; + + case CNK_PTR: + cnk->strvalue = va_arg (args, void *); + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->strvalue = cnk->strvalue; + } + break; + + case CNK_NUM: + if (cnk->cflags == DP_C_CHAR) + cnk->pnum = va_arg (args, char *); + else if (cnk->cflags == DP_C_SHORT) + cnk->pnum = va_arg (args, short int *); + else if (cnk->cflags == DP_C_LONG) + cnk->pnum = va_arg (args, long int *); + else if (cnk->cflags == DP_C_LLONG) + cnk->pnum = va_arg (args, LLONG *); + else if (cnk->cflags == DP_C_SIZET) + cnk->pnum = va_arg (args, ssize_t *); + else + cnk->pnum = va_arg (args, int *); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->pnum = cnk->pnum; + } + break; + + case CNK_PRCNT: + break; + + default: + /* what ?? */ + goto done; + } + } + /* print out the actual string from chunks */ + currlen = 0; + cnk = chunks; + while (cnk) { + int len, min, max; + + if (cnk->min_star) min = cnk->min_star->value; + else min = cnk->min; + if (cnk->max_star) max = cnk->max_star->value; + else max = cnk->max; + + switch (cnk->type) { + + case CNK_FMT_STR: + if (maxlen != 0 && maxlen > currlen) { + if (maxlen > (currlen + cnk->len)) len = cnk->len; + else len = maxlen - currlen; + + memcpy(&(buffer[currlen]), &(base[cnk->start]), len); + } + currlen += cnk->len; + + break; + + case CNK_INT: + case CNK_UINT: + fmtint (buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags); + break; + + case CNK_OCTAL: + fmtint (buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags); + break; + + case CNK_HEX: + fmtint (buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags); + break; + + case CNK_FLOAT: + fmtfp (buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags); + break; + + case CNK_CHAR: + dopr_outch (buffer, &currlen, maxlen, cnk->value); + break; + + case CNK_STRING: + if (max == -1) { + max = strlen(cnk->strvalue); + } + fmtstr (buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max); + break; + + case CNK_PTR: + fmtint (buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags); + break; + + case CNK_NUM: + if (cnk->cflags == DP_C_CHAR) + *((char *)(cnk->pnum)) = (char)currlen; + else if (cnk->cflags == DP_C_SHORT) + *((short int *)(cnk->pnum)) = (short int)currlen; + else if (cnk->cflags == DP_C_LONG) + *((long int *)(cnk->pnum)) = (long int)currlen; + else if (cnk->cflags == DP_C_LLONG) + *((LLONG *)(cnk->pnum)) = (LLONG)currlen; + else if (cnk->cflags == DP_C_SIZET) + *((ssize_t *)(cnk->pnum)) = (ssize_t)currlen; + else + *((int *)(cnk->pnum)) = (int)currlen; + break; + + case CNK_PRCNT: + dopr_outch (buffer, &currlen, maxlen, '%'); + break; + + default: + /* what ?? */ + goto done; + } + cnk = cnk->next; + } + if (maxlen != 0) { + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else if (maxlen > 0) + buffer[maxlen - 1] = '\0'; + } + ret = currlen; + +done: + va_end(args); + + while (chunks) { + cnk = chunks->next; + free(chunks); + chunks = cnk; + } + if (clist) { + for (pnum = 0; pnum < max_pos; pnum++) { + if (clist[pnum].chunks) free(clist[pnum].chunks); + } + free(clist); + } + return ret; +} + +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; + +#ifdef DEBUG_SNPRINTF + printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); +#endif + if (value == 0) { + value = ""; + } + + for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + while (*value && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while (padlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, + LLONG value, int base, int min, int max, int flags) +{ + int signvalue = 0; + unsigned LLONG 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 + printf("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 LDOUBLE abs_val(LDOUBLE value) +{ + LDOUBLE result = value; + + if (value < 0) + result = -value; + + return result; +} + +static LDOUBLE POW10(int exp) +{ + LDOUBLE result = 1; + + while (exp) { + result *= 10; + exp--; + } + + return result; +} + +static LLONG ROUND(LDOUBLE value) +{ + LLONG intpart; + + intpart = (LLONG)value; + value = value - intpart; + if (value >= 0.5) intpart++; + + return intpart; +} + +/* a replacement for modf that doesn't need the math library. Should + be portable, but slow */ +static double my_modf(double x0, double *iptr) +{ + int i; + LLONG l=0; + double x = x0; + double f = 1.0; + + for (i=0;i<100;i++) { + l = (long)x; + if (l <= (x+1) && l >= (x-1)) break; + x *= 0.1; + f *= 10.0; + } + + if (i == 100) { + /* yikes! the number is beyond what we can handle. What do we do? */ + (*iptr) = 0; + return 0; + } + + if (i != 0) { + double i2; + double ret; + + ret = my_modf(x0-l*f, &i2); + (*iptr) = l*f + i2; + return ret; + } + + (*iptr) = l; + return x - (*iptr); +} + + +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) +{ + int signvalue = 0; + double ufvalue; + char iconvert[311]; + char fconvert[311]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + int idx; + double intpart; + double fracpart; + double temp; + + /* + * 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 + +#if 0 + if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ +#endif + + /* + * 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 + */ + + temp = ufvalue; + my_modf(temp, &intpart); + + fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); + + if (fracpart >= POW10(max)) { + intpart++; + fracpart -= POW10(max); + } + + + /* Convert integer part */ + do { + temp = intpart*0.1; + my_modf(temp, &intpart); + idx = (int) ((temp -intpart +0.05)* 10.0); + /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ + /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while (intpart && (iplace < 311)); + if (iplace == 311) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + if (fracpart) + { + do { + temp = fracpart*0.1; + my_modf(temp, &fracpart); + idx = (int) ((temp -fracpart +0.05)* 10.0); + /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ + /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while(fracpart && (fplace < 311)); + if (fplace == 311) 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]); + +#ifdef DEBUG_SNPRINTF + printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); +#endif + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0) { + dopr_outch (buffer, currlen, maxlen, '.'); + + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + } + + 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; + } + (*currlen)++; +} + +static struct pr_chunk *new_chunk(void) { + struct pr_chunk *new_c = (struct pr_chunk *)malloc(sizeof(struct pr_chunk)); + + if (!new_c) + return NULL; + + new_c->type = 0; + new_c->num = 0; + new_c->min = 0; + new_c->min_star = NULL; + new_c->max = -1; + new_c->max_star = NULL; + new_c->flags = 0; + new_c->cflags = 0; + new_c->start = 0; + new_c->len = 0; + new_c->value = 0; + new_c->fvalue = 0; + new_c->strvalue = NULL; + new_c->pnum = NULL; + new_c->next = NULL; + + return new_c; +} + +static int add_cnk_list_entry(struct pr_chunk_x **list, + int max_num, struct pr_chunk *chunk) { + struct pr_chunk_x *l; + struct pr_chunk **c; + int max; + int cnum; + int i, pos; + + if (chunk->num > max_num) { + max = chunk->num; + + if (*list == NULL) { + l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max); + pos = 0; + } else { + l = (struct pr_chunk_x *)realloc(*list, sizeof(struct pr_chunk_x) * max); + pos = max_num; + } + if (l == NULL) { + for (i = 0; i < max; i++) { + if ((*list)[i].chunks) free((*list)[i].chunks); + } + return 0; + } + for (i = pos; i < max; i++) { + l[i].chunks = NULL; + l[i].num = 0; + } + } else { + l = *list; + max = max_num; + } + + i = chunk->num - 1; + cnum = l[i].num + 1; + if (l[i].chunks == NULL) { + c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum); + } else { + c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum); + } + if (c == NULL) { + for (i = 0; i < max; i++) { + if (l[i].chunks) free(l[i].chunks); + } + return 0; + } + c[l[i].num] = chunk; + l[i].chunks = c; + l[i].num = cnum; + + *list = l; + return max; +} + + int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + return dopr(str, count, fmt, args); +} +#endif + +/* yes this really must be a ||. Don't muck with this (tridge) + * + * The logic for these two is that we need our own definition if the + * OS *either* has no definition of *sprintf, or if it does have one + * that doesn't work properly according to the autoconf test. + */ +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) + int snprintf(char *str,size_t count,const char *fmt,...) +{ + size_t ret; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(str, count, fmt, ap); + va_end(ap); + return ret; +} +#endif + +#ifndef HAVE_C99_VSNPRINTF + int printf(const char *fmt, ...) +{ + va_list ap; + int ret; + char *s; + + s = NULL; + va_start(ap, fmt); + ret = vasprintf(&s, fmt, ap); + va_end(ap); + + if (s) { + fwrite(s, 1, strlen(s), stdout); + } + free(s); + + return ret; +} +#endif + +#ifndef HAVE_C99_VSNPRINTF + int fprintf(FILE *stream, const char *fmt, ...) +{ + va_list ap; + int ret; + char *s; + + s = NULL; + va_start(ap, fmt); + ret = vasprintf(&s, fmt, ap); + va_end(ap); + + if (s) { + fwrite(s, 1, strlen(s), stream); + } + free(s); + + return ret; +} +#endif + +#endif + +#ifndef HAVE_VASPRINTF + int vasprintf(char **ptr, const char *format, va_list ap) +{ + int ret; + va_list ap2; + + VA_COPY(ap2, ap); + ret = vsnprintf(NULL, 0, format, ap2); + va_end(ap2); + if (ret < 0) return ret; + + (*ptr) = (char *)malloc(ret+1); + if (!*ptr) return -1; + + VA_COPY(ap2, ap); + ret = vsnprintf(*ptr, ret+1, format, ap2); + va_end(ap2); + + return ret; +} +#endif + + +#ifndef HAVE_ASPRINTF + int asprintf(char **ptr, const char *format, ...) +{ + va_list ap; + int ret; + + *ptr = NULL; + va_start(ap, format); + ret = vasprintf(ptr, format, ap); + va_end(ap); + + return ret; +} +#endif + +#ifdef TEST_SNPRINTF + + int sprintf(char *str,const char *fmt,...); + int printf(const char *fmt,...); + + int main (void) +{ + char buf1[1024]; + char buf2[1024]; + char *buf3; + char *fp_fmt[] = { + "%1.1f", + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + "%.0f", + "%f", + "%-8.8f", + "%-9.9f", + NULL + }; + double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 5.030201, 0.00205, + /* END LIST */ 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + "%d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 1234567890, 0}; + char *str_fmt[] = { + "%10.5s", + "%-10.5s", + "%5.10s", + "%-5.10s", + "%10.1s", + "%0.10s", + "%10.0s", + "%1.10s", + "%s", + "%.1s", + "%.10s", + "%10s", + NULL + }; + char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; +#ifdef HAVE_LONG_LONG + char *ll_fmt[] = { + "%llu", + NULL + }; + LLONG ll_nums[] = { 134, 91340, 341, 0203, 1234567890, 128006186140000000LL, 0}; +#endif + int x, y; + int fail = 0; + int num = 0; + int l1, l2; + char *ss_fmt[] = { + "%zd", + "%zu", + NULL + }; + size_t ss_nums[] = {134, 91340, 123456789, 0203, 1234567890, 0}; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] ; x++) { + for (y = 0; fp_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); + l2 = sprintf (buf2, fp_fmt[x], fp_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + fp_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + + for (x = 0; int_fmt[x] ; x++) { + for (y = 0; int_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); + l2 = sprintf (buf2, int_fmt[x], int_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + int_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + + for (x = 0; str_fmt[x] ; x++) { + for (y = 0; str_vals[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); + l2 = sprintf (buf2, str_fmt[x], str_vals[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + str_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + +#ifdef HAVE_LONG_LONG + for (x = 0; ll_fmt[x] ; x++) { + for (y = 0; ll_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), ll_fmt[x], ll_nums[y]); + l2 = sprintf (buf2, ll_fmt[x], ll_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + ll_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } +#endif + +#define BUFSZ 2048 + + buf1[0] = buf2[0] = '\0'; + if ((buf3 = malloc(BUFSZ)) == NULL) { + fail++; + } else { + num++; + memset(buf3, 'a', BUFSZ); + snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3); + buf1[1023] = '\0'; + if (strcmp(buf1, "a") != 0) { + printf("length limit buf1 '%s' expected 'a'\n", buf1); + fail++; + } + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); + l2 = sprintf(buf2, "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); + fail++; + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); + l2 = sprintf(buf2, "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); + fail++; + } + + for (x = 0; ss_fmt[x] ; x++) { + for (y = 0; ss_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), ss_fmt[x], ss_nums[y]); + l2 = sprintf (buf2, ss_fmt[x], ss_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + ss_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } +#if 0 + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%lld", (LLONG)1234567890); + l2 = sprintf(buf2, "%lld", (LLONG)1234567890); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%lld", l1, buf1, l2, buf2); + fail++; + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%Lf", (LDOUBLE)890.1234567890123); + l2 = sprintf(buf2, "%Lf", (LDOUBLE)890.1234567890123); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%Lf", l1, buf1, l2, buf2); + fail++; + } +#endif + printf ("%d tests failed out of %d.\n", fail, num); + + printf("seeing how many digits we support\n"); + { + double v0 = 0.12345678901234567890123456789012345678901; + for (x=0; x<100; x++) { + double p = pow(10, x); + double r = v0*p; + snprintf(buf1, sizeof(buf1), "%1.1f", r); + sprintf(buf2, "%1.1f", r); + if (strcmp(buf1, buf2)) { + printf("we seem to support %d digits\n", x-1); + break; + } + } + } + + return 0; +} +#endif /* TEST_SNPRINTF */ diff --git a/lib/replace/socket.c b/lib/replace/socket.c new file mode 100644 index 0000000000..35e975fce7 --- /dev/null +++ b/lib/replace/socket.c @@ -0,0 +1,35 @@ +/* + * Unix SMB/CIFS implementation. + * + * Dummy replacements for socket functions. + * + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "replace.h" +#include "system/network.h" + +int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + errno = ENOSYS; + return -1; +} + +struct hostent *rep_gethostbyname(const char *name) +{ + errno = ENOSYS; + return NULL; +} diff --git a/lib/replace/socketpair.c b/lib/replace/socketpair.c new file mode 100644 index 0000000000..c775730952 --- /dev/null +++ b/lib/replace/socketpair.c @@ -0,0 +1,46 @@ +/* + * Unix SMB/CIFS implementation. + * replacement routines for broken systems + * Copyright (C) Jelmer Vernooij 2006 + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/network.h" + +int rep_socketpair(int d, int type, int protocol, int sv[2]) +{ + if (d != AF_UNIX) { + errno = EAFNOSUPPORT; + return -1; + } + + if (protocol != 0) { + errno = EPROTONOSUPPORT; + return -1; + } + + if (type != SOCK_STREAM) { + errno = EOPNOTSUPP; + return -1; + } + + return pipe(sv); +} diff --git a/lib/replace/strptime.c b/lib/replace/strptime.c new file mode 100644 index 0000000000..0e40f7561a --- /dev/null +++ b/lib/replace/strptime.c @@ -0,0 +1,990 @@ +/* Convert a string representation of time to a time value. + Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + see . */ + +/* XXX This version of the implementation is not really complete. + Some of the fields cannot add information alone. But if seeing + some of them in the same format (such as year, week and weekday) + this is enough information for determining the date. */ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" + +#ifndef __P +# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ +#endif /* Not __P. */ + +#if ! HAVE_LOCALTIME_R && ! defined localtime_r +# ifdef _LIBC +# define localtime_r __localtime_r +# else +/* Approximate localtime_r as best we can in its absence. */ +# define localtime_r my_localtime_r +static struct tm *localtime_r __P ((const time_t *, struct tm *)); +static struct tm * +localtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! _LIBC */ +#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ + + +#define match_char(ch1, ch2) if (ch1 != ch2) return NULL +#if defined __GNUC__ && __GNUC__ >= 2 +# define match_string(cs1, s2) \ + ({ size_t len = strlen (cs1); \ + int result = strncasecmp ((cs1), (s2), len) == 0; \ + if (result) (s2) += len; \ + result; }) +#else +/* Oh come on. Get a reasonable compiler. */ +# define match_string(cs1, s2) \ + (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) +#endif +/* We intentionally do not use isdigit() for testing because this will + lead to problems with the wide character version. */ +#define get_number(from, to, n) \ + do { \ + int __n = n; \ + val = 0; \ + while (*rp == ' ') \ + ++rp; \ + if (*rp < '0' || *rp > '9') \ + return NULL; \ + do { \ + val *= 10; \ + val += *rp++ - '0'; \ + } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ + if (val < from || val > to) \ + return NULL; \ + } while (0) +#ifdef _NL_CURRENT +# define get_alt_number(from, to, n) \ + ({ \ + __label__ do_normal; \ + if (*decided != raw) \ + { \ + const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ + int __n = n; \ + int any = 0; \ + while (*rp == ' ') \ + ++rp; \ + val = 0; \ + do { \ + val *= 10; \ + while (*alts != '\0') \ + { \ + size_t len = strlen (alts); \ + if (strncasecmp (alts, rp, len) == 0) \ + break; \ + alts += len + 1; \ + ++val; \ + } \ + if (*alts == '\0') \ + { \ + if (*decided == not && ! any) \ + goto do_normal; \ + /* If we haven't read anything it's an error. */ \ + if (! any) \ + return NULL; \ + /* Correct the premature multiplication. */ \ + val /= 10; \ + break; \ + } \ + else \ + *decided = loc; \ + } while (--__n > 0 && val * 10 <= to); \ + if (val < from || val > to) \ + return NULL; \ + } \ + else \ + { \ + do_normal: \ + get_number (from, to, n); \ + } \ + 0; \ + }) +#else +# define get_alt_number(from, to, n) \ + /* We don't have the alternate representation. */ \ + get_number(from, to, n) +#endif +#define recursive(new_fmt) \ + (*(new_fmt) != '\0' \ + && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) + + +#ifdef _LIBC +/* This is defined in locale/C-time.c in the GNU libc. */ +extern const struct locale_data _nl_C_LC_TIME; +extern const unsigned short int __mon_yday[2][13]; + +# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) +# define ab_weekday_name \ + (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) +# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) +# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) +# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) +# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) +# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) +# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) +# define HERE_T_FMT_AMPM \ + (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) +# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) + +# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) +#else +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const ab_weekday_name[][4] = + { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +static char const ab_month_name[][4] = + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; +# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" +# define HERE_D_FMT "%m/%d/%y" +# define HERE_AM_STR "AM" +# define HERE_PM_STR "PM" +# define HERE_T_FMT_AMPM "%I:%M:%S %p" +# define HERE_T_FMT "%H:%M:%S" + +static const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; +#endif + +/* Status of lookup: do we use the locale data or the raw data? */ +enum locale_status { not, loc, raw }; + + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +/* Compute the day of the week. */ +static void +day_of_the_week (struct tm *tm) +{ + /* We know that January 1st 1970 was a Thursday (= 4). Compute the + the difference between this data in the one on TM and so determine + the weekday. */ + int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); + int wday = (-473 + + (365 * (tm->tm_year - 70)) + + (corr_year / 4) + - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) + + (((corr_year / 4) / 25) / 4) + + __mon_yday[0][tm->tm_mon] + + tm->tm_mday - 1); + tm->tm_wday = ((wday % 7) + 7) % 7; +} + +/* Compute the day of the year. */ +static void +day_of_the_year (struct tm *tm) +{ + tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] + + (tm->tm_mday - 1)); +} + +static char * +#ifdef _LIBC +internal_function +#endif +strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, + enum locale_status *decided, int era_cnt)); + +static char * +#ifdef _LIBC +internal_function +#endif +strptime_internal (rp, fmt, tm, decided, era_cnt) + const char *rp; + const char *fmt; + struct tm *tm; + enum locale_status *decided; + int era_cnt; +{ + const char *rp_backup; + int cnt; + size_t val; + int have_I, is_pm; + int century, want_century; + int want_era; + int have_wday, want_xday; + int have_yday; + int have_mon, have_mday; +#ifdef _NL_CURRENT + size_t num_eras; +#endif + struct era_entry *era; + + have_I = is_pm = 0; + century = -1; + want_century = 0; + want_era = 0; + era = NULL; + + have_wday = want_xday = have_yday = have_mon = have_mday = 0; + + while (*fmt != '\0') + { + /* A white space in the format string matches 0 more or white + space in the input string. */ + if (isspace (*fmt)) + { + while (isspace (*rp)) + ++rp; + ++fmt; + continue; + } + + /* Any character but `%' must be matched by the same character + in the iput string. */ + if (*fmt != '%') + { + match_char (*fmt++, *rp++); + continue; + } + + ++fmt; +#ifndef _NL_CURRENT + /* We need this for handling the `E' modifier. */ + start_over: +#endif + + /* Make back up of current processing pointer. */ + rp_backup = rp; + + switch (*fmt++) + { + case '%': + /* Match the `%' character itself. */ + match_char ('%', *rp++); + break; + case 'a': + case 'A': + /* Match day of week. */ + for (cnt = 0; cnt < 7; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), + weekday_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), + ab_weekday_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (*decided != loc + && (match_string (weekday_name[cnt], rp) + || match_string (ab_weekday_name[cnt], rp))) + { + *decided = raw; + break; + } + } + if (cnt == 7) + /* Does not match a weekday name. */ + return NULL; + tm->tm_wday = cnt; + have_wday = 1; + break; + case 'b': + case 'B': + case 'h': + /* Match month name. */ + for (cnt = 0; cnt < 12; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), + month_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), + ab_month_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (match_string (month_name[cnt], rp) + || match_string (ab_month_name[cnt], rp)) + { + *decided = raw; + break; + } + } + if (cnt == 12) + /* Does not match a month name. */ + return NULL; + tm->tm_mon = cnt; + want_xday = 1; + break; + case 'c': + /* Match locale's date and time format. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + /* Match century number. */ +#ifdef _NL_CURRENT + match_century: +#endif + get_number (0, 99, 2); + century = val; + want_xday = 1; + break; + case 'd': + case 'e': + /* Match day of month. */ + get_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'F': + if (!recursive ("%Y-%m-%d")) + return NULL; + want_xday = 1; + break; + case 'x': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + /* Fall through. */ + case 'D': + /* Match standard day format. */ + if (!recursive (HERE_D_FMT)) + return NULL; + want_xday = 1; + break; + case 'k': + case 'H': + /* Match hour in 24-hour clock. */ + get_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock. */ + get_number (1, 12, 2); + tm->tm_hour = val % 12; + have_I = 1; + break; + case 'j': + /* Match day number of year. */ + get_number (1, 366, 3); + tm->tm_yday = val - 1; + have_yday = 1; + break; + case 'm': + /* Match number of month. */ + get_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minute. */ + get_number (0, 59, 2); + tm->tm_min = val; + break; + case 'n': + case 't': + /* Match any white space. */ + while (isspace (*rp)) + ++rp; + break; + case 'p': + /* Match locale's equivalent of AM/PM. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) + *decided = loc; + is_pm = 1; + break; + } + *decided = raw; + } +#endif + if (!match_string (HERE_AM_STR, rp)) { + if (match_string (HERE_PM_STR, rp)) { + is_pm = 1; + } else { + return NULL; + } + } + break; + case 'r': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), + HERE_T_FMT_AMPM)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_T_FMT_AMPM)) + return NULL; + break; + case 'R': + if (!recursive ("%H:%M")) + return NULL; + break; + case 's': + { + /* The number of seconds may be very high so we cannot use + the `get_number' macro. Instead read the number + character for character and construct the result while + doing this. */ + time_t secs = 0; + if (*rp < '0' || *rp > '9') + /* We need at least one digit. */ + return NULL; + + do + { + secs *= 10; + secs += *rp++ - '0'; + } + while (*rp >= '0' && *rp <= '9'); + + if (localtime_r (&secs, tm) == NULL) + /* Error in function. */ + return NULL; + } + break; + case 'S': + get_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'X': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + /* Fall through. */ + case 'T': + if (!recursive (HERE_T_FMT)) + return NULL; + break; + case 'u': + get_number (1, 7, 1); + tm->tm_wday = val % 7; + have_wday = 1; + break; + case 'g': + get_number (0, 99, 2); + /* XXX This cannot determine any field in TM. */ + break; + case 'G': + if (*rp < '0' || *rp > '9') + return NULL; + /* XXX Ignore the number since we would need some more + information to compute a real date. */ + do + ++rp; + while (*rp >= '0' && *rp <= '9'); + break; + case 'U': + case 'V': + case 'W': + get_number (0, 53, 2); + /* XXX This cannot determine any field in TM without some + information. */ + break; + case 'w': + /* Match number of weekday. */ + get_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': +#ifdef _NL_CURRENT + match_year_in_century: +#endif + /* Match year within century. */ + get_number (0, 99, 2); + /* The "Year 2000: The Millennium Rollover" paper suggests that + values in the range 69-99 refer to the twentieth century. */ + tm->tm_year = val >= 69 ? val : val + 100; + /* Indicate that we want to use the century, if specified. */ + want_century = 1; + want_xday = 1; + break; + case 'Y': + /* Match year including century number. */ + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'Z': + /* XXX How to handle this? */ + break; + case 'E': +#ifdef _NL_CURRENT + switch (*fmt++) + { + case 'c': + /* Match locale's alternate date and time format. */ + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + if (*decided != raw) + { + if (era_cnt >= 0) + { + era = _nl_select_era_entry (era_cnt); + if (match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + else + return NULL; + } + else + { + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt); + if (match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + } + if (era_cnt == (int) num_eras) + { + era_cnt = -1; + if (*decided == loc) + return NULL; + } + else + break; + } + + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + goto match_century; + case 'y': + if (*decided == raw) + goto match_year_in_century; + + get_number(0, 9999, 4); + tm->tm_year = val; + want_era = 1; + want_xday = 1; + break; + case 'Y': + if (*decided != raw) + { + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt); + if (recursive (era->era_format)) + break; + } + if (era_cnt == (int) num_eras) + { + era_cnt = -1; + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + *decided = loc; + era_cnt = -1; + break; + } + + *decided = raw; + } + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'x': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_D_FMT)) + return NULL; + break; + case 'X': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_T_FMT)) + return NULL; + break; + default: + return NULL; + } + break; +#else + /* We have no information about the era format. Just use + the normal format. */ + if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' + && *fmt != 'x' && *fmt != 'X') + /* This is an illegal format. */ + return NULL; + + goto start_over; +#endif + case 'O': + switch (*fmt++) + { + case 'd': + case 'e': + /* Match day of month using alternate numeric symbols. */ + get_alt_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'H': + /* Match hour in 24-hour clock using alternate numeric + symbols. */ + get_alt_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock using alternate numeric + symbols. */ + get_alt_number (1, 12, 2); + tm->tm_hour = val - 1; + have_I = 1; + break; + case 'm': + /* Match month using alternate numeric symbols. */ + get_alt_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minutes using alternate numeric symbols. */ + get_alt_number (0, 59, 2); + tm->tm_min = val; + break; + case 'S': + /* Match seconds using alternate numeric symbols. */ + get_alt_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'U': + case 'V': + case 'W': + get_alt_number (0, 53, 2); + /* XXX This cannot determine any field in TM without + further information. */ + break; + case 'w': + /* Match number of weekday using alternate numeric symbols. */ + get_alt_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': + /* Match year within century using alternate numeric symbols. */ + get_alt_number (0, 99, 2); + tm->tm_year = val >= 69 ? val : val + 100; + want_xday = 1; + break; + default: + return NULL; + } + break; + default: + return NULL; + } + } + + if (have_I && is_pm) + tm->tm_hour += 12; + + if (century != -1) + { + if (want_century) + tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; + else + /* Only the century, but not the year. Strange, but so be it. */ + tm->tm_year = (century - 19) * 100; + } + +#ifdef _NL_CURRENT + if (era_cnt != -1) + { + era = _nl_select_era_entry(era_cnt); + if (want_era) + tm->tm_year = (era->start_date[0] + + ((tm->tm_year - era->offset) + * era->absolute_direction)); + else + /* Era start year assumed. */ + tm->tm_year = era->start_date[0]; + } + else +#endif + if (want_era) + return NULL; + + if (want_xday && !have_wday) + { + if ( !(have_mon && have_mday) && have_yday) + { + /* We don't have tm_mon and/or tm_mday, compute them. */ + int t_mon = 0; + while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) + t_mon++; + if (!have_mon) + tm->tm_mon = t_mon - 1; + if (!have_mday) + tm->tm_mday = + (tm->tm_yday + - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); + } + day_of_the_week (tm); + } + if (want_xday && !have_yday) + day_of_the_year (tm); + + return discard_const_p(char, rp); +} + + +char *rep_strptime(const char *buf, const char *format, struct tm *tm) +{ + enum locale_status decided; + +#ifdef _NL_CURRENT + decided = not; +#else + decided = raw; +#endif + return strptime_internal (buf, format, tm, &decided, -1); +} diff --git a/lib/replace/strptime.m4 b/lib/replace/strptime.m4 new file mode 100644 index 0000000000..da22fc5a97 --- /dev/null +++ b/lib/replace/strptime.m4 @@ -0,0 +1,13 @@ +AC_CACHE_CHECK([whether strptime is available and works],libreplace_cv_STRPTIME_OK,[ + AC_TRY_RUN([ + #define LIBREPLACE_CONFIGURE_TEST_STRPTIME + #include "$libreplacedir/test/strptime.c" + ], + [libreplace_cv_STRPTIME_OK=yes], + [libreplace_cv_STRPTIME_OK=no], + [libreplace_cv_STRPTIME_OK="assuming not"]) +]) +if test x"$libreplace_cv_STRPTIME_OK" != x"yes"; then + AC_DEFINE(REPLACE_STRPTIME,1,[Whether strptime should be replaced]) + LIBREPLACEOBJ="${LIBREPLACEOBJ} strptime.o" +fi diff --git a/lib/replace/system/README b/lib/replace/system/README new file mode 100644 index 0000000000..69a2b80b56 --- /dev/null +++ b/lib/replace/system/README @@ -0,0 +1,4 @@ +This directory contains wrappers around logical groups of system +include files. The idea is to avoid #ifdef blocks in the main code, +and instead put all the necessary conditional includes in subsystem +specific header files in this directory. diff --git a/lib/replace/system/aio.h b/lib/replace/system/aio.h new file mode 100644 index 0000000000..784d77fa28 --- /dev/null +++ b/lib/replace/system/aio.h @@ -0,0 +1,32 @@ +#ifndef _system_aio_h +#define _system_aio_h +/* + Unix SMB/CIFS implementation. + + AIO system include wrappers + + Copyright (C) Andrew Tridgell 2006 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifdef HAVE_LIBAIO_H +#include +#endif + +#endif diff --git a/lib/replace/system/capability.h b/lib/replace/system/capability.h new file mode 100644 index 0000000000..a7b78f0275 --- /dev/null +++ b/lib/replace/system/capability.h @@ -0,0 +1,55 @@ +#ifndef _system_capability_h +#define _system_capability_h +/* + Unix SMB/CIFS implementation. + + capability system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifdef HAVE_SYS_CAPABILITY_H + +#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) +#define _I386_STATFS_H +#define _PPC_STATFS_H +#define BROKEN_REDHAT_7_STATFS_WORKAROUND +#endif + +#if defined(BROKEN_RHEL5_SYS_CAP_HEADER) && !defined(_LINUX_TYPES_H) +#define BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND +#endif + +#include + +#ifdef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND +#undef _LINUX_TYPES_H +#undef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND +#endif + +#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND +#undef _PPC_STATFS_H +#undef _I386_STATFS_H +#undef BROKEN_REDHAT_7_STATFS_WORKAROUND +#endif + +#endif + +#endif diff --git a/lib/replace/system/config.m4 b/lib/replace/system/config.m4 new file mode 100644 index 0000000000..5c9b53d5c5 --- /dev/null +++ b/lib/replace/system/config.m4 @@ -0,0 +1,130 @@ +# filesys +AC_HEADER_DIRENT +AC_CHECK_HEADERS(fcntl.h sys/fcntl.h sys/resource.h sys/ioctl.h sys/mode.h sys/filio.h sys/fs/s5param.h sys/filsys.h) +AC_CHECK_HEADERS(sys/acl.h acl/libacl.h) + +# select +AC_CHECK_HEADERS(sys/select.h) + +# time +AC_CHECK_HEADERS(sys/time.h utime.h) +AC_HEADER_TIME +AC_CHECK_FUNCS(utime utimes) + +# wait +AC_HEADER_SYS_WAIT + +# capability +AC_CHECK_HEADERS(sys/capability.h) + +case "$host_os" in +*linux*) +AC_CACHE_CHECK([for broken RedHat 7.2 system header files],libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS,[ +AC_TRY_COMPILE([ + #ifdef HAVE_SYS_VFS_H + #include + #endif + #ifdef HAVE_SYS_CAPABILITY_H + #include + #endif + ],[ + int i; + ], + libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no, + libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=yes +)]) +if test x"$libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" = x"yes"; then + AC_DEFINE(BROKEN_REDHAT_7_SYSTEM_HEADERS,1,[Broken RedHat 7.2 system header files]) +fi + +AC_CACHE_CHECK([for broken RHEL5 sys/capability.h],libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER,[ +AC_TRY_COMPILE([ + #ifdef HAVE_SYS_CAPABILITY_H + #include + #endif + #include + ],[ + __s8 i; + ], + libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER=no, + libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER=yes +)]) +if test x"$libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER" = x"yes"; then + AC_DEFINE(BROKEN_RHEL5_SYS_CAP_HEADER,1,[Broken RHEL5 sys/capability.h]) +fi +;; +esac + +# passwd +AC_CHECK_HEADERS(grp.h sys/id.h compat.h shadow.h sys/priv.h pwd.h sys/security.h) +AC_CHECK_FUNCS(getpwnam_r getpwuid_r getpwent_r) +AC_HAVE_DECL(getpwent_r, [ + #include + #include + ]) +AC_VERIFY_C_PROTOTYPE([struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)], + [ + #ifndef HAVE_GETPWENT_R_DECL + #error missing getpwent_r prototype + #endif + return NULL; + ],[ + AC_DEFINE(SOLARIS_GETPWENT_R, 1, [getpwent_r solaris function prototype]) + ],[],[ + #include + #include + ]) +AC_VERIFY_C_PROTOTYPE([struct passwd *getpwent_r(struct passwd *src, char *buf, size_t buflen)], + [ + #ifndef HAVE_GETPWENT_R_DECL + #error missing getpwent_r prototype + #endif + return NULL; + ],[ + AC_DEFINE(SOLARIS_GETPWENT_R, 1, [getpwent_r irix (similar to solaris) function prototype]) + ],[],[ + #include + #include + ]) +AC_CHECK_FUNCS(getgrnam_r getgrgid_r getgrent_r) +AC_HAVE_DECL(getgrent_r, [ + #include + #include + ]) +AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, int buflen)], + [ + #ifndef HAVE_GETGRENT_R_DECL + #error missing getgrent_r prototype + #endif + return NULL; + ],[ + AC_DEFINE(SOLARIS_GETGRENT_R, 1, [getgrent_r solaris function prototype]) + ],[],[ + #include + #include + ]) + +AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, size_t buflen)], + [ + #ifndef HAVE_GETGRENT_R_DECL + #error missing getgrent_r prototype + #endif + return NULL; + ],[ + AC_DEFINE(SOLARIS_GETGRENT_R, 1, [getgrent_r irix (similar to solaris) function prototype]) + ],[],[ + #include + #include + ]) + +# locale +AC_CHECK_HEADERS(ctype.h locale.h) + +# glob +AC_CHECK_HEADERS(fnmatch.h) + +# shmem +AC_CHECK_HEADERS(sys/ipc.h sys/mman.h sys/shm.h ) + +# terminal +AC_CHECK_HEADERS(termios.h termio.h sys/termio.h ) diff --git a/lib/replace/system/dir.h b/lib/replace/system/dir.h new file mode 100644 index 0000000000..dec2d54649 --- /dev/null +++ b/lib/replace/system/dir.h @@ -0,0 +1,67 @@ +#ifndef _system_dir_h +#define _system_dir_h +/* + Unix SMB/CIFS implementation. + + directory system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif + +#ifndef HAVE_MKDIR_MODE +#define mkdir(dir, mode) mkdir(dir) +#endif + +/* Test whether a file name is the "." or ".." directory entries. + * These really should be inline functions. + */ +#ifndef ISDOT +#define ISDOT(path) ( \ + *((const char *)(path)) == '.' && \ + *(((const char *)(path)) + 1) == '\0' \ + ) +#endif + +#ifndef ISDOTDOT +#define ISDOTDOT(path) ( \ + *((const char *)(path)) == '.' && \ + *(((const char *)(path)) + 1) == '.' && \ + *(((const char *)(path)) + 2) == '\0' \ + ) +#endif + +#endif diff --git a/lib/replace/system/filesys.h b/lib/replace/system/filesys.h new file mode 100644 index 0000000000..4bf1f64865 --- /dev/null +++ b/lib/replace/system/filesys.h @@ -0,0 +1,182 @@ +#ifndef _system_filesys_h +#define _system_filesys_h +/* + Unix SMB/CIFS implementation. + + filesystem system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#include +#include + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_MOUNT_H +#include +#endif + +#ifdef HAVE_MNTENT_H +#include +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_ACL_H +#include +#endif + +#ifdef HAVE_ACL_LIBACL_H +#include +#endif + +#ifdef HAVE_SYS_FS_S5PARAM_H +#include +#endif + +#if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) +#include +#endif + +#ifdef HAVE_SYS_STATFS_H +# include +#endif + +#ifdef HAVE_DUSTAT_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#ifdef HAVE_SYS_FILIO_H +#include +#endif + +#include + +#ifdef HAVE_FCNTL_H +#include +#else +#ifdef HAVE_SYS_FCNTL_H +#include +#endif +#endif + +#ifdef HAVE_SYS_MODE_H +/* apparently AIX needs this for S_ISLNK */ +#ifndef S_ISLNK +#include +#endif +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +/* + * Veritas File System. Often in addition to native. + * Quotas different. + */ +#if defined(HAVE_SYS_FS_VX_QUOTA_H) +#define VXFS_QUOTA +#endif + +#if HAVE_SYS_ATTRIBUTES_H +#include +#endif + +/* mutually exclusive (SuSE 8.2) */ +#if HAVE_ATTR_XATTR_H +#include +#elif HAVE_SYS_XATTR_H +#include +#endif + + +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +/* Some POSIX definitions for those without */ + +#ifndef S_IFDIR +#define S_IFDIR 0x4000 +#endif +#ifndef S_ISDIR +#define S_ISDIR(mode) ((mode & 0xF000) == S_IFDIR) +#endif +#ifndef S_IRWXU +#define S_IRWXU 00700 /* read, write, execute: owner */ +#endif +#ifndef S_IRUSR +#define S_IRUSR 00400 /* read permission: owner */ +#endif +#ifndef S_IWUSR +#define S_IWUSR 00200 /* write permission: owner */ +#endif +#ifndef S_IXUSR +#define S_IXUSR 00100 /* execute permission: owner */ +#endif +#ifndef S_IRWXG +#define S_IRWXG 00070 /* read, write, execute: group */ +#endif +#ifndef S_IRGRP +#define S_IRGRP 00040 /* read permission: group */ +#endif +#ifndef S_IWGRP +#define S_IWGRP 00020 /* write permission: group */ +#endif +#ifndef S_IXGRP +#define S_IXGRP 00010 /* execute permission: group */ +#endif +#ifndef S_IRWXO +#define S_IRWXO 00007 /* read, write, execute: other */ +#endif +#ifndef S_IROTH +#define S_IROTH 00004 /* read permission: other */ +#endif +#ifndef S_IWOTH +#define S_IWOTH 00002 /* write permission: other */ +#endif +#ifndef S_IXOTH +#define S_IXOTH 00001 /* execute permission: other */ +#endif + +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#endif diff --git a/lib/replace/system/glob.h b/lib/replace/system/glob.h new file mode 100644 index 0000000000..3e23db6828 --- /dev/null +++ b/lib/replace/system/glob.h @@ -0,0 +1,37 @@ +#ifndef _system_glob_h +#define _system_glob_h +/* + Unix SMB/CIFS implementation. + + glob system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_GLOB_H +#include +#endif + +#ifdef HAVE_FNMATCH_H +#include +#endif + +#endif diff --git a/lib/replace/system/iconv.h b/lib/replace/system/iconv.h new file mode 100644 index 0000000000..3c8a71f2f7 --- /dev/null +++ b/lib/replace/system/iconv.h @@ -0,0 +1,57 @@ +#ifndef _system_iconv_h +#define _system_iconv_h +/* + Unix SMB/CIFS implementation. + + iconv memory system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#if !defined(HAVE_ICONV) && defined(HAVE_ICONV_H) +#define HAVE_ICONV +#endif + +#if !defined(HAVE_GICONV) && defined(HAVE_GICONV_H) +#define HAVE_GICONV +#endif + +#if !defined(HAVE_BICONV) && defined(HAVE_BICONV_H) +#define HAVE_BICONV +#endif + +#ifdef HAVE_NATIVE_ICONV +#if defined(HAVE_ICONV) +#include +#elif defined(HAVE_GICONV) +#include +#elif defined(HAVE_BICONV) +#include +#endif +#endif /* HAVE_NATIVE_ICONV */ + +/* needed for some systems without iconv. Doesn't really matter + what error code we use */ +#ifndef EILSEQ +#define EILSEQ EIO +#endif + +#endif diff --git a/lib/replace/system/kerberos.h b/lib/replace/system/kerberos.h new file mode 100644 index 0000000000..2981024bee --- /dev/null +++ b/lib/replace/system/kerberos.h @@ -0,0 +1,137 @@ +#ifndef _system_kerberos_h +#define _system_kerberos_h + +/* + Unix SMB/CIFS implementation. + + kerberos system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_KRB5 +/* Whether the krb5_address struct has a addrtype property */ +/* #undef HAVE_ADDRTYPE_IN_KRB5_ADDRESS */ +/* Whether the krb5_address struct has a addr_type property */ +#define HAVE_ADDR_TYPE_IN_KRB5_ADDRESS 1 +/* Define to 1 if you have the `gsskrb5_extract_authz_data_from_sec_context' */ +#define HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT 1 +/* Define to 1 if you have the `gsskrb5_get_initiator_subkey' function. */ +#define HAVE_GSSKRB5_GET_INITIATOR_SUBKEY 1 +/* Define to 1 if you have the `gsskrb5_register_acceptor_identity' function. */ +#define HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY 1 +/* Define to 1 if you have the `gss_krb5_ccache_name' function. */ +#define HAVE_GSS_KRB5_CCACHE_NAME 1 +/* Define to 1 if you have the `krb5_addlog_func' function. */ +#define HAVE_KRB5_ADDLOG_FUNC 1 +/* Define to 1 if you have the `krb5_auth_con_setkey' function. */ +#define HAVE_KRB5_AUTH_CON_SETKEY 1 +/* Define to 1 if you have the `krb5_auth_con_setuseruserkey' function. */ +/* #undef HAVE_KRB5_AUTH_CON_SETUSERUSERKEY */ +/* Define to 1 if you have the `krb5_c_enctype_compare' function. */ +#define HAVE_KRB5_C_ENCTYPE_COMPARE 1 +/* Define to 1 if you have the `krb5_c_verify_checksum' function. */ +#define HAVE_KRB5_C_VERIFY_CHECKSUM 1 +/* Whether the type krb5_encrypt_block exists */ +/* #undef HAVE_KRB5_ENCRYPT_BLOCK */ +/* Define to 1 if you have the `krb5_encrypt_data' function. */ +/* #undef HAVE_KRB5_ENCRYPT_DATA */ +/* Define to 1 if you have the `krb5_enctypes_compatible_keys' function. */ +#define HAVE_KRB5_ENCTYPES_COMPATIBLE_KEYS 1 +/* Define to 1 if you have the `krb5_free_data_contents' function. */ +#define HAVE_KRB5_FREE_DATA_CONTENTS 1 +/* Define to 1 if you have the `krb5_free_error_string' function. */ +#define HAVE_KRB5_FREE_ERROR_STRING 1 +/* Define to 1 if you have the `krb5_free_keytab_entry_contents' function. */ +/* #undef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS */ +/* Define to 1 if you have the `krb5_free_ktypes' function. */ +/* #undef HAVE_KRB5_FREE_KTYPES */ +/* Define to 1 if you have the `krb5_free_unparsed_name' function. */ +/* #undef HAVE_KRB5_FREE_UNPARSED_NAME */ +/* Define to 1 if you have the `krb5_get_default_in_tkt_etypes' function. */ +#define HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES 1 +/* Define to 1 if you have the `krb5_get_error_string' function. */ +#define HAVE_KRB5_GET_ERROR_STRING 1 +/* Define to 1 if you have the `krb5_get_permitted_enctypes' function. */ +/* #undef HAVE_KRB5_GET_PERMITTED_ENCTYPES */ +/* Define to 1 if you have the `krb5_get_pw_salt' function. */ +#define HAVE_KRB5_GET_PW_SALT 1 +/* Define to 1 if you have the header file. */ +#define HAVE_KRB5_H 1 +/* Define to 1 if you have the `krb5_initlog' function. */ +#define HAVE_KRB5_INITLOG 1 +/* Define to 1 if you have the `krb5_kdc_default_config' function. */ +#define HAVE_KRB5_KDC_DEFAULT_CONFIG 1 +/* Whether the krb5_creds struct has a keyblock property */ +/* #undef HAVE_KRB5_KEYBLOCK_IN_CREDS */ +/* Whether the krb5_keyblock struct has a keyvalue property */ +#define HAVE_KRB5_KEYBLOCK_KEYVALUE 1 +/* Whether krb5_keytab_entry has key member */ +/* #undef HAVE_KRB5_KEYTAB_ENTRY_KEY */ +/* Whether krb5_keytab_entry has keyblock member */ +#define HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK 1 +/* Define to 1 if you have the `krb5_krbhst_get_addrinfo' function. */ +#define HAVE_KRB5_KRBHST_GET_ADDRINFO 1 +/* Define to 1 if you have the `krb5_kt_compare' function. */ +#define HAVE_KRB5_KT_COMPARE 1 +/* Define to 1 if you have the `krb5_kt_free_entry' function. */ +#define HAVE_KRB5_KT_FREE_ENTRY 1 +/* Whether the type krb5_log_facility exists */ +#define HAVE_KRB5_LOG_FACILITY 1 +/* Define to 1 if you have the `krb5_mk_req_extended' function. */ +#define HAVE_KRB5_MK_REQ_EXTENDED 1 +/* Define to 1 if you have the `krb5_principal2salt' function. */ +/* #undef HAVE_KRB5_PRINCIPAL2SALT */ +/* Define to 1 if you have the `krb5_principal_get_comp_string' function. */ +#define HAVE_KRB5_PRINCIPAL_GET_COMP_STRING 1 +/* Whether krb5_princ_component is available */ +/* #undef HAVE_KRB5_PRINC_COMPONENT */ +/* Whether the krb5_creds struct has a session property */ +#define HAVE_KRB5_SESSION_IN_CREDS 1 +/* Define to 1 if you have the `krb5_set_default_in_tkt_etypes' function. */ +#define HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES 1 +/* Define to 1 if you have the `krb5_set_default_tgs_ktypes' function. */ +/* #undef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES */ +/* Define to 1 if you have the `krb5_set_real_time' function. */ +#define HAVE_KRB5_SET_REAL_TIME 1 +/* Define to 1 if you have the `krb5_set_warn_dest' function. */ +#define HAVE_KRB5_SET_WARN_DEST 1 +/* Define to 1 if you have the `krb5_string_to_key' function. */ +#define HAVE_KRB5_STRING_TO_KEY 1 +/* Define to 1 if you have the `krb5_string_to_key_salt' function. */ +#define HAVE_KRB5_STRING_TO_KEY_SALT 1 +/* Define to 1 if you have the `krb5_ticket_get_authorization_data_type' */ +#define HAVE_KRB5_TICKET_GET_AUTHORIZATION_DATA_TYPE 1 +/* Whether the krb5_ticket struct has a enc_part2 property */ +/* #undef HAVE_KRB5_TKT_ENC_PART2 */ +/* Define to 1 if you have the `krb5_use_enctype' function. */ +/* #undef HAVE_KRB5_USE_ENCTYPE */ +/* Define to 1 if you have the `krb5_verify_checksum' function. */ +#define HAVE_KRB5_VERIFY_CHECKSUM 1 +/* Whether krb5_princ_realm returns krb5_realm or krb5_data */ +#define KRB5_PRINC_REALM_RETURNS_REALM 1 + +#include +#include + +#endif + +#endif diff --git a/lib/replace/system/locale.h b/lib/replace/system/locale.h new file mode 100644 index 0000000000..e73a9bb274 --- /dev/null +++ b/lib/replace/system/locale.h @@ -0,0 +1,38 @@ +#ifndef _system_locale_h +#define _system_locale_h + +/* + Unix SMB/CIFS implementation. + + locale include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_CTYPE_H +#include +#endif + +#ifdef HAVE_LOCALE_H +#include +#endif + +#endif diff --git a/lib/replace/system/network.h b/lib/replace/system/network.h new file mode 100644 index 0000000000..473d79b5f2 --- /dev/null +++ b/lib/replace/system/network.h @@ -0,0 +1,332 @@ +#ifndef _system_network_h +#define _system_network_h +/* + Unix SMB/CIFS implementation. + + networking system include wrappers + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Jelmer Vernooij 2007 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifndef LIBREPLACE_NETWORK_CHECKS +#error "AC_LIBREPLACE_NETWORK_CHECKS missing in configure" +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_UNIXSOCKET +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_NETINET_TCP_H +#include +#endif + +/* + * The next three defines are needed to access the IPTOS_* options + * on some systems. + */ + +#ifdef HAVE_NETINET_IN_SYSTM_H +#include +#endif + +#ifdef HAVE_NETINET_IN_IP_H +#include +#endif + +#ifdef HAVE_NETINET_IP_H +#include +#endif + +#ifdef HAVE_NET_IF_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_STROPTS_H +#include +#endif + +#ifndef HAVE_SOCKLEN_T +#define HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + +#if !defined (HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) +/* define is in "replace.h" */ +char *rep_inet_ntoa(struct in_addr ip); +#endif + +#ifndef HAVE_INET_PTON +/* define is in "replace.h" */ +int rep_inet_pton(int af, const char *src, void *dst); +#endif + +#ifndef HAVE_INET_NTOP +/* define is in "replace.h" */ +const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); +#endif + +#ifndef HAVE_INET_ATON +/* define is in "replace.h" */ +int rep_inet_aton(const char *src, struct in_addr *dst); +#endif + +#ifndef HAVE_CONNECT +/* define is in "replace.h" */ +int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +#endif + +#ifndef HAVE_GETHOSTBYNAME +/* define is in "replace.h" */ +struct hostent *rep_gethostbyname(const char *name); +#endif + +#ifdef HAVE_IFADDRS_H +#include +#endif + +#ifndef HAVE_STRUCT_IFADDRS +struct ifaddrs { + struct ifaddrs *ifa_next; /* Pointer to next struct */ + char *ifa_name; /* Interface name */ + unsigned int ifa_flags; /* Interface flags */ + struct sockaddr *ifa_addr; /* Interface address */ + struct sockaddr *ifa_netmask; /* Interface netmask */ +#undef ifa_dstaddr + struct sockaddr *ifa_dstaddr; /* P2P interface destination */ + void *ifa_data; /* Address specific data */ +}; +#endif + +#ifndef HAVE_GETIFADDRS +int rep_getifaddrs(struct ifaddrs **); +#endif + +#ifndef HAVE_FREEIFADDRS +void rep_freeifaddrs(struct ifaddrs *); +#endif + +#ifndef HAVE_SOCKETPAIR +/* define is in "replace.h" */ +int rep_socketpair(int d, int type, int protocol, int sv[2]); +#endif + +/* + * Some systems have getaddrinfo but not the + * defines needed to use it. + */ + +/* Various macros that ought to be in , but might not be */ + +#ifndef EAI_FAIL +#define EAI_BADFLAGS (-1) +#define EAI_NONAME (-2) +#define EAI_AGAIN (-3) +#define EAI_FAIL (-4) +#define EAI_FAMILY (-6) +#define EAI_SOCKTYPE (-7) +#define EAI_SERVICE (-8) +#define EAI_MEMORY (-10) +#define EAI_SYSTEM (-11) +#endif /* !EAI_FAIL */ + +#ifndef AI_PASSIVE +#define AI_PASSIVE 0x0001 +#endif + +#ifndef AI_CANONNAME +#define AI_CANONNAME 0x0002 +#endif + +#ifndef AI_NUMERICHOST +/* + * some platforms don't support AI_NUMERICHOST; define as zero if using + * the system version of getaddrinfo... + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_NUMERICHOST 0 +#else +#define AI_NUMERICHOST 0x0004 +#endif +#endif + +#ifndef AI_ADDRCONFIG +/* + * logic copied from AI_NUMERICHOST + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_ADDRCONFIG 0 +#else +#define AI_ADDRCONFIG 0x0020 +#endif +#endif + +#ifndef AI_NUMERICSERV +/* + * logic copied from AI_NUMERICHOST + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_NUMERICSERV 0 +#else +#define AI_NUMERICSERV 0x0400 +#endif +#endif + +#ifndef NI_NUMERICHOST +#define NI_NUMERICHOST 1 +#endif + +#ifndef NI_NUMERICSERV +#define NI_NUMERICSERV 2 +#endif + +#ifndef NI_NOFQDN +#define NI_NOFQDN 4 +#endif + +#ifndef NI_NAMEREQD +#define NI_NAMEREQD 8 +#endif + +#ifndef NI_DGRAM +#define NI_DGRAM 16 +#endif + + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif + +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + +/* + * glibc on linux doesn't seem to have MSG_WAITALL + * defined. I think the kernel has it though.. + */ +#ifndef MSG_WAITALL +#define MSG_WAITALL 0 +#endif + +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK 0x7f000001 +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT EINVAL +#endif + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 256 +#endif + +#ifndef HAVE_SA_FAMILY_T +#define HAVE_SA_FAMILY_T +typedef unsigned short int sa_family_t; +#endif + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +#define HAVE_STRUCT_SOCKADDR_STORAGE +#ifdef HAVE_STRUCT_SOCKADDR_IN6 +#define sockaddr_storage sockaddr_in6 +#define ss_family sin6_family +#define HAVE_SS_FAMILY 1 +#else +#define sockaddr_storage sockaddr_in +#define ss_family sin_family +#define HAVE_SS_FAMILY 1 +#endif +#endif + +#ifndef HAVE_SS_FAMILY +#ifdef HAVE___SS_FAMILY +#define ss_family __ss_family +#define HAVE_SS_FAMILY 1 +#endif +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +#define HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + socklen_t ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; +}; +#endif /* HAVE_STRUCT_ADDRINFO */ + +#if !defined(HAVE_GETADDRINFO) +#include "getaddrinfo.h" +#endif + +/* Needed for some systems that don't define it (Solaris). */ +#ifndef ifr_netmask +#define ifr_netmask ifr_addr +#endif + +#ifdef SOCKET_WRAPPER +#ifndef SOCKET_WRAPPER_NOT_REPLACE +#define SOCKET_WRAPPER_REPLACE +#endif +#include "../socket_wrapper/socket_wrapper.h" +#endif + +#endif diff --git a/lib/replace/system/passwd.h b/lib/replace/system/passwd.h new file mode 100644 index 0000000000..9d7de34bce --- /dev/null +++ b/lib/replace/system/passwd.h @@ -0,0 +1,110 @@ +#ifndef _system_passwd_h +#define _system_passwd_h + +/* + Unix SMB/CIFS implementation. + + passwd system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +/* this needs to be included before nss_wrapper.h on some systems */ +#include + +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif +#ifdef HAVE_SYS_PRIV_H +#include +#endif +#ifdef HAVE_SYS_ID_H +#include +#endif + +#ifdef HAVE_CRYPT_H +#include +#endif + +#ifdef HAVE_SHADOW_H +#include +#endif + +#ifdef HAVE_SYS_SECURITY_H +#include +#include +#define PASSWORD_LENGTH 16 +#endif /* HAVE_SYS_SECURITY_H */ + +#ifdef HAVE_GETPWANAM +#include +#include +#include +#endif + +#ifdef HAVE_COMPAT_H +#include +#endif + +#ifdef REPLACE_GETPASS +#if defined(REPLACE_GETPASS_BY_GETPASSPHRASE) +#define getpass(prompt) getpassphrase(prompt) +#else +#define getpass(prompt) rep_getpass(prompt) +char *rep_getpass(const char *prompt); +#endif +#endif + +#ifndef NGROUPS_MAX +#define NGROUPS_MAX 32 /* Guess... */ +#endif + +/* what is the longest significant password available on your system? + Knowing this speeds up password searches a lot */ +#ifndef PASSWORD_LENGTH +#define PASSWORD_LENGTH 8 +#endif + +#if defined(HAVE_PUTPRPWNAM) && defined(AUTH_CLEARTEXT_SEG_CHARS) +#define OSF1_ENH_SEC 1 +#endif + +#ifndef ALLOW_CHANGE_PASSWORD +#if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID)) +#define ALLOW_CHANGE_PASSWORD 1 +#endif +#endif + +#if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID) +#define ULTRIX_AUTH 1 +#endif + +#ifdef NSS_WRAPPER +#ifndef NSS_WRAPPER_NOT_REPLACE +#define NSS_WRAPPER_REPLACE +#endif +#include "../nss_wrapper/nss_wrapper.h" +#endif + +#endif diff --git a/lib/replace/system/readline.h b/lib/replace/system/readline.h new file mode 100644 index 0000000000..ba34dc6a61 --- /dev/null +++ b/lib/replace/system/readline.h @@ -0,0 +1,52 @@ +#ifndef _system_readline_h +#define _system_readline_h +/* + Unix SMB/CIFS implementation. + + Readline wrappers + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_LIBREADLINE +# ifdef HAVE_READLINE_READLINE_H +# include +# ifdef HAVE_READLINE_HISTORY_H +# include +# endif +# else +# ifdef HAVE_READLINE_H +# include +# ifdef HAVE_HISTORY_H +# include +# endif +# else +# undef HAVE_LIBREADLINE +# endif +# endif +#endif + +#ifdef HAVE_NEW_LIBREADLINE +# define RL_COMPLETION_CAST (rl_completion_func_t *) +#else +/* This type is missing from libreadline<4.0 (approximately) */ +# define RL_COMPLETION_CAST +#endif /* HAVE_NEW_LIBREADLINE */ + +#endif diff --git a/lib/replace/system/select.h b/lib/replace/system/select.h new file mode 100644 index 0000000000..da18de0cfc --- /dev/null +++ b/lib/replace/system/select.h @@ -0,0 +1,41 @@ +#ifndef _system_select_h +#define _system_select_h +/* + Unix SMB/CIFS implementation. + + select system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifdef HAVE_SYS_EPOLL_H +#include +#endif + +#ifndef SELECT_CAST +#define SELECT_CAST +#endif + +#endif diff --git a/lib/replace/system/shmem.h b/lib/replace/system/shmem.h new file mode 100644 index 0000000000..64fe39b6cb --- /dev/null +++ b/lib/replace/system/shmem.h @@ -0,0 +1,59 @@ +#ifndef _system_shmem_h +#define _system_shmem_h +/* + Unix SMB/CIFS implementation. + + shared memory system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#if defined(HAVE_SYS_IPC_H) +#include +#endif /* HAVE_SYS_IPC_H */ + +#if defined(HAVE_SYS_SHM_H) +#include +#endif /* HAVE_SYS_SHM_H */ + +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +/* NetBSD doesn't have these */ +#ifndef SHM_R +#define SHM_R 0400 +#endif + +#ifndef SHM_W +#define SHM_W 0200 +#endif + + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +#endif diff --git a/lib/replace/system/syslog.h b/lib/replace/system/syslog.h new file mode 100644 index 0000000000..104be1df84 --- /dev/null +++ b/lib/replace/system/syslog.h @@ -0,0 +1,70 @@ +#ifndef _system_syslog_h +#define _system_syslog_h +/* + Unix SMB/CIFS implementation. + + syslog system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_SYSLOG_H +#include +#else +#ifdef HAVE_SYS_SYSLOG_H +#include +#endif +#endif + +/* For sys_adminlog(). */ +#ifndef LOG_EMERG +#define LOG_EMERG 0 /* system is unusable */ +#endif + +#ifndef LOG_ALERT +#define LOG_ALERT 1 /* action must be taken immediately */ +#endif + +#ifndef LOG_CRIT +#define LOG_CRIT 2 /* critical conditions */ +#endif + +#ifndef LOG_ERR +#define LOG_ERR 3 /* error conditions */ +#endif + +#ifndef LOG_WARNING +#define LOG_WARNING 4 /* warning conditions */ +#endif + +#ifndef LOG_NOTICE +#define LOG_NOTICE 5 /* normal but significant condition */ +#endif + +#ifndef LOG_INFO +#define LOG_INFO 6 /* informational */ +#endif + +#ifndef LOG_DEBUG +#define LOG_DEBUG 7 /* debug-level messages */ +#endif + +#endif diff --git a/lib/replace/system/terminal.h b/lib/replace/system/terminal.h new file mode 100644 index 0000000000..9ad601ace0 --- /dev/null +++ b/lib/replace/system/terminal.h @@ -0,0 +1,46 @@ +#ifndef _system_terminal_h +#define _system_terminal_h +/* + Unix SMB/CIFS implementation. + + terminal system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef SUNOS4 +/* on SUNOS4 termios.h conflicts with sys/ioctl.h */ +#undef HAVE_TERMIOS_H +#endif + + +#if defined(HAVE_TERMIOS_H) +/* POSIX terminal handling. */ +#include +#elif defined(HAVE_TERMIO_H) +/* Older SYSV terminal handling - don't use if we can avoid it. */ +#include +#elif defined(HAVE_SYS_TERMIO_H) +/* Older SYSV terminal handling - don't use if we can avoid it. */ +#include +#endif + +#endif diff --git a/lib/replace/system/time.h b/lib/replace/system/time.h new file mode 100644 index 0000000000..4abf295d1a --- /dev/null +++ b/lib/replace/system/time.h @@ -0,0 +1,69 @@ +#ifndef _system_time_h +#define _system_time_h +/* + Unix SMB/CIFS implementation. + + time system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef TIME_WITH_SYS_TIME +#include +#include +#else +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + +#ifdef HAVE_UTIME_H +#include +#else +struct utimbuf { + time_t actime; /* access time */ + time_t modtime; /* modification time */ +}; +#endif + +#ifndef HAVE_MKTIME +/* define is in "replace.h" */ +time_t rep_mktime(struct tm *t); +#endif + +#ifndef HAVE_TIMEGM +/* define is in "replace.h" */ +time_t rep_timegm(struct tm *tm); +#endif + +#ifndef HAVE_UTIME +/* define is in "replace.h" */ +int rep_utime(const char *filename, const struct utimbuf *buf); +#endif + +#ifndef HAVE_UTIMES +/* define is in "replace.h" */ +int rep_utimes(const char *filename, const struct timeval tv[2]); +#endif + +#endif diff --git a/lib/replace/system/wait.h b/lib/replace/system/wait.h new file mode 100644 index 0000000000..5784b1ae92 --- /dev/null +++ b/lib/replace/system/wait.h @@ -0,0 +1,55 @@ +#ifndef _system_wait_h +#define _system_wait_h +/* + Unix SMB/CIFS implementation. + + waitpid system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#include + +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif + +#ifndef SIGNAL_CAST +#define SIGNAL_CAST (RETSIGTYPE (*)(int)) +#endif + +#ifdef HAVE_SETJMP_H +#include +#endif + +#ifndef SA_RESETHAND +#define SA_RESETHAND SA_ONESHOT +#endif + +#if !defined(HAVE_SIG_ATOMIC_T_TYPE) +typedef int sig_atomic_t; +#endif + +#endif diff --git a/lib/replace/test/getifaddrs.c b/lib/replace/test/getifaddrs.c new file mode 100644 index 0000000000..8b00ac2f40 --- /dev/null +++ b/lib/replace/test/getifaddrs.c @@ -0,0 +1,100 @@ +/* + * Unix SMB/CIFS implementation. + * + * libreplace getifaddrs test + * + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef AUTOCONF_TEST +#include "replace.h" +#include "system/network.h" +#endif + +#ifdef HAVE_INET_NTOP +#define rep_inet_ntop inet_ntop +#endif + +static const char *format_sockaddr(struct sockaddr *addr, + char *addrstring, + socklen_t addrlen) +{ + const char *result = NULL; + + if (addr->sa_family == AF_INET) { + result = rep_inet_ntop(AF_INET, + &((struct sockaddr_in *)addr)->sin_addr, + addrstring, + addrlen); +#ifdef HAVE_STRUCT_SOCKADDR_IN6 + } else if (addr->sa_family == AF_INET6) { + result = rep_inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)addr)->sin6_addr, + addrstring, + addrlen); +#endif + } + return result; +} + +int getifaddrs_test(void) +{ + struct ifaddrs *ifs = NULL; + struct ifaddrs *ifs_head = NULL; + int ret; + + ret = getifaddrs(&ifs); + ifs_head = ifs; + if (ret != 0) { + fprintf(stderr, "getifaddrs() failed: %s\n", strerror(errno)); + return 1; + } + + while (ifs) { + printf("%-10s ", ifs->ifa_name); + if (ifs->ifa_addr != NULL) { + char addrstring[INET6_ADDRSTRLEN]; + const char *result; + + result = format_sockaddr(ifs->ifa_addr, + addrstring, + sizeof(addrstring)); + if (result != NULL) { + printf("IP=%s ", addrstring); + } + + if (ifs->ifa_netmask != NULL) { + result = format_sockaddr(ifs->ifa_netmask, + addrstring, + sizeof(addrstring)); + if (result != NULL) { + printf("NETMASK=%s", addrstring); + } + } else { + printf("AF=%d ", ifs->ifa_addr->sa_family); + } + } else { + printf(""); + } + + printf("\n"); + ifs = ifs->ifa_next; + } + + freeifaddrs(ifs_head); + + return 0; +} diff --git a/lib/replace/test/os2_delete.c b/lib/replace/test/os2_delete.c new file mode 100644 index 0000000000..b45c135355 --- /dev/null +++ b/lib/replace/test/os2_delete.c @@ -0,0 +1,124 @@ +/* + test readdir/unlink pattern that OS/2 uses + tridge@samba.org July 2005 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_FILES 700 +#define READDIR_SIZE 100 +#define DELETE_SIZE 4 + +#define TESTDIR "test.dir" + +static int test_readdir_os2_delete_ret; + +#define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1, 1) + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +static void cleanup(void) +{ + /* I'm a lazy bastard */ + system("rm -rf " TESTDIR); + mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); +} + +static void create_files(void) +{ + int i; + for (i=0;id_name); + } + + if (i == 0) { + return 0; + } + + /* delete the first few */ + for (j=0; jd_name, ".") == 0 || FAILED("match ."); + de = readdir(d); + strcmp(de->d_name, "..") == 0 || FAILED("match .."); + + while (1) { + int n = os2_delete(d); + if (n == 0) break; + total_deleted += n; + } + closedir(d); + + fprintf(stderr, "Deleted %d files of %d\n", total_deleted, NUM_FILES); + + rmdir(TESTDIR) == 0 || FAILED("rmdir"); + + system("rm -rf " TESTDIR); + + return test_readdir_os2_delete_ret; +} diff --git a/lib/replace/test/shared_mmap.c b/lib/replace/test/shared_mmap.c new file mode 100644 index 0000000000..50dad8d696 --- /dev/null +++ b/lib/replace/test/shared_mmap.c @@ -0,0 +1,68 @@ +/* this tests whether we can use a shared writeable mmap on a file - + as needed for the mmap variant of FAST_SHARE_MODES */ + +#if defined(HAVE_UNISTD_H) +#include +#endif +#include +#include +#include +#include + +#define DATA "conftest.mmap" + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +main() +{ + int *buf; + int i; + int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); + int count=7; + + if (fd == -1) exit(1); + + for (i=0;i<10000;i++) { + write(fd,&i,sizeof(i)); + } + + close(fd); + + if (fork() == 0) { + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + while (count-- && buf[9124] != 55732) sleep(1); + + if (count <= 0) exit(1); + + buf[1763] = 7268; + exit(0); + } + + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + if (buf == (int *)-1) exit(1); + + buf[9124] = 55732; + + while (count-- && buf[1763] != 7268) sleep(1); + + unlink(DATA); + + if (count > 0) exit(0); + exit(1); +} diff --git a/lib/replace/test/strptime.c b/lib/replace/test/strptime.c new file mode 100644 index 0000000000..fade3ecc57 --- /dev/null +++ b/lib/replace/test/strptime.c @@ -0,0 +1,172 @@ + +#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME + +#include +#include +#include + +#define true 1 +#define false 0 + +#ifndef __STRING +#define __STRING(x) #x +#endif + +/* make printf a no-op */ +#define printf if(0) printf + +#else /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ + +#include "replace.h" +#include "system/time.h" + +#endif /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ + +int libreplace_test_strptime(void) +{ + const char *s = "20070414101546Z"; + char *ret; + struct tm t, t2; + + memset(&t, 0, sizeof(t)); + memset(&t2, 0, sizeof(t2)); + + printf("test: strptime\n"); + + ret = strptime(s, "%Y%m%d%H%M%S", &t); + if ( ret == NULL ) { + printf("failure: strptime [\n" + "returned NULL\n" + "]\n"); + return false; + } + + if ( *ret != 'Z' ) { + printf("failure: strptime [\n" + "ret doesn't point to 'Z'\n" + "]\n"); + return false; + } + + ret = strptime(s, "%Y%m%d%H%M%SZ", &t2); + if ( ret == NULL ) { + printf("failure: strptime [\n" + "returned NULL with Z\n" + "]\n"); + return false; + } + + if ( *ret != '\0' ) { + printf("failure: strptime [\n" + "ret doesn't point to '\\0'\n" + "]\n"); + return false; + } + +#define CMP_TM_ELEMENT(t1,t2,elem) \ + if (t1.elem != t2.elem) { \ + printf("failure: strptime [\n" \ + "result differs if the format string has a 'Z' at the end\n" \ + "element: %s %d != %d\n" \ + "]\n", \ + __STRING(elen), t1.elem, t2.elem); \ + return false; \ + } + + CMP_TM_ELEMENT(t,t2,tm_sec); + CMP_TM_ELEMENT(t,t2,tm_min); + CMP_TM_ELEMENT(t,t2,tm_hour); + CMP_TM_ELEMENT(t,t2,tm_mday); + CMP_TM_ELEMENT(t,t2,tm_mon); + CMP_TM_ELEMENT(t,t2,tm_year); + CMP_TM_ELEMENT(t,t2,tm_wday); + CMP_TM_ELEMENT(t,t2,tm_yday); + CMP_TM_ELEMENT(t,t2,tm_isdst); + + if (t.tm_sec != 46) { + printf("failure: strptime [\n" + "tm_sec: expected: 46, got: %d\n" + "]\n", + t.tm_sec); + return false; + } + + if (t.tm_min != 15) { + printf("failure: strptime [\n" + "tm_min: expected: 15, got: %d\n" + "]\n", + t.tm_min); + return false; + } + + if (t.tm_hour != 10) { + printf("failure: strptime [\n" + "tm_hour: expected: 10, got: %d\n" + "]\n", + t.tm_hour); + return false; + } + + if (t.tm_mday != 14) { + printf("failure: strptime [\n" + "tm_mday: expected: 14, got: %d\n" + "]\n", + t.tm_mday); + return false; + } + + if (t.tm_mon != 3) { + printf("failure: strptime [\n" + "tm_mon: expected: 3, got: %d\n" + "]\n", + t.tm_mon); + return false; + } + + if (t.tm_year != 107) { + printf("failure: strptime [\n" + "tm_year: expected: 107, got: %d\n" + "]\n", + t.tm_year); + return false; + } + + if (t.tm_wday != 6) { /* saturday */ + printf("failure: strptime [\n" + "tm_wday: expected: 6, got: %d\n" + "]\n", + t.tm_wday); + return false; + } + + if (t.tm_yday != 103) { + printf("failure: strptime [\n" + "tm_yday: expected: 103, got: %d\n" + "]\n", + t.tm_yday); + return false; + } + + /* we don't test this as it depends on the host configuration + if (t.tm_isdst != 0) { + printf("failure: strptime [\n" + "tm_isdst: expected: 0, got: %d\n" + "]\n", + t.tm_isdst); + return false; + }*/ + + printf("success: strptime\n"); + + return true; +} + +#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME +int main (void) +{ + int ret; + ret = libreplace_test_strptime(); + if (ret == false) return 1; + return 0; +} +#endif diff --git a/lib/replace/test/testsuite.c b/lib/replace/test/testsuite.c new file mode 100644 index 0000000000..1e8290906e --- /dev/null +++ b/lib/replace/test/testsuite.c @@ -0,0 +1,1080 @@ +/* + Unix SMB/CIFS implementation. + + libreplace tests + + Copyright (C) Jelmer Vernooij 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" + +/* + we include all the system/ include files here so that libreplace tests + them in the build farm +*/ +#include "system/capability.h" +#include "system/dir.h" +#include "system/filesys.h" +#include "system/glob.h" +#include "system/iconv.h" +#include "system/locale.h" +#include "system/network.h" +#include "system/passwd.h" +#include "system/readline.h" +#include "system/select.h" +#include "system/shmem.h" +#include "system/syslog.h" +#include "system/terminal.h" +#include "system/time.h" +#include "system/wait.h" +#include "system/aio.h" + +#define TESTFILE "testfile.dat" + +/* + test ftruncate() function + */ +static int test_ftruncate(void) +{ + struct stat st; + int fd; + const int size = 1234; + printf("test: ftruncate\n"); + unlink(TESTFILE); + fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); + if (fd == -1) { + printf("failure: ftruncate [\n" + "creating '%s' failed - %s\n]\n", TESTFILE, strerror(errno)); + return false; + } + if (ftruncate(fd, size) != 0) { + printf("failure: ftruncate [\n%s\n]\n", strerror(errno)); + return false; + } + if (fstat(fd, &st) != 0) { + printf("failure: ftruncate [\nfstat failed - %s\n]\n", strerror(errno)); + return false; + } + if (st.st_size != size) { + printf("failure: ftruncate [\ngave wrong size %d - expected %d\n]\n", + (int)st.st_size, size); + return false; + } + unlink(TESTFILE); + printf("success: ftruncate\n"); + return true; +} + +/* + test strlcpy() function. + see http://www.gratisoft.us/todd/papers/strlcpy.html + */ +static int test_strlcpy(void) +{ + char buf[4]; + const struct { + const char *src; + size_t result; + } tests[] = { + { "abc", 3 }, + { "abcdef", 6 }, + { "abcd", 4 }, + { "", 0 }, + { NULL, 0 } + }; + int i; + printf("test: strlcpy\n"); + for (i=0;tests[i].src;i++) { + if (strlcpy(buf, tests[i].src, sizeof(buf)) != tests[i].result) { + printf("failure: strlcpy [\ntest %d failed\n]\n", i); + return false; + } + } + printf("success: strlcpy\n"); + return true; +} + +static int test_strlcat(void) +{ + char tmp[10]; + printf("test: strlcat\n"); + strlcpy(tmp, "", sizeof(tmp)); + if (strlcat(tmp, "bla", 3) != 3) { + printf("failure: strlcat [\ninvalid return code\n]\n"); + return false; + } + if (strcmp(tmp, "bl") != 0) { + printf("failure: strlcat [\nexpected \"bl\", got \"%s\"\n]\n", + tmp); + return false; + } + + strlcpy(tmp, "da", sizeof(tmp)); + if (strlcat(tmp, "me", 4) != 4) { + printf("failure: strlcat [\nexpected \"dam\", got \"%s\"\n]\n", + tmp); + return false; + } + + printf("success: strlcat\n"); + return true; +} + +static int test_mktime(void) +{ + /* FIXME */ + return true; +} + +static int test_initgroups(void) +{ + /* FIXME */ + return true; +} + +static int test_memmove(void) +{ + /* FIXME */ + return true; +} + +static int test_strdup(void) +{ + char *x; + printf("test: strdup\n"); + x = strdup("bla"); + if (strcmp("bla", x) != 0) { + printf("failure: strdup [\nfailed: expected \"bla\", got \"%s\"\n]\n", + x); + return false; + } + free(x); + printf("success: strdup\n"); + return true; +} + +static int test_setlinebuf(void) +{ + printf("test: setlinebuf\n"); + setlinebuf(stdout); + printf("success: setlinebuf\n"); + return true; +} + +static int test_vsyslog(void) +{ + /* FIXME */ + return true; +} + +static int test_timegm(void) +{ + /* FIXME */ + return true; +} + +static int test_setenv(void) +{ +#define TEST_SETENV(key, value, overwrite, result) do { \ + int _ret; \ + char *_v; \ + _ret = setenv(key, value, overwrite); \ + if (_ret != 0) { \ + printf("failure: setenv [\n" \ + "setenv(%s, %s, %d) failed\n" \ + "]\n", \ + key, value, overwrite); \ + return false; \ + } \ + _v=getenv(key); \ + if (!_v) { \ + printf("failure: setenv [\n" \ + "getenv(%s) returned NULL\n" \ + "]\n", \ + key); \ + return false; \ + } \ + if (strcmp(result, _v) != 0) { \ + printf("failure: setenv [\n" \ + "getenv(%s): '%s' != '%s'\n" \ + "]\n", \ + key, result, _v); \ + return false; \ + } \ +} while(0) + +#define TEST_UNSETENV(key) do { \ + char *_v; \ + unsetenv(key); \ + _v=getenv(key); \ + if (_v) { \ + printf("failure: setenv [\n" \ + "getenv(%s): NULL != '%s'\n" \ + "]\n", \ + SETENVTEST_KEY, _v); \ + return false; \ + } \ +} while (0) + +#define SETENVTEST_KEY "SETENVTESTKEY" +#define SETENVTEST_VAL "SETENVTESTVAL" + + printf("test: setenv\n"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"1", 0, SETENVTEST_VAL"1"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"2", 0, SETENVTEST_VAL"1"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"3", 1, SETENVTEST_VAL"3"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"4", 1, SETENVTEST_VAL"4"); + TEST_UNSETENV(SETENVTEST_KEY); + TEST_UNSETENV(SETENVTEST_KEY); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"5", 0, SETENVTEST_VAL"5"); + TEST_UNSETENV(SETENVTEST_KEY); + TEST_UNSETENV(SETENVTEST_KEY); + printf("success: setenv\n"); + return true; +} + +static int test_strndup(void) +{ + char *x; + printf("test: strndup\n"); + x = strndup("bla", 0); + if (strcmp(x, "") != 0) { + printf("failure: strndup [\ninvalid\n]\n"); + return false; + } + free(x); + x = strndup("bla", 2); + if (strcmp(x, "bl") != 0) { + printf("failure: strndup [\ninvalid\n]\n"); + return false; + } + free(x); + x = strndup("bla", 10); + if (strcmp(x, "bla") != 0) { + printf("failure: strndup [\ninvalid\n]\n"); + return false; + } + free(x); + printf("success: strndup\n"); + return true; +} + +static int test_strnlen(void) +{ + printf("test: strnlen\n"); + if (strnlen("bla", 2) != 2) { + printf("failure: strnlen [\nunexpected length\n]\n"); + return false; + } + + if (strnlen("some text\n", 0) != 0) { + printf("failure: strnlen [\nunexpected length\n]\n"); + return false; + } + + if (strnlen("some text", 20) != 9) { + printf("failure: strnlen [\nunexpected length\n]\n"); + return false; + } + + printf("success: strnlen\n"); + return true; +} + +static int test_waitpid(void) +{ + /* FIXME */ + return true; +} + +static int test_seteuid(void) +{ + /* FIXME */ + return true; +} + +static int test_setegid(void) +{ + /* FIXME */ + return true; +} + +static int test_asprintf(void) +{ + char *x; + printf("test: asprintf\n"); + if (asprintf(&x, "%d", 9) != 1) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + if (strcmp(x, "9") != 0) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + if (asprintf(&x, "dat%s", "a") != 4) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + if (strcmp(x, "data") != 0) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + printf("success: asprintf\n"); + return true; +} + +static int test_snprintf(void) +{ + char tmp[10]; + printf("test: snprintf\n"); + if (snprintf(tmp, 3, "foo%d", 9) != 4) { + printf("failure: snprintf [\nsnprintf return code failed\n]\n"); + return false; + } + + if (strcmp(tmp, "fo") != 0) { + printf("failure: snprintf [\nsnprintf failed\n]\n"); + return false; + } + + printf("success: snprintf\n"); + return true; +} + +static int test_vasprintf(void) +{ + /* FIXME */ + return true; +} + +static int test_vsnprintf(void) +{ + /* FIXME */ + return true; +} + +static int test_opendir(void) +{ + /* FIXME */ + return true; +} + +extern int test_readdir_os2_delete(void); + +static int test_readdir(void) +{ + printf("test: readdir\n"); + if (test_readdir_os2_delete() != 0) { + return false; + } + printf("success: readdir\n"); + return true; +} + +static int test_telldir(void) +{ + /* FIXME */ + return true; +} + +static int test_seekdir(void) +{ + /* FIXME */ + return true; +} + +static int test_dlopen(void) +{ + /* FIXME: test dlopen, dlsym, dlclose, dlerror */ + return true; +} + + +static int test_chroot(void) +{ + /* FIXME: chroot() */ + return true; +} + +static int test_bzero(void) +{ + /* FIXME: bzero */ + return true; +} + +static int test_strerror(void) +{ + /* FIXME */ + return true; +} + +static int test_errno(void) +{ + printf("test: errno\n"); + errno = 3; + if (errno != 3) { + printf("failure: errno [\nerrno failed\n]\n"); + return false; + } + + printf("success: errno\n"); + return true; +} + +static int test_mkdtemp(void) +{ + /* FIXME */ + return true; +} + +static int test_mkstemp(void) +{ + /* FIXME */ + return true; +} + +static int test_pread(void) +{ + /* FIXME */ + return true; +} + +static int test_pwrite(void) +{ + /* FIXME */ + return true; +} + +static int test_getpass(void) +{ + /* FIXME */ + return true; +} + +static int test_inet_ntoa(void) +{ + /* FIXME */ + return true; +} + +#define TEST_STRTO_X(type,fmt,func,str,base,res,diff,rrnoo) do {\ + type _v; \ + char _s[64]; \ + char *_p = NULL;\ + char *_ep = NULL; \ + strlcpy(_s, str, sizeof(_s));\ + if (diff >= 0) { \ + _ep = &_s[diff]; \ + } \ + errno = 0; \ + _v = func(_s, &_p, base); \ + if (errno != rrnoo) { \ + printf("failure: %s [\n" \ + "\t%s\n" \ + "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ + "\terrno: %d != %d\n" \ + "]\n", \ + __STRING(func), __location__, __STRING(func), \ + str, diff, base, res, _v, rrnoo, errno); \ + return false; \ + } else if (_v != res) { \ + printf("failure: %s [\n" \ + "\t%s\n" \ + "\t%s(\"%s\",%d,%d): " fmt " != " fmt "\n" \ + "]\n", \ + __STRING(func), __location__, __STRING(func), \ + str, diff, base, res, _v); \ + return false; \ + } else if (_p != _ep) { \ + printf("failure: %s [\n" \ + "\t%s\n" \ + "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ + "\tptr: %p - %p = %d != %d\n" \ + "]\n", \ + __STRING(func), __location__, __STRING(func), \ + str, diff, base, res, _v, _ep, _p, (int)(diff - (_ep - _p)), diff); \ + return false; \ + } \ +} while (0) + +static int test_strtoll(void) +{ + printf("test: strtoll\n"); + +#define TEST_STRTOLL(str,base,res,diff,errnoo) TEST_STRTO_X(long long int, "%lld", strtoll,str,base,res,diff,errnoo) + + TEST_STRTOLL("15", 10, 15LL, 2, 0); + TEST_STRTOLL(" 15", 10, 15LL, 4, 0); + TEST_STRTOLL("15", 0, 15LL, 2, 0); + TEST_STRTOLL(" 15 ", 0, 15LL, 3, 0); + TEST_STRTOLL("+15", 10, 15LL, 3, 0); + TEST_STRTOLL(" +15", 10, 15LL, 5, 0); + TEST_STRTOLL("+15", 0, 15LL, 3, 0); + TEST_STRTOLL(" +15 ", 0, 15LL, 4, 0); + TEST_STRTOLL("-15", 10, -15LL, 3, 0); + TEST_STRTOLL(" -15", 10, -15LL, 5, 0); + TEST_STRTOLL("-15", 0, -15LL, 3, 0); + TEST_STRTOLL(" -15 ", 0, -15LL, 4, 0); + TEST_STRTOLL("015", 10, 15LL, 3, 0); + TEST_STRTOLL(" 015", 10, 15LL, 5, 0); + TEST_STRTOLL("015", 0, 13LL, 3, 0); + TEST_STRTOLL(" 015", 0, 13LL, 5, 0); + TEST_STRTOLL("0x15", 10, 0LL, 1, 0); + TEST_STRTOLL(" 0x15", 10, 0LL, 3, 0); + TEST_STRTOLL("0x15", 0, 21LL, 4, 0); + TEST_STRTOLL(" 0x15", 0, 21LL, 6, 0); + + TEST_STRTOLL("10", 16, 16LL, 2, 0); + TEST_STRTOLL(" 10 ", 16, 16LL, 4, 0); + TEST_STRTOLL("0x10", 16, 16LL, 4, 0); + TEST_STRTOLL("0x10", 0, 16LL, 4, 0); + TEST_STRTOLL(" 0x10 ", 0, 16LL, 5, 0); + TEST_STRTOLL("+10", 16, 16LL, 3, 0); + TEST_STRTOLL(" +10 ", 16, 16LL, 5, 0); + TEST_STRTOLL("+0x10", 16, 16LL, 5, 0); + TEST_STRTOLL("+0x10", 0, 16LL, 5, 0); + TEST_STRTOLL(" +0x10 ", 0, 16LL, 6, 0); + TEST_STRTOLL("-10", 16, -16LL, 3, 0); + TEST_STRTOLL(" -10 ", 16, -16LL, 5, 0); + TEST_STRTOLL("-0x10", 16, -16LL, 5, 0); + TEST_STRTOLL("-0x10", 0, -16LL, 5, 0); + TEST_STRTOLL(" -0x10 ", 0, -16LL, 6, 0); + TEST_STRTOLL("010", 16, 16LL, 3, 0); + TEST_STRTOLL(" 010 ", 16, 16LL, 5, 0); + TEST_STRTOLL("-010", 16, -16LL, 4, 0); + + TEST_STRTOLL("11", 8, 9LL, 2, 0); + TEST_STRTOLL("011", 8, 9LL, 3, 0); + TEST_STRTOLL("011", 0, 9LL, 3, 0); + TEST_STRTOLL("-11", 8, -9LL, 3, 0); + TEST_STRTOLL("-011", 8, -9LL, 4, 0); + TEST_STRTOLL("-011", 0, -9LL, 4, 0); + + TEST_STRTOLL("011", 8, 9LL, 3, 0); + TEST_STRTOLL("011", 0, 9LL, 3, 0); + TEST_STRTOLL("-11", 8, -9LL, 3, 0); + TEST_STRTOLL("-011", 8, -9LL, 4, 0); + TEST_STRTOLL("-011", 0, -9LL, 4, 0); + + TEST_STRTOLL("Text", 0, 0LL, 0, 0); + + TEST_STRTOLL("9223372036854775807", 10, 9223372036854775807LL, 19, 0); + TEST_STRTOLL("9223372036854775807", 0, 9223372036854775807LL, 19, 0); + TEST_STRTOLL("9223372036854775808", 0, 9223372036854775807LL, 19, ERANGE); + TEST_STRTOLL("9223372036854775808", 10, 9223372036854775807LL, 19, ERANGE); + TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LL, 18, 0); + TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 18, 0); + TEST_STRTOLL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 16, 0); + TEST_STRTOLL("0x8000000000000000", 0, 9223372036854775807LL, 18, ERANGE); + TEST_STRTOLL("0x8000000000000000", 16, 9223372036854775807LL, 18, ERANGE); + TEST_STRTOLL("80000000000000000", 16, 9223372036854775807LL, 17, ERANGE); + TEST_STRTOLL("0777777777777777777777", 0, 9223372036854775807LL, 22, 0); + TEST_STRTOLL("0777777777777777777777", 8, 9223372036854775807LL, 22, 0); + TEST_STRTOLL("777777777777777777777", 8, 9223372036854775807LL, 21, 0); + TEST_STRTOLL("01000000000000000000000", 0, 9223372036854775807LL, 23, ERANGE); + TEST_STRTOLL("01000000000000000000000", 8, 9223372036854775807LL, 23, ERANGE); + TEST_STRTOLL("1000000000000000000000", 8, 9223372036854775807LL, 22, ERANGE); + + TEST_STRTOLL("-9223372036854775808", 10, -9223372036854775807LL -1, 20, 0); + TEST_STRTOLL("-9223372036854775808", 0, -9223372036854775807LL -1, 20, 0); + TEST_STRTOLL("-9223372036854775809", 0, -9223372036854775807LL -1, 20, ERANGE); + TEST_STRTOLL("-9223372036854775809", 10, -9223372036854775807LL -1, 20, ERANGE); + TEST_STRTOLL("-0x8000000000000000", 0, -9223372036854775807LL -1, 19, 0); + TEST_STRTOLL("-0x8000000000000000", 16, -9223372036854775807LL -1, 19, 0); + TEST_STRTOLL("-8000000000000000", 16, -9223372036854775807LL -1, 17, 0); + TEST_STRTOLL("-0x8000000000000001", 0, -9223372036854775807LL -1, 19, ERANGE); + TEST_STRTOLL("-0x8000000000000001", 16, -9223372036854775807LL -1, 19, ERANGE); + TEST_STRTOLL("-80000000000000001", 16, -9223372036854775807LL -1, 18, ERANGE); + TEST_STRTOLL("-01000000000000000000000",0, -9223372036854775807LL -1, 24, 0); + TEST_STRTOLL("-01000000000000000000000",8, -9223372036854775807LL -1, 24, 0); + TEST_STRTOLL("-1000000000000000000000", 8, -9223372036854775807LL -1, 23, 0); + TEST_STRTOLL("-01000000000000000000001",0, -9223372036854775807LL -1, 24, ERANGE); + TEST_STRTOLL("-01000000000000000000001",8, -9223372036854775807LL -1, 24, ERANGE); + TEST_STRTOLL("-1000000000000000000001", 8, -9223372036854775807LL -1, 23, ERANGE); + + printf("success: strtoll\n"); + return true; +} + +static int test_strtoull(void) +{ + printf("test: strtoull\n"); + +#define TEST_STRTOULL(str,base,res,diff,errnoo) TEST_STRTO_X(long long unsigned int,"%llu",strtoull,str,base,res,diff,errnoo) + + TEST_STRTOULL("15", 10, 15LLU, 2, 0); + TEST_STRTOULL(" 15", 10, 15LLU, 4, 0); + TEST_STRTOULL("15", 0, 15LLU, 2, 0); + TEST_STRTOULL(" 15 ", 0, 15LLU, 3, 0); + TEST_STRTOULL("+15", 10, 15LLU, 3, 0); + TEST_STRTOULL(" +15", 10, 15LLU, 5, 0); + TEST_STRTOULL("+15", 0, 15LLU, 3, 0); + TEST_STRTOULL(" +15 ", 0, 15LLU, 4, 0); + TEST_STRTOULL("-15", 10, 18446744073709551601LLU, 3, 0); + TEST_STRTOULL(" -15", 10, 18446744073709551601LLU, 5, 0); + TEST_STRTOULL("-15", 0, 18446744073709551601LLU, 3, 0); + TEST_STRTOULL(" -15 ", 0, 18446744073709551601LLU, 4, 0); + TEST_STRTOULL("015", 10, 15LLU, 3, 0); + TEST_STRTOULL(" 015", 10, 15LLU, 5, 0); + TEST_STRTOULL("015", 0, 13LLU, 3, 0); + TEST_STRTOULL(" 015", 0, 13LLU, 5, 0); + TEST_STRTOULL("0x15", 10, 0LLU, 1, 0); + TEST_STRTOULL(" 0x15", 10, 0LLU, 3, 0); + TEST_STRTOULL("0x15", 0, 21LLU, 4, 0); + TEST_STRTOULL(" 0x15", 0, 21LLU, 6, 0); + + TEST_STRTOULL("10", 16, 16LLU, 2, 0); + TEST_STRTOULL(" 10 ", 16, 16LLU, 4, 0); + TEST_STRTOULL("0x10", 16, 16LLU, 4, 0); + TEST_STRTOULL("0x10", 0, 16LLU, 4, 0); + TEST_STRTOULL(" 0x10 ", 0, 16LLU, 5, 0); + TEST_STRTOULL("+10", 16, 16LLU, 3, 0); + TEST_STRTOULL(" +10 ", 16, 16LLU, 5, 0); + TEST_STRTOULL("+0x10", 16, 16LLU, 5, 0); + TEST_STRTOULL("+0x10", 0, 16LLU, 5, 0); + TEST_STRTOULL(" +0x10 ", 0, 16LLU, 6, 0); + TEST_STRTOULL("-10", 16, -16LLU, 3, 0); + TEST_STRTOULL(" -10 ", 16, -16LLU, 5, 0); + TEST_STRTOULL("-0x10", 16, -16LLU, 5, 0); + TEST_STRTOULL("-0x10", 0, -16LLU, 5, 0); + TEST_STRTOULL(" -0x10 ", 0, -16LLU, 6, 0); + TEST_STRTOULL("010", 16, 16LLU, 3, 0); + TEST_STRTOULL(" 010 ", 16, 16LLU, 5, 0); + TEST_STRTOULL("-010", 16, -16LLU, 4, 0); + + TEST_STRTOULL("11", 8, 9LLU, 2, 0); + TEST_STRTOULL("011", 8, 9LLU, 3, 0); + TEST_STRTOULL("011", 0, 9LLU, 3, 0); + TEST_STRTOULL("-11", 8, -9LLU, 3, 0); + TEST_STRTOULL("-011", 8, -9LLU, 4, 0); + TEST_STRTOULL("-011", 0, -9LLU, 4, 0); + + TEST_STRTOULL("011", 8, 9LLU, 3, 0); + TEST_STRTOULL("011", 0, 9LLU, 3, 0); + TEST_STRTOULL("-11", 8, -9LLU, 3, 0); + TEST_STRTOULL("-011", 8, -9LLU, 4, 0); + TEST_STRTOULL("-011", 0, -9LLU, 4, 0); + + TEST_STRTOULL("Text", 0, 0LLU, 0, 0); + + TEST_STRTOULL("9223372036854775807", 10, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("9223372036854775807", 0, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("9223372036854775808", 0, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("9223372036854775808", 10, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LLU, 18, 0); + TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 18, 0); + TEST_STRTOULL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 16, 0); + TEST_STRTOULL("0x8000000000000000", 0, 9223372036854775808LLU, 18, 0); + TEST_STRTOULL("0x8000000000000000", 16, 9223372036854775808LLU, 18, 0); + TEST_STRTOULL("8000000000000000", 16, 9223372036854775808LLU, 16, 0); + TEST_STRTOULL("0777777777777777777777", 0, 9223372036854775807LLU, 22, 0); + TEST_STRTOULL("0777777777777777777777", 8, 9223372036854775807LLU, 22, 0); + TEST_STRTOULL("777777777777777777777", 8, 9223372036854775807LLU, 21, 0); + TEST_STRTOULL("01000000000000000000000",0, 9223372036854775808LLU, 23, 0); + TEST_STRTOULL("01000000000000000000000",8, 9223372036854775808LLU, 23, 0); + TEST_STRTOULL("1000000000000000000000", 8, 9223372036854775808LLU, 22, 0); + + TEST_STRTOULL("-9223372036854775808", 10, 9223372036854775808LLU, 20, 0); + TEST_STRTOULL("-9223372036854775808", 0, 9223372036854775808LLU, 20, 0); + TEST_STRTOULL("-9223372036854775809", 0, 9223372036854775807LLU, 20, 0); + TEST_STRTOULL("-9223372036854775809", 10, 9223372036854775807LLU, 20, 0); + TEST_STRTOULL("-0x8000000000000000", 0, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("-0x8000000000000000", 16, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("-8000000000000000", 16, 9223372036854775808LLU, 17, 0); + TEST_STRTOULL("-0x8000000000000001", 0, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("-0x8000000000000001", 16, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("-8000000000000001", 16, 9223372036854775807LLU, 17, 0); + TEST_STRTOULL("-01000000000000000000000",0, 9223372036854775808LLU, 24, 0); + TEST_STRTOULL("-01000000000000000000000",8, 9223372036854775808LLU, 24, 0); + TEST_STRTOULL("-1000000000000000000000",8, 9223372036854775808LLU, 23, 0); + TEST_STRTOULL("-01000000000000000000001",0, 9223372036854775807LLU, 24, 0); + TEST_STRTOULL("-01000000000000000000001",8, 9223372036854775807LLU, 24, 0); + TEST_STRTOULL("-1000000000000000000001",8, 9223372036854775807LLU, 23, 0); + + TEST_STRTOULL("18446744073709551615", 0, 18446744073709551615LLU, 20, 0); + TEST_STRTOULL("18446744073709551615", 10, 18446744073709551615LLU, 20, 0); + TEST_STRTOULL("18446744073709551616", 0, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("18446744073709551616", 10, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 0, 18446744073709551615LLU, 18, 0); + TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 18, 0); + TEST_STRTOULL("FFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 16, 0); + TEST_STRTOULL("0x10000000000000000", 0, 18446744073709551615LLU, 19, ERANGE); + TEST_STRTOULL("0x10000000000000000", 16, 18446744073709551615LLU, 19, ERANGE); + TEST_STRTOULL("10000000000000000", 16, 18446744073709551615LLU, 17, ERANGE); + TEST_STRTOULL("01777777777777777777777",0, 18446744073709551615LLU, 23, 0); + TEST_STRTOULL("01777777777777777777777",8, 18446744073709551615LLU, 23, 0); + TEST_STRTOULL("1777777777777777777777", 8, 18446744073709551615LLU, 22, 0); + TEST_STRTOULL("02000000000000000000000",0, 18446744073709551615LLU, 23, ERANGE); + TEST_STRTOULL("02000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); + TEST_STRTOULL("2000000000000000000000", 8, 18446744073709551615LLU, 22, ERANGE); + + TEST_STRTOULL("-18446744073709551615", 0, 1LLU, 21, 0); + TEST_STRTOULL("-18446744073709551615", 10, 1LLU, 21, 0); + TEST_STRTOULL("-18446744073709551616", 0, 18446744073709551615LLU, 21, ERANGE); + TEST_STRTOULL("-18446744073709551616", 10, 18446744073709551615LLU, 21, ERANGE); + TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 0, 1LLU, 19, 0); + TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 16, 1LLU, 19, 0); + TEST_STRTOULL("-FFFFFFFFFFFFFFFF", 16, 1LLU, 17, 0); + TEST_STRTOULL("-0x10000000000000000", 0, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("-0x10000000000000000", 16, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("-10000000000000000", 16, 18446744073709551615LLU, 18, ERANGE); + TEST_STRTOULL("-01777777777777777777777",0, 1LLU, 24, 0); + TEST_STRTOULL("-01777777777777777777777",8, 1LLU, 24, 0); + TEST_STRTOULL("-1777777777777777777777",8, 1LLU, 23, 0); + TEST_STRTOULL("-02000000000000000000000",0, 18446744073709551615LLU, 24, ERANGE); + TEST_STRTOULL("-02000000000000000000000",8, 18446744073709551615LLU, 24, ERANGE); + TEST_STRTOULL("-2000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); + + printf("success: strtoull\n"); + return true; +} + +/* +FIXME: +Types: +bool +socklen_t +uint_t +uint{8,16,32,64}_t +int{8,16,32,64}_t +intptr_t + +Constants: +PATH_NAME_MAX +UINT{16,32,64}_MAX +INT32_MAX +*/ + +static int test_va_copy(void) +{ + /* FIXME */ + return true; +} + +static int test_FUNCTION(void) +{ + printf("test: FUNCTION\n"); + if (strcmp(__FUNCTION__, "test_FUNCTION") != 0) { + printf("failure: FAILURE [\nFAILURE invalid\n]\n"); + return false; + } + printf("success: FUNCTION\n"); + return true; +} + +static int test_MIN(void) +{ + printf("test: MIN\n"); + if (MIN(20, 1) != 1) { + printf("failure: MIN [\nMIN invalid\n]\n"); + return false; + } + if (MIN(1, 20) != 1) { + printf("failure: MIN [\nMIN invalid\n]\n"); + return false; + } + printf("success: MIN\n"); + return true; +} + +static int test_MAX(void) +{ + printf("test: MAX\n"); + if (MAX(20, 1) != 20) { + printf("failure: MAX [\nMAX invalid\n]\n"); + return false; + } + if (MAX(1, 20) != 20) { + printf("failure: MAX [\nMAX invalid\n]\n"); + return false; + } + printf("success: MAX\n"); + return true; +} + +static int test_socketpair(void) +{ + int sock[2]; + char buf[20]; + + printf("test: socketpair\n"); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock) == -1) { + printf("failure: socketpair [\n" + "socketpair() failed\n" + "]\n"); + return false; + } + + if (write(sock[1], "automatisch", 12) == -1) { + printf("failure: socketpair [\n" + "write() failed: %s\n" + "]\n", strerror(errno)); + return false; + } + + if (read(sock[0], buf, 12) == -1) { + printf("failure: socketpair [\n" + "read() failed: %s\n" + "]\n", strerror(errno)); + return false; + } + + if (strcmp(buf, "automatisch") != 0) { + printf("failure: socketpair [\n" + "expected: automatisch, got: %s\n" + "]\n", buf); + return false; + } + + printf("success: socketpair\n"); + + return true; +} + +extern int libreplace_test_strptime(void); + +static int test_strptime(void) +{ + return libreplace_test_strptime(); +} + +extern int getifaddrs_test(void); + +static int test_getifaddrs(void) +{ + + printf("test: getifaddrs\n"); + + if (getifaddrs_test() != 0) { + printf("failure: getifaddrs\n"); + return false; + } + + printf("success: getifaddrs\n"); + return true; +} + +static int test_utime(void) +{ + struct utimbuf u; + struct stat st1, st2, st3; + int fd; + + printf("test: utime\n"); + unlink(TESTFILE); + + fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); + if (fd == -1) { + printf("failure: utime [\n" + "creating '%s' failed - %s\n]\n", + TESTFILE, strerror(errno)); + return false; + } + + if (fstat(fd, &st1) != 0) { + printf("failure: utime [\n" + "fstat (1) failed - %s\n]\n", + strerror(errno)); + return false; + } + + u.actime = st1.st_atime + 300; + u.modtime = st1.st_mtime - 300; + if (utime(TESTFILE, &u) != 0) { + printf("failure: utime [\n" + "utime(&u) failed - %s\n]\n", + strerror(errno)); + return false; + } + + if (fstat(fd, &st2) != 0) { + printf("failure: utime [\n" + "fstat (2) failed - %s\n]\n", + strerror(errno)); + return false; + } + + if (utime(TESTFILE, NULL) != 0) { + printf("failure: utime [\n" + "utime(NULL) failed - %s\n]\n", + strerror(errno)); + return false; + } + + if (fstat(fd, &st3) != 0) { + printf("failure: utime [\n" + "fstat (3) failed - %s\n]\n", + strerror(errno)); + return false; + } + +#define CMP_VAL(a,c,b) do { \ + if (a c b) { \ + printf("failure: utime [\n" \ + "%s: %s(%d) %s %s(%d)\n]\n", \ + __location__, \ + #a, (int)a, #c, #b, (int)b); \ + return false; \ + } \ +} while(0) +#define EQUAL_VAL(a,b) CMP_VAL(a,!=,b) +#define GREATER_VAL(a,b) CMP_VAL(a,<=,b) +#define LESSER_VAL(a,b) CMP_VAL(a,>=,b) + + EQUAL_VAL(st2.st_atime, st1.st_atime + 300); + EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); + LESSER_VAL(st3.st_atime, st2.st_atime); + GREATER_VAL(st3.st_mtime, st2.st_mtime); + +#undef CMP_VAL +#undef EQUAL_VAL +#undef GREATER_VAL +#undef LESSER_VAL + + unlink(TESTFILE); + printf("success: utime\n"); + return true; +} + +static int test_utimes(void) +{ + struct timeval tv[2]; + struct stat st1, st2; + int fd; + + printf("test: utimes\n"); + unlink(TESTFILE); + + fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); + if (fd == -1) { + printf("failure: utimes [\n" + "creating '%s' failed - %s\n]\n", + TESTFILE, strerror(errno)); + return false; + } + + if (fstat(fd, &st1) != 0) { + printf("failure: utimes [\n" + "fstat (1) failed - %s\n]\n", + strerror(errno)); + return false; + } + + ZERO_STRUCT(tv); + tv[0].tv_sec = st1.st_atime + 300; + tv[1].tv_sec = st1.st_mtime - 300; + if (utimes(TESTFILE, tv) != 0) { + printf("failure: utimes [\n" + "utimes(tv) failed - %s\n]\n", + strerror(errno)); + return false; + } + + if (fstat(fd, &st2) != 0) { + printf("failure: utimes [\n" + "fstat (2) failed - %s\n]\n", + strerror(errno)); + return false; + } + +#define EQUAL_VAL(a,b) do { \ + if (a != b) { \ + printf("failure: utimes [\n" \ + "%s: %s(%d) != %s(%d)\n]\n", \ + __location__, \ + #a, (int)a, #b, (int)b); \ + return false; \ + } \ +} while(0) + + EQUAL_VAL(st2.st_atime, st1.st_atime + 300); + EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); + +#undef EQUAL_VAL + + unlink(TESTFILE); + printf("success: utimes\n"); + return true; +} + +struct torture_context; +bool torture_local_replace(struct torture_context *ctx) +{ + bool ret = true; + ret &= test_ftruncate(); + ret &= test_strlcpy(); + ret &= test_strlcat(); + ret &= test_mktime(); + ret &= test_initgroups(); + ret &= test_memmove(); + ret &= test_strdup(); + ret &= test_setlinebuf(); + ret &= test_vsyslog(); + ret &= test_timegm(); + ret &= test_setenv(); + ret &= test_strndup(); + ret &= test_strnlen(); + ret &= test_waitpid(); + ret &= test_seteuid(); + ret &= test_setegid(); + ret &= test_asprintf(); + ret &= test_snprintf(); + ret &= test_vasprintf(); + ret &= test_vsnprintf(); + ret &= test_opendir(); + ret &= test_readdir(); + ret &= test_telldir(); + ret &= test_seekdir(); + ret &= test_dlopen(); + ret &= test_chroot(); + ret &= test_bzero(); + ret &= test_strerror(); + ret &= test_errno(); + ret &= test_mkdtemp(); + ret &= test_mkstemp(); + ret &= test_pread(); + ret &= test_pwrite(); + ret &= test_getpass(); + ret &= test_inet_ntoa(); + ret &= test_strtoll(); + ret &= test_strtoull(); + ret &= test_va_copy(); + ret &= test_FUNCTION(); + ret &= test_MIN(); + ret &= test_MAX(); + ret &= test_socketpair(); + ret &= test_strptime(); + ret &= test_getifaddrs(); + ret &= test_utime(); + ret &= test_utimes(); + + return ret; +} + +#if _SAMBA_BUILD_<4 +int main(void) +{ + bool ret = torture_local_replace(NULL); + if (ret) + return 0; + return -1; +} +#endif diff --git a/lib/replace/timegm.c b/lib/replace/timegm.c new file mode 100644 index 0000000000..395c684e11 --- /dev/null +++ b/lib/replace/timegm.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + */ + +/* + adapted for Samba4 by Andrew Tridgell +*/ + +#include "replace.h" +#include "system/time.h" + +static int is_leap(unsigned y) +{ + y += 1900; + return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); +} + +time_t rep_timegm(struct tm *tm) +{ + static const unsigned ndays[2][12] ={ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; + time_t res = 0; + unsigned i; + + if (tm->tm_mon > 12 || + tm->tm_mon < 0 || + tm->tm_mday > 31 || + tm->tm_min > 60 || + tm->tm_sec > 60 || + tm->tm_hour > 24) { + /* invalid tm structure */ + return 0; + } + + for (i = 70; i < tm->tm_year; ++i) + res += is_leap(i) ? 366 : 365; + + for (i = 0; i < tm->tm_mon; ++i) + res += ndays[is_leap(tm->tm_year)][i]; + res += tm->tm_mday - 1; + res *= 24; + res += tm->tm_hour; + res *= 60; + res += tm->tm_min; + res *= 60; + res += tm->tm_sec; + return res; +} diff --git a/lib/replace/timegm.m4 b/lib/replace/timegm.m4 new file mode 100644 index 0000000000..59f3ae0521 --- /dev/null +++ b/lib/replace/timegm.m4 @@ -0,0 +1 @@ +AC_CHECK_FUNCS(timegm,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} timegm.o"]) diff --git a/lib/replace/win32.m4 b/lib/replace/win32.m4 new file mode 100644 index 0000000000..eb364e2cb9 --- /dev/null +++ b/lib/replace/win32.m4 @@ -0,0 +1,20 @@ +AC_CHECK_HEADERS(direct.h windows.h winsock2.h ws2tcpip.h) + +####################################### +# Check for mkdir mode +AC_CACHE_CHECK( [whether mkdir supports mode], libreplace_cv_mkdir_has_mode, + AC_TRY_COMPILE([ + #include + #ifdef HAVE_DIRECT_H + #include + #endif],[ + mkdir("foo",0777); + return 0; + ], + libreplace_cv_mkdir_has_mode="yes", + libreplace_cv_mkdir_has_mode="no") ) + +if test "$libreplace_cv_mkdir_has_mode" = "yes" +then + AC_DEFINE(HAVE_MKDIR_MODE, 1, [Define if target mkdir supports mode option]) +fi diff --git a/lib/replace/win32_replace.h b/lib/replace/win32_replace.h new file mode 100644 index 0000000000..9901e72f6e --- /dev/null +++ b/lib/replace/win32_replace.h @@ -0,0 +1,159 @@ +#ifndef _WIN32_REPLACE_H +#define _WIN32_REPLACE_H + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +#ifdef HAVE_WINDOWS_H +#include +#endif + +/* Map BSD Socket errorcodes to the WSA errorcodes (if possible) */ + +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define ECONNREFUSED WSAECONNREFUSED +#define EINPROGRESS WSAEINPROGRESS +#define EMSGSIZE WSAEMSGSIZE +#define ENOBUFS WSAENOBUFS +#define ENOTSOCK WSAENOTSOCK +#define ENETUNREACH WSAENETUNREACH +#define ENOPROTOOPT WSAENOPROTOOPT +#define ENOTCONN WSAENOTCONN +#define ENOTSUP 134 + +/* We undefine the following constants due to conflicts with the w32api headers + * and the Windows Platform SDK/DDK. + */ + +#undef interface + +#undef ERROR_INVALID_PARAMETER +#undef ERROR_INSUFFICIENT_BUFFER +#undef ERROR_INVALID_DATATYPE + +#undef FILE_GENERIC_READ +#undef FILE_GENERIC_WRITE +#undef FILE_GENERIC_EXECUTE +#undef FILE_ATTRIBUTE_READONLY +#undef FILE_ATTRIBUTE_HIDDEN +#undef FILE_ATTRIBUTE_SYSTEM +#undef FILE_ATTRIBUTE_DIRECTORY +#undef FILE_ATTRIBUTE_ARCHIVE +#undef FILE_ATTRIBUTE_DEVICE +#undef FILE_ATTRIBUTE_NORMAL +#undef FILE_ATTRIBUTE_TEMPORARY +#undef FILE_ATTRIBUTE_REPARSE_POINT +#undef FILE_ATTRIBUTE_COMPRESSED +#undef FILE_ATTRIBUTE_OFFLINE +#undef FILE_ATTRIBUTE_ENCRYPTED +#undef FILE_FLAG_WRITE_THROUGH +#undef FILE_FLAG_NO_BUFFERING +#undef FILE_FLAG_RANDOM_ACCESS +#undef FILE_FLAG_SEQUENTIAL_SCAN +#undef FILE_FLAG_DELETE_ON_CLOSE +#undef FILE_FLAG_BACKUP_SEMANTICS +#undef FILE_FLAG_POSIX_SEMANTICS +#undef FILE_TYPE_DISK +#undef FILE_TYPE_UNKNOWN +#undef FILE_CASE_SENSITIVE_SEARCH +#undef FILE_CASE_PRESERVED_NAMES +#undef FILE_UNICODE_ON_DISK +#undef FILE_PERSISTENT_ACLS +#undef FILE_FILE_COMPRESSION +#undef FILE_VOLUME_QUOTAS +#undef FILE_VOLUME_IS_COMPRESSED +#undef FILE_NOTIFY_CHANGE_FILE_NAME +#undef FILE_NOTIFY_CHANGE_DIR_NAME +#undef FILE_NOTIFY_CHANGE_ATTRIBUTES +#undef FILE_NOTIFY_CHANGE_SIZE +#undef FILE_NOTIFY_CHANGE_LAST_WRITE +#undef FILE_NOTIFY_CHANGE_LAST_ACCESS +#undef FILE_NOTIFY_CHANGE_CREATION +#undef FILE_NOTIFY_CHANGE_EA +#undef FILE_NOTIFY_CHANGE_SECURITY +#undef FILE_NOTIFY_CHANGE_STREAM_NAME +#undef FILE_NOTIFY_CHANGE_STREAM_SIZE +#undef FILE_NOTIFY_CHANGE_STREAM_WRITE +#undef FILE_NOTIFY_CHANGE_NAME + +#undef PRINTER_ATTRIBUTE_QUEUED +#undef PRINTER_ATTRIBUTE_DIRECT +#undef PRINTER_ATTRIBUTE_DEFAULT +#undef PRINTER_ATTRIBUTE_SHARED +#undef PRINTER_ATTRIBUTE_NETWORK +#undef PRINTER_ATTRIBUTE_HIDDEN +#undef PRINTER_ATTRIBUTE_LOCAL +#undef PRINTER_ATTRIBUTE_ENABLE_DEVQ +#undef PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS +#undef PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST +#undef PRINTER_ATTRIBUTE_WORK_OFFLINE +#undef PRINTER_ATTRIBUTE_ENABLE_BIDI +#undef PRINTER_ATTRIBUTE_RAW_ONLY +#undef PRINTER_ATTRIBUTE_PUBLISHED +#undef PRINTER_ENUM_DEFAULT +#undef PRINTER_ENUM_LOCAL +#undef PRINTER_ENUM_CONNECTIONS +#undef PRINTER_ENUM_FAVORITE +#undef PRINTER_ENUM_NAME +#undef PRINTER_ENUM_REMOTE +#undef PRINTER_ENUM_SHARED +#undef PRINTER_ENUM_NETWORK +#undef PRINTER_ENUM_EXPAND +#undef PRINTER_ENUM_CONTAINER +#undef PRINTER_ENUM_ICON1 +#undef PRINTER_ENUM_ICON2 +#undef PRINTER_ENUM_ICON3 +#undef PRINTER_ENUM_ICON4 +#undef PRINTER_ENUM_ICON5 +#undef PRINTER_ENUM_ICON6 +#undef PRINTER_ENUM_ICON7 +#undef PRINTER_ENUM_ICON8 +#undef PRINTER_STATUS_PAUSED +#undef PRINTER_STATUS_ERROR +#undef PRINTER_STATUS_PENDING_DELETION +#undef PRINTER_STATUS_PAPER_JAM +#undef PRINTER_STATUS_PAPER_OUT +#undef PRINTER_STATUS_MANUAL_FEED +#undef PRINTER_STATUS_PAPER_PROBLEM +#undef PRINTER_STATUS_OFFLINE +#undef PRINTER_STATUS_IO_ACTIVE +#undef PRINTER_STATUS_BUSY +#undef PRINTER_STATUS_PRINTING +#undef PRINTER_STATUS_OUTPUT_BIN_FULL +#undef PRINTER_STATUS_NOT_AVAILABLE +#undef PRINTER_STATUS_WAITING +#undef PRINTER_STATUS_PROCESSING +#undef PRINTER_STATUS_INITIALIZING +#undef PRINTER_STATUS_WARMING_UP +#undef PRINTER_STATUS_TONER_LOW +#undef PRINTER_STATUS_NO_TONER +#undef PRINTER_STATUS_PAGE_PUNT +#undef PRINTER_STATUS_USER_INTERVENTION +#undef PRINTER_STATUS_OUT_OF_MEMORY +#undef PRINTER_STATUS_DOOR_OPEN +#undef PRINTER_STATUS_SERVER_UNKNOWN +#undef PRINTER_STATUS_POWER_SAVE + +#undef DWORD +#undef HKEY_CLASSES_ROOT +#undef HKEY_CURRENT_USER +#undef HKEY_LOCAL_MACHINE +#undef HKEY_USERS +#undef HKEY_PERFORMANCE_DATA +#undef HKEY_CURRENT_CONFIG +#undef HKEY_DYN_DATA +#undef REG_DWORD +#undef REG_QWORD + +#undef SERVICE_STATE_ALL + +#undef SE_GROUP_MANDATORY +#undef SE_GROUP_ENABLED_BY_DEFAULT +#undef SE_GROUP_ENABLED + +#endif /* _WIN32_REPLACE_H */ diff --git a/lib/socket_wrapper/config.m4 b/lib/socket_wrapper/config.m4 new file mode 100644 index 0000000000..68e392b3e7 --- /dev/null +++ b/lib/socket_wrapper/config.m4 @@ -0,0 +1,22 @@ +AC_ARG_ENABLE(socket-wrapper, +[ --enable-socket-wrapper Turn on socket wrapper library (default=no)]) + +DEFAULT_TEST_OPTIONS= +HAVE_SOCKET_WRAPPER=no + +if eval "test x$developer = xyes"; then + enable_socket_wrapper=yes +fi + +if eval "test x$enable_socket_wrapper = xyes"; then + AC_DEFINE(SOCKET_WRAPPER,1,[Use socket wrapper library]) + DEFAULT_TEST_OPTIONS=--socket-wrapper + HAVE_SOCKET_WRAPPER=yes + + # this is only used for samba3 + SOCKET_WRAPPER_OBJS="../lib/socket_wrapper/socket_wrapper.o" +fi + +AC_SUBST(DEFAULT_TEST_OPTIONS) +AC_SUBST(HAVE_SOCKET_WRAPPER) +AC_SUBST(SOCKET_WRAPPER_OBJS) diff --git a/lib/socket_wrapper/config.mk b/lib/socket_wrapper/config.mk new file mode 100644 index 0000000000..60cfb3209a --- /dev/null +++ b/lib/socket_wrapper/config.mk @@ -0,0 +1,8 @@ +############################## +# Start SUBSYSTEM SOCKET_WRAPPER +[SUBSYSTEM::SOCKET_WRAPPER] +PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK +# End SUBSYSTEM SOCKET_WRAPPER +############################## + +SOCKET_WRAPPER_OBJ_FILES = $(socketwrappersrcdir)/socket_wrapper.o diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c new file mode 100644 index 0000000000..e8d27adc37 --- /dev/null +++ b/lib/socket_wrapper/socket_wrapper.c @@ -0,0 +1,1841 @@ +/* + * Copyright (C) Jelmer Vernooij 2005,2008 + * Copyright (C) Stefan Metzmacher 2006 + * + * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. + * + */ + +/* + Socket wrapper library. Passes all socket communication over + unix domain sockets if the environment variable SOCKET_WRAPPER_DIR + is set. +*/ + +#ifdef _SAMBA_BUILD_ + +#define SOCKET_WRAPPER_NOT_REPLACE +#include "../replace/replace.h" +#include "system/network.h" +#include "system/filesys.h" +#include "system/time.h" + +#else /* _SAMBA_BUILD_ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#ifndef _PUBLIC_ +#define _PUBLIC_ +#endif + +#define SWRAP_DLIST_ADD(list,item) do { \ + if (!(list)) { \ + (item)->prev = NULL; \ + (item)->next = NULL; \ + (list) = (item); \ + } else { \ + (item)->prev = NULL; \ + (item)->next = (list); \ + (list)->prev = (item); \ + (list) = (item); \ + } \ +} while (0) + +#define SWRAP_DLIST_REMOVE(list,item) do { \ + if ((list) == (item)) { \ + (list) = (item)->next; \ + if (list) { \ + (list)->prev = NULL; \ + } \ + } else { \ + if ((item)->prev) { \ + (item)->prev->next = (item)->next; \ + } \ + if ((item)->next) { \ + (item)->next->prev = (item)->prev; \ + } \ + } \ + (item)->prev = NULL; \ + (item)->next = NULL; \ +} while (0) + +/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support + * for now */ +#define REWRITE_CALLS + +#ifdef REWRITE_CALLS +#define real_accept accept +#define real_connect connect +#define real_bind bind +#define real_listen listen +#define real_getpeername getpeername +#define real_getsockname getsockname +#define real_getsockopt getsockopt +#define real_setsockopt setsockopt +#define real_recvfrom recvfrom +#define real_sendto sendto +#define real_ioctl ioctl +#define real_recv recv +#define real_send send +#define real_socket socket +#define real_close close +#endif + +#ifdef HAVE_GETTIMEOFDAY_TZ +#define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL) +#else +#define swrapGetTimeOfDay(tval) gettimeofday(tval) +#endif + +/* we need to use a very terse format here as IRIX 6.4 silently + truncates names to 16 chars, so if we use a longer name then we + can't tell which port a packet came from with recvfrom() + + with this format we have 8 chars left for the directory name +*/ +#define SOCKET_FORMAT "%c%02X%04X" +#define SOCKET_TYPE_CHAR_TCP 'T' +#define SOCKET_TYPE_CHAR_UDP 'U' +#define SOCKET_TYPE_CHAR_TCP_V6 'X' +#define SOCKET_TYPE_CHAR_UDP_V6 'Y' + +#define MAX_WRAPPED_INTERFACES 16 + +#define SW_IPV6_ADDRESS 1 + +static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) +{ + struct sockaddr *ret = (struct sockaddr *)malloc(len); + memcpy(ret, data, len); + return ret; +} + +static void set_port(int family, int prt, struct sockaddr *addr) +{ + switch (family) { + case AF_INET: + ((struct sockaddr_in *)addr)->sin_port = htons(prt); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt); + break; +#endif + } +} + +static size_t socket_length(int family) +{ + switch (family) { + case AF_INET: + return sizeof(struct sockaddr_in); +#ifdef HAVE_IPV6 + case AF_INET6: + return sizeof(struct sockaddr_in6); +#endif + } + return 0; +} + + + +struct socket_info +{ + int fd; + + int family; + int type; + int protocol; + int bound; + int bcast; + int is_server; + + char *path; + char *tmp_path; + + struct sockaddr *myname; + socklen_t myname_len; + + struct sockaddr *peername; + socklen_t peername_len; + + struct { + unsigned long pck_snd; + unsigned long pck_rcv; + } io; + + struct socket_info *prev, *next; +}; + +static struct socket_info *sockets; + +const char *socket_wrapper_dir(void) +{ + const char *s = getenv("SOCKET_WRAPPER_DIR"); + if (s == NULL) { + return NULL; + } + if (strncmp(s, "./", 2) == 0) { + s += 2; + } + return s; +} + +unsigned int socket_wrapper_default_iface(void) +{ + const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); + if (s) { + unsigned int iface; + if (sscanf(s, "%u", &iface) == 1) { + if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { + return iface; + } + } + } + + return 1;/* 127.0.0.1 */ +} + +static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len) +{ + unsigned int iface; + unsigned int prt; + const char *p; + char type; + + p = strrchr(un->sun_path, '/'); + if (p) p++; else p = un->sun_path; + + if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) { + errno = EINVAL; + return -1; + } + + if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { + errno = EINVAL; + return -1; + } + + if (prt > 0xFFFF) { + errno = EINVAL; + return -1; + } + + switch(type) { + case SOCKET_TYPE_CHAR_TCP: + case SOCKET_TYPE_CHAR_UDP: { + struct sockaddr_in *in2 = (struct sockaddr_in *)in; + + if ((*len) < sizeof(*in2)) { + errno = EINVAL; + return -1; + } + + memset(in2, 0, sizeof(*in2)); + in2->sin_family = AF_INET; + in2->sin_addr.s_addr = htonl((127<<24) | iface); + in2->sin_port = htons(prt); + + *len = sizeof(*in2); + break; + } +#ifdef HAVE_IPV6 + case SOCKET_TYPE_CHAR_TCP_V6: + case SOCKET_TYPE_CHAR_UDP_V6: { + struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in; + + if ((*len) < sizeof(*in2)) { + errno = EINVAL; + return -1; + } + + memset(in2, 0, sizeof(*in2)); + in2->sin6_family = AF_INET6; + in2->sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS; + in2->sin6_port = htons(prt); + + *len = sizeof(*in2); + break; + } +#endif + default: + errno = EINVAL; + return -1; + } + + return 0; +} + +static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un, + int *bcast) +{ + char type = '\0'; + unsigned int prt; + unsigned int iface; + int is_bcast = 0; + + if (bcast) *bcast = 0; + + switch (si->family) { + case AF_INET: { + const struct sockaddr_in *in = + (const struct sockaddr_in *)inaddr; + unsigned int addr = ntohl(in->sin_addr.s_addr); + char u_type = '\0'; + char b_type = '\0'; + char a_type = '\0'; + + switch (si->type) { + case SOCK_STREAM: + u_type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + u_type = SOCKET_TYPE_CHAR_UDP; + a_type = SOCKET_TYPE_CHAR_UDP; + b_type = SOCKET_TYPE_CHAR_UDP; + break; + } + + prt = ntohs(in->sin_port); + if (a_type && addr == 0xFFFFFFFF) { + /* 255.255.255.255 only udp */ + is_bcast = 2; + type = a_type; + iface = socket_wrapper_default_iface(); + } else if (b_type && addr == 0x7FFFFFFF) { + /* 127.255.255.255 only udp */ + is_bcast = 1; + type = b_type; + iface = socket_wrapper_default_iface(); + } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + /* 127.0.0.X */ + is_bcast = 0; + type = u_type; + iface = (addr & 0x000000FF); + } else { + errno = ENETUNREACH; + return -1; + } + if (bcast) *bcast = is_bcast; + break; + } +#ifdef HAVE_IPV6 + case AF_INET6: { + const struct sockaddr_in6 *in = + (const struct sockaddr_in6 *)inaddr; + + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP_V6; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP_V6; + break; + } + + /* XXX no multicast/broadcast */ + + prt = ntohs(in->sin6_port); + iface = SW_IPV6_ADDRESS; + + break; + } +#endif + default: + errno = ENETUNREACH; + return -1; + } + + if (prt == 0) { + errno = EINVAL; + return -1; + } + + if (is_bcast) { + snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", + socket_wrapper_dir()); + /* the caller need to do more processing */ + return 0; + } + + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, iface, prt); + + return 0; +} + +static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un, + int *bcast) +{ + char type = '\0'; + unsigned int prt; + unsigned int iface; + struct stat st; + int is_bcast = 0; + + if (bcast) *bcast = 0; + + switch (si->family) { + case AF_INET: { + const struct sockaddr_in *in = + (const struct sockaddr_in *)inaddr; + unsigned int addr = ntohl(in->sin_addr.s_addr); + char u_type = '\0'; + char d_type = '\0'; + char b_type = '\0'; + char a_type = '\0'; + + prt = ntohs(in->sin_port); + + switch (si->type) { + case SOCK_STREAM: + u_type = SOCKET_TYPE_CHAR_TCP; + d_type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + u_type = SOCKET_TYPE_CHAR_UDP; + d_type = SOCKET_TYPE_CHAR_UDP; + a_type = SOCKET_TYPE_CHAR_UDP; + b_type = SOCKET_TYPE_CHAR_UDP; + break; + } + + if (addr == 0) { + /* 0.0.0.0 */ + is_bcast = 0; + type = d_type; + iface = socket_wrapper_default_iface(); + } else if (a_type && addr == 0xFFFFFFFF) { + /* 255.255.255.255 only udp */ + is_bcast = 2; + type = a_type; + iface = socket_wrapper_default_iface(); + } else if (b_type && addr == 0x7FFFFFFF) { + /* 127.255.255.255 only udp */ + is_bcast = 1; + type = b_type; + iface = socket_wrapper_default_iface(); + } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + /* 127.0.0.X */ + is_bcast = 0; + type = u_type; + iface = (addr & 0x000000FF); + } else { + errno = EADDRNOTAVAIL; + return -1; + } + break; + } +#ifdef HAVE_IPV6 + case AF_INET6: { + const struct sockaddr_in6 *in = + (const struct sockaddr_in6 *)inaddr; + + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP_V6; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP_V6; + break; + } + + /* XXX no multicast/broadcast */ + + prt = ntohs(in->sin6_port); + iface = SW_IPV6_ADDRESS; + + break; + } +#endif + default: + errno = ENETUNREACH; + return -1; + } + + + if (bcast) *bcast = is_bcast; + + if (prt == 0) { + /* handle auto-allocation of ephemeral ports */ + for (prt = 5001; prt < 10000; prt++) { + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, iface, prt); + if (stat(un->sun_path, &st) == 0) continue; + + set_port(si->family, prt, si->myname); + break; + } + if (prt == 10000) { + errno = ENFILE; + return -1; + } + } + + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, iface, prt); + return 0; +} + +static struct socket_info *find_socket_info(int fd) +{ + struct socket_info *i; + for (i = sockets; i; i = i->next) { + if (i->fd == fd) + return i; + } + + return NULL; +} + +static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, + struct sockaddr_un *out_addr, int alloc_sock, int *bcast) +{ + if (!out_addr) + return 0; + + out_addr->sun_family = AF_UNIX; + + switch (in_addr->sa_family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + switch (si->type) { + case SOCK_STREAM: + case SOCK_DGRAM: + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + if (alloc_sock) { + return convert_in_un_alloc(si, in_addr, out_addr, bcast); + } else { + return convert_in_un_remote(si, in_addr, out_addr, bcast); + } + default: + break; + } + + errno = EAFNOSUPPORT; + return -1; +} + +static int sockaddr_convert_from_un(const struct socket_info *si, + const struct sockaddr_un *in_addr, + socklen_t un_addrlen, + int family, + struct sockaddr *out_addr, + socklen_t *out_addrlen) +{ + if (out_addr == NULL || out_addrlen == NULL) + return 0; + + if (un_addrlen == 0) { + *out_addrlen = 0; + return 0; + } + + switch (family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + switch (si->type) { + case SOCK_STREAM: + case SOCK_DGRAM: + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + return convert_un_in(in_addr, out_addr, out_addrlen); + default: + break; + } + + errno = EAFNOSUPPORT; + return -1; +} + +enum swrap_packet_type { + SWRAP_CONNECT_SEND, + SWRAP_CONNECT_UNREACH, + SWRAP_CONNECT_RECV, + SWRAP_CONNECT_ACK, + SWRAP_ACCEPT_SEND, + SWRAP_ACCEPT_RECV, + SWRAP_ACCEPT_ACK, + SWRAP_RECVFROM, + SWRAP_SENDTO, + SWRAP_SENDTO_UNREACH, + SWRAP_PENDING_RST, + SWRAP_RECV, + SWRAP_RECV_RST, + SWRAP_SEND, + SWRAP_SEND_RST, + SWRAP_CLOSE_SEND, + SWRAP_CLOSE_RECV, + SWRAP_CLOSE_ACK +}; + +struct swrap_file_hdr { + uint32_t magic; + uint16_t version_major; + uint16_t version_minor; + int32_t timezone; + uint32_t sigfigs; + uint32_t frame_max_len; +#define SWRAP_FRAME_LENGTH_MAX 0xFFFF + uint32_t link_type; +}; +#define SWRAP_FILE_HDR_SIZE 24 + +struct swrap_packet { + struct { + uint32_t seconds; + uint32_t micro_seconds; + uint32_t recorded_length; + uint32_t full_length; + } frame; +#define SWRAP_PACKET__FRAME_SIZE 16 + + struct { + struct { + uint8_t ver_hdrlen; + uint8_t tos; + uint16_t packet_length; + uint16_t identification; + uint8_t flags; + uint8_t fragment; + uint8_t ttl; + uint8_t protocol; + uint16_t hdr_checksum; + uint32_t src_addr; + uint32_t dest_addr; + } hdr; +#define SWRAP_PACKET__IP_HDR_SIZE 20 + + union { + struct { + uint16_t source_port; + uint16_t dest_port; + uint32_t seq_num; + uint32_t ack_num; + uint8_t hdr_length; + uint8_t control; + uint16_t window; + uint16_t checksum; + uint16_t urg; + } tcp; +#define SWRAP_PACKET__IP_P_TCP_SIZE 20 + struct { + uint16_t source_port; + uint16_t dest_port; + uint16_t length; + uint16_t checksum; + } udp; +#define SWRAP_PACKET__IP_P_UDP_SIZE 8 + struct { + uint8_t type; + uint8_t code; + uint16_t checksum; + uint32_t unused; + } icmp; +#define SWRAP_PACKET__IP_P_ICMP_SIZE 8 + } p; + } ip; +}; +#define SWRAP_PACKET_SIZE 56 + +static const char *socket_wrapper_pcap_file(void) +{ + static int initialized = 0; + static const char *s = NULL; + static const struct swrap_file_hdr h = { 0, }; + static const struct swrap_packet p = { { 0, }, { { 0, }, { { 0, } } } }; + + if (initialized == 1) { + return s; + } + initialized = 1; + + /* + * TODO: don't use the structs use plain buffer offsets + * and PUSH_U8(), PUSH_U16() and PUSH_U32() + * + * for now make sure we disable PCAP support + * if the struct has alignment! + */ + if (sizeof(h) != SWRAP_FILE_HDR_SIZE) { + return NULL; + } + if (sizeof(p) != SWRAP_PACKET_SIZE) { + return NULL; + } + if (sizeof(p.frame) != SWRAP_PACKET__FRAME_SIZE) { + return NULL; + } + if (sizeof(p.ip.hdr) != SWRAP_PACKET__IP_HDR_SIZE) { + return NULL; + } + if (sizeof(p.ip.p.tcp) != SWRAP_PACKET__IP_P_TCP_SIZE) { + return NULL; + } + if (sizeof(p.ip.p.udp) != SWRAP_PACKET__IP_P_UDP_SIZE) { + return NULL; + } + if (sizeof(p.ip.p.icmp) != SWRAP_PACKET__IP_P_ICMP_SIZE) { + return NULL; + } + + s = getenv("SOCKET_WRAPPER_PCAP_FILE"); + if (s == NULL) { + return NULL; + } + if (strncmp(s, "./", 2) == 0) { + s += 2; + } + return s; +} + +static struct swrap_packet *swrap_packet_init(struct timeval *tval, + const struct sockaddr_in *src_addr, + const struct sockaddr_in *dest_addr, + int socket_type, + const unsigned char *payload, + size_t payload_len, + unsigned long tcp_seq, + unsigned long tcp_ack, + unsigned char tcp_ctl, + int unreachable, + size_t *_packet_len) +{ + struct swrap_packet *ret; + struct swrap_packet *packet; + size_t packet_len; + size_t alloc_len; + size_t nonwire_len = sizeof(packet->frame); + size_t wire_hdr_len = 0; + size_t wire_len = 0; + size_t icmp_hdr_len = 0; + size_t icmp_truncate_len = 0; + unsigned char protocol = 0, icmp_protocol = 0; + unsigned short src_port = src_addr->sin_port; + unsigned short dest_port = dest_addr->sin_port; + + switch (socket_type) { + case SOCK_STREAM: + protocol = 0x06; /* TCP */ + wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.tcp); + wire_len = wire_hdr_len + payload_len; + break; + + case SOCK_DGRAM: + protocol = 0x11; /* UDP */ + wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp); + wire_len = wire_hdr_len + payload_len; + break; + + default: + return NULL; + } + + if (unreachable) { + icmp_protocol = protocol; + protocol = 0x01; /* ICMP */ + if (wire_len > 64 ) { + icmp_truncate_len = wire_len - 64; + } + icmp_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.icmp); + wire_hdr_len += icmp_hdr_len; + wire_len += icmp_hdr_len; + } + + packet_len = nonwire_len + wire_len; + alloc_len = packet_len; + if (alloc_len < sizeof(struct swrap_packet)) { + alloc_len = sizeof(struct swrap_packet); + } + ret = (struct swrap_packet *)malloc(alloc_len); + if (!ret) return NULL; + + packet = ret; + + packet->frame.seconds = tval->tv_sec; + packet->frame.micro_seconds = tval->tv_usec; + packet->frame.recorded_length = wire_len - icmp_truncate_len; + packet->frame.full_length = wire_len - icmp_truncate_len; + + packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ + packet->ip.hdr.tos = 0x00; + packet->ip.hdr.packet_length = htons(wire_len - icmp_truncate_len); + packet->ip.hdr.identification = htons(0xFFFF); + packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ + packet->ip.hdr.fragment = htons(0x0000); + packet->ip.hdr.ttl = 0xFF; + packet->ip.hdr.protocol = protocol; + packet->ip.hdr.hdr_checksum = htons(0x0000); + packet->ip.hdr.src_addr = src_addr->sin_addr.s_addr; + packet->ip.hdr.dest_addr = dest_addr->sin_addr.s_addr; + + if (unreachable) { + packet->ip.p.icmp.type = 0x03; /* destination unreachable */ + packet->ip.p.icmp.code = 0x01; /* host unreachable */ + packet->ip.p.icmp.checksum = htons(0x0000); + packet->ip.p.icmp.unused = htonl(0x00000000); + + /* set the ip header in the ICMP payload */ + packet = (struct swrap_packet *)(((unsigned char *)ret) + icmp_hdr_len); + packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ + packet->ip.hdr.tos = 0x00; + packet->ip.hdr.packet_length = htons(wire_len - icmp_hdr_len); + packet->ip.hdr.identification = htons(0xFFFF); + packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ + packet->ip.hdr.fragment = htons(0x0000); + packet->ip.hdr.ttl = 0xFF; + packet->ip.hdr.protocol = icmp_protocol; + packet->ip.hdr.hdr_checksum = htons(0x0000); + packet->ip.hdr.src_addr = dest_addr->sin_addr.s_addr; + packet->ip.hdr.dest_addr = src_addr->sin_addr.s_addr; + + src_port = dest_addr->sin_port; + dest_port = src_addr->sin_port; + } + + switch (socket_type) { + case SOCK_STREAM: + packet->ip.p.tcp.source_port = src_port; + packet->ip.p.tcp.dest_port = dest_port; + packet->ip.p.tcp.seq_num = htonl(tcp_seq); + packet->ip.p.tcp.ack_num = htonl(tcp_ack); + packet->ip.p.tcp.hdr_length = 0x50; /* 5 * 32 bit words */ + packet->ip.p.tcp.control = tcp_ctl; + packet->ip.p.tcp.window = htons(0x7FFF); + packet->ip.p.tcp.checksum = htons(0x0000); + packet->ip.p.tcp.urg = htons(0x0000); + + break; + + case SOCK_DGRAM: + packet->ip.p.udp.source_port = src_addr->sin_port; + packet->ip.p.udp.dest_port = dest_addr->sin_port; + packet->ip.p.udp.length = htons(8 + payload_len); + packet->ip.p.udp.checksum = htons(0x0000); + + break; + } + + if (payload && payload_len > 0) { + unsigned char *p = (unsigned char *)ret; + p += nonwire_len; + p += wire_hdr_len; + memcpy(p, payload, payload_len); + } + + *_packet_len = packet_len - icmp_truncate_len; + return ret; +} + +static int swrap_get_pcap_fd(const char *fname) +{ + static int fd = -1; + + if (fd != -1) return fd; + + fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644); + if (fd != -1) { + struct swrap_file_hdr file_hdr; + file_hdr.magic = 0xA1B2C3D4; + file_hdr.version_major = 0x0002; + file_hdr.version_minor = 0x0004; + file_hdr.timezone = 0x00000000; + file_hdr.sigfigs = 0x00000000; + file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX; + file_hdr.link_type = 0x0065; /* 101 RAW IP */ + + write(fd, &file_hdr, sizeof(file_hdr)); + return fd; + } + + fd = open(fname, O_WRONLY|O_APPEND, 0644); + + return fd; +} + +static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, + const struct sockaddr *addr, + enum swrap_packet_type type, + const void *buf, size_t len, + size_t *packet_len) +{ + const struct sockaddr_in *src_addr; + const struct sockaddr_in *dest_addr; + unsigned long tcp_seq = 0; + unsigned long tcp_ack = 0; + unsigned char tcp_ctl = 0; + int unreachable = 0; + + struct timeval tv; + + switch (si->family) { + case AF_INET: + break; + default: + return NULL; + } + + switch (type) { + case SWRAP_CONNECT_SEND: + if (si->type != SOCK_STREAM) return NULL; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x02; /* SYN */ + + si->io.pck_snd += 1; + + break; + + case SWRAP_CONNECT_RECV: + if (si->type != SOCK_STREAM) return NULL; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x12; /** SYN,ACK */ + + si->io.pck_rcv += 1; + + break; + + case SWRAP_CONNECT_UNREACH: + if (si->type != SOCK_STREAM) return NULL; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ + tcp_seq = si->io.pck_snd - 1; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x02; /* SYN */ + unreachable = 1; + + break; + + case SWRAP_CONNECT_ACK: + if (si->type != SOCK_STREAM) return NULL; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x10; /* ACK */ + + break; + + case SWRAP_ACCEPT_SEND: + if (si->type != SOCK_STREAM) return NULL; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x02; /* SYN */ + + si->io.pck_rcv += 1; + + break; + + case SWRAP_ACCEPT_RECV: + if (si->type != SOCK_STREAM) return NULL; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x12; /* SYN,ACK */ + + si->io.pck_snd += 1; + + break; + + case SWRAP_ACCEPT_ACK: + if (si->type != SOCK_STREAM) return NULL; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x10; /* ACK */ + + break; + + case SWRAP_SEND: + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x18; /* PSH,ACK */ + + si->io.pck_snd += len; + + break; + + case SWRAP_SEND_RST: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + if (si->type == SOCK_DGRAM) { + return swrap_marshall_packet(si, si->peername, + SWRAP_SENDTO_UNREACH, + buf, len, packet_len); + } + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x14; /** RST,ACK */ + + break; + + case SWRAP_PENDING_RST: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + if (si->type == SOCK_DGRAM) { + return NULL; + } + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x14; /* RST,ACK */ + + break; + + case SWRAP_RECV: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x18; /* PSH,ACK */ + + si->io.pck_rcv += len; + + break; + + case SWRAP_RECV_RST: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + if (si->type == SOCK_DGRAM) { + return NULL; + } + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x14; /* RST,ACK */ + + break; + + case SWRAP_SENDTO: + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)addr; + + si->io.pck_snd += len; + + break; + + case SWRAP_SENDTO_UNREACH: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + unreachable = 1; + + break; + + case SWRAP_RECVFROM: + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)addr; + + si->io.pck_rcv += len; + + break; + + case SWRAP_CLOSE_SEND: + if (si->type != SOCK_STREAM) return NULL; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x11; /* FIN, ACK */ + + si->io.pck_snd += 1; + + break; + + case SWRAP_CLOSE_RECV: + if (si->type != SOCK_STREAM) return NULL; + + dest_addr = (const struct sockaddr_in *)si->myname; + src_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_rcv; + tcp_ack = si->io.pck_snd; + tcp_ctl = 0x11; /* FIN,ACK */ + + si->io.pck_rcv += 1; + + break; + + case SWRAP_CLOSE_ACK: + if (si->type != SOCK_STREAM) return NULL; + + src_addr = (const struct sockaddr_in *)si->myname; + dest_addr = (const struct sockaddr_in *)si->peername; + + tcp_seq = si->io.pck_snd; + tcp_ack = si->io.pck_rcv; + tcp_ctl = 0x10; /* ACK */ + + break; + default: + return NULL; + } + + swrapGetTimeOfDay(&tv); + + return swrap_packet_init(&tv, src_addr, dest_addr, si->type, + (const unsigned char *)buf, len, + tcp_seq, tcp_ack, tcp_ctl, unreachable, + packet_len); +} + +static void swrap_dump_packet(struct socket_info *si, + const struct sockaddr *addr, + enum swrap_packet_type type, + const void *buf, size_t len) +{ + const char *file_name; + struct swrap_packet *packet; + size_t packet_len = 0; + int fd; + + file_name = socket_wrapper_pcap_file(); + if (!file_name) { + return; + } + + packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len); + if (!packet) { + return; + } + + fd = swrap_get_pcap_fd(file_name); + if (fd != -1) { + write(fd, packet, packet_len); + } + + free(packet); +} + +_PUBLIC_ int swrap_socket(int family, int type, int protocol) +{ + struct socket_info *si; + int fd; + + if (!socket_wrapper_dir()) { + return real_socket(family, type, protocol); + } + + switch (family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + break; + case AF_UNIX: + return real_socket(family, type, protocol); + default: + errno = EAFNOSUPPORT; + return -1; + } + + switch (type) { + case SOCK_STREAM: + break; + case SOCK_DGRAM: + break; + default: + errno = EPROTONOSUPPORT; + return -1; + } + + switch (protocol) { + case 0: + break; + case 6: + if (type == SOCK_STREAM) { + break; + } + /*fall through*/ + case 17: + if (type == SOCK_DGRAM) { + break; + } + /*fall through*/ + default: + errno = EPROTONOSUPPORT; + return -1; + } + + fd = real_socket(AF_UNIX, type, 0); + + if (fd == -1) return -1; + + si = (struct socket_info *)calloc(1, sizeof(struct socket_info)); + + si->family = family; + si->type = type; + si->protocol = protocol; + si->fd = fd; + + SWRAP_DLIST_ADD(sockets, si); + + return si->fd; +} + +_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct socket_info *parent_si, *child_si; + int fd; + struct sockaddr_un un_addr; + socklen_t un_addrlen = sizeof(un_addr); + struct sockaddr_un un_my_addr; + socklen_t un_my_addrlen = sizeof(un_my_addr); + struct sockaddr *my_addr; + socklen_t my_addrlen, len; + int ret; + + parent_si = find_socket_info(s); + if (!parent_si) { + return real_accept(s, addr, addrlen); + } + + /* + * assume out sockaddr have the same size as the in parent + * socket family + */ + my_addrlen = socket_length(parent_si->family); + if (my_addrlen <= 0) { + errno = EINVAL; + return -1; + } + + my_addr = (struct sockaddr *)malloc(my_addrlen); + if (my_addr == NULL) { + return -1; + } + + memset(&un_addr, 0, sizeof(un_addr)); + memset(&un_my_addr, 0, sizeof(un_my_addr)); + + ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); + if (ret == -1) { + free(my_addr); + return ret; + } + + fd = ret; + + len = my_addrlen; + ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, + parent_si->family, my_addr, &len); + if (ret == -1) { + free(my_addr); + close(fd); + return ret; + } + + child_si = (struct socket_info *)malloc(sizeof(struct socket_info)); + memset(child_si, 0, sizeof(*child_si)); + + child_si->fd = fd; + child_si->family = parent_si->family; + child_si->type = parent_si->type; + child_si->protocol = parent_si->protocol; + child_si->bound = 1; + child_si->is_server = 1; + + child_si->peername_len = len; + child_si->peername = sockaddr_dup(my_addr, len); + + if (addr != NULL && addrlen != NULL) { + *addrlen = len; + if (*addrlen >= len) + memcpy(addr, my_addr, len); + *addrlen = 0; + } + + ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); + if (ret == -1) { + free(child_si); + close(fd); + return ret; + } + + len = my_addrlen; + ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, + child_si->family, my_addr, &len); + if (ret == -1) { + free(child_si); + free(my_addr); + close(fd); + return ret; + } + + child_si->myname_len = len; + child_si->myname = sockaddr_dup(my_addr, len); + free(my_addr); + + SWRAP_DLIST_ADD(sockets, child_si); + + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0); + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0); + swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0); + + return fd; +} + +static int autobind_start_init; +static int autobind_start; + +/* using sendto() or connect() on an unbound socket would give the + recipient no way to reply, as unlike UDP and TCP, a unix domain + socket can't auto-assign emphemeral port numbers, so we need to + assign it here */ +static int swrap_auto_bind(struct socket_info *si) +{ + struct sockaddr_un un_addr; + int i; + char type; + int ret; + int port; + struct stat st; + + if (autobind_start_init != 1) { + autobind_start_init = 1; + autobind_start = getpid(); + autobind_start %= 50000; + autobind_start += 10000; + } + + un_addr.sun_family = AF_UNIX; + + switch (si->family) { + case AF_INET: { + struct sockaddr_in in; + + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP; + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + in.sin_addr.s_addr = htonl(127<<24 | + socket_wrapper_default_iface()); + + si->myname_len = sizeof(in); + si->myname = sockaddr_dup(&in, si->myname_len); + break; + } +#ifdef HAVE_IPV6 + case AF_INET6: { + struct sockaddr_in6 in6; + + switch (si->type) { + case SOCK_STREAM: + type = SOCKET_TYPE_CHAR_TCP_V6; + break; + case SOCK_DGRAM: + type = SOCKET_TYPE_CHAR_UDP_V6; + break; + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + + memset(&in6, 0, sizeof(in6)); + in6.sin6_family = AF_INET6; + in6.sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS; + si->myname_len = sizeof(in6); + si->myname = sockaddr_dup(&in6, si->myname_len); + break; + } +#endif + default: + errno = ESOCKTNOSUPPORT; + return -1; + } + + if (autobind_start > 60000) { + autobind_start = 10000; + } + + for (i=0;i<1000;i++) { + port = autobind_start + i; + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), + "%s/"SOCKET_FORMAT, socket_wrapper_dir(), + type, socket_wrapper_default_iface(), port); + if (stat(un_addr.sun_path, &st) == 0) continue; + + ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)); + if (ret == -1) return ret; + + si->tmp_path = strdup(un_addr.sun_path); + si->bound = 1; + autobind_start = port + 1; + break; + } + if (i == 1000) { + errno = ENFILE; + return -1; + } + + set_port(si->family, port, si->myname); + + return 0; +} + + +_PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + int ret; + struct sockaddr_un un_addr; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_connect(s, serv_addr, addrlen); + } + + if (si->bound == 0) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; + } + + if (si->family != serv_addr->sa_family) { + errno = EINVAL; + return -1; + } + + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); + if (ret == -1) return -1; + + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); + + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == 0) { + si->peername_len = addrlen; + si->peername = sockaddr_dup(serv_addr, addrlen); + + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0); + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0); + } else { + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0); + } + + return ret; +} + +_PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) +{ + int ret; + struct sockaddr_un un_addr; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_bind(s, myaddr, addrlen); + } + + si->myname_len = addrlen; + si->myname = sockaddr_dup(myaddr, addrlen); + + ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast); + if (ret == -1) return -1; + + unlink(un_addr.sun_path); + + ret = real_bind(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + + if (ret == 0) { + si->bound = 1; + } + + return ret; +} + +_PUBLIC_ int swrap_listen(int s, int backlog) +{ + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_listen(s, backlog); + } + + ret = real_listen(s, backlog); + + return ret; +} + +_PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_getpeername(s, name, addrlen); + } + + if (!si->peername) + { + errno = ENOTCONN; + return -1; + } + + memcpy(name, si->peername, si->peername_len); + *addrlen = si->peername_len; + + return 0; +} + +_PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_getsockname(s, name, addrlen); + } + + memcpy(name, si->myname, si->myname_len); + *addrlen = si->myname_len; + + return 0; +} + +_PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_getsockopt(s, level, optname, optval, optlen); + } + + if (level == SOL_SOCKET) { + return real_getsockopt(s, level, optname, optval, optlen); + } + + errno = ENOPROTOOPT; + return -1; +} + +_PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_setsockopt(s, level, optname, optval, optlen); + } + + if (level == SOL_SOCKET) { + return real_setsockopt(s, level, optname, optval, optlen); + } + + switch (si->family) { + case AF_INET: + return 0; + default: + errno = ENOPROTOOPT; + return -1; + } +} + +_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) +{ + struct sockaddr_un un_addr; + socklen_t un_addrlen = sizeof(un_addr); + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_recvfrom(s, buf, len, flags, from, fromlen); + } + + len = MIN(len, 1500); + + /* irix 6.4 forgets to null terminate the sun_path string :-( */ + memset(&un_addr, 0, sizeof(un_addr)); + ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); + if (ret == -1) + return ret; + + if (sockaddr_convert_from_un(si, &un_addr, un_addrlen, + si->family, from, fromlen) == -1) { + return -1; + } + + swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret); + + return ret; +} + + +_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) +{ + struct sockaddr_un un_addr; + int ret; + struct socket_info *si = find_socket_info(s); + int bcast = 0; + + if (!si) { + return real_sendto(s, buf, len, flags, to, tolen); + } + + len = MIN(len, 1500); + + switch (si->type) { + case SOCK_STREAM: + ret = real_send(s, buf, len, flags); + break; + case SOCK_DGRAM: + if (si->bound == 0) { + ret = swrap_auto_bind(si); + if (ret == -1) return -1; + } + + ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast); + if (ret == -1) return -1; + + if (bcast) { + struct stat st; + unsigned int iface; + unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port); + char type; + + type = SOCKET_TYPE_CHAR_UDP; + + for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, iface, prt); + if (stat(un_addr.sun_path, &st) != 0) continue; + + /* ignore the any errors in broadcast sends */ + real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + } + + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); + + return len; + } + + ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); + break; + default: + ret = -1; + errno = EHOSTUNREACH; + break; + } + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == -1) { + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); + swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len); + } else { + swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret); + } + + return ret; +} + +_PUBLIC_ int swrap_ioctl(int s, int r, void *p) +{ + int ret; + struct socket_info *si = find_socket_info(s); + int value; + + if (!si) { + return real_ioctl(s, r, p); + } + + ret = real_ioctl(s, r, p); + + switch (r) { + case FIONREAD: + value = *((int *)p); + if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { + swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); + } else if (value == 0) { /* END OF FILE */ + swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); + } + break; + } + + return ret; +} + +_PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) +{ + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_recv(s, buf, len, flags); + } + + len = MIN(len, 1500); + + ret = real_recv(s, buf, len, flags); + if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { + swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); + } else if (ret == 0) { /* END OF FILE */ + swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); + } else { + swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); + } + + return ret; +} + + +_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) +{ + int ret; + struct socket_info *si = find_socket_info(s); + + if (!si) { + return real_send(s, buf, len, flags); + } + + len = MIN(len, 1500); + + ret = real_send(s, buf, len, flags); + + if (ret == -1) { + swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len); + swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0); + } else { + swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret); + } + + return ret; +} + +_PUBLIC_ int swrap_close(int fd) +{ + struct socket_info *si = find_socket_info(fd); + int ret; + + if (!si) { + return real_close(fd); + } + + SWRAP_DLIST_REMOVE(sockets, si); + + if (si->myname && si->peername) { + swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0); + } + + ret = real_close(fd); + + if (si->myname && si->peername) { + swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0); + swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0); + } + + if (si->path) free(si->path); + if (si->myname) free(si->myname); + if (si->peername) free(si->peername); + if (si->tmp_path) { + unlink(si->tmp_path); + free(si->tmp_path); + } + free(si); + + return ret; +} diff --git a/lib/socket_wrapper/socket_wrapper.h b/lib/socket_wrapper/socket_wrapper.h new file mode 100644 index 0000000000..cc8b937608 --- /dev/null +++ b/lib/socket_wrapper/socket_wrapper.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) Jelmer Vernooij 2005 + * Copyright (C) Stefan Metzmacher 2006 + * + * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef __SOCKET_WRAPPER_H__ +#define __SOCKET_WRAPPER_H__ + +const char *socket_wrapper_dir(void); +unsigned int socket_wrapper_default_iface(void); +int swrap_socket(int family, int type, int protocol); +int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); +int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen); +int swrap_listen(int s, int backlog); +int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen); +int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen); +int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); +int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); +ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); +ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); +int swrap_ioctl(int s, int req, void *ptr); +ssize_t swrap_recv(int s, void *buf, size_t len, int flags); +ssize_t swrap_send(int s, const void *buf, size_t len, int flags); +int swrap_close(int); + +#ifdef SOCKET_WRAPPER_REPLACE + +#ifdef accept +#undef accept +#endif +#define accept(s,addr,addrlen) swrap_accept(s,addr,addrlen) + +#ifdef connect +#undef connect +#endif +#define connect(s,serv_addr,addrlen) swrap_connect(s,serv_addr,addrlen) + +#ifdef bind +#undef bind +#endif +#define bind(s,myaddr,addrlen) swrap_bind(s,myaddr,addrlen) + +#ifdef listen +#undef listen +#endif +#define listen(s,blog) swrap_listen(s,blog) + +#ifdef getpeername +#undef getpeername +#endif +#define getpeername(s,name,addrlen) swrap_getpeername(s,name,addrlen) + +#ifdef getsockname +#undef getsockname +#endif +#define getsockname(s,name,addrlen) swrap_getsockname(s,name,addrlen) + +#ifdef getsockopt +#undef getsockopt +#endif +#define getsockopt(s,level,optname,optval,optlen) swrap_getsockopt(s,level,optname,optval,optlen) + +#ifdef setsockopt +#undef setsockopt +#endif +#define setsockopt(s,level,optname,optval,optlen) swrap_setsockopt(s,level,optname,optval,optlen) + +#ifdef recvfrom +#undef recvfrom +#endif +#define recvfrom(s,buf,len,flags,from,fromlen) swrap_recvfrom(s,buf,len,flags,from,fromlen) + +#ifdef sendto +#undef sendto +#endif +#define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen) + +#ifdef ioctl +#undef ioctl +#endif +#define ioctl(s,req,ptr) swrap_ioctl(s,req,ptr) + +#ifdef recv +#undef recv +#endif +#define recv(s,buf,len,flags) swrap_recv(s,buf,len,flags) + +#ifdef send +#undef send +#endif +#define send(s,buf,len,flags) swrap_send(s,buf,len,flags) + +#ifdef socket +#undef socket +#endif +#define socket(domain,type,protocol) swrap_socket(domain,type,protocol) + +#ifdef close +#undef close +#endif +#define close(s) swrap_close(s) +#endif + + +#endif /* __SOCKET_WRAPPER_H__ */ diff --git a/lib/socket_wrapper/testsuite.c b/lib/socket_wrapper/testsuite.c new file mode 100644 index 0000000000..e6e08e3be6 --- /dev/null +++ b/lib/socket_wrapper/testsuite.c @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + + local testing of the socket wrapper + + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "system/network.h" +#include "../socket_wrapper/socket_wrapper.h" +#include "torture/torture.h" + +static char *old_dir = NULL; +static char *old_iface = NULL; + +static void backup_env(void) +{ + old_dir = getenv("SOCKET_WRAPPER_DIR"); + old_iface = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); +} + +static void restore_env(void) +{ + if (old_dir == NULL) + unsetenv("SOCKET_WRAPPER_DIR"); + else + setenv("SOCKET_WRAPPER_DIR", old_dir, 1); + if (old_iface == NULL) + unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE"); + else + setenv("SOCKET_WRAPPER_DEFAULT_IFACE", old_iface, 1); +} + +static bool test_socket_wrapper_dir(struct torture_context *tctx) +{ + backup_env(); + + setenv("SOCKET_WRAPPER_DIR", "foo", 1); + torture_assert_str_equal(tctx, socket_wrapper_dir(), "foo", "setting failed"); + setenv("SOCKET_WRAPPER_DIR", "./foo", 1); + torture_assert_str_equal(tctx, socket_wrapper_dir(), "foo", "setting failed"); + unsetenv("SOCKET_WRAPPER_DIR"); + torture_assert_str_equal(tctx, socket_wrapper_dir(), NULL, "resetting failed"); + + restore_env(); + + return true; +} + +static bool test_swrap_socket(struct torture_context *tctx) +{ + backup_env(); + setenv("SOCKET_WRAPPER_DIR", "foo", 1); + + torture_assert_int_equal(tctx, swrap_socket(1337, 1337, 0), -1, "unknown address family fails"); + torture_assert_int_equal(tctx, errno, EAFNOSUPPORT, "correct errno set"); + torture_assert_int_equal(tctx, swrap_socket(AF_INET, 1337, 0), -1, "unknown type fails"); + torture_assert_int_equal(tctx, errno, EPROTONOSUPPORT, "correct errno set"); + torture_assert_int_equal(tctx, swrap_socket(AF_INET, SOCK_DGRAM, 10), -1, "unknown protocol fails"); + torture_assert_int_equal(tctx, errno, EPROTONOSUPPORT, "correct errno set"); + + restore_env(); + + return true; +} + +unsigned int socket_wrapper_default_iface(void); +static bool test_socket_wrapper_default_iface(struct torture_context *tctx) +{ + backup_env(); + unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE"); + torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset"); + setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "2", 1); + torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 2, "unset"); + setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "bla", 1); + torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset"); + restore_env(); + return true; +} + +struct torture_suite *torture_local_socket_wrapper(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, + "SOCKET-WRAPPER"); + + torture_suite_add_simple_test(suite, "socket_wrapper_dir", test_socket_wrapper_dir); + torture_suite_add_simple_test(suite, "socket", test_swrap_socket); + torture_suite_add_simple_test(suite, "socket_wrapper_default_iface", test_socket_wrapper_default_iface); + + return suite; +} diff --git a/lib/talloc/Makefile.in b/lib/talloc/Makefile.in new file mode 100644 index 0000000000..07b8fd4ff0 --- /dev/null +++ b/lib/talloc/Makefile.in @@ -0,0 +1,43 @@ +#!gmake +# +prefix = @prefix@ +datarootdir = @datarootdir@ +exec_prefix = @exec_prefix@ +includedir = @includedir@ +libdir = @libdir@ +mandir = @mandir@ +VPATH = @srcdir@:@libreplacedir@ +srcdir = @srcdir@ +builddir = @builddir@ +XSLTPROC = @XSLTPROC@ +INSTALLCMD = @INSTALL@ +CC = @CC@ +CFLAGS = @CFLAGS@ -DHAVE_CONFIG_H= -I. -I@srcdir@ +EXTRA_TARGETS = @DOC_TARGET@ +PICFLAG = @PICFLAG@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +SHLIBEXT = @SHLIBEXT@ +SHLD = @SHLD@ +SHLD_FLAGS = @SHLD_FLAGS@ +tallocdir = @tallocdir@ + +LIBOBJ = $(TALLOC_OBJ) @LIBREPLACEOBJ@ + +all:: showflags $(EXTRA_TARGETS) + +include $(tallocdir)/rules.mk +include $(tallocdir)/talloc.mk + +$(TALLOC_SOLIB): $(LIBOBJ) + $(SHLD) $(SHLD_FLAGS) -o $@ $(LIBOBJ) @SONAMEFLAG@$(TALLOC_SONAME) + +check: test + +installcheck:: test install + +distclean:: clean + rm -f Makefile + rm -f config.log config.status config.h config.cache + +realdistclean:: distclean + rm -f configure config.h.in diff --git a/lib/talloc/NEWS b/lib/talloc/NEWS new file mode 100644 index 0000000000..e5b3aa0731 --- /dev/null +++ b/lib/talloc/NEWS @@ -0,0 +1,13 @@ +1.0.1 26 May 2007 + + BUGS + + * Set name of correctly when using talloc_append_string() (metze) + + LICENSE + + * Change license of files in lib/replace to LGPL (was GPL). (jelmer) + +1.0.0 30 April 2007 + + Initial release. diff --git a/lib/talloc/aclocal.m4 b/lib/talloc/aclocal.m4 new file mode 100644 index 0000000000..5605e476ba --- /dev/null +++ b/lib/talloc/aclocal.m4 @@ -0,0 +1 @@ +m4_include(libreplace.m4) diff --git a/lib/talloc/autogen.sh b/lib/talloc/autogen.sh new file mode 100755 index 0000000000..bf84eeee19 --- /dev/null +++ b/lib/talloc/autogen.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +rm -rf autom4te.cache +rm -f configure config.h.in + +IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace" +autoconf $IPATHS || exit 1 +autoheader $IPATHS || exit 1 + +rm -rf autom4te.cache + +echo "Now run ./configure and then make." +exit 0 + diff --git a/lib/talloc/config.guess b/lib/talloc/config.guess new file mode 100755 index 0000000000..354dbe175a --- /dev/null +++ b/lib/talloc/config.guess @@ -0,0 +1,1464 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-08-03' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/talloc/config.mk b/lib/talloc/config.mk new file mode 100644 index 0000000000..5cdf3a1a8e --- /dev/null +++ b/lib/talloc/config.mk @@ -0,0 +1,7 @@ +[LIBRARY::LIBTALLOC] +OUTPUT_TYPE = MERGED_OBJ +CFLAGS = -I$(tallocsrcdir) + +LIBTALLOC_OBJ_FILES = $(tallocsrcdir)/talloc.o + +MANPAGES += $(tallocdir)/talloc.3 diff --git a/lib/talloc/config.sub b/lib/talloc/config.sub new file mode 100755 index 0000000000..23cd6fd75c --- /dev/null +++ b/lib/talloc/config.sub @@ -0,0 +1,1577 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ms1 \ + | msp430 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | ms1-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/talloc/configure.ac b/lib/talloc/configure.ac new file mode 100644 index 0000000000..4719aa04b5 --- /dev/null +++ b/lib/talloc/configure.ac @@ -0,0 +1,24 @@ +AC_PREREQ(2.50) +AC_INIT(talloc, 1.2.0) +AC_CONFIG_SRCDIR([talloc.c]) +AC_SUBST(datarootdir) +AC_CONFIG_HEADER(config.h) + +AC_LIBREPLACE_ALL_CHECKS + +m4_include(libtalloc.m4) + +AC_PATH_PROG(XSLTPROC,xsltproc) +DOC_TARGET="" +if test -n "$XSLTPROC"; then + DOC_TARGET=doc +fi +AC_SUBST(DOC_TARGET) + +AC_LD_PICFLAG +AC_LD_SHLIBEXT +AC_LD_SONAMEFLAG +AC_LIBREPLACE_SHLD +AC_LIBREPLACE_SHLD_FLAGS + +AC_OUTPUT(Makefile talloc.pc) diff --git a/lib/talloc/install-sh b/lib/talloc/install-sh new file mode 100755 index 0000000000..58719246f0 --- /dev/null +++ b/lib/talloc/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +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=: + 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 diff --git a/lib/talloc/libtalloc.m4 b/lib/talloc/libtalloc.m4 new file mode 100644 index 0000000000..e6830fbef6 --- /dev/null +++ b/lib/talloc/libtalloc.m4 @@ -0,0 +1,33 @@ +dnl find the talloc sources. This is meant to work both for +dnl talloc standalone builds, and builds of packages using talloc +tallocdir="" +tallocpaths=". lib/talloc talloc ../talloc ../lib/talloc" +for d in $tallocpaths; do + if test -f "$srcdir/$d/talloc.c"; then + tallocdir="$d" + AC_SUBST(tallocdir) + break; + fi +done +if test x"$tallocdir" = "x"; then + AC_MSG_ERROR([cannot find talloc source in $tallocpaths]) +fi +TALLOC_OBJ="talloc.o" +AC_SUBST(TALLOC_OBJ) + +TALLOC_CFLAGS="-I$srcdir/$tallocdir" +AC_SUBST(TALLOC_CFLAGS) + +TALLOC_LIBS="" +AC_SUBST(TALLOC_LIBS) + +AC_CHECK_SIZEOF(size_t,cross) +AC_CHECK_SIZEOF(void *,cross) + +if test $ac_cv_sizeof_size_t -lt $ac_cv_sizeof_void_p; then + AC_WARN([size_t cannot represent the amount of used memory of a process]) + AC_WARN([please report this to ]) + AC_WARN([sizeof(size_t) = $ac_cv_sizeof_size_t]) + AC_WARN([sizeof(void *) = $ac_cv_sizeof_void_p]) + AC_ERROR([sizeof(size_t) < sizeof(void *)]) +fi diff --git a/lib/talloc/rules.mk b/lib/talloc/rules.mk new file mode 100644 index 0000000000..6cee126529 --- /dev/null +++ b/lib/talloc/rules.mk @@ -0,0 +1,18 @@ +.SUFFIXES: .c .o .3 .3.xml .xml .html + +showflags:: + @echo 'talloc will be compiled with flags:' + @echo ' CFLAGS = $(CFLAGS)' + @echo ' LIBS = $(LIBS)' + +.c.o: + $(CC) $(PICFLAG) -o $@ -c $< $(CFLAGS) + +.3.xml.3: + -test -z "$(XSLTPROC)" || $(XSLTPROC) --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + +.xml.html: + -test -z "$(XSLTPROC)" || $(XSLTPROC) --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< + +distclean:: + rm -f *~ */*~ diff --git a/lib/talloc/talloc.3.xml b/lib/talloc/talloc.3.xml new file mode 100644 index 0000000000..67de15bfc8 --- /dev/null +++ b/lib/talloc/talloc.3.xml @@ -0,0 +1,738 @@ + + + + + talloc + 3 + + + talloc +hierarchical reference counted memory pool system with destructors + + +#include <talloc/talloc.h> + + DESCRIPTION + + If you are used to talloc from Samba3 then please read this + carefully, as talloc has changed a lot. + + + The new talloc is a hierarchical, reference counted memory pool + system with destructors. Quite a mouthful really, but not too bad + once you get used to it. + + + Perhaps the biggest change from Samba3 is that there is no + distinction between a "talloc context" and a "talloc pointer". Any + pointer returned from talloc() is itself a valid talloc context. + This means you can do this: + + + struct foo *X = talloc(mem_ctx, struct foo); + X->name = talloc_strdup(X, "foo"); + + + and the pointer X->name + would be a "child" of the talloc context X which is itself a child of + mem_ctx. So if you do + talloc_free(mem_ctx) then + it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if + you do talloc_free(X->name) then just + the name element of X is + destroyed. + + + If you think about this, then what this effectively gives you is an + n-ary tree, where you can free any part of the tree with + talloc_free(). + + + If you find this confusing, then I suggest you run the testsuite program to watch talloc + in action. You may also like to add your own tests to testsuite.c to clarify how some + particular situation is handled. + + + TALLOC API + + The following is a complete guide to the talloc API. Read it all at + least twice. + + (type *)talloc(const void *ctx, type); + + The talloc() macro is the core of the talloc library. It takes a + memory ctx and a type, and returns a pointer to a new + area of memory of the given type. + + + The returned pointer is itself a talloc context, so you can use + it as the ctx argument to more + calls to talloc() if you wish. + + + The returned pointer is a "child" of the supplied context. This + means that if you talloc_free() the ctx then the new child disappears as + well. Alternatively you can free just the child. + + + The ctx argument to talloc() + can be NULL, in which case a new top level context is created. + + + void *talloc_size(const void *ctx, size_t size); + + The function talloc_size() should be used when you don't have a + convenient type to pass to talloc(). Unlike talloc(), it is not + type safe (as it returns a void *), so you are on your own for + type checking. + + + (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); + + The talloc_ptrtype() macro should be used when you have a pointer and + want to allocate memory to point at with this pointer. When compiling + with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() + and talloc_get_name() will return the current location in the source file. + and not the type. + + + int talloc_free(void *ptr); + + The talloc_free() function frees a piece of talloc memory, and + all its children. You can call talloc_free() on any pointer + returned by talloc(). + + + The return value of talloc_free() indicates success or failure, + with 0 returned for success and -1 for failure. The only + possible failure condition is if ptr had a destructor attached to it and + the destructor returned -1. See talloc_set_destructor() + for details on destructors. + + + If this pointer has an additional parent when talloc_free() is + called then the memory is not actually released, but instead the + most recently established parent is destroyed. See talloc_reference() + for details on establishing additional parents. + + + For more control on which parent is removed, see talloc_unlink(). + + + talloc_free() operates recursively on its children. + + + void *talloc_reference(const void *ctx, const void *ptr); + + The talloc_reference() function makes ctx an additional parent of ptr. + + + The return value of talloc_reference() is always the original + pointer ptr, unless talloc ran + out of memory in creating the reference in which case it will + return NULL (each additional reference consumes around 48 bytes + of memory on intel x86 platforms). + + + If ptr is NULL, then the + function is a no-op, and simply returns NULL. + + + After creating a reference you can free it in one of the + following ways: + + + + + + you can talloc_free() any parent of the original pointer. + That will reduce the number of parents of this pointer by 1, + and will cause this pointer to be freed if it runs out of + parents. + + + + + you can talloc_free() the pointer itself. That will destroy + the most recently established parent to the pointer and leave + the pointer as a child of its current parent. + + + + + + For more control on which parent to remove, see talloc_unlink(). + + + int talloc_unlink(const void *ctx, const void *ptr); + + The talloc_unlink() function removes a specific parent from + ptr. The ctx passed must either be a context used + in talloc_reference() with this pointer, or must be a direct + parent of ptr. + + + Note that if the parent has already been removed using + talloc_free() then this function will fail and will return -1. + Likewise, if ptr is NULL, then + the function will make no modifications and return -1. + + + Usually you can just use talloc_free() instead of + talloc_unlink(), but sometimes it is useful to have the + additional control on which parent is removed. + + + void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + + The function talloc_set_destructor() sets the destructor for the pointer ptr. A destructor is a function that is called + when the memory used by a pointer is about to be released. The + destructor receives ptr as an + argument, and should return 0 for success and -1 for failure. + + + The destructor can do anything + it wants to, including freeing other pieces of memory. A common + use for destructors is to clean up operating system resources + (such as open file descriptors) contained in the structure the + destructor is placed on. + + + You can only place one destructor on a pointer. If you need more + than one destructor then you can create a zero-length child of + the pointer and place an additional destructor on that. + + + To remove a destructor call talloc_set_destructor() with NULL for + the destructor. + + + If your destructor attempts to talloc_free() the pointer that it + is the destructor for then talloc_free() will return -1 and the + free will be ignored. This would be a pointless operation + anyway, as the destructor is only called when the memory is just + about to go away. + + + int talloc_increase_ref_count(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_increase_ref_count(ptr) function is exactly equivalent to: + + talloc_reference(NULL, ptr); + + You can use either syntax, depending on which you think is + clearer in your code. + + + It returns 0 on success and -1 on failure. + + + size_t talloc_reference_count(const void *<emphasis role="italic">ptr</emphasis>); + + Return the number of references to the pointer. + + + void talloc_set_name(const void *ptr, const char *fmt, ...); + + Each talloc pointer has a "name". The name is used principally + for debugging purposes, although it is also possible to set and + get the name on a pointer in as a way of "marking" pointers in + your code. + + + The main use for names on pointer is for "talloc reports". See + talloc_report_depth_cb(), + talloc_report_depth_file(), + talloc_report() + talloc_report() + and talloc_report_full() + for details. Also see talloc_enable_leak_report() + and talloc_enable_leak_report_full(). + + + The talloc_set_name() function allocates memory as a child of the + pointer. It is logically equivalent to: + + talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + + Note that multiple calls to talloc_set_name() will allocate more + memory without releasing the name. All of the memory is released + when the ptr is freed using talloc_free(). + + + void talloc_set_name_const(const void *<emphasis role="italic">ptr</emphasis>, const char *<emphasis role="italic">name</emphasis>); + + The function talloc_set_name_const() is just like + talloc_set_name(), but it takes a string constant, and is much + faster. It is extensively used by the "auto naming" macros, such + as talloc_p(). + + + This function does not allocate any memory. It just copies the + supplied pointer into the internal representation of the talloc + ptr. This means you must not pass a name pointer to memory that will + disappear before ptr is freed + with talloc_free(). + + + void *talloc_named(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); + + The talloc_named() function creates a named talloc pointer. It + is equivalent to: + + ptr = talloc_size(ctx, size); +talloc_set_name(ptr, fmt, ....); + + void *talloc_named_const(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">name</emphasis>); + + This is equivalent to: + + ptr = talloc_size(ctx, size); +talloc_set_name_const(ptr, name); + + const char *talloc_get_name(const void *<emphasis role="italic">ptr</emphasis>); + + This returns the current name for the given talloc pointer, + ptr. See talloc_set_name() + for details. + + + void *talloc_init(const char *<emphasis role="italic">fmt</emphasis>, ...); + + This function creates a zero length named talloc context as a top + level context. It is equivalent to: + + talloc_named(NULL, 0, fmt, ...); + + void *talloc_new(void *<emphasis role="italic">ctx</emphasis>); + + This is a utility macro that creates a new memory context hanging + off an exiting context, automatically naming it "talloc_new: + __location__" where __location__ is the source line it is called + from. It is particularly useful for creating a new temporary + working context. + + + (<emphasis role="italic">type</emphasis> *)talloc_realloc(const void *<emphasis role="italic">ctx</emphasis>, void *<emphasis role="italic">ptr</emphasis>, <emphasis role="italic">type</emphasis>, <emphasis role="italic">count</emphasis>); + + The talloc_realloc() macro changes the size of a talloc pointer. + It has the following equivalences: + + talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); +talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); + + The ctx argument is only used + if ptr is not NULL, otherwise + it is ignored. + + + talloc_realloc() returns the new pointer, or NULL on failure. + The call will fail either due to a lack of memory, or because the + pointer has more than one parent (see talloc_reference()). + + + void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); + + the talloc_realloc_size() function is useful when the type is not + known so the type-safe talloc_realloc() cannot be used. + + + TYPE *talloc_steal(const void *<emphasis role="italic">new_ctx</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); + + The talloc_steal() function changes the parent context of a + talloc pointer. It is typically used when the context that the + pointer is currently a child of is going to be freed and you wish + to keep the memory for a longer time. + + + The talloc_steal() function returns the pointer that you pass it. + It does not have any failure modes. + + + NOTE: It is possible to produce loops in the parent/child + relationship if you are not careful with talloc_steal(). No + guarantees are provided as to your sanity or the safety of your + data if you do this. + + + TYPE *talloc_move(const void *<emphasis role="italic">new_ctx</emphasis>, TYPE **<emphasis role="italic">ptr</emphasis>); + + The talloc_move() function is a wrapper around + talloc_steal() which zeros the source pointer after the + move. This avoids a potential source of bugs where a + programmer leaves a pointer in two structures, and uses the + pointer from the old structure after it has been moved to a + new one. + + + size_t talloc_total_size(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_total_size() function returns the total size in bytes + used by this pointer and all child pointers. Mostly useful for + debugging. + + + Passing NULL is allowed, but it will only give a meaningful + result if talloc_enable_leak_report() or + talloc_enable_leak_report_full() has been called. + + + size_t talloc_total_blocks(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_total_blocks() function returns the total memory block + count used by this pointer and all child pointers. Mostly useful + for debugging. + + + Passing NULL is allowed, but it will only give a meaningful + result if talloc_enable_leak_report() or + talloc_enable_leak_report_full() has been called. + + + void talloc_report(const void *ptr, FILE *f); + + The talloc_report() function prints a summary report of all + memory used by ptr. One line + of report is printed for each immediate child of ptr, showing the + total memory and number of blocks used by that child. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + void talloc_report_full(const void *<emphasis role="italic">ptr</emphasis>, FILE *<emphasis role="italic">f</emphasis>); + + This provides a more detailed report than talloc_report(). It + will recursively print the entire tree of memory referenced by + the pointer. References in the tree are shown by giving the name + of the pointer that is referenced. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + + + void talloc_report_depth_cb + const void *ptr + int depth + int max_depth + void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv) + void *priv + + + This provides a more flexible reports than talloc_report(). It + will recursively call the callback for the entire tree of memory + referenced by the pointer. References in the tree are passed with + is_ref = 1 and the pointer that is referenced. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + The recursion is stopped when depth >= max_depth. + max_depth = -1 means only stop at leaf nodes. + + + + + void talloc_report_depth_file + const void *ptr + int depth + int max_depth + FILE *f + + + This provides a more flexible reports than talloc_report(). It + will let you specify the depth and max_depth. + + + void talloc_enable_leak_report(void); + + This enables calling of talloc_report(NULL, stderr) when the + program exits. In Samba4 this is enabled by using the + --leak-report command line option. + + + For it to be useful, this function must be called before any + other talloc function as it establishes a "null context" that + acts as the top of the tree. If you don't call this function + first then passing NULL to talloc_report() or + talloc_report_full() won't give you the full tree printout. + + + Here is a typical talloc report: + + talloc report on 'null_context' (total 267 bytes in 15 blocks) +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +iconv(UTF8,CP850) contains 42 bytes in 2 blocks +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +iconv(CP850,UTF8) contains 42 bytes in 2 blocks +iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks +iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks + + + void talloc_enable_leak_report_full(void); + + This enables calling of talloc_report_full(NULL, stderr) when the + program exits. In Samba4 this is enabled by using the + --leak-report-full command line option. + + + For it to be useful, this function must be called before any + other talloc function as it establishes a "null context" that + acts as the top of the tree. If you don't call this function + first then passing NULL to talloc_report() or + talloc_report_full() won't give you the full tree printout. + + + Here is a typical full report: + + full talloc report on 'root' (total 18 bytes in 8 blocks) +p1 contains 18 bytes in 7 blocks (ref 0) + r1 contains 13 bytes in 2 blocks (ref 0) + reference to: p2 + p2 contains 1 bytes in 1 blocks (ref 1) + x3 contains 1 bytes in 1 blocks (ref 0) + x2 contains 1 bytes in 1 blocks (ref 0) + x1 contains 1 bytes in 1 blocks (ref 0) + + + (<emphasis role="italic">type</emphasis> *)talloc_zero(const void *<emphasis role="italic">ctx</emphasis>, <emphasis role="italic">type</emphasis>); + + The talloc_zero() macro is equivalent to: + + ptr = talloc(ctx, type); +if (ptr) memset(ptr, 0, sizeof(type)); + + void *talloc_zero_size(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>) + + The talloc_zero_size() function is useful when you don't have a + known type. + + + void *talloc_memdup(const void *<emphasis role="italic">ctx</emphasis>, const void *<emphasis role="italic">p</emphasis>, size_t size); + + The talloc_memdup() function is equivalent to: + + ptr = talloc_size(ctx, size); +if (ptr) memcpy(ptr, p, size); + + char *talloc_strdup(const void *<emphasis role="italic">ctx</emphasis>, const char *<emphasis role="italic">p</emphasis>); + + The talloc_strdup() function is equivalent to: + + ptr = talloc_size(ctx, strlen(p)+1); +if (ptr) memcpy(ptr, p, strlen(p)+1); + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_strndup(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">p</emphasis>, size_t <emphasis role="italic">n</emphasis>); + + The talloc_strndup() function is the talloc equivalent of the C + library function strndup(3). + + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_append_string(const void *<emphasis role="italic">t</emphasis>, char *<emphasis role="italic">orig</emphasis>, const char *<emphasis role="italic">append</emphasis>); + + The talloc_append_string() function appends the given formatted + string to the given string. + + + This function sets the name of the new pointer to the new + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>); + + The talloc_vasprintf() function is the talloc equivalent of the C + library function vasprintf(3). + + + This function sets the name of the new pointer to the new + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); + + The talloc_asprintf() function is the talloc equivalent of the C + library function asprintf(3). + + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_asprintf_append(char *s, const char *fmt, ...); + + The talloc_asprintf_append() function appends the given formatted + string to the given string. + + + This function sets the name of the new pointer to the new + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + (type *)talloc_array(const void *ctx, type, uint_t count); + + The talloc_array() macro is equivalent to: + + (type *)talloc_size(ctx, sizeof(type) * count); + + except that it provides integer overflow protection for the + multiply, returning NULL if the multiply overflows. + + + void *talloc_array_size(const void *ctx, size_t size, uint_t count); + + The talloc_array_size() function is useful when the type is not + known. It operates in the same way as talloc_array(), but takes a + size instead of a type. + + + (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count); + + The talloc_ptrtype() macro should be used when you have a pointer to an array + and want to allocate memory of an array to point at with this pointer. When compiling + with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() + and talloc_get_name() will return the current location in the source file. + and not the type. + + + void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size) + + This is a non-macro version of talloc_realloc(), which is useful + as libraries sometimes want a realloc function pointer. A + realloc(3) implementation encapsulates the functionality of + malloc(3), free(3) and realloc(3) in one call, which is why it is + useful to be able to pass around a single function pointer. + + + void *talloc_autofree_context(void); + + This is a handy utility function that returns a talloc context + which will be automatically freed on program exit. This can be + used to reduce the noise in memory leak reports. + + + void *talloc_check_name(const void *ptr, const char *name); + + This function checks if a pointer has the specified name. If it does then the pointer is + returned. It it doesn't then NULL is returned. + + + (type *)talloc_get_type(const void *ptr, type); + + This macro allows you to do type checking on talloc pointers. It + is particularly useful for void* private pointers. It is + equivalent to this: + + (type *)talloc_check_name(ptr, #type) + + talloc_set_type(const void *ptr, type); + + This macro allows you to force the name of a pointer to be a + particular type. This can be + used in conjunction with talloc_get_type() to do type checking on + void* pointers. + + + It is equivalent to this: + + talloc_set_name_const(ptr, #type) + + + PERFORMANCE + + All the additional features of talloc(3) over malloc(3) do come at a + price. We have a simple performance test in Samba4 that measures + talloc() versus malloc() performance, and it seems that talloc() is + about 10% slower than malloc() on my x86 Debian Linux box. For + Samba, the great reduction in code complexity that we get by using + talloc makes this worthwhile, especially as the total overhead of + talloc/malloc in Samba is already quite small. + + + SEE ALSO + + malloc(3), strndup(3), vasprintf(3), asprintf(3), + + + + COPYRIGHT/LICENSE + + Copyright (C) Andrew Tridgell 2004 + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or (at + your option) any later version. + + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + + You should have received a copy of the GNU General Public License + along with this program; if not, see http://www.gnu.org/licenses/. + + + diff --git a/lib/talloc/talloc.c b/lib/talloc/talloc.c new file mode 100644 index 0000000000..1f7e52439f --- /dev/null +++ b/lib/talloc/talloc.c @@ -0,0 +1,1732 @@ +/* + Samba Unix SMB/CIFS implementation. + + Samba trivial allocation library - new interface + + NOTE: Please read talloc_guide.txt for full documentation + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + inspired by http://swapped.cc/halloc/ +*/ + +#ifdef _SAMBA_BUILD_ +#include "version.h" +#if (SAMBA_VERSION_MAJOR<4) +#include "includes.h" +/* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file + * we trust ourselves... */ +#ifdef malloc +#undef malloc +#endif +#ifdef realloc +#undef realloc +#endif +#define _TALLOC_SAMBA3 +#endif /* (SAMBA_VERSION_MAJOR<4) */ +#endif /* _SAMBA_BUILD_ */ + +#ifndef _TALLOC_SAMBA3 +#include "replace.h" +#include "talloc.h" +#endif /* not _TALLOC_SAMBA3 */ + +/* use this to force every realloc to change the pointer, to stress test + code that might not cope */ +#define ALWAYS_REALLOC 0 + + +#define MAX_TALLOC_SIZE 0x10000000 +#define TALLOC_MAGIC 0xe814ec70 +#define TALLOC_FLAG_FREE 0x01 +#define TALLOC_FLAG_LOOP 0x02 +#define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ +#define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ +#define TALLOC_MAGIC_REFERENCE ((const char *)1) + +/* by default we abort when given a bad pointer (such as when talloc_free() is called + on a pointer that came from malloc() */ +#ifndef TALLOC_ABORT +#define TALLOC_ABORT(reason) abort() +#endif + +#ifndef discard_const_p +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) +# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) +#else +# define discard_const_p(type, ptr) ((type *)(ptr)) +#endif +#endif + +/* these macros gain us a few percent of speed on gcc */ +#if (__GNUC__ >= 3) +/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 + as its first argument */ +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#else +#ifndef likely +#define likely(x) (x) +#endif +#ifndef unlikely +#define unlikely(x) (x) +#endif +#endif + +/* this null_context is only used if talloc_enable_leak_report() or + talloc_enable_leak_report_full() is called, otherwise it remains + NULL +*/ +static void *null_context; +static void *autofree_context; + +struct talloc_reference_handle { + struct talloc_reference_handle *next, *prev; + void *ptr; +}; + +typedef int (*talloc_destructor_t)(void *); + +struct talloc_chunk { + struct talloc_chunk *next, *prev; + struct talloc_chunk *parent, *child; + struct talloc_reference_handle *refs; + talloc_destructor_t destructor; + const char *name; + size_t size; + unsigned flags; + + /* + * "pool" has dual use: + * + * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" + * marks the end of the currently allocated area. + * + * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" + * is a pointer to the struct talloc_chunk of the pool that it was + * allocated from. This way children can quickly find the pool to chew + * from. + */ + void *pool; +}; + +/* 16 byte alignment seems to keep everyone happy */ +#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15) +#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) + +static void talloc_abort_double_free(void) +{ + TALLOC_ABORT("Bad talloc magic value - double free"); +} + +static void talloc_abort_unknown_value(void) +{ + TALLOC_ABORT("Bad talloc magic value - unknown value"); +} + +/* panic if we get a bad magic value */ +static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) +{ + const char *pp = (const char *)ptr; + struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); + if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { + if (tc->flags & TALLOC_FLAG_FREE) { + talloc_abort_double_free(); + } else { + talloc_abort_unknown_value(); + } + } + return tc; +} + +/* hook into the front of the list */ +#define _TLIST_ADD(list, p) \ +do { \ + if (!(list)) { \ + (list) = (p); \ + (p)->next = (p)->prev = NULL; \ + } else { \ + (list)->prev = (p); \ + (p)->next = (list); \ + (p)->prev = NULL; \ + (list) = (p); \ + }\ +} while (0) + +/* remove an element from a list - element doesn't have to be in list. */ +#define _TLIST_REMOVE(list, p) \ +do { \ + if ((p) == (list)) { \ + (list) = (p)->next; \ + if (list) (list)->prev = NULL; \ + } else { \ + if ((p)->prev) (p)->prev->next = (p)->next; \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + } \ + if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ +} while (0) + + +/* + return the parent chunk of a pointer +*/ +static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return NULL; + } + + tc = talloc_chunk_from_ptr(ptr); + while (tc->prev) tc=tc->prev; + + return tc->parent; +} + +void *talloc_parent(const void *ptr) +{ + struct talloc_chunk *tc = talloc_parent_chunk(ptr); + return tc? TC_PTR_FROM_CHUNK(tc) : NULL; +} + +/* + find parents name +*/ +const char *talloc_parent_name(const void *ptr) +{ + struct talloc_chunk *tc = talloc_parent_chunk(ptr); + return tc? tc->name : NULL; +} + +/* + A pool carries an in-pool object count count in the first 16 bytes. + bytes. This is done to support talloc_steal() to a parent outside of the + pool. The count includes the pool itself, so a talloc_free() on a pool will + only destroy the pool if the count has dropped to zero. A talloc_free() of a + pool member will reduce the count, and eventually also call free(3) on the + pool memory. + + The object count is not put into "struct talloc_chunk" because it is only + relevant for talloc pools and the alignment to 16 bytes would increase the + memory footprint of each talloc chunk by those 16 bytes. +*/ + +#define TALLOC_POOL_HDR_SIZE 16 + +static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc) +{ + return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk)); +} + +/* + Allocate from a pool +*/ + +static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, + size_t size) +{ + struct talloc_chunk *pool_ctx = NULL; + size_t space_left; + struct talloc_chunk *result; + size_t chunk_size; + + if (parent == NULL) { + return NULL; + } + + if (parent->flags & TALLOC_FLAG_POOL) { + pool_ctx = parent; + } + else if (parent->flags & TALLOC_FLAG_POOLMEM) { + pool_ctx = (struct talloc_chunk *)parent->pool; + } + + if (pool_ctx == NULL) { + return NULL; + } + + space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size) + - ((char *)pool_ctx->pool); + + /* + * Align size to 16 bytes + */ + chunk_size = ((size + 15) & ~15); + + if (space_left < chunk_size) { + return NULL; + } + + result = (struct talloc_chunk *)pool_ctx->pool; + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) + VALGRIND_MAKE_MEM_UNDEFINED(result, size); +#endif + + pool_ctx->pool = (void *)((char *)result + chunk_size); + + result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; + result->pool = pool_ctx; + + *talloc_pool_objectcount(pool_ctx) += 1; + + return result; +} + +/* + Allocate a bit of memory as a child of an existing pointer +*/ +static inline void *__talloc(const void *context, size_t size) +{ + struct talloc_chunk *tc = NULL; + + if (unlikely(context == NULL)) { + context = null_context; + } + + if (unlikely(size >= MAX_TALLOC_SIZE)) { + return NULL; + } + + if (context != NULL) { + tc = talloc_alloc_pool(talloc_chunk_from_ptr(context), + TC_HDR_SIZE+size); + } + + if (tc == NULL) { + tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); + if (unlikely(tc == NULL)) return NULL; + tc->flags = TALLOC_MAGIC; + tc->pool = NULL; + } + + tc->size = size; + tc->destructor = NULL; + tc->child = NULL; + tc->name = NULL; + tc->refs = NULL; + + if (likely(context)) { + struct talloc_chunk *parent = talloc_chunk_from_ptr(context); + + if (parent->child) { + parent->child->parent = NULL; + tc->next = parent->child; + tc->next->prev = tc; + } else { + tc->next = NULL; + } + tc->parent = parent; + tc->prev = NULL; + parent->child = tc; + } else { + tc->next = tc->prev = tc->parent = NULL; + } + + return TC_PTR_FROM_CHUNK(tc); +} + +/* + * Create a talloc pool + */ + +void *talloc_pool(const void *context, size_t size) +{ + void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE); + struct talloc_chunk *tc; + + if (unlikely(result == NULL)) { + return NULL; + } + + tc = talloc_chunk_from_ptr(result); + + tc->flags |= TALLOC_FLAG_POOL; + tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE; + + *talloc_pool_objectcount(tc) = 1; + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size); +#endif + + return result; +} + +/* + setup a destructor to be called on free of a pointer + the destructor should return 0 on success, or -1 on failure. + if the destructor fails then the free is failed, and the memory can + be continued to be used +*/ +void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + tc->destructor = destructor; +} + +/* + increase the reference count on a piece of memory. +*/ +int talloc_increase_ref_count(const void *ptr) +{ + if (unlikely(!talloc_reference(null_context, ptr))) { + return -1; + } + return 0; +} + +/* + helper for talloc_reference() + + this is referenced by a function pointer and should not be inline +*/ +static int talloc_reference_destructor(struct talloc_reference_handle *handle) +{ + struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr); + _TLIST_REMOVE(ptr_tc->refs, handle); + return 0; +} + +/* + more efficient way to add a name to a pointer - the name must point to a + true string constant +*/ +static inline void _talloc_set_name_const(const void *ptr, const char *name) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + tc->name = name; +} + +/* + internal talloc_named_const() +*/ +static inline void *_talloc_named_const(const void *context, size_t size, const char *name) +{ + void *ptr; + + ptr = __talloc(context, size); + if (unlikely(ptr == NULL)) { + return NULL; + } + + _talloc_set_name_const(ptr, name); + + return ptr; +} + +/* + make a secondary reference to a pointer, hanging off the given context. + the pointer remains valid until both the original caller and this given + context are freed. + + the major use for this is when two different structures need to reference the + same underlying data, and you want to be able to free the two instances separately, + and in either order +*/ +void *_talloc_reference(const void *context, const void *ptr) +{ + struct talloc_chunk *tc; + struct talloc_reference_handle *handle; + if (unlikely(ptr == NULL)) return NULL; + + tc = talloc_chunk_from_ptr(ptr); + handle = (struct talloc_reference_handle *)_talloc_named_const(context, + sizeof(struct talloc_reference_handle), + TALLOC_MAGIC_REFERENCE); + if (unlikely(handle == NULL)) return NULL; + + /* note that we hang the destructor off the handle, not the + main context as that allows the caller to still setup their + own destructor on the context if they want to */ + talloc_set_destructor(handle, talloc_reference_destructor); + handle->ptr = discard_const_p(void, ptr); + _TLIST_ADD(tc->refs, handle); + return handle->ptr; +} + + +/* + internal talloc_free call +*/ +static inline int _talloc_free(void *ptr) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return -1; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (unlikely(tc->refs)) { + int is_child; + /* check this is a reference from a child or grantchild + * back to it's parent or grantparent + * + * in that case we need to remove the reference and + * call another instance of talloc_free() on the current + * pointer. + */ + is_child = talloc_is_parent(tc->refs, ptr); + _talloc_free(tc->refs); + if (is_child) { + return _talloc_free(ptr); + } + return -1; + } + + if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) { + /* we have a free loop - stop looping */ + return 0; + } + + if (unlikely(tc->destructor)) { + talloc_destructor_t d = tc->destructor; + if (d == (talloc_destructor_t)-1) { + return -1; + } + tc->destructor = (talloc_destructor_t)-1; + if (d(ptr) == -1) { + tc->destructor = d; + return -1; + } + tc->destructor = NULL; + } + + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + while (tc->child) { + /* we need to work out who will own an abandoned child + if it cannot be freed. In priority order, the first + choice is owner of any remaining reference to this + pointer, the second choice is our parent, and the + final choice is the null context. */ + void *child = TC_PTR_FROM_CHUNK(tc->child); + const void *new_parent = null_context; + if (unlikely(tc->child->refs)) { + struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + if (unlikely(_talloc_free(child) == -1)) { + if (new_parent == null_context) { + struct talloc_chunk *p = talloc_parent_chunk(ptr); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + talloc_steal(new_parent, child); + } + } + + tc->flags |= TALLOC_FLAG_FREE; + + if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) { + struct talloc_chunk *pool; + unsigned int *pool_object_count; + + pool = (tc->flags & TALLOC_FLAG_POOL) + ? tc : (struct talloc_chunk *)tc->pool; + + pool_object_count = talloc_pool_objectcount(pool); + + if (*pool_object_count == 0) { + TALLOC_ABORT("Pool object count zero!"); + } + + *pool_object_count -= 1; + + if (*pool_object_count == 0) { + free(pool); + } + } + else { + free(tc); + } + return 0; +} + +/* + move a lump of memory from one talloc context to another return the + ptr on success, or NULL if it could not be transferred. + passing NULL as ptr will always return NULL with no side effects. +*/ +void *_talloc_steal(const void *new_ctx, const void *ptr) +{ + struct talloc_chunk *tc, *new_tc; + + if (unlikely(!ptr)) { + return NULL; + } + + if (unlikely(new_ctx == NULL)) { + new_ctx = null_context; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (unlikely(new_ctx == NULL)) { + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } + + tc->parent = tc->next = tc->prev = NULL; + return discard_const_p(void, ptr); + } + + new_tc = talloc_chunk_from_ptr(new_ctx); + + if (unlikely(tc == new_tc || tc->parent == new_tc)) { + return discard_const_p(void, ptr); + } + + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } + + tc->parent = new_tc; + if (new_tc->child) new_tc->child->parent = NULL; + _TLIST_ADD(new_tc->child, tc); + + return discard_const_p(void, ptr); +} + + + +/* + remove a secondary reference to a pointer. This undo's what + talloc_reference() has done. The context and pointer arguments + must match those given to a talloc_reference() +*/ +static inline int talloc_unreference(const void *context, const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + struct talloc_reference_handle *h; + + if (unlikely(context == NULL)) { + context = null_context; + } + + for (h=tc->refs;h;h=h->next) { + struct talloc_chunk *p = talloc_parent_chunk(h); + if (p == NULL) { + if (context == NULL) break; + } else if (TC_PTR_FROM_CHUNK(p) == context) { + break; + } + } + if (h == NULL) { + return -1; + } + + return _talloc_free(h); +} + +/* + remove a specific parent context from a pointer. This is a more + controlled varient of talloc_free() +*/ +int talloc_unlink(const void *context, void *ptr) +{ + struct talloc_chunk *tc_p, *new_p; + void *new_parent; + + if (ptr == NULL) { + return -1; + } + + if (context == NULL) { + context = null_context; + } + + if (talloc_unreference(context, ptr) == 0) { + return 0; + } + + if (context == NULL) { + if (talloc_parent_chunk(ptr) != NULL) { + return -1; + } + } else { + if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) { + return -1; + } + } + + tc_p = talloc_chunk_from_ptr(ptr); + + if (tc_p->refs == NULL) { + return _talloc_free(ptr); + } + + new_p = talloc_parent_chunk(tc_p->refs); + if (new_p) { + new_parent = TC_PTR_FROM_CHUNK(new_p); + } else { + new_parent = NULL; + } + + if (talloc_unreference(new_parent, ptr) != 0) { + return -1; + } + + talloc_steal(new_parent, ptr); + + return 0; +} + +/* + add a name to an existing pointer - va_list version +*/ +static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + tc->name = talloc_vasprintf(ptr, fmt, ap); + if (likely(tc->name)) { + _talloc_set_name_const(tc->name, ".name"); + } + return tc->name; +} + +/* + add a name to an existing pointer +*/ +const char *talloc_set_name(const void *ptr, const char *fmt, ...) +{ + const char *name; + va_list ap; + va_start(ap, fmt); + name = talloc_set_name_v(ptr, fmt, ap); + va_end(ap); + return name; +} + + +/* + create a named talloc pointer. Any talloc pointer can be named, and + talloc_named() operates just like talloc() except that it allows you + to name the pointer. +*/ +void *talloc_named(const void *context, size_t size, const char *fmt, ...) +{ + va_list ap; + void *ptr; + const char *name; + + ptr = __talloc(context, size); + if (unlikely(ptr == NULL)) return NULL; + + va_start(ap, fmt); + name = talloc_set_name_v(ptr, fmt, ap); + va_end(ap); + + if (unlikely(name == NULL)) { + _talloc_free(ptr); + return NULL; + } + + return ptr; +} + +/* + return the name of a talloc ptr, or "UNNAMED" +*/ +const char *talloc_get_name(const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { + return ".reference"; + } + if (likely(tc->name)) { + return tc->name; + } + return "UNNAMED"; +} + + +/* + check if a pointer has the given name. If it does, return the pointer, + otherwise return NULL +*/ +void *talloc_check_name(const void *ptr, const char *name) +{ + const char *pname; + if (unlikely(ptr == NULL)) return NULL; + pname = talloc_get_name(ptr); + if (likely(pname == name || strcmp(pname, name) == 0)) { + return discard_const_p(void, ptr); + } + return NULL; +} + + +/* + this is for compatibility with older versions of talloc +*/ +void *talloc_init(const char *fmt, ...) +{ + va_list ap; + void *ptr; + const char *name; + + /* + * samba3 expects talloc_report_depth_cb(NULL, ...) + * reports all talloc'ed memory, so we need to enable + * null_tracking + */ + talloc_enable_null_tracking(); + + ptr = __talloc(NULL, 0); + if (unlikely(ptr == NULL)) return NULL; + + va_start(ap, fmt); + name = talloc_set_name_v(ptr, fmt, ap); + va_end(ap); + + if (unlikely(name == NULL)) { + _talloc_free(ptr); + return NULL; + } + + return ptr; +} + +/* + this is a replacement for the Samba3 talloc_destroy_pool functionality. It + should probably not be used in new code. It's in here to keep the talloc + code consistent across Samba 3 and 4. +*/ +void talloc_free_children(void *ptr) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return; + } + + tc = talloc_chunk_from_ptr(ptr); + + while (tc->child) { + /* we need to work out who will own an abandoned child + if it cannot be freed. In priority order, the first + choice is owner of any remaining reference to this + pointer, the second choice is our parent, and the + final choice is the null context. */ + void *child = TC_PTR_FROM_CHUNK(tc->child); + const void *new_parent = null_context; + if (unlikely(tc->child->refs)) { + struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + if (unlikely(_talloc_free(child) == -1)) { + if (new_parent == null_context) { + struct talloc_chunk *p = talloc_parent_chunk(ptr); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + talloc_steal(new_parent, child); + } + } + + if ((tc->flags & TALLOC_FLAG_POOL) + && (*talloc_pool_objectcount(tc) == 1)) { + tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE); +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_MAKE_MEM_NOACCESS( + tc->pool, tc->size - TALLOC_POOL_HDR_SIZE); +#endif + } +} + +/* + Allocate a bit of memory as a child of an existing pointer +*/ +void *_talloc(const void *context, size_t size) +{ + return __talloc(context, size); +} + +/* + externally callable talloc_set_name_const() +*/ +void talloc_set_name_const(const void *ptr, const char *name) +{ + _talloc_set_name_const(ptr, name); +} + +/* + create a named talloc pointer. Any talloc pointer can be named, and + talloc_named() operates just like talloc() except that it allows you + to name the pointer. +*/ +void *talloc_named_const(const void *context, size_t size, const char *name) +{ + return _talloc_named_const(context, size, name); +} + +/* + free a talloc pointer. This also frees all child pointers of this + pointer recursively + + return 0 if the memory is actually freed, otherwise -1. The memory + will not be freed if the ref_count is > 1 or the destructor (if + any) returns non-zero +*/ +int talloc_free(void *ptr) +{ + return _talloc_free(ptr); +} + + + +/* + A talloc version of realloc. The context argument is only used if + ptr is NULL +*/ +void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) +{ + struct talloc_chunk *tc; + void *new_ptr; + bool malloced = false; + + /* size zero is equivalent to free() */ + if (unlikely(size == 0)) { + _talloc_free(ptr); + return NULL; + } + + if (unlikely(size >= MAX_TALLOC_SIZE)) { + return NULL; + } + + /* realloc(NULL) is equivalent to malloc() */ + if (ptr == NULL) { + return _talloc_named_const(context, size, name); + } + + tc = talloc_chunk_from_ptr(ptr); + + /* don't allow realloc on referenced pointers */ + if (unlikely(tc->refs)) { + return NULL; + } + + /* don't shrink if we have less than 1k to gain */ + if ((size < tc->size) && ((tc->size - size) < 1024)) { + tc->size = size; + return ptr; + } + + /* by resetting magic we catch users of the old memory */ + tc->flags |= TALLOC_FLAG_FREE; + +#if ALWAYS_REALLOC + new_ptr = malloc(size + TC_HDR_SIZE); + if (new_ptr) { + memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE); + free(tc); + } +#else + if (tc->flags & TALLOC_FLAG_POOLMEM) { + + new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); + *talloc_pool_objectcount((struct talloc_chunk *) + (tc->pool)) -= 1; + + if (new_ptr == NULL) { + new_ptr = malloc(TC_HDR_SIZE+size); + malloced = true; + } + + if (new_ptr) { + memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); + } + } + else { + new_ptr = realloc(tc, size + TC_HDR_SIZE); + } +#endif + if (unlikely(!new_ptr)) { + tc->flags &= ~TALLOC_FLAG_FREE; + return NULL; + } + + tc = (struct talloc_chunk *)new_ptr; + tc->flags &= ~TALLOC_FLAG_FREE; + if (malloced) { + tc->flags &= ~TALLOC_FLAG_POOLMEM; + } + if (tc->parent) { + tc->parent->child = tc; + } + if (tc->child) { + tc->child->parent = tc; + } + + if (tc->prev) { + tc->prev->next = tc; + } + if (tc->next) { + tc->next->prev = tc; + } + + tc->size = size; + _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); + + return TC_PTR_FROM_CHUNK(tc); +} + +/* + a wrapper around talloc_steal() for situations where you are moving a pointer + between two structures, and want the old pointer to be set to NULL +*/ +void *_talloc_move(const void *new_ctx, const void *_pptr) +{ + const void **pptr = discard_const_p(const void *,_pptr); + void *ret = _talloc_steal(new_ctx, *pptr); + (*pptr) = NULL; + return ret; +} + +/* + return the total size of a talloc pool (subtree) +*/ +size_t talloc_total_size(const void *ptr) +{ + size_t total = 0; + struct talloc_chunk *c, *tc; + + if (ptr == NULL) { + ptr = null_context; + } + if (ptr == NULL) { + return 0; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_LOOP) { + return 0; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + total = tc->size; + for (c=tc->child;c;c=c->next) { + total += talloc_total_size(TC_PTR_FROM_CHUNK(c)); + } + + tc->flags &= ~TALLOC_FLAG_LOOP; + + return total; +} + +/* + return the total number of blocks in a talloc pool (subtree) +*/ +size_t talloc_total_blocks(const void *ptr) +{ + size_t total = 0; + struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_LOOP) { + return 0; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + total++; + for (c=tc->child;c;c=c->next) { + total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); + } + + tc->flags &= ~TALLOC_FLAG_LOOP; + + return total; +} + +/* + return the number of external references to a pointer +*/ +size_t talloc_reference_count(const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + struct talloc_reference_handle *h; + size_t ret = 0; + + for (h=tc->refs;h;h=h->next) { + ret++; + } + return ret; +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *private_data), + void *private_data) +{ + struct talloc_chunk *c, *tc; + + if (ptr == NULL) { + ptr = null_context; + } + if (ptr == NULL) return; + + tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_LOOP) { + return; + } + + callback(ptr, depth, max_depth, 0, private_data); + + if (max_depth >= 0 && depth >= max_depth) { + return; + } + + tc->flags |= TALLOC_FLAG_LOOP; + for (c=tc->child;c;c=c->next) { + if (c->name == TALLOC_MAGIC_REFERENCE) { + struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c); + callback(h->ptr, depth + 1, max_depth, 1, private_data); + } else { + talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data); + } + } + tc->flags &= ~TALLOC_FLAG_LOOP; +} + +static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) +{ + const char *name = talloc_get_name(ptr); + FILE *f = (FILE *)_f; + + if (is_ref) { + fprintf(f, "%*sreference to: %s\n", depth*4, "", name); + return; + } + + if (depth == 0) { + fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", + (max_depth < 0 ? "full " :""), name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr)); + return; + } + + fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", + depth*4, "", + name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr), + (int)talloc_reference_count(ptr), ptr); + +#if 0 + fprintf(f, "content: "); + if (talloc_total_size(ptr)) { + int tot = talloc_total_size(ptr); + int i; + + for (i = 0; i < tot; i++) { + if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { + fprintf(f, "%c", ((char *)ptr)[i]); + } else { + fprintf(f, "~%02x", ((char *)ptr)[i]); + } + } + } + fprintf(f, "\n"); +#endif +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f) +{ + talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); + fflush(f); +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +void talloc_report_full(const void *ptr, FILE *f) +{ + talloc_report_depth_file(ptr, 0, -1, f); +} + +/* + report on memory usage by all children of a pointer +*/ +void talloc_report(const void *ptr, FILE *f) +{ + talloc_report_depth_file(ptr, 0, 1, f); +} + +/* + report on any memory hanging off the null context +*/ +static void talloc_report_null(void) +{ + if (talloc_total_size(null_context) != 0) { + talloc_report(null_context, stderr); + } +} + +/* + report on any memory hanging off the null context +*/ +static void talloc_report_null_full(void) +{ + if (talloc_total_size(null_context) != 0) { + talloc_report_full(null_context, stderr); + } +} + +/* + enable tracking of the NULL context +*/ +void talloc_enable_null_tracking(void) +{ + if (null_context == NULL) { + null_context = _talloc_named_const(NULL, 0, "null_context"); + } +} + +/* + disable tracking of the NULL context +*/ +void talloc_disable_null_tracking(void) +{ + _talloc_free(null_context); + null_context = NULL; +} + +/* + enable leak reporting on exit +*/ +void talloc_enable_leak_report(void) +{ + talloc_enable_null_tracking(); + atexit(talloc_report_null); +} + +/* + enable full leak reporting on exit +*/ +void talloc_enable_leak_report_full(void) +{ + talloc_enable_null_tracking(); + atexit(talloc_report_null_full); +} + +/* + talloc and zero memory. +*/ +void *_talloc_zero(const void *ctx, size_t size, const char *name) +{ + void *p = _talloc_named_const(ctx, size, name); + + if (p) { + memset(p, '\0', size); + } + + return p; +} + +/* + memdup with a talloc. +*/ +void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) +{ + void *newp = _talloc_named_const(t, size, name); + + if (likely(newp)) { + memcpy(newp, p, size); + } + + return newp; +} + +static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) +{ + char *ret; + + ret = (char *)__talloc(t, len + 1); + if (unlikely(!ret)) return NULL; + + memcpy(ret, p, len); + ret[len] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + +/* + strdup with a talloc +*/ +char *talloc_strdup(const void *t, const char *p) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strlen(p)); +} + +/* + strndup with a talloc +*/ +char *talloc_strndup(const void *t, const char *p, size_t n) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strnlen(p, n)); +} + +static inline char *__talloc_strlendup_append(char *s, size_t slen, + const char *a, size_t alen) +{ + char *ret; + + ret = talloc_realloc(NULL, s, char, slen + alen + 1); + if (unlikely(!ret)) return NULL; + + /* append the string and the trailing \0 */ + memcpy(&ret[slen], a, alen); + ret[slen+alen] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + +/* + * Appends at the end of the string. + */ +char *talloc_strdup_append(char *s, const char *a) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); +} + +/* + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strdup_append_buffer(char *s, const char *a) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strlen(a)); +} + +/* + * Appends at the end of the string. + */ +char *talloc_strndup_append(char *s, const char *a, size_t n) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); +} + +/* + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); +} + +#ifndef HAVE_VA_COPY +#ifdef HAVE___VA_COPY +#define va_copy(dest, src) __va_copy(dest, src) +#else +#define va_copy(dest, src) (dest) = (src) +#endif +#endif + +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) +{ + int len; + char *ret; + va_list ap2; + char c; + + /* this call looks strange, but it makes it work on older solaris boxes */ + va_copy(ap2, ap); + len = vsnprintf(&c, 1, fmt, ap2); + va_end(ap2); + if (unlikely(len < 0)) { + return NULL; + } + + ret = (char *)__talloc(t, len+1); + if (unlikely(!ret)) return NULL; + + va_copy(ap2, ap); + vsnprintf(ret, len+1, fmt, ap2); + va_end(ap2); + + _talloc_set_name_const(ret, ret); + return ret; +} + + +/* + Perform string formatting, and return a pointer to newly allocated + memory holding the result, inside a memory pool. + */ +char *talloc_asprintf(const void *t, const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = talloc_vasprintf(t, fmt, ap); + va_end(ap); + return ret; +} + +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) + PRINTF_ATTRIBUTE(3,0); + +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) +{ + ssize_t alen; + va_list ap2; + char c; + + va_copy(ap2, ap); + alen = vsnprintf(&c, 1, fmt, ap2); + va_end(ap2); + + if (alen <= 0) { + /* Either the vsnprintf failed or the format resulted in + * no characters being formatted. In the former case, we + * ought to return NULL, in the latter we ought to return + * the original string. Most current callers of this + * function expect it to never return NULL. + */ + return s; + } + + s = talloc_realloc(NULL, s, char, slen + alen + 1); + if (!s) return NULL; + + va_copy(ap2, ap); + vsnprintf(s + slen, alen + 1, fmt, ap2); + va_end(ap2); + + _talloc_set_name_const(s, s); + return s; +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Good for gradually + * accumulating output into a string buffer. Appends at the end + * of the string. + **/ +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) +{ + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Always appends at the + * end of the talloc'ed buffer, not the end of the string. + **/ +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_vaslenprintf_append(s, slen, fmt, ap); +} + +/* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a string buffer. + */ +char *talloc_asprintf_append(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append(s, fmt, ap); + va_end(ap); + return s; +} + +/* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a buffer. + */ +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append_buffer(s, fmt, ap); + va_end(ap); + return s; +} + +/* + alloc an array, checking for integer overflow in the array size +*/ +void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + return NULL; + } + return _talloc_named_const(ctx, el_size * count, name); +} + +/* + alloc an zero array, checking for integer overflow in the array size +*/ +void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + return NULL; + } + return _talloc_zero(ctx, el_size * count, name); +} + +/* + realloc an array, checking for integer overflow in the array size +*/ +void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + return NULL; + } + return _talloc_realloc(ctx, ptr, el_size * count, name); +} + +/* + a function version of talloc_realloc(), so it can be passed as a function pointer + to libraries that want a realloc function (a realloc function encapsulates + all the basic capabilities of an allocation library, which is why this is useful) +*/ +void *talloc_realloc_fn(const void *context, void *ptr, size_t size) +{ + return _talloc_realloc(context, ptr, size, NULL); +} + + +static int talloc_autofree_destructor(void *ptr) +{ + autofree_context = NULL; + return 0; +} + +static void talloc_autofree(void) +{ + _talloc_free(autofree_context); +} + +/* + return a context which will be auto-freed on exit + this is useful for reducing the noise in leak reports +*/ +void *talloc_autofree_context(void) +{ + if (autofree_context == NULL) { + autofree_context = _talloc_named_const(NULL, 0, "autofree_context"); + talloc_set_destructor(autofree_context, talloc_autofree_destructor); + atexit(talloc_autofree); + } + return autofree_context; +} + +size_t talloc_get_size(const void *context) +{ + struct talloc_chunk *tc; + + if (context == NULL) + return 0; + + tc = talloc_chunk_from_ptr(context); + + return tc->size; +} + +/* + find a parent of this context that has the given name, if any +*/ +void *talloc_find_parent_byname(const void *context, const char *name) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + return NULL; + } + + tc = talloc_chunk_from_ptr(context); + while (tc) { + if (tc->name && strcmp(tc->name, name) == 0) { + return TC_PTR_FROM_CHUNK(tc); + } + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + return NULL; +} + +/* + show the parentage of a context +*/ +void talloc_show_parents(const void *context, FILE *file) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + fprintf(file, "talloc no parents for NULL\n"); + return; + } + + tc = talloc_chunk_from_ptr(context); + fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); + while (tc) { + fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + fflush(file); +} + +/* + return 1 if ptr is a parent of context +*/ +int talloc_is_parent(const void *context, const void *ptr) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + return 0; + } + + tc = talloc_chunk_from_ptr(context); + while (tc) { + if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + return 0; +} diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h new file mode 100644 index 0000000000..5431971655 --- /dev/null +++ b/lib/talloc/talloc.h @@ -0,0 +1,183 @@ +#ifndef _TALLOC_H_ +#define _TALLOC_H_ +/* + Unix SMB/CIFS implementation. + Samba temporary memory allocation functions + + Copyright (C) Andrew Tridgell 2004-2005 + Copyright (C) Stefan Metzmacher 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include +#include +#include + +/* this is only needed for compatibility with the old talloc */ +typedef void TALLOC_CTX; + +/* + this uses a little trick to allow __LINE__ to be stringified +*/ +#ifndef __location__ +#define __TALLOC_STRING_LINE1__(s) #s +#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s) +#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__) +#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__ +#endif + +#ifndef TALLOC_DEPRECATED +#define TALLOC_DEPRECATED 0 +#endif + +#ifndef PRINTF_ATTRIBUTE +#if (__GNUC__ >= 3) +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +/* try to make talloc_set_destructor() and talloc_steal() type safe, + if we have a recent gcc */ +#if (__GNUC__ >= 3) +#define _TALLOC_TYPEOF(ptr) __typeof__(ptr) +#define talloc_set_destructor(ptr, function) \ + do { \ + int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \ + _talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \ + } while(0) +/* this extremely strange macro is to avoid some braindamaged warning + stupidity in gcc 4.1.x */ +#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; }) +#else +#define talloc_set_destructor(ptr, function) \ + _talloc_set_destructor((ptr), (int (*)(void *))(function)) +#define _TALLOC_TYPEOF(ptr) void * +#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)) +#endif + +#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr)) +#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr)) + +/* useful macros for creating type checked pointers */ +#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) +#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) +#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) + +#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) + +#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) +#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) + +#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) +#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) +#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) +#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) + +#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) +#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) + +#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) + +#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) +#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) + +#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) + +#if TALLOC_DEPRECATED +#define talloc_zero_p(ctx, type) talloc_zero(ctx, type) +#define talloc_p(ctx, type) talloc(ctx, type) +#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) +#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) +#define talloc_destroy(ctx) talloc_free(ctx) +#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) +#endif + +/* The following definitions come from talloc.c */ +void *_talloc(const void *context, size_t size); +void *talloc_pool(const void *context, size_t size); +void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); +int talloc_increase_ref_count(const void *ptr); +size_t talloc_reference_count(const void *ptr); +void *_talloc_reference(const void *context, const void *ptr); +int talloc_unlink(const void *context, void *ptr); +const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +void talloc_set_name_const(const void *ptr, const char *name); +void *talloc_named(const void *context, size_t size, + const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); +void *talloc_named_const(const void *context, size_t size, const char *name); +const char *talloc_get_name(const void *ptr); +void *talloc_check_name(const void *ptr, const char *name); +void *talloc_parent(const void *ptr); +const char *talloc_parent_name(const void *ptr); +void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); +int talloc_free(void *ptr); +void talloc_free_children(void *ptr); +void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); +void *_talloc_steal(const void *new_ctx, const void *ptr); +void *_talloc_move(const void *new_ctx, const void *pptr); +size_t talloc_total_size(const void *ptr); +size_t talloc_total_blocks(const void *ptr); +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *private_data), + void *private_data); +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); +void talloc_report_full(const void *ptr, FILE *f); +void talloc_report(const void *ptr, FILE *f); +void talloc_enable_null_tracking(void); +void talloc_disable_null_tracking(void); +void talloc_enable_leak_report(void); +void talloc_enable_leak_report_full(void); +void *_talloc_zero(const void *ctx, size_t size, const char *name); +void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); +void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); +void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); +void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); +void *talloc_realloc_fn(const void *context, void *ptr, size_t size); +void *talloc_autofree_context(void); +size_t talloc_get_size(const void *ctx); +void *talloc_find_parent_byname(const void *ctx, const char *name); +void talloc_show_parents(const void *context, FILE *file); +int talloc_is_parent(const void *context, const void *ptr); + +char *talloc_strdup(const void *t, const char *p); +char *talloc_strdup_append(char *s, const char *a); +char *talloc_strdup_append_buffer(char *s, const char *a); + +char *talloc_strndup(const void *t, const char *p, size_t n); +char *talloc_strndup_append(char *s, const char *a, size_t n); +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); + +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +#endif diff --git a/lib/talloc/talloc.i b/lib/talloc/talloc.i new file mode 100644 index 0000000000..a9afb97ed7 --- /dev/null +++ b/lib/talloc/talloc.i @@ -0,0 +1,31 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* Don't expose talloc contexts in Python code. Python does reference + counting for us, so just create a new top-level talloc context. + */ +%typemap(in, numinputs=0, noblock=1) TALLOC_CTX * { + $1 = NULL; +} + +%define %talloctype(TYPE) +%nodefaultctor TYPE; +%extend TYPE { + ~TYPE() { talloc_free($self); } +} +%enddef diff --git a/lib/talloc/talloc.mk b/lib/talloc/talloc.mk new file mode 100644 index 0000000000..e1fe88c84b --- /dev/null +++ b/lib/talloc/talloc.mk @@ -0,0 +1,37 @@ +TALLOC_OBJ = $(tallocdir)/talloc.o + +TALLOC_SOLIB = libtalloc.$(SHLIBEXT).$(PACKAGE_VERSION) +TALLOC_SONAME = libtalloc.$(SHLIBEXT).1 + +all:: libtalloc.a $(TALLOC_SOLIB) testsuite + +testsuite:: $(LIBOBJ) testsuite.o + $(CC) $(CFLAGS) -o testsuite testsuite.o $(LIBOBJ) $(LIBS) + +libtalloc.a: $(LIBOBJ) + ar -rv $@ $(LIBOBJ) + @-ranlib $@ + +install:: all + ${INSTALLCMD} -d $(DESTDIR)$(libdir) + ${INSTALLCMD} -d $(DESTDIR)$(libdir)/pkgconfig + ${INSTALLCMD} -m 755 libtalloc.a $(DESTDIR)$(libdir) + ${INSTALLCMD} -m 755 $(TALLOC_SOLIB) $(DESTDIR)$(libdir) + ${INSTALLCMD} -d $(DESTDIR)${includedir} + ${INSTALLCMD} -m 644 $(srcdir)/talloc.h $(DESTDIR)$(includedir) + ${INSTALLCMD} -m 644 talloc.pc $(DESTDIR)$(libdir)/pkgconfig + if [ -f talloc.3 ];then ${INSTALLCMD} -d $(DESTDIR)$(mandir)/man3; fi + if [ -f talloc.3 ];then ${INSTALLCMD} -m 644 talloc.3 $(DESTDIR)$(mandir)/man3; fi + which swig >/dev/null 2>&1 && ${INSTALLCMD} -d $(DESTDIR)`swig -swiglib` || true + which swig >/dev/null 2>&1 && ${INSTALLCMD} -m 644 talloc.i $(DESTDIR)`swig -swiglib` || true + +doc:: talloc.3 talloc.3.html + +clean:: + rm -f *~ $(LIBOBJ) $(TALLOC_SOLIB) libtalloc.a testsuite testsuite.o *.gc?? talloc.3 talloc.3.html + +test:: testsuite + ./testsuite + +gcov:: + gcov talloc.c diff --git a/lib/talloc/talloc.pc.in b/lib/talloc/talloc.pc.in new file mode 100644 index 0000000000..459cce70b1 --- /dev/null +++ b/lib/talloc/talloc.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: talloc +Description: A hierarchical pool based memory system with destructors +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -ltalloc +Cflags: -I${includedir} +URL: http://talloc.samba.org/ diff --git a/lib/talloc/talloc_guide.txt b/lib/talloc/talloc_guide.txt new file mode 100644 index 0000000000..18663b370d --- /dev/null +++ b/lib/talloc/talloc_guide.txt @@ -0,0 +1,685 @@ +Using talloc in Samba4 +---------------------- + +Andrew Tridgell +September 2004 + +The most current version of this document is available at + http://samba.org/ftp/unpacked/samba4/source/lib/talloc/talloc_guide.txt + +If you are used to the "old" talloc from Samba3 before 3.0.20 then please read +this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the +Samba4 talloc has been ported back to Samba3, so this guide applies to both. + +The new talloc is a hierarchical, reference counted memory pool system +with destructors. Quite a mouthful really, but not too bad once you +get used to it. + +Perhaps the biggest change from Samba3 is that there is no distinction +between a "talloc context" and a "talloc pointer". Any pointer +returned from talloc() is itself a valid talloc context. This means +you can do this: + + struct foo *X = talloc(mem_ctx, struct foo); + X->name = talloc_strdup(X, "foo"); + +and the pointer X->name would be a "child" of the talloc context "X" +which is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) +then it is all destroyed, whereas if you do talloc_free(X) then just X +and X->name are destroyed, and if you do talloc_free(X->name) then +just the name element of X is destroyed. + +If you think about this, then what this effectively gives you is an +n-ary tree, where you can free any part of the tree with +talloc_free(). + +If you find this confusing, then I suggest you run the testsuite to +watch talloc in action. You may also like to add your own tests to +testsuite.c to clarify how some particular situation is handled. + + +Performance +----------- + +All the additional features of talloc() over malloc() do come at a +price. We have a simple performance test in Samba4 that measures +talloc() versus malloc() performance, and it seems that talloc() is +about 4% slower than malloc() on my x86 Debian Linux box. For Samba, +the great reduction in code complexity that we get by using talloc +makes this worthwhile, especially as the total overhead of +talloc/malloc in Samba is already quite small. + + +talloc API +---------- + +The following is a complete guide to the talloc API. Read it all at +least twice. + +Multi-threading +--------------- + +talloc itself does not deal with threads. It is thread-safe (assuming +the underlying "malloc" is), as long as each thread uses different +memory contexts. +If two threads uses the same context then they need to synchronize in +order to be safe. In particular: +- when using talloc_enable_leak_report(), giving directly NULL as a +parent context implicitly refers to a hidden "null context" global +variable, so this should not be used in a multi-threaded environment +without proper synchronization ; +- the context returned by talloc_autofree_context() is also global so +shouldn't be used by several threads simultaneously without +synchronization. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc(const void *context, type); + +The talloc() macro is the core of the talloc library. It takes a +memory context and a type, and returns a pointer to a new area of +memory of the given type. + +The returned pointer is itself a talloc context, so you can use it as +the context argument to more calls to talloc if you wish. + +The returned pointer is a "child" of the supplied context. This means +that if you talloc_free() the context then the new child disappears as +well. Alternatively you can free just the child. + +The context argument to talloc() can be NULL, in which case a new top +level context is created. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_size(const void *context, size_t size); + +The function talloc_size() should be used when you don't have a +convenient type to pass to talloc(). Unlike talloc(), it is not type +safe (as it returns a void *), so you are on your own for type checking. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); + +The talloc_ptrtype() macro should be used when you have a pointer and +want to allocate memory to point at with this pointer. When compiling +with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() +and talloc_get_name() will return the current location in the source file. +and not the type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_free(void *ptr); + +The talloc_free() function frees a piece of talloc memory, and all its +children. You can call talloc_free() on any pointer returned by +talloc(). + +The return value of talloc_free() indicates success or failure, with 0 +returned for success and -1 for failure. The only possible failure +condition is if the pointer had a destructor attached to it and the +destructor returned -1. See talloc_set_destructor() for details on +destructors. + +If this pointer has an additional parent when talloc_free() is called +then the memory is not actually released, but instead the most +recently established parent is destroyed. See talloc_reference() for +details on establishing additional parents. + +For more control on which parent is removed, see talloc_unlink() + +talloc_free() operates recursively on its children. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_free_children(void *ptr); + +The talloc_free_children() walks along the list of all children of a +talloc context and talloc_free()s only the children, not the context +itself. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_reference(const void *context, const void *ptr); + +The talloc_reference() function makes "context" an additional parent +of "ptr". + +The return value of talloc_reference() is always the original pointer +"ptr", unless talloc ran out of memory in creating the reference in +which case it will return NULL (each additional reference consumes +around 48 bytes of memory on intel x86 platforms). + +If "ptr" is NULL, then the function is a no-op, and simply returns NULL. + +After creating a reference you can free it in one of the following +ways: + + - you can talloc_free() any parent of the original pointer. That + will reduce the number of parents of this pointer by 1, and will + cause this pointer to be freed if it runs out of parents. + + - you can talloc_free() the pointer itself. That will destroy the + most recently established parent to the pointer and leave the + pointer as a child of its current parent. + +For more control on which parent to remove, see talloc_unlink() + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_unlink(const void *context, const void *ptr); + +The talloc_unlink() function removes a specific parent from ptr. The +context passed must either be a context used in talloc_reference() +with this pointer, or must be a direct parent of ptr. + +Note that if the parent has already been removed using talloc_free() +then this function will fail and will return -1. Likewise, if "ptr" +is NULL, then the function will make no modifications and return -1. + +Usually you can just use talloc_free() instead of talloc_unlink(), but +sometimes it is useful to have the additional control on which parent +is removed. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + +The function talloc_set_destructor() sets the "destructor" for the +pointer "ptr". A destructor is a function that is called when the +memory used by a pointer is about to be released. The destructor +receives the pointer as an argument, and should return 0 for success +and -1 for failure. + +The destructor can do anything it wants to, including freeing other +pieces of memory. A common use for destructors is to clean up +operating system resources (such as open file descriptors) contained +in the structure the destructor is placed on. + +You can only place one destructor on a pointer. If you need more than +one destructor then you can create a zero-length child of the pointer +and place an additional destructor on that. + +To remove a destructor call talloc_set_destructor() with NULL for the +destructor. + +If your destructor attempts to talloc_free() the pointer that it is +the destructor for then talloc_free() will return -1 and the free will +be ignored. This would be a pointless operation anyway, as the +destructor is only called when the memory is just about to go away. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_increase_ref_count(const void *ptr); + +The talloc_increase_ref_count(ptr) function is exactly equivalent to: + + talloc_reference(NULL, ptr); + +You can use either syntax, depending on which you think is clearer in +your code. + +It returns 0 on success and -1 on failure. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_reference_count(const void *ptr); + +Return the number of references to the pointer. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_name(const void *ptr, const char *fmt, ...); + +Each talloc pointer has a "name". The name is used principally for +debugging purposes, although it is also possible to set and get the +name on a pointer in as a way of "marking" pointers in your code. + +The main use for names on pointer is for "talloc reports". See +talloc_report() and talloc_report_full() for details. Also see +talloc_enable_leak_report() and talloc_enable_leak_report_full(). + +The talloc_set_name() function allocates memory as a child of the +pointer. It is logically equivalent to: + talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + +Note that multiple calls to talloc_set_name() will allocate more +memory without releasing the name. All of the memory is released when +the ptr is freed using talloc_free(). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_name_const(const void *ptr, const char *name); + +The function talloc_set_name_const() is just like talloc_set_name(), +but it takes a string constant, and is much faster. It is extensively +used by the "auto naming" macros, such as talloc_p(). + +This function does not allocate any memory. It just copies the +supplied pointer into the internal representation of the talloc +ptr. This means you must not pass a name pointer to memory that will +disappear before the ptr is freed with talloc_free(). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_named(const void *context, size_t size, const char *fmt, ...); + +The talloc_named() function creates a named talloc pointer. It is +equivalent to: + + ptr = talloc_size(context, size); + talloc_set_name(ptr, fmt, ....); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_named_const(const void *context, size_t size, const char *name); + +This is equivalent to: + + ptr = talloc_size(context, size); + talloc_set_name_const(ptr, name); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +const char *talloc_get_name(const void *ptr); + +This returns the current name for the given talloc pointer. See +talloc_set_name() for details. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_init(const char *fmt, ...); + +This function creates a zero length named talloc context as a top +level context. It is equivalent to: + + talloc_named(NULL, 0, fmt, ...); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_new(void *ctx); + +This is a utility macro that creates a new memory context hanging +off an exiting context, automatically naming it "talloc_new: __location__" +where __location__ is the source line it is called from. It is +particularly useful for creating a new temporary working context. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_realloc(const void *context, void *ptr, type, count); + +The talloc_realloc() macro changes the size of a talloc +pointer. The "count" argument is the number of elements of type "type" +that you want the resulting pointer to hold. + +talloc_realloc() has the following equivalences: + + talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); + talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); + talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); + +The "context" argument is only used if "ptr" is NULL, otherwise it is +ignored. + +talloc_realloc() returns the new pointer, or NULL on failure. The call +will fail either due to a lack of memory, or because the pointer has +more than one parent (see talloc_reference()). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_realloc_size(const void *context, void *ptr, size_t size); + +the talloc_realloc_size() function is useful when the type is not +known so the typesafe talloc_realloc() cannot be used. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_steal(const void *new_ctx, const void *ptr); + +The talloc_steal() function changes the parent context of a talloc +pointer. It is typically used when the context that the pointer is +currently a child of is going to be freed and you wish to keep the +memory for a longer time. + +The talloc_steal() function returns the pointer that you pass it. It +does not have any failure modes. + +NOTE: It is possible to produce loops in the parent/child relationship +if you are not careful with talloc_steal(). No guarantees are provided +as to your sanity or the safety of your data if you do this. + +talloc_steal (new_ctx, NULL) will return NULL with no sideeffects. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_total_size(const void *ptr); + +The talloc_total_size() function returns the total size in bytes used +by this pointer and all child pointers. Mostly useful for debugging. + +Passing NULL is allowed, but it will only give a meaningful result if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_total_blocks(const void *ptr); + +The talloc_total_blocks() function returns the total memory block +count used by this pointer and all child pointers. Mostly useful for +debugging. + +Passing NULL is allowed, but it will only give a meaningful result if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *priv), + void *priv); + +This provides a more flexible reports than talloc_report(). It +will recursively call the callback for the entire tree of memory +referenced by the pointer. References in the tree are passed with +is_ref = 1 and the pointer that is referenced. + +You can pass NULL for the pointer, in which case a report is +printed for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() +has been called. + +The recursion is stopped when depth >= max_depth. +max_depth = -1 means only stop at leaf nodes. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); + +This provides a more flexible reports than talloc_report(). It +will let you specify the depth and max_depth. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report(const void *ptr, FILE *f); + +The talloc_report() function prints a summary report of all memory +used by ptr. One line of report is printed for each immediate child of +ptr, showing the total memory and number of blocks used by that child. + +You can pass NULL for the pointer, in which case a report is printed +for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_full(const void *ptr, FILE *f); + +This provides a more detailed report than talloc_report(). It will +recursively print the ensire tree of memory referenced by the +pointer. References in the tree are shown by giving the name of the +pointer that is referenced. + +You can pass NULL for the pointer, in which case a report is printed +for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_leak_report(void); + +This enables calling of talloc_report(NULL, stderr) when the program +exits. In Samba4 this is enabled by using the --leak-report command +line option. + +For it to be useful, this function must be called before any other +talloc function as it establishes a "null context" that acts as the +top of the tree. If you don't call this function first then passing +NULL to talloc_report() or talloc_report_full() won't give you the +full tree printout. + +Here is a typical talloc report: + +talloc report on 'null_context' (total 267 bytes in 15 blocks) + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(UTF8,CP850) contains 42 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(CP850,UTF8) contains 42 bytes in 2 blocks + iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks + iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_leak_report_full(void); + +This enables calling of talloc_report_full(NULL, stderr) when the +program exits. In Samba4 this is enabled by using the +--leak-report-full command line option. + +For it to be useful, this function must be called before any other +talloc function as it establishes a "null context" that acts as the +top of the tree. If you don't call this function first then passing +NULL to talloc_report() or talloc_report_full() won't give you the +full tree printout. + +Here is a typical full report: + +full talloc report on 'root' (total 18 bytes in 8 blocks) + p1 contains 18 bytes in 7 blocks (ref 0) + r1 contains 13 bytes in 2 blocks (ref 0) + reference to: p2 + p2 contains 1 bytes in 1 blocks (ref 1) + x3 contains 1 bytes in 1 blocks (ref 0) + x2 contains 1 bytes in 1 blocks (ref 0) + x1 contains 1 bytes in 1 blocks (ref 0) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_null_tracking(void); + +This enables tracking of the NULL memory context without enabling leak +reporting on exit. Useful for when you want to do your own leak +reporting call via talloc_report_null_full(); + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_disable_null_tracking(void); + +This disables tracking of the NULL memory context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_zero(const void *ctx, type); + +The talloc_zero() macro is equivalent to: + + ptr = talloc(ctx, type); + if (ptr) memset(ptr, 0, sizeof(type)); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_zero_size(const void *ctx, size_t size) + +The talloc_zero_size() function is useful when you don't have a known type + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_memdup(const void *ctx, const void *p, size_t size); + +The talloc_memdup() function is equivalent to: + + ptr = talloc_size(ctx, size); + if (ptr) memcpy(ptr, p, size); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_strdup(const void *ctx, const char *p); + +The talloc_strdup() function is equivalent to: + + ptr = talloc_size(ctx, strlen(p)+1); + if (ptr) memcpy(ptr, p, strlen(p)+1); + +This functions sets the name of the new pointer to the passed +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_strndup(const void *t, const char *p, size_t n); + +The talloc_strndup() function is the talloc equivalent of the C +library function strndup() + +This functions sets the name of the new pointer to the passed +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_append_string(const void *t, char *orig, const char *append); + +The talloc_append_string() function appends the given formatted +string to the given string. + +This function sets the name of the new pointer to the new +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); + +The talloc_vasprintf() function is the talloc equivalent of the C +library function vasprintf() + +This functions sets the name of the new pointer to the new +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf(const void *t, const char *fmt, ...); + +The talloc_asprintf() function is the talloc equivalent of the C +library function asprintf() + +This functions sets the name of the new pointer to the new +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append(char *s, const char *fmt, ...); + +The talloc_asprintf_append() function appends the given formatted +string to the given string. +Use this varient when the string in the current talloc buffer may +have been truncated in length. + +This functions sets the name of the new pointer to the new +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); + +The talloc_asprintf_append() function appends the given formatted +string to the end of the currently allocated talloc buffer. +Use this varient when the string in the current talloc buffer has +not been changed. + +This functions sets the name of the new pointer to the new +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +((type *)talloc_array(const void *ctx, type, uint_t count); + +The talloc_array() macro is equivalent to: + + (type *)talloc_size(ctx, sizeof(type) * count); + +except that it provides integer overflow protection for the multiply, +returning NULL if the multiply overflows. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_array_size(const void *ctx, size_t size, uint_t count); + +The talloc_array_size() function is useful when the type is not +known. It operates in the same way as talloc_array(), but takes a size +instead of a type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count); + +The talloc_ptrtype() macro should be used when you have a pointer to an array +and want to allocate memory of an array to point at with this pointer. When compiling +with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() +and talloc_get_name() will return the current location in the source file. +and not the type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size); + +This is a non-macro version of talloc_realloc(), which is useful +as libraries sometimes want a ralloc function pointer. A realloc() +implementation encapsulates the functionality of malloc(), free() and +realloc() in one call, which is why it is useful to be able to pass +around a single function pointer. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_autofree_context(void); + +This is a handy utility function that returns a talloc context +which will be automatically freed on program exit. This can be used +to reduce the noise in memory leak reports. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_check_name(const void *ptr, const char *name); + +This function checks if a pointer has the specified name. If it does +then the pointer is returned. It it doesn't then NULL is returned. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_get_type(const void *ptr, type); + +This macro allows you to do type checking on talloc pointers. It is +particularly useful for void* private pointers. It is equivalent to +this: + + (type *)talloc_check_name(ptr, #type) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +talloc_set_type(const void *ptr, type); + +This macro allows you to force the name of a pointer to be a +particular type. This can be used in conjunction with +talloc_get_type() to do type checking on void* pointers. + +It is equivalent to this: + talloc_set_name_const(ptr, #type) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +talloc_get_size(const void *ctx); + +This function lets you know the amount of memory alloced so far by +this context. It does NOT account for subcontext memory. +This can be used to calculate the size of an array. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_find_parent_byname(const void *ctx, const char *name); + +Find a parent memory context of the current context that has the given +name. This can be very useful in complex programs where it may be +difficult to pass all information down to the level you need, but you +know the structure you want is a parent of another context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_find_parent_bytype(ctx, type); + +Like talloc_find_parent_byname() but takes a type, making it typesafe. + diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c new file mode 100644 index 0000000000..3f06eee566 --- /dev/null +++ b/lib/talloc/testsuite.c @@ -0,0 +1,1152 @@ +/* + Unix SMB/CIFS implementation. + + local testing of talloc routines. + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/time.h" +#include "talloc.h" + +static struct timeval timeval_current(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv; +} + +static double timeval_elapsed(struct timeval *tv) +{ + struct timeval tv2 = timeval_current(); + return (tv2.tv_sec - tv->tv_sec) + + (tv2.tv_usec - tv->tv_usec)*1.0e-6; +} + +#define torture_assert(test, expr, str) if (!(expr)) { \ + printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \ + test, __location__, #expr, str); \ + return false; \ +} + +#define torture_assert_str_equal(test, arg1, arg2, desc) \ + if (arg1 == NULL && arg2 == NULL) { \ + } else if (strcmp(arg1, arg2)) { \ + printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \ + test, __location__, arg1, arg2, desc); \ + return false; \ + } + +#if _SAMBA_BUILD_==3 +#ifdef malloc +#undef malloc +#endif +#ifdef strdup +#undef strdup +#endif +#endif + +#define CHECK_SIZE(test, ptr, tsize) do { \ + if (talloc_total_size(ptr) != (tsize)) { \ + printf("failed: %s [\nwrong '%s' tree size: got %u expected %u\n]\n", \ + test, #ptr, \ + (unsigned)talloc_total_size(ptr), \ + (unsigned)tsize); \ + talloc_report_full(ptr, stdout); \ + return false; \ + } \ +} while (0) + +#define CHECK_BLOCKS(test, ptr, tblocks) do { \ + if (talloc_total_blocks(ptr) != (tblocks)) { \ + printf("failed: %s [\nwrong '%s' tree blocks: got %u expected %u\n]\n", \ + test, #ptr, \ + (unsigned)talloc_total_blocks(ptr), \ + (unsigned)tblocks); \ + talloc_report_full(ptr, stdout); \ + return false; \ + } \ +} while (0) + +#define CHECK_PARENT(test, ptr, parent) do { \ + if (talloc_parent(ptr) != (parent)) { \ + printf("failed: %s [\n'%s' has wrong parent: got %p expected %p\n]\n", \ + test, #ptr, \ + talloc_parent(ptr), \ + (parent)); \ + talloc_report_full(ptr, stdout); \ + talloc_report_full(parent, stdout); \ + talloc_report_full(NULL, stdout); \ + return false; \ + } \ +} while (0) + + +/* + test references +*/ +static bool test_ref1(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref1\n# SINGLE REFERENCE FREE\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + p2 = talloc_named_const(p1, 1, "p2"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 2, "x2"); + talloc_named_const(p1, 3, "x3"); + + r1 = talloc_named_const(root, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref1", p1, 5); + CHECK_BLOCKS("ref1", p2, 1); + CHECK_BLOCKS("ref1", r1, 2); + + fprintf(stderr, "Freeing p2\n"); + talloc_free(p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref1", p1, 5); + CHECK_BLOCKS("ref1", p2, 1); + CHECK_BLOCKS("ref1", r1, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref1", r1, 1); + + fprintf(stderr, "Freeing r1\n"); + talloc_free(r1); + talloc_report_full(NULL, stderr); + + fprintf(stderr, "Testing NULL\n"); + if (talloc_reference(root, NULL)) { + return false; + } + + CHECK_BLOCKS("ref1", root, 1); + + CHECK_SIZE("ref1", root, 0); + + talloc_free(root); + printf("success: ref1\n"); + return true; +} + +/* + test references +*/ +static bool test_ref2(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref2\n# DOUBLE REFERENCE FREE\n"); + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 1, "x2"); + talloc_named_const(p1, 1, "x3"); + p2 = talloc_named_const(p1, 1, "p2"); + + r1 = talloc_named_const(root, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", p1, 5); + CHECK_BLOCKS("ref2", p2, 1); + CHECK_BLOCKS("ref2", r1, 2); + + fprintf(stderr, "Freeing ref\n"); + talloc_free(ref); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", p1, 5); + CHECK_BLOCKS("ref2", p2, 1); + CHECK_BLOCKS("ref2", r1, 1); + + fprintf(stderr, "Freeing p2\n"); + talloc_free(p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", p1, 4); + CHECK_BLOCKS("ref2", r1, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", r1, 1); + + fprintf(stderr, "Freeing r1\n"); + talloc_free(r1); + talloc_report_full(root, stderr); + + CHECK_SIZE("ref2", root, 0); + + talloc_free(root); + printf("success: ref2\n"); + return true; +} + +/* + test references +*/ +static bool test_ref3(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref3\n# PARENT REFERENCE FREE\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + p2 = talloc_named_const(root, 1, "p2"); + r1 = talloc_named_const(p1, 1, "r1"); + ref = talloc_reference(p2, r1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref3", p1, 2); + CHECK_BLOCKS("ref3", p2, 2); + CHECK_BLOCKS("ref3", r1, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref3", p2, 2); + CHECK_BLOCKS("ref3", r1, 1); + + fprintf(stderr, "Freeing p2\n"); + talloc_free(p2); + talloc_report_full(root, stderr); + + CHECK_SIZE("ref3", root, 0); + + talloc_free(root); + + printf("success: ref3\n"); + return true; +} + +/* + test references +*/ +static bool test_ref4(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref4\n# REFERRER REFERENCE FREE\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 1, "x2"); + talloc_named_const(p1, 1, "x3"); + p2 = talloc_named_const(p1, 1, "p2"); + + r1 = talloc_named_const(root, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref4", p1, 5); + CHECK_BLOCKS("ref4", p2, 1); + CHECK_BLOCKS("ref4", r1, 2); + + fprintf(stderr, "Freeing r1\n"); + talloc_free(r1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref4", p1, 5); + CHECK_BLOCKS("ref4", p2, 1); + + fprintf(stderr, "Freeing p2\n"); + talloc_free(p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref4", p1, 4); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_SIZE("ref4", root, 0); + + talloc_free(root); + + printf("success: ref4\n"); + return true; +} + + +/* + test references +*/ +static bool test_unlink1(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: unlink\n# UNLINK\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 1, "x2"); + talloc_named_const(p1, 1, "x3"); + p2 = talloc_named_const(p1, 1, "p2"); + + r1 = talloc_named_const(p1, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("unlink", p1, 7); + CHECK_BLOCKS("unlink", p2, 1); + CHECK_BLOCKS("unlink", r1, 2); + + fprintf(stderr, "Unreferencing r1\n"); + talloc_unlink(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("unlink", p1, 6); + CHECK_BLOCKS("unlink", p2, 1); + CHECK_BLOCKS("unlink", r1, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_SIZE("unlink", root, 0); + + talloc_free(root); + + printf("success: unlink\n"); + return true; +} + +static int fail_destructor(void *ptr) +{ + return -1; +} + +/* + miscellaneous tests to try to get a higher test coverage percentage +*/ +static bool test_misc(void) +{ + void *root, *p1; + char *p2; + double *d; + const char *name; + + printf("test: misc\n# MISCELLANEOUS\n"); + + root = talloc_new(NULL); + + p1 = talloc_size(root, 0x7fffffff); + torture_assert("misc", !p1, "failed: large talloc allowed\n"); + + p1 = talloc_strdup(root, "foo"); + talloc_increase_ref_count(p1); + talloc_increase_ref_count(p1); + talloc_increase_ref_count(p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + talloc_free(p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + talloc_unlink(NULL, p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + p2 = talloc_strdup(p1, "foo"); + torture_assert("misc", talloc_unlink(root, p2) == -1, + "failed: talloc_unlink() of non-reference context should return -1\n"); + torture_assert("misc", talloc_unlink(p1, p2) == 0, + "failed: talloc_unlink() of parent should succeed\n"); + talloc_free(p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + + name = talloc_set_name(p1, "my name is %s", "foo"); + torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", + "failed: wrong name after talloc_set_name(my name is foo)"); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + + talloc_set_name_const(p1, NULL); + torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", + "failed: wrong name after talloc_set_name(NULL)"); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + + torture_assert("misc", talloc_free(NULL) == -1, + "talloc_free(NULL) should give -1\n"); + + talloc_set_destructor(p1, fail_destructor); + torture_assert("misc", talloc_free(p1) == -1, + "Failed destructor should cause talloc_free to fail\n"); + talloc_set_destructor(p1, NULL); + + talloc_report(root, stderr); + + + p2 = (char *)talloc_zero_size(p1, 20); + torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); + talloc_free(p2); + + torture_assert("misc", talloc_strdup(root, NULL) == NULL, + "failed: strdup on NULL should give NULL\n"); + + p2 = talloc_strndup(p1, "foo", 2); + torture_assert("misc", strcmp("fo", p2) == 0, + "strndup doesn't work\n"); + p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); + torture_assert("misc", strcmp("food", p2) == 0, + "talloc_asprintf_append_buffer doesn't work\n"); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 3); + + p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); + torture_assert("misc", strcmp("hello world", p2) == 0, + "talloc_asprintf_append_buffer doesn't work\n"); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 3); + talloc_free(p2); + + d = talloc_array(p1, double, 0x20000000); + torture_assert("misc", !d, "failed: integer overflow not detected\n"); + + d = talloc_realloc(p1, d, double, 0x20000000); + torture_assert("misc", !d, "failed: integer overflow not detected\n"); + + talloc_free(p1); + CHECK_BLOCKS("misc", root, 1); + + p1 = talloc_named(root, 100, "%d bytes", 100); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + talloc_unlink(root, p1); + + p1 = talloc_init("%d bytes", 200); + p2 = talloc_asprintf(p1, "my test '%s'", "string"); + torture_assert_str_equal("misc", p2, "my test 'string'", + "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); + CHECK_BLOCKS("misc", p1, 3); + CHECK_SIZE("misc", p2, 17); + CHECK_BLOCKS("misc", root, 1); + talloc_unlink(NULL, p1); + + p1 = talloc_named_const(root, 10, "p1"); + p2 = (char *)talloc_named_const(root, 20, "p2"); + (void)talloc_reference(p1, p2); + talloc_report_full(root, stderr); + talloc_unlink(root, p2); + talloc_report_full(root, stderr); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + talloc_unlink(p1, p2); + talloc_unlink(root, p1); + + p1 = talloc_named_const(root, 10, "p1"); + p2 = (char *)talloc_named_const(root, 20, "p2"); + (void)talloc_reference(NULL, p2); + talloc_report_full(root, stderr); + talloc_unlink(root, p2); + talloc_report_full(root, stderr); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + talloc_unlink(NULL, p2); + talloc_unlink(root, p1); + + /* Test that talloc_unlink is a no-op */ + + torture_assert("misc", talloc_unlink(root, NULL) == -1, + "failed: talloc_unlink(root, NULL) == -1\n"); + + talloc_report(root, stderr); + talloc_report(NULL, stderr); + + CHECK_SIZE("misc", root, 0); + + talloc_free(root); + + CHECK_SIZE("misc", NULL, 0); + + talloc_enable_leak_report(); + talloc_enable_leak_report_full(); + + printf("success: misc\n"); + + return true; +} + + +/* + test realloc +*/ +static bool test_realloc(void) +{ + void *root, *p1, *p2; + + printf("test: realloc\n# REALLOC\n"); + + root = talloc_new(NULL); + + p1 = talloc_size(root, 10); + CHECK_SIZE("realloc", p1, 10); + + p1 = talloc_realloc_size(NULL, p1, 20); + CHECK_SIZE("realloc", p1, 20); + + talloc_new(p1); + + p2 = talloc_realloc_size(p1, NULL, 30); + + talloc_new(p1); + + p2 = talloc_realloc_size(p1, p2, 40); + + CHECK_SIZE("realloc", p2, 40); + CHECK_SIZE("realloc", root, 60); + CHECK_BLOCKS("realloc", p1, 4); + + p1 = talloc_realloc_size(NULL, p1, 20); + CHECK_SIZE("realloc", p1, 60); + + talloc_increase_ref_count(p2); + torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL, + "failed: talloc_realloc() on a referenced pointer should fail\n"); + CHECK_BLOCKS("realloc", p1, 4); + + talloc_realloc_size(NULL, p2, 0); + talloc_realloc_size(NULL, p2, 0); + CHECK_BLOCKS("realloc", p1, 3); + + torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL, + "failed: oversize talloc should fail\n"); + + talloc_realloc_size(NULL, p1, 0); + + CHECK_BLOCKS("realloc", root, 1); + CHECK_SIZE("realloc", root, 0); + + talloc_free(root); + + printf("success: realloc\n"); + + return true; +} + +/* + test realloc with a child +*/ +static bool test_realloc_child(void) +{ + void *root; + struct el2 { + const char *name; + } *el2; + struct el1 { + int count; + struct el2 **list, **list2, **list3; + } *el1; + + printf("test: REALLOC WITH CHILD\n"); + + root = talloc_new(NULL); + + el1 = talloc(root, struct el1); + el1->list = talloc(el1, struct el2 *); + el1->list[0] = talloc(el1->list, struct el2); + el1->list[0]->name = talloc_strdup(el1->list[0], "testing"); + + el1->list2 = talloc(el1, struct el2 *); + el1->list2[0] = talloc(el1->list2, struct el2); + el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2"); + + el1->list3 = talloc(el1, struct el2 *); + el1->list3[0] = talloc(el1->list3, struct el2); + el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2"); + + el2 = talloc(el1->list, struct el2); + el2 = talloc(el1->list2, struct el2); + el2 = talloc(el1->list3, struct el2); + + el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); + el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200); + el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300); + + talloc_free(root); + + printf("success: REALLOC WITH CHILD\n"); + return true; +} + +/* + test type checking +*/ +static bool test_type(void) +{ + void *root; + struct el1 { + int count; + }; + struct el2 { + int count; + }; + struct el1 *el1; + + printf("test: type\n# talloc type checking\n"); + + root = talloc_new(NULL); + + el1 = talloc(root, struct el1); + + el1->count = 1; + + torture_assert("type", talloc_get_type(el1, struct el1) == el1, + "type check failed on el1\n"); + torture_assert("type", talloc_get_type(el1, struct el2) == NULL, + "type check failed on el1 with el2\n"); + talloc_set_type(el1, struct el2); + torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1, + "type set failed on el1 with el2\n"); + + talloc_free(root); + + printf("success: type\n"); + return true; +} + +/* + test steal +*/ +static bool test_steal(void) +{ + void *root, *p1, *p2; + + printf("test: steal\n# STEAL\n"); + + root = talloc_new(NULL); + + p1 = talloc_array(root, char, 10); + CHECK_SIZE("steal", p1, 10); + + p2 = talloc_realloc(root, NULL, char, 20); + CHECK_SIZE("steal", p1, 10); + CHECK_SIZE("steal", root, 30); + + torture_assert("steal", talloc_steal(p1, NULL) == NULL, + "failed: stealing NULL should give NULL\n"); + + torture_assert("steal", talloc_steal(p1, p1) == p1, + "failed: stealing to ourselves is a nop\n"); + CHECK_BLOCKS("steal", root, 3); + CHECK_SIZE("steal", root, 30); + + talloc_steal(NULL, p1); + talloc_steal(NULL, p2); + CHECK_BLOCKS("steal", root, 1); + CHECK_SIZE("steal", root, 0); + + talloc_free(p1); + talloc_steal(root, p2); + CHECK_BLOCKS("steal", root, 2); + CHECK_SIZE("steal", root, 20); + + talloc_free(p2); + + CHECK_BLOCKS("steal", root, 1); + CHECK_SIZE("steal", root, 0); + + talloc_free(root); + + p1 = talloc_size(NULL, 3); + talloc_report_full(NULL, stderr); + CHECK_SIZE("steal", NULL, 3); + talloc_free(p1); + + printf("success: steal\n"); + return true; +} + +/* + test move +*/ +static bool test_move(void) +{ + void *root; + struct t_move { + char *p; + int *x; + } *t1, *t2; + + printf("test: move\n# MOVE\n"); + + root = talloc_new(NULL); + + t1 = talloc(root, struct t_move); + t2 = talloc(root, struct t_move); + t1->p = talloc_strdup(t1, "foo"); + t1->x = talloc(t1, int); + *t1->x = 42; + + t2->p = talloc_move(t2, &t1->p); + t2->x = talloc_move(t2, &t1->x); + torture_assert("move", t1->p == NULL && t1->x == NULL && + strcmp(t2->p, "foo") == 0 && *t2->x == 42, + "talloc move failed"); + + talloc_free(root); + + printf("success: move\n"); + + return true; +} + +/* + test talloc_realloc_fn +*/ +static bool test_realloc_fn(void) +{ + void *root, *p1; + + printf("test: realloc_fn\n# talloc_realloc_fn\n"); + + root = talloc_new(NULL); + + p1 = talloc_realloc_fn(root, NULL, 10); + CHECK_BLOCKS("realloc_fn", root, 2); + CHECK_SIZE("realloc_fn", root, 10); + p1 = talloc_realloc_fn(root, p1, 20); + CHECK_BLOCKS("realloc_fn", root, 2); + CHECK_SIZE("realloc_fn", root, 20); + p1 = talloc_realloc_fn(root, p1, 0); + CHECK_BLOCKS("realloc_fn", root, 1); + CHECK_SIZE("realloc_fn", root, 0); + + talloc_free(root); + + printf("success: realloc_fn\n"); + return true; +} + + +static bool test_unref_reparent(void) +{ + void *root, *p1, *p2, *c1; + + printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "orig parent"); + p2 = talloc_named_const(root, 1, "parent by reference"); + + c1 = talloc_named_const(p1, 1, "child"); + talloc_reference(p2, c1); + + CHECK_PARENT("unref_reparent", c1, p1); + + talloc_free(p1); + + CHECK_PARENT("unref_reparent", c1, p2); + + talloc_unlink(p2, c1); + + CHECK_SIZE("unref_reparent", root, 1); + + talloc_free(p2); + talloc_free(root); + + printf("success: unref_reparent\n"); + return true; +} + +/* + measure the speed of talloc versus malloc +*/ +static bool test_speed(void) +{ + void *ctx = talloc_new(NULL); + unsigned count; + const int loop = 1000; + int i; + struct timeval tv; + + printf("test: speed\n# TALLOC VS MALLOC SPEED\n"); + + tv = timeval_current(); + count = 0; + do { + void *p1, *p2, *p3; + for (i=0;ireq2 = talloc_strdup(req1, "req2"); + talloc_set_destructor(req1->req2, test_loop_destructor); + req1->req3 = talloc_strdup(req1, "req3"); + (void)talloc_reference(req1->req3, req1); + talloc_report_full(top, stderr); + talloc_free(parent); + talloc_report_full(top, stderr); + talloc_report_full(NULL, stderr); + talloc_free(top); + + torture_assert("loop", loop_destructor_count == 1, + "FAILED TO FIRE LOOP DESTRUCTOR\n"); + loop_destructor_count = 0; + + printf("success: loop\n"); + return true; +} + +static int fail_destructor_str(char *ptr) +{ + return -1; +} + +static bool test_free_parent_deny_child(void) +{ + void *top = talloc_new(NULL); + char *level1; + char *level2; + char *level3; + + printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n"); + + level1 = talloc_strdup(top, "level1"); + level2 = talloc_strdup(level1, "level2"); + level3 = talloc_strdup(level2, "level3"); + + talloc_set_destructor(level3, fail_destructor_str); + talloc_free(level1); + talloc_set_destructor(level3, NULL); + + CHECK_PARENT("free_parent_deny_child", level3, top); + + talloc_free(top); + + printf("success: free_parent_deny_child\n"); + return true; +} + +static bool test_talloc_ptrtype(void) +{ + void *top = talloc_new(NULL); + struct struct1 { + int foo; + int bar; + } *s1, *s2, **s3, ***s4; + const char *location1; + const char *location2; + const char *location3; + const char *location4; + + printf("test: ptrtype\n# TALLOC PTRTYPE\n"); + + s1 = talloc_ptrtype(top, s1);location1 = __location__; + + if (talloc_get_size(s1) != sizeof(struct struct1)) { + printf("failure: ptrtype [\n" + "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n" + "]\n", (unsigned long)talloc_get_size(s1), + (unsigned long)sizeof(struct struct1)); + return false; + } + + if (strcmp(location1, talloc_get_name(s1)) != 0) { + printf("failure: ptrtype [\n" + "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", + talloc_get_name(s1), location1); + return false; + } + + s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__; + + if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() allocated the wrong size " + "%lu (should be %lu)\n]\n", + (unsigned long)talloc_get_size(s2), + (unsigned long)(sizeof(struct struct1)*10)); + return false; + } + + if (strcmp(location2, talloc_get_name(s2)) != 0) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", + talloc_get_name(s2), location2); + return false; + } + + s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__; + + if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() allocated the wrong size " + "%lu (should be %lu)\n]\n", + (unsigned long)talloc_get_size(s3), + (unsigned long)(sizeof(struct struct1 *)*10)); + return false; + } + + torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3), + "talloc_array_ptrtype() sets the wrong name"); + + s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; + + if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() allocated the wrong size " + "%lu (should be %lu)\n]\n", + (unsigned long)talloc_get_size(s4), + (unsigned long)(sizeof(struct struct1 **)*10)); + return false; + } + + torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4), + "talloc_array_ptrtype() sets the wrong name"); + + talloc_free(top); + + printf("success: ptrtype\n"); + return true; +} + +static int _test_talloc_free_in_destructor(void **ptr) +{ + talloc_free(*ptr); + return 0; +} + +static bool test_talloc_free_in_destructor(void) +{ + void *level0; + void *level1; + void *level2; + void *level3; + void *level4; + void **level5; + + printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n"); + + level0 = talloc_new(NULL); + level1 = talloc_new(level0); + level2 = talloc_new(level1); + level3 = talloc_new(level2); + level4 = talloc_new(level3); + level5 = talloc(level4, void *); + + *level5 = level3; + (void)talloc_reference(level0, level3); + (void)talloc_reference(level3, level3); + (void)talloc_reference(level5, level3); + + talloc_set_destructor(level5, _test_talloc_free_in_destructor); + + talloc_free(level1); + + talloc_free(level0); + + printf("success: free_in_destructor\n"); + return true; +} + +static bool test_autofree(void) +{ +#if _SAMBA_BUILD_ < 4 + /* autofree test would kill smbtorture */ + void *p; + printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n"); + + p = talloc_autofree_context(); + talloc_free(p); + + p = talloc_autofree_context(); + talloc_free(p); + + printf("success: autofree\n"); +#endif + return true; +} + +static bool test_pool(void) +{ + void *pool; + void *p1, *p2, *p3, *p4; + + pool = talloc_pool(NULL, 1024); + + p1 = talloc_size(pool, 80); + p2 = talloc_size(pool, 20); + p3 = talloc_size(p1, 50); + p4 = talloc_size(p3, 1000); + + talloc_free(pool); + + return true; +} + +struct torture_context; +bool torture_local_talloc(struct torture_context *tctx) +{ + bool ret = true; + + setlinebuf(stdout); + + talloc_disable_null_tracking(); + talloc_enable_null_tracking(); + + ret &= test_ref1(); + ret &= test_ref2(); + ret &= test_ref3(); + ret &= test_ref4(); + ret &= test_unlink1(); + ret &= test_misc(); + ret &= test_realloc(); + ret &= test_realloc_child(); + ret &= test_steal(); + ret &= test_move(); + ret &= test_unref_reparent(); + ret &= test_realloc_fn(); + ret &= test_type(); + ret &= test_lifeless(); + ret &= test_loop(); + ret &= test_free_parent_deny_child(); + ret &= test_talloc_ptrtype(); + ret &= test_talloc_free_in_destructor(); + ret &= test_pool(); + + if (ret) { + ret &= test_speed(); + } + ret &= test_autofree(); + + return ret; +} + +#if _SAMBA_BUILD_ < 4 +int main(void) +{ + bool ret = torture_local_talloc(NULL); + if (!ret) + return -1; + return 0; +} +#endif diff --git a/lib/talloc/web/index.html b/lib/talloc/web/index.html new file mode 100644 index 0000000000..5deab93665 --- /dev/null +++ b/lib/talloc/web/index.html @@ -0,0 +1,46 @@ + + + +talloc + + + +

talloc

+ +talloc is a hierarchical pool based memory allocator with +destructors. It is the core memory allocator used in Samba4, and has +made a huge difference in many aspects of Samba4 development.

+ +To get started with talloc, I would recommend you read the talloc guide. + +

Discussion and bug reports

+ +talloc does not currently have its own mailing list or bug tracking +system. For now, please use the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +

Download

+ +You can download the latest release either via rsync or git.
+
+To fetch via git see the following guide:
+Using Git for Samba Development
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/talloc directory.
+
+To fetch via rsync use this command: + +
+  rsync -Pavz samba.org::ftp/unpacked/talloc .
+
+ +
+ +Andrew Tridgell
+talloc AT tridgell.net +
+ + + diff --git a/lib/tdb/Makefile.in b/lib/tdb/Makefile.in new file mode 100644 index 0000000000..090bb6e2dc --- /dev/null +++ b/lib/tdb/Makefile.in @@ -0,0 +1,59 @@ +#!gmake +# +# Makefile for tdb directory +# + +CC = @CC@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +includedir = @includedir@ +libdir = @libdir@ +VPATH = @srcdir@:@libreplacedir@ +srcdir = @srcdir@ +builddir = @builddir@ +CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude +CFLAGS = $(CPPFLAGS) @CFLAGS@ +LDFLAGS = @LDFLAGS@ +EXEEXT = @EXEEXT@ +SHLD = @SHLD@ +SHLD_FLAGS = @SHLD_FLAGS@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PICFLAG = @PICFLAG@ +SHLIBEXT = @SHLIBEXT@ +SWIG = swig +PYTHON = @PYTHON@ +PYTHON_CONFIG = @PYTHON_CONFIG@ +PYTHON_BUILD_TARGET = @PYTHON_BUILD_TARGET@ +PYTHON_INSTALL_TARGET = @PYTHON_INSTALL_TARGET@ +PYTHON_CHECK_TARGET = @PYTHON_CHECK_TARGET@ +LIB_PATH_VAR = @LIB_PATH_VAR@ +tdbdir = @tdbdir@ + +TDB_OBJ = @TDB_OBJ@ @LIBREPLACEOBJ@ + +default: all + +include $(tdbdir)/tdb.mk +include $(tdbdir)/rules.mk + +all:: showflags dirs $(PROGS) $(TDB_SOLIB) libtdb.a $(PYTHON_BUILD_TARGET) + +install:: all +$(TDB_SOLIB): $(TDB_OBJ) + $(SHLD) $(SHLD_FLAGS) -o $@ $(TDB_OBJ) @SONAMEFLAG@$(TDB_SONAME) + +check: test + +test:: $(PYTHON_CHECK_TARGET) +installcheck:: test install + +clean:: + rm -f *.o *.a */*.o + +distclean:: clean + rm -f config.log config.status include/config.h config.cache + rm -f Makefile + +realdistclean:: distclean + rm -f configure include/config.h.in diff --git a/lib/tdb/aclocal.m4 b/lib/tdb/aclocal.m4 new file mode 100644 index 0000000000..5605e476ba --- /dev/null +++ b/lib/tdb/aclocal.m4 @@ -0,0 +1 @@ +m4_include(libreplace.m4) diff --git a/lib/tdb/autogen.sh b/lib/tdb/autogen.sh new file mode 100755 index 0000000000..88ac4cfcf7 --- /dev/null +++ b/lib/tdb/autogen.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +rm -rf autom4te.cache +rm -f configure config.h.in + +IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace" +autoconf $IPATHS || exit 1 +autoheader $IPATHS || exit 1 + +rm -rf autom4te.cache + +swig -O -Wall -python -keyword tdb.i # Ignore errors for now + +echo "Now run ./configure and then make." +exit 0 + diff --git a/lib/tdb/common/dump.c b/lib/tdb/common/dump.c new file mode 100644 index 0000000000..d1c902ddfd --- /dev/null +++ b/lib/tdb/common/dump.c @@ -0,0 +1,137 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash, + tdb_off_t offset) +{ + struct list_struct rec; + tdb_off_t tailer_ofs, tailer; + + if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, + sizeof(rec), DOCONV()) == -1) { + printf("ERROR: failed to read record at %u\n", offset); + return 0; + } + + printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%d " + "key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", + hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, + rec.full_hash, rec.magic); + + tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t); + + if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) { + printf("ERROR: failed to read tailer at %u\n", tailer_ofs); + return rec.next; + } + + if (tailer != rec.rec_len + sizeof(rec)) { + printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", + (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec))); + } + return rec.next; +} + +static int tdb_dump_chain(struct tdb_context *tdb, int i) +{ + tdb_off_t rec_ptr, top; + + top = TDB_HASH_TOP(i); + + if (tdb_lock(tdb, i, F_WRLCK) != 0) + return -1; + + if (tdb_ofs_read(tdb, top, &rec_ptr) == -1) + return tdb_unlock(tdb, i, F_WRLCK); + + if (rec_ptr) + printf("hash=%d\n", i); + + while (rec_ptr) { + rec_ptr = tdb_dump_record(tdb, i, rec_ptr); + } + + return tdb_unlock(tdb, i, F_WRLCK); +} + +void tdb_dump_all(struct tdb_context *tdb) +{ + int i; + for (i=0;iheader.hash_size;i++) { + tdb_dump_chain(tdb, i); + } + printf("freelist:\n"); + tdb_dump_chain(tdb, -1); +} + +int tdb_printfreelist(struct tdb_context *tdb) +{ + int ret; + long total_free = 0; + tdb_off_t offset, rec_ptr; + struct list_struct rec; + + if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) + return ret; + + offset = FREELIST_TOP; + + /* read in the freelist top */ + if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + } + + printf("freelist top=[0x%08x]\n", rec_ptr ); + while (rec_ptr) { + if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, + sizeof(rec), DOCONV()) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + if (rec.magic != TDB_FREE_MAGIC) { + printf("bad magic 0x%08x in free list\n", rec.magic); + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n", + rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); + total_free += rec.rec_len; + + /* move to the next record */ + rec_ptr = rec.next; + } + printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, + (int)total_free); + + return tdb_unlock(tdb, -1, F_WRLCK); +} + diff --git a/lib/tdb/common/error.c b/lib/tdb/common/error.c new file mode 100644 index 0000000000..195ab23815 --- /dev/null +++ b/lib/tdb/common/error.c @@ -0,0 +1,57 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +enum TDB_ERROR tdb_error(struct tdb_context *tdb) +{ + return tdb->ecode; +} + +static struct tdb_errname { + enum TDB_ERROR ecode; const char *estring; +} emap[] = { {TDB_SUCCESS, "Success"}, + {TDB_ERR_CORRUPT, "Corrupt database"}, + {TDB_ERR_IO, "IO Error"}, + {TDB_ERR_LOCK, "Locking error"}, + {TDB_ERR_OOM, "Out of memory"}, + {TDB_ERR_EXISTS, "Record exists"}, + {TDB_ERR_NOLOCK, "Lock exists on other keys"}, + {TDB_ERR_EINVAL, "Invalid parameter"}, + {TDB_ERR_NOEXIST, "Record does not exist"}, + {TDB_ERR_RDONLY, "write not permitted"} }; + +/* Error string for the last tdb error */ +const char *tdb_errorstr(struct tdb_context *tdb) +{ + uint32_t i; + for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) + if (tdb->ecode == emap[i].ecode) + return emap[i].estring; + return "Invalid error code"; +} + diff --git a/lib/tdb/common/freelist.c b/lib/tdb/common/freelist.c new file mode 100644 index 0000000000..2f2a4c379b --- /dev/null +++ b/lib/tdb/common/freelist.c @@ -0,0 +1,382 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* 'right' merges can involve O(n^2) cost when combined with a + traverse, so they are disabled until we find a way to do them in + O(1) time +*/ +#define USE_RIGHT_MERGES 0 + +/* read a freelist record and check for simple errors */ +int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct *rec) +{ + if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + + if (rec->magic == TDB_MAGIC) { + /* this happens when a app is showdown while deleting a record - we should + not completely fail when this happens */ + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", + rec->magic, off)); + rec->magic = TDB_FREE_MAGIC; + if (tdb->methods->tdb_write(tdb, off, rec, sizeof(*rec)) == -1) + return -1; + } + + if (rec->magic != TDB_FREE_MAGIC) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%d\n", + rec->magic, off)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) + return -1; + return 0; +} + + +#if USE_RIGHT_MERGES +/* Remove an element from the freelist. Must have alloc lock. */ +static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next) +{ + tdb_off_t last_ptr, i; + + /* read in the freelist top */ + last_ptr = FREELIST_TOP; + while (tdb_ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { + if (i == off) { + /* We've found it! */ + return tdb_ofs_write(tdb, last_ptr, &next); + } + /* Follow chain (next offset is at start of record) */ + last_ptr = i; + } + TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); +} +#endif + + +/* update a record tailer (must hold allocation lock) */ +static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, + const struct list_struct *rec) +{ + tdb_off_t totalsize; + + /* Offset of tailer from record header */ + totalsize = sizeof(*rec) + rec->rec_len; + return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t), + &totalsize); +} + +/* Add an element into the freelist. Merge adjacent records if + neccessary. */ +int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) +{ + /* Allocation and tailer lock */ + if (tdb_lock(tdb, -1, F_WRLCK) != 0) + return -1; + + /* set an initial tailer, so if we fail we don't leave a bogus record */ + if (update_tailer(tdb, offset, rec) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n")); + goto fail; + } + +#if USE_RIGHT_MERGES + /* Look right first (I'm an Australian, dammit) */ + if (offset + sizeof(*rec) + rec->rec_len + sizeof(*rec) <= tdb->map_size) { + tdb_off_t right = offset + sizeof(*rec) + rec->rec_len; + struct list_struct r; + + if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right read failed at %u\n", right)); + goto left; + } + + /* If it's free, expand to include it. */ + if (r.magic == TDB_FREE_MAGIC) { + if (remove_from_freelist(tdb, right, r.next) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right free failed at %u\n", right)); + goto left; + } + rec->rec_len += sizeof(r) + r.rec_len; + if (update_tailer(tdb, offset, rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } + } + } +left: +#endif + + /* Look left */ + if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->header.hash_size)) { + tdb_off_t left = offset - sizeof(tdb_off_t); + struct list_struct l; + tdb_off_t leftsize; + + /* Read in tailer and jump back to header */ + if (tdb_ofs_read(tdb, left, &leftsize) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left)); + goto update; + } + + /* it could be uninitialised data */ + if (leftsize == 0 || leftsize == TDB_PAD_U32) { + goto update; + } + + left = offset - leftsize; + + if (leftsize > offset || + left < TDB_DATA_START(tdb->header.hash_size)) { + goto update; + } + + /* Now read in the left record */ + if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); + goto update; + } + + /* If it's free, expand to include it. */ + if (l.magic == TDB_FREE_MAGIC) { + /* we now merge the new record into the left record, rather than the other + way around. This makes the operation O(1) instead of O(n). This change + prevents traverse from being O(n^2) after a lot of deletes */ + l.rec_len += sizeof(*rec) + rec->rec_len; + if (tdb_rec_write(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_left failed at %u\n", left)); + goto fail; + } + if (update_tailer(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + } + } + +update: + + /* Now, prepend to free list */ + rec->magic = TDB_FREE_MAGIC; + + if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || + tdb_rec_write(tdb, offset, rec) == -1 || + tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%d\n", offset)); + goto fail; + } + + /* And we're done. */ + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + + + +/* + the core of tdb_allocate - called when we have decided which + free list entry to use + + Note that we try to allocate by grabbing data from the end of an existing record, + not the beginning. This is so the left merge in a free is more likely to be + able to free up the record without fragmentation + */ +static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, + tdb_len_t length, tdb_off_t rec_ptr, + struct list_struct *rec, tdb_off_t last_ptr) +{ +#define MIN_REC_SIZE (sizeof(struct list_struct) + sizeof(tdb_off_t) + 8) + + if (rec->rec_len < length + MIN_REC_SIZE) { + /* we have to grab the whole record */ + + /* unlink it from the previous record */ + if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { + return 0; + } + + /* mark it not free */ + rec->magic = TDB_MAGIC; + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; + } + return rec_ptr; + } + + /* we're going to just shorten the existing record */ + rec->rec_len -= (length + sizeof(*rec)); + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; + } + if (update_tailer(tdb, rec_ptr, rec) == -1) { + return 0; + } + + /* and setup the new record */ + rec_ptr += sizeof(*rec) + rec->rec_len; + + memset(rec, '\0', sizeof(*rec)); + rec->rec_len = length; + rec->magic = TDB_MAGIC; + + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; + } + + if (update_tailer(tdb, rec_ptr, rec) == -1) { + return 0; + } + + return rec_ptr; +} + +/* allocate some space from the free list. The offset returned points + to a unconnected list_struct within the database with room for at + least length bytes of total data + + 0 is returned if the space could not be allocated + */ +tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec) +{ + tdb_off_t rec_ptr, last_ptr, newrec_ptr; + struct { + tdb_off_t rec_ptr, last_ptr; + tdb_len_t rec_len; + } bestfit; + float multiplier = 1.0; + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) + return 0; + + /* Extra bytes required for tailer */ + length += sizeof(tdb_off_t); + length = TDB_ALIGN(length, TDB_ALIGNMENT); + + again: + last_ptr = FREELIST_TOP; + + /* read in the freelist top */ + if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) + goto fail; + + bestfit.rec_ptr = 0; + bestfit.last_ptr = 0; + bestfit.rec_len = 0; + + /* + this is a best fit allocation strategy. Originally we used + a first fit strategy, but it suffered from massive fragmentation + issues when faced with a slowly increasing record size. + */ + while (rec_ptr) { + if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { + goto fail; + } + + if (rec->rec_len >= length) { + if (bestfit.rec_ptr == 0 || + rec->rec_len < bestfit.rec_len) { + bestfit.rec_len = rec->rec_len; + bestfit.rec_ptr = rec_ptr; + bestfit.last_ptr = last_ptr; + } + } + + /* move to the next record */ + last_ptr = rec_ptr; + rec_ptr = rec->next; + + /* if we've found a record that is big enough, then + stop searching if its also not too big. The + definition of 'too big' changes as we scan + through */ + if (bestfit.rec_len > 0 && + bestfit.rec_len < length * multiplier) { + break; + } + + /* this multiplier means we only extremely rarely + search more than 50 or so records. At 50 records we + accept records up to 11 times larger than what we + want */ + multiplier *= 1.05; + } + + if (bestfit.rec_ptr != 0) { + if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { + goto fail; + } + + newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, + rec, bestfit.last_ptr); + tdb_unlock(tdb, -1, F_WRLCK); + return newrec_ptr; + } + + /* we didn't find enough space. See if we can expand the + database and if we can then try again */ + if (tdb_expand(tdb, length + sizeof(*rec)) == 0) + goto again; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return 0; +} + + + +/* + return the size of the freelist - used to decide if we should repack +*/ +int tdb_freelist_size(struct tdb_context *tdb) +{ + tdb_off_t ptr; + int count=0; + + if (tdb_lock(tdb, -1, F_RDLCK) == -1) { + return -1; + } + + ptr = FREELIST_TOP; + while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { + count++; + } + + tdb_unlock(tdb, -1, F_RDLCK); + return count; +} diff --git a/lib/tdb/common/freelistcheck.c b/lib/tdb/common/freelistcheck.c new file mode 100644 index 0000000000..efc050df9c --- /dev/null +++ b/lib/tdb/common/freelistcheck.c @@ -0,0 +1,107 @@ +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Jeremy Allison 2006 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* Check the freelist is good and contains no loops. + Very memory intensive - only do this as a consistency + checker. Heh heh - uses an in memory tdb as the storage + for the "seen" record list. For some reason this strikes + me as extremely clever as I don't have to write another tree + data structure implementation :-). + */ + +static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) +{ + TDB_DATA key, data; + + memset(&data, '\0', sizeof(data)); + key.dptr = (unsigned char *)&rec_ptr; + key.dsize = sizeof(rec_ptr); + return tdb_store(mem_tdb, key, data, TDB_INSERT); +} + +int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) +{ + struct tdb_context *mem_tdb = NULL; + struct list_struct rec; + tdb_off_t rec_ptr, last_ptr; + int ret = -1; + + *pnum_entries = 0; + + mem_tdb = tdb_open("flval", tdb->header.hash_size, + TDB_INTERNAL, O_RDWR, 0600); + if (!mem_tdb) { + return -1; + } + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + tdb_close(mem_tdb); + return 0; + } + + last_ptr = FREELIST_TOP; + + /* Store the FREELIST_TOP record. */ + if (seen_insert(mem_tdb, last_ptr) == -1) { + ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + goto fail; + } + + /* read in the freelist top */ + if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) { + goto fail; + } + + while (rec_ptr) { + + /* If we can't store this record (we've seen it + before) then the free list has a loop and must + be corrupt. */ + + if (seen_insert(mem_tdb, rec_ptr)) { + ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + goto fail; + } + + if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) { + goto fail; + } + + /* move to the next record */ + last_ptr = rec_ptr; + rec_ptr = rec.next; + *pnum_entries += 1; + } + + ret = 0; + + fail: + + tdb_close(mem_tdb); + tdb_unlock(tdb, -1, F_WRLCK); + return ret; +} diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c new file mode 100644 index 0000000000..661f761489 --- /dev/null +++ b/lib/tdb/common/io.c @@ -0,0 +1,473 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + + +#include "tdb_private.h" + +/* check for an out of bounds access - if it is out of bounds then + see if the database has been expanded by someone else and expand + if necessary + note that "len" is the minimum length needed for the db +*/ +static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, int probe) +{ + struct stat st; + if (len <= tdb->map_size) + return 0; + if (tdb->flags & TDB_INTERNAL) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond internal malloc size %d\n", + (int)len, (int)tdb->map_size)); + } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + + if (fstat(tdb->fd, &st) == -1) { + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + + if (st.st_size < (size_t)len) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond eof at %d\n", + (int)len, (int)st.st_size)); + } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + + /* Unmap, update size, remap */ + if (tdb_munmap(tdb) == -1) + return TDB_ERRCODE(TDB_ERR_IO, -1); + tdb->map_size = st.st_size; + tdb_mmap(tdb); + return 0; +} + +/* write a lump of data at a specified offset */ +static int tdb_write(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + if (len == 0) { + return 0; + } + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) + return -1; + + if (tdb->map_ptr) { + memcpy(off + (char *)tdb->map_ptr, buf, len); + } else { + ssize_t written = pwrite(tdb->fd, buf, len, off); + if ((written != (ssize_t)len) && (written != -1)) { + /* try once more */ + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only " + "%d of %d bytes at %d, trying once more\n", + (int)written, len, off)); + errno = ENOSPC; + written = pwrite(tdb->fd, (const void *)((const char *)buf+written), + len-written, + off+written); + } + if (written == -1) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d " + "len=%d (%s)\n", off, len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_IO, -1); + } else if (written != (ssize_t)len) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to " + "write %d bytes at %d in two attempts\n", + len, off)); + errno = ENOSPC; + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + } + return 0; +} + +/* Endian conversion: we only ever deal with 4 byte quantities */ +void *tdb_convert(void *buf, uint32_t size) +{ + uint32_t i, *p = (uint32_t *)buf; + for (i = 0; i < size / 4; i++) + p[i] = TDB_BYTEREV(p[i]); + return buf; +} + + +/* read a lump of data at a specified offset, maybe convert */ +static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, + tdb_len_t len, int cv) +{ + if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) { + return -1; + } + + if (tdb->map_ptr) { + memcpy(buf, off + (char *)tdb->map_ptr, len); + } else { + ssize_t ret = pread(tdb->fd, buf, len, off); + if (ret != (ssize_t)len) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %d " + "len=%d ret=%d (%s) map_size=%d\n", + (int)off, (int)len, (int)ret, strerror(errno), + (int)tdb->map_size)); + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + } + if (cv) { + tdb_convert(buf, len); + } + return 0; +} + + + +/* + do an unlocked scan of the hash table heads to find the next non-zero head. The value + will then be confirmed with the lock held +*/ +static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) +{ + uint32_t h = *chain; + if (tdb->map_ptr) { + for (;h < tdb->header.hash_size;h++) { + if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { + break; + } + } + } else { + uint32_t off=0; + for (;h < tdb->header.hash_size;h++) { + if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { + break; + } + } + } + (*chain) = h; +} + + +int tdb_munmap(struct tdb_context *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return 0; + +#ifdef HAVE_MMAP + if (tdb->map_ptr) { + int ret; + + ret = munmap(tdb->map_ptr, tdb->map_size); + if (ret != 0) + return ret; + } +#endif + tdb->map_ptr = NULL; + return 0; +} + +void tdb_mmap(struct tdb_context *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return; + +#ifdef HAVE_MMAP + if (!(tdb->flags & TDB_NOMMAP)) { + tdb->map_ptr = mmap(NULL, tdb->map_size, + PROT_READ|(tdb->read_only? 0:PROT_WRITE), + MAP_SHARED|MAP_FILE, tdb->fd, 0); + + /* + * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! + */ + + if (tdb->map_ptr == MAP_FAILED) { + tdb->map_ptr = NULL; + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", + tdb->map_size, strerror(errno))); + } + } else { + tdb->map_ptr = NULL; + } +#else + tdb->map_ptr = NULL; +#endif +} + +/* expand a file. we prefer to use ftruncate, as that is what posix + says to use for mmap expansion */ +static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) +{ + char buf[8192]; + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + if (ftruncate(tdb->fd, size+addition) == -1) { + char b = 0; + ssize_t written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); + if (written == 0) { + /* try once more, potentially revealing errno */ + written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); + } + if (written == 0) { + /* again - give up, guessing errno */ + errno = ENOSPC; + } + if (written != 1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } + } + + /* now fill the file with something. This ensures that the + file isn't sparse, which would be very bad if we ran out of + disk. This must be done with write, not via mmap */ + memset(buf, TDB_PAD_BYTE, sizeof(buf)); + while (addition) { + size_t n = addition>sizeof(buf)?sizeof(buf):addition; + ssize_t written = pwrite(tdb->fd, buf, n, size); + if (written == 0) { + /* prevent infinite loops: try _once_ more */ + written = pwrite(tdb->fd, buf, n, size); + } + if (written == 0) { + /* give up, trying to provide a useful errno */ + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " + "returned 0 twice: giving up!\n")); + errno = ENOSPC; + return -1; + } else if (written == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of " + "%d bytes failed (%s)\n", (int)n, + strerror(errno))); + return -1; + } else if (written != n) { + TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote " + "only %d of %d bytes - retrying\n", (int)written, + (int)n)); + } + addition -= written; + size += written; + } + return 0; +} + + +/* expand the database at least size bytes by expanding the underlying + file and doing the mmap again if necessary */ +int tdb_expand(struct tdb_context *tdb, tdb_off_t size) +{ + struct list_struct rec; + tdb_off_t offset, new_size; + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); + return -1; + } + + /* must know about any previous expansions by another process */ + tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); + + /* always make room for at least 100 more records, and at + least 25% more space. Round the database up to a multiple + of the page size */ + new_size = MAX(tdb->map_size + size*100, tdb->map_size * 1.25); + size = TDB_ALIGN(new_size, tdb->page_size) - tdb->map_size; + + if (!(tdb->flags & TDB_INTERNAL)) + tdb_munmap(tdb); + + /* + * We must ensure the file is unmapped before doing this + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ + + /* expand the file itself */ + if (!(tdb->flags & TDB_INTERNAL)) { + if (tdb->methods->tdb_expand_file(tdb, tdb->map_size, size) != 0) + goto fail; + } + + tdb->map_size += size; + + if (tdb->flags & TDB_INTERNAL) { + char *new_map_ptr = (char *)realloc(tdb->map_ptr, + tdb->map_size); + if (!new_map_ptr) { + tdb->map_size -= size; + goto fail; + } + tdb->map_ptr = new_map_ptr; + } else { + /* + * We must ensure the file is remapped before adding the space + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ + + /* We're ok if the mmap fails as we'll fallback to read/write */ + tdb_mmap(tdb); + } + + /* form a new freelist record */ + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = size - sizeof(rec); + + /* link it into the free list */ + offset = tdb->map_size - size; + if (tdb_free(tdb, offset, &rec) == -1) + goto fail; + + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + +/* read/write a tdb_off_t */ +int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) +{ + return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); +} + +int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) +{ + tdb_off_t off = *d; + return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); +} + + +/* read a lump of data, allocating the space for it */ +unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len) +{ + unsigned char *buf; + + /* some systems don't like zero length malloc */ + if (len == 0) { + len = 1; + } + + if (!(buf = (unsigned char *)malloc(len))) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%d (%s)\n", + len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_OOM, buf); + } + if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) { + SAFE_FREE(buf); + return NULL; + } + return buf; +} + +/* Give a piece of tdb data to a parser */ + +int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, + tdb_off_t offset, tdb_len_t len, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data) +{ + TDB_DATA data; + int result; + + data.dsize = len; + + if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { + /* + * Optimize by avoiding the malloc/memcpy/free, point the + * parser directly at the mmap area. + */ + if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) { + return -1; + } + data.dptr = offset + (unsigned char *)tdb->map_ptr; + return parser(key, data, private_data); + } + + if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) { + return -1; + } + + result = parser(key, data, private_data); + free(data.dptr); + return result; +} + +/* read/write a record */ +int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) +{ + if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + if (TDB_BAD_MAGIC(rec)) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + return tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0); +} + +int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) +{ + struct list_struct r = *rec; + return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); +} + +static const struct tdb_methods io_methods = { + tdb_read, + tdb_write, + tdb_next_hash_chain, + tdb_oob, + tdb_expand_file, + tdb_brlock +}; + +/* + initialise the default methods table +*/ +void tdb_io_init(struct tdb_context *tdb) +{ + tdb->methods = &io_methods; +} diff --git a/lib/tdb/common/lock.c b/lib/tdb/common/lock.c new file mode 100644 index 0000000000..f156c0fa7b --- /dev/null +++ b/lib/tdb/common/lock.c @@ -0,0 +1,553 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +#define TDB_MARK_LOCK 0x80000000 + +void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) +{ + tdb->interrupt_sig_ptr = ptr; +} + +/* a byte range locking function - return 0 on success + this functions locks/unlocks 1 byte at the specified offset. + + On error, errno is also set so that errors are passed back properly + through tdb_open(). + + note that a len of zero means lock to end of file +*/ +int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, + int rw_type, int lck_type, int probe, size_t len) +{ + struct flock fl; + int ret; + + if (tdb->flags & TDB_NOLOCK) { + return 0; + } + + if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + fl.l_type = rw_type; + fl.l_whence = SEEK_SET; + fl.l_start = offset; + fl.l_len = len; + fl.l_pid = 0; + + do { + ret = fcntl(tdb->fd,lck_type,&fl); + + /* Check for a sigalarm break. */ + if (ret == -1 && errno == EINTR && + tdb->interrupt_sig_ptr && + *tdb->interrupt_sig_ptr) { + break; + } + } while (ret == -1 && errno == EINTR); + + if (ret == -1) { + /* Generic lock error. errno set by fcntl. + * EAGAIN is an expected return from non-blocking + * locks. */ + if (!probe && lck_type != F_SETLK) { + /* Ensure error code is set for log fun to examine. */ + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n", + tdb->fd, offset, rw_type, lck_type, (int)len)); + } + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + return 0; +} + + +/* + upgrade a read lock to a write lock. This needs to be handled in a + special way as some OSes (such as solaris) have too conservative + deadlock detection and claim a deadlock when progress can be + made. For those OSes we may loop for a while. +*/ +int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len) +{ + int count = 1000; + while (count--) { + struct timeval tv; + if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) { + return 0; + } + if (errno != EDEADLK) { + break; + } + /* sleep for as short a time as we can - more portable than usleep() */ + tv.tv_sec = 0; + tv.tv_usec = 1; + select(0, NULL, NULL, NULL, &tv); + } + TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock_upgrade failed at offset %d\n", offset)); + return -1; +} + + +/* lock a list in the database. list -1 is the alloc list */ +static int _tdb_lock(struct tdb_context *tdb, int list, int ltype, int op) +{ + struct tdb_lock_type *new_lck; + int i; + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; + + /* a global lock allows us to avoid per chain locks */ + if (tdb->global_lock.count && + (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { + return 0; + } + + if (tdb->global_lock.count) { + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + if (list < -1 || list >= (int)tdb->header.hash_size) { + TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid list %d for ltype=%d\n", + list, ltype)); + return -1; + } + if (tdb->flags & TDB_NOLOCK) + return 0; + + for (i=0; inum_lockrecs; i++) { + if (tdb->lockrecs[i].list == list) { + if (tdb->lockrecs[i].count == 0) { + /* + * Can't happen, see tdb_unlock(). It should + * be an assert. + */ + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock: " + "lck->count == 0 for list %d", list)); + } + /* + * Just increment the in-memory struct, posix locks + * don't stack. + */ + tdb->lockrecs[i].count++; + return 0; + } + } + + new_lck = (struct tdb_lock_type *)realloc( + tdb->lockrecs, + sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); + if (new_lck == NULL) { + errno = ENOMEM; + return -1; + } + tdb->lockrecs = new_lck; + + /* Since fcntl locks don't nest, we do a lock for the first one, + and simply bump the count for future ones */ + if (!mark_lock && + tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list, ltype, op, + 0, 1)) { + return -1; + } + + tdb->num_locks++; + + tdb->lockrecs[tdb->num_lockrecs].list = list; + tdb->lockrecs[tdb->num_lockrecs].count = 1; + tdb->lockrecs[tdb->num_lockrecs].ltype = ltype; + tdb->num_lockrecs += 1; + + return 0; +} + +/* lock a list in the database. list -1 is the alloc list */ +int tdb_lock(struct tdb_context *tdb, int list, int ltype) +{ + int ret; + ret = _tdb_lock(tdb, list, ltype, F_SETLKW); + if (ret) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " + "ltype=%d (%s)\n", list, ltype, strerror(errno))); + } + return ret; +} + +/* lock a list in the database. list -1 is the alloc list. non-blocking lock */ +int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) +{ + return _tdb_lock(tdb, list, ltype, F_SETLK); +} + + +/* unlock the database: returns void because it's too late for errors. */ + /* changed to return int it may be interesting to know there + has been an error --simo */ +int tdb_unlock(struct tdb_context *tdb, int list, int ltype) +{ + int ret = -1; + int i; + struct tdb_lock_type *lck = NULL; + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; + + /* a global lock allows us to avoid per chain locks */ + if (tdb->global_lock.count && + (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { + return 0; + } + + if (tdb->global_lock.count) { + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + if (tdb->flags & TDB_NOLOCK) + return 0; + + /* Sanity checks */ + if (list < -1 || list >= (int)tdb->header.hash_size) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); + return ret; + } + + for (i=0; inum_lockrecs; i++) { + if (tdb->lockrecs[i].list == list) { + lck = &tdb->lockrecs[i]; + break; + } + } + + if ((lck == NULL) || (lck->count == 0)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); + return -1; + } + + if (lck->count > 1) { + lck->count--; + return 0; + } + + /* + * This lock has count==1 left, so we need to unlock it in the + * kernel. We don't bother with decrementing the in-memory array + * element, we're about to overwrite it with the last array element + * anyway. + */ + + if (mark_lock) { + ret = 0; + } else { + ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, + F_SETLKW, 0, 1); + } + tdb->num_locks--; + + /* + * Shrink the array by overwriting the element just unlocked with the + * last array element. + */ + + if (tdb->num_lockrecs > 1) { + *lck = tdb->lockrecs[tdb->num_lockrecs-1]; + } + tdb->num_lockrecs -= 1; + + /* + * We don't bother with realloc when the array shrinks, but if we have + * a completely idle tdb we should get rid of the locked array. + */ + + if (tdb->num_lockrecs == 0) { + SAFE_FREE(tdb->lockrecs); + } + + if (ret) + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); + return ret; +} + +/* + get the transaction lock + */ +int tdb_transaction_lock(struct tdb_context *tdb, int ltype) +{ + if (tdb->have_transaction_lock || tdb->global_lock.count) { + return 0; + } + if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype, + F_SETLKW, 0, 1) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n")); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + tdb->have_transaction_lock = 1; + return 0; +} + +/* + release the transaction lock + */ +int tdb_transaction_unlock(struct tdb_context *tdb) +{ + int ret; + if (!tdb->have_transaction_lock) { + return 0; + } + ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); + if (ret == 0) { + tdb->have_transaction_lock = 0; + } + return ret; +} + + + + +/* lock/unlock entire database */ +static int _tdb_lockall(struct tdb_context *tdb, int ltype, int op) +{ + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; + + /* There are no locks on read-only dbs */ + if (tdb->read_only || tdb->traverse_read) + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + + if (tdb->global_lock.count && tdb->global_lock.ltype == ltype) { + tdb->global_lock.count++; + return 0; + } + + if (tdb->global_lock.count) { + /* a global lock of a different type exists */ + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + if (tdb->num_locks != 0) { + /* can't combine global and chain locks */ + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + if (!mark_lock && + tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, op, + 0, 4*tdb->header.hash_size)) { + if (op == F_SETLKW) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno))); + } + return -1; + } + + tdb->global_lock.count = 1; + tdb->global_lock.ltype = ltype; + + return 0; +} + + + +/* unlock entire db */ +static int _tdb_unlockall(struct tdb_context *tdb, int ltype) +{ + bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); + + ltype &= ~TDB_MARK_LOCK; + + /* There are no locks on read-only dbs */ + if (tdb->read_only || tdb->traverse_read) { + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + if (tdb->global_lock.ltype != ltype || tdb->global_lock.count == 0) { + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + if (tdb->global_lock.count > 1) { + tdb->global_lock.count--; + return 0; + } + + if (!mark_lock && + tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, + 0, 4*tdb->header.hash_size)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno))); + return -1; + } + + tdb->global_lock.count = 0; + tdb->global_lock.ltype = 0; + + return 0; +} + +/* lock entire database with write lock */ +int tdb_lockall(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_WRLCK, F_SETLKW); +} + +/* lock entire database with write lock - mark only */ +int tdb_lockall_mark(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW); +} + +/* unlock entire database with write lock - unmark only */ +int tdb_lockall_unmark(struct tdb_context *tdb) +{ + return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK); +} + +/* lock entire database with write lock - nonblocking varient */ +int tdb_lockall_nonblock(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_WRLCK, F_SETLK); +} + +/* unlock entire database with write lock */ +int tdb_unlockall(struct tdb_context *tdb) +{ + return _tdb_unlockall(tdb, F_WRLCK); +} + +/* lock entire database with read lock */ +int tdb_lockall_read(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_RDLCK, F_SETLKW); +} + +/* lock entire database with read lock - nonblock varient */ +int tdb_lockall_read_nonblock(struct tdb_context *tdb) +{ + return _tdb_lockall(tdb, F_RDLCK, F_SETLK); +} + +/* unlock entire database with read lock */ +int tdb_unlockall_read(struct tdb_context *tdb) +{ + return _tdb_unlockall(tdb, F_RDLCK); +} + +/* lock/unlock one hash chain. This is meant to be used to reduce + contention - it cannot guarantee how many records will be locked */ +int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); +} + +/* lock/unlock one hash chain, non-blocking. This is meant to be used + to reduce contention - it cannot guarantee how many records will be + locked */ +int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); +} + +/* mark a chain as locked without actually locking it. Warning! use with great caution! */ +int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); +} + +/* unmark a chain as locked without actually locking it. Warning! use with great caution! */ +int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); +} + +int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); +} + +int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); +} + +int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); +} + + + +/* record lock stops delete underneath */ +int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) +{ + if (tdb->global_lock.count) { + return 0; + } + return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0; +} + +/* + Write locks override our own fcntl readlocks, so check it here. + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ +int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off) +{ + struct tdb_traverse_lock *i; + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + return -1; + return tdb->methods->tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1, 1); +} + +/* + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ +int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off) +{ + return tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0, 1); +} + +/* fcntl locks don't stack: avoid unlocking someone else's */ +int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) +{ + struct tdb_traverse_lock *i; + uint32_t count = 0; + + if (tdb->global_lock.count) { + return 0; + } + + if (off == 0) + return 0; + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + count++; + return (count == 1 ? tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0, 1) : 0); +} diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c new file mode 100644 index 0000000000..b19e4cea29 --- /dev/null +++ b/lib/tdb/common/open.c @@ -0,0 +1,488 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ +static struct tdb_context *tdbs = NULL; + + +/* This is based on the hash algorithm from gdbm */ +static unsigned int default_tdb_hash(TDB_DATA *key) +{ + uint32_t value; /* Used to compute the hash value. */ + uint32_t i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) + value = (value + (key->dptr[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + + +/* initialise a new database with a specified hash size */ +static int tdb_new_database(struct tdb_context *tdb, int hash_size) +{ + struct tdb_header *newdb; + size_t size; + int ret = -1; + ssize_t written; + + /* We make it up in memory, then write it out if not internal */ + size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t); + if (!(newdb = (struct tdb_header *)calloc(size, 1))) + return TDB_ERRCODE(TDB_ERR_OOM, -1); + + /* Fill in the header */ + newdb->version = TDB_VERSION; + newdb->hash_size = hash_size; + if (tdb->flags & TDB_INTERNAL) { + tdb->map_size = size; + tdb->map_ptr = (char *)newdb; + memcpy(&tdb->header, newdb, sizeof(tdb->header)); + /* Convert the `ondisk' version if asked. */ + CONVERT(*newdb); + return 0; + } + if (lseek(tdb->fd, 0, SEEK_SET) == -1) + goto fail; + + if (ftruncate(tdb->fd, 0) == -1) + goto fail; + + /* This creates an endian-converted header, as if read from disk */ + CONVERT(*newdb); + memcpy(&tdb->header, newdb, sizeof(tdb->header)); + /* Don't endian-convert the magic food! */ + memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); + /* we still have "ret == -1" here */ + written = write(tdb->fd, newdb, size); + if (written == size) { + ret = 0; + } else if (written != -1) { + /* call write once again, this usually should return -1 and + * set errno appropriately */ + size -= written; + written = write(tdb->fd, newdb+written, size); + if (written == size) { + ret = 0; + } else if (written >= 0) { + /* a second incomplete write - we give up. + * guessing the errno... */ + errno = ENOSPC; + } + } + + fail: + SAFE_FREE(newdb); + return ret; +} + + + +static int tdb_already_open(dev_t device, + ino_t ino) +{ + struct tdb_context *i; + + for (i = tdbs; i; i = i->next) { + if (i->device == device && i->inode == ino) { + return 1; + } + } + + return 0; +} + +/* open the database, creating it if necessary + + The open_flags and mode are passed straight to the open call on the + database file. A flags value of O_WRONLY is invalid. The hash size + is advisory, use zero for a default value. + + Return is NULL on error, in which case errno is also set. Don't + try to call tdb_error or tdb_errname, just do strerror(errno). + + @param name may be NULL for internal databases. */ +struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); +} + +/* a default logging function */ +static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ +} + + +struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + const struct tdb_logging_context *log_ctx, + tdb_hash_func hash_fn) +{ + struct tdb_context *tdb; + struct stat st; + int rev = 0, locked = 0; + unsigned char *vp; + uint32_t vertest; + unsigned v; + + if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { + /* Can't log this */ + errno = ENOMEM; + goto fail; + } + tdb_io_init(tdb); + tdb->fd = -1; + tdb->name = NULL; + tdb->map_ptr = NULL; + tdb->flags = tdb_flags; + tdb->open_flags = open_flags; + if (log_ctx) { + tdb->log = *log_ctx; + } else { + tdb->log.log_fn = null_log_fn; + tdb->log.log_private = NULL; + } + tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash; + + /* cache the page size */ + tdb->page_size = getpagesize(); + if (tdb->page_size <= 0) { + tdb->page_size = 0x2000; + } + + tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0; + + if ((open_flags & O_ACCMODE) == O_WRONLY) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", + name)); + errno = EINVAL; + goto fail; + } + + if (hash_size == 0) + hash_size = DEFAULT_HASH_SIZE; + if ((open_flags & O_ACCMODE) == O_RDONLY) { + tdb->read_only = 1; + /* read only databases don't do locking or clear if first */ + tdb->flags |= TDB_NOLOCK; + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + } + + /* internal databases don't mmap or lock, and start off cleared */ + if (tdb->flags & TDB_INTERNAL) { + tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + if (tdb_new_database(tdb, hash_size) != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!")); + goto fail; + } + goto internal; + } + + if ((tdb->fd = open(name, open_flags, mode)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by open(2) */ + } + + /* on exec, don't inherit the fd */ + v = fcntl(tdb->fd, F_GETFD, 0); + fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); + + /* ensure there is only one process initialising at once */ + if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by tdb_brlock */ + } + + /* we need to zero database if we are the only one with it open */ + if ((tdb_flags & TDB_CLEAR_IF_FIRST) && + (!tdb->read_only) && + (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) { + open_flags |= O_CREAT; + if (ftruncate(tdb->fd, 0) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "failed to truncate %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by ftruncate */ + } + } + + errno = 0; + if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) + || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 + || (tdb->header.version != TDB_VERSION + && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { + /* its not a valid database - possibly initialise it */ + if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { + if (errno == 0) { + errno = EIO; /* ie bad format or something */ + } + goto fail; + } + rev = (tdb->flags & TDB_CONVERT); + } + vp = (unsigned char *)&tdb->header.version; + vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | + (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; + tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; + if (!rev) + tdb->flags &= ~TDB_CONVERT; + else { + tdb->flags |= TDB_CONVERT; + tdb_convert(&tdb->header, sizeof(tdb->header)); + } + if (fstat(tdb->fd, &st) == -1) + goto fail; + + if (tdb->header.rwlocks != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n")); + goto fail; + } + + /* Is it already in the open list? If so, fail. */ + if (tdb_already_open(st.st_dev, st.st_ino)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "%s (%d,%d) is already open in this process\n", + name, (int)st.st_dev, (int)st.st_ino)); + errno = EBUSY; + goto fail; + } + + if (!(tdb->name = (char *)strdup(name))) { + errno = ENOMEM; + goto fail; + } + + tdb->map_size = st.st_size; + tdb->device = st.st_dev; + tdb->inode = st.st_ino; + tdb_mmap(tdb); + if (locked) { + if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "failed to take ACTIVE_LOCK on %s: %s\n", + name, strerror(errno))); + goto fail; + } + + } + + /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if + we didn't get the initial exclusive lock as we need to let all other + users know we're using it. */ + + if (tdb_flags & TDB_CLEAR_IF_FIRST) { + /* leave this lock in place to indicate it's in use */ + if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) + goto fail; + } + + /* if needed, run recovery */ + if (tdb_transaction_recover(tdb) == -1) { + goto fail; + } + + internal: + /* Internal (memory-only) databases skip all the code above to + * do with disk files, and resume here by releasing their + * global lock and hooking into the active list. */ + if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1) + goto fail; + tdb->next = tdbs; + tdbs = tdb; + return tdb; + + fail: + { int save_errno = errno; + + if (!tdb) + return NULL; + + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + SAFE_FREE(tdb->name); + if (tdb->fd != -1) + if (close(tdb->fd) != 0) + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); + SAFE_FREE(tdb); + errno = save_errno; + return NULL; + } +} + +/* + * Set the maximum number of dead records per hash chain + */ + +void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) +{ + tdb->max_dead_records = max_dead; +} + +/** + * Close a database. + * + * @returns -1 for error; 0 for success. + **/ +int tdb_close(struct tdb_context *tdb) +{ + struct tdb_context **i; + int ret = 0; + + if (tdb->transaction) { + tdb_transaction_cancel(tdb); + } + + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + SAFE_FREE(tdb->name); + if (tdb->fd != -1) + ret = close(tdb->fd); + SAFE_FREE(tdb->lockrecs); + + /* Remove from contexts list */ + for (i = &tdbs; *i; i = &(*i)->next) { + if (*i == tdb) { + *i = tdb->next; + break; + } + } + + memset(tdb, 0, sizeof(*tdb)); + SAFE_FREE(tdb); + + return ret; +} + +/* register a loging function */ +void tdb_set_logging_function(struct tdb_context *tdb, + const struct tdb_logging_context *log_ctx) +{ + tdb->log = *log_ctx; +} + +void *tdb_get_logging_private(struct tdb_context *tdb) +{ + return tdb->log.log_private; +} + +/* reopen a tdb - this can be used after a fork to ensure that we have an independent + seek pointer from our parent and to re-establish locks */ +int tdb_reopen(struct tdb_context *tdb) +{ + struct stat st; + + if (tdb->flags & TDB_INTERNAL) { + return 0; /* Nothing to do. */ + } + + if (tdb->num_locks != 0 || tdb->global_lock.count) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n")); + goto fail; + } + + if (tdb->transaction != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n")); + goto fail; + } + + if (tdb_munmap(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); + goto fail; + } + if (close(tdb->fd) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n")); + tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); + if (tdb->fd == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno))); + goto fail; + } + if ((tdb->flags & TDB_CLEAR_IF_FIRST) && + (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n")); + goto fail; + } + if (fstat(tdb->fd, &st) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); + goto fail; + } + if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); + goto fail; + } + tdb_mmap(tdb); + + return 0; + +fail: + tdb_close(tdb); + return -1; +} + +/* reopen all tdb's */ +int tdb_reopen_all(int parent_longlived) +{ + struct tdb_context *tdb; + + for (tdb=tdbs; tdb; tdb = tdb->next) { + /* + * If the parent is longlived (ie. a + * parent daemon architecture), we know + * it will keep it's active lock on a + * tdb opened with CLEAR_IF_FIRST. Thus + * for child processes we don't have to + * add an active lock. This is essential + * to improve performance on systems that + * keep POSIX locks as a non-scalable data + * structure in the kernel. + */ + if (parent_longlived) { + /* Ensure no clear-if-first. */ + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + } + + if (tdb_reopen(tdb) != 0) + return -1; + } + + return 0; +} diff --git a/lib/tdb/common/tdb.c b/lib/tdb/common/tdb.c new file mode 100644 index 0000000000..c7cec297f6 --- /dev/null +++ b/lib/tdb/common/tdb.c @@ -0,0 +1,802 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +TDB_DATA tdb_null; + +/* + non-blocking increment of the tdb sequence number if the tdb has been opened using + the TDB_SEQNUM flag +*/ +void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) +{ + tdb_off_t seqnum=0; + + if (!(tdb->flags & TDB_SEQNUM)) { + return; + } + + /* we ignore errors from this, as we have no sane way of + dealing with them. + */ + tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); + seqnum++; + tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); +} + +/* + increment the tdb sequence number if the tdb has been opened using + the TDB_SEQNUM flag +*/ +static void tdb_increment_seqnum(struct tdb_context *tdb) +{ + if (!(tdb->flags & TDB_SEQNUM)) { + return; + } + + if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) { + return; + } + + tdb_increment_seqnum_nonblock(tdb); + + tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1); +} + +static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) +{ + return memcmp(data.dptr, key.dptr, data.dsize); +} + +/* Returns 0 on fail. On success, return offset of record, and fills + in rec */ +static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, + struct list_struct *r) +{ + tdb_off_t rec_ptr; + + /* read in the hash top */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) + return 0; + + /* keep looking until we find the right record */ + while (rec_ptr) { + if (tdb_rec_read(tdb, rec_ptr, r) == -1) + return 0; + + if (!TDB_DEAD(r) && hash==r->full_hash + && key.dsize==r->key_len + && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), + r->key_len, tdb_key_compare, + NULL) == 0) { + return rec_ptr; + } + rec_ptr = r->next; + } + return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); +} + +/* As tdb_find, but if you succeed, keep the lock */ +tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, + struct list_struct *rec) +{ + uint32_t rec_ptr; + + if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) + return 0; + if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) + tdb_unlock(tdb, BUCKET(hash), locktype); + return rec_ptr; +} + + +/* update an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1. +*/ +static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf) +{ + struct list_struct rec; + tdb_off_t rec_ptr; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) + return -1; + + /* must be long enough key, data and tailer */ + if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) { + tdb->ecode = TDB_SUCCESS; /* Not really an error */ + return -1; + } + + if (tdb->methods->tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, + dbuf.dptr, dbuf.dsize) == -1) + return -1; + + if (dbuf.dsize != rec.data_len) { + /* update size */ + rec.data_len = dbuf.dsize; + return tdb_rec_write(tdb, rec_ptr, &rec); + } + + return 0; +} + +/* find an entry in the database given a key */ +/* If an entry doesn't exist tdb_err will be set to + * TDB_ERR_NOEXIST. If a key has no data attached + * then the TDB_DATA will have zero length but + * a non-zero pointer + */ +TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) +{ + tdb_off_t rec_ptr; + struct list_struct rec; + TDB_DATA ret; + uint32_t hash; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) + return tdb_null; + + ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, + rec.data_len); + ret.dsize = rec.data_len; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return ret; +} + +/* + * Find an entry in the database and hand the record's data to a parsing + * function. The parsing function is executed under the chain read lock, so it + * should be fast and should not block on other syscalls. + * + * DONT CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS. + * + * For mmapped tdb's that do not have a transaction open it points the parsing + * function directly at the mmap area, it avoids the malloc/memcpy in this + * case. If a transaction is open or no mmap is available, it has to do + * malloc/read/parse/free. + * + * This is interesting for all readers of potentially large data structures in + * the tdb records, ldb indexes being one example. + */ + +int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data) +{ + tdb_off_t rec_ptr; + struct list_struct rec; + int ret; + uint32_t hash; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + + if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { + return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); + } + + ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, + rec.data_len, parser, private_data); + + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + + return ret; +} + +/* check if an entry in the database exists + + note that 1 is returned if the key is found and 0 is returned if not found + this doesn't match the conventions in the rest of this module, but is + compatible with gdbm +*/ +static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) +{ + struct list_struct rec; + + if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) + return 0; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return 1; +} + +int tdb_exists(struct tdb_context *tdb, TDB_DATA key) +{ + uint32_t hash = tdb->hash_fn(&key); + return tdb_exists_hash(tdb, key, hash); +} + +/* actually delete an entry in the database given the offset */ +int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec) +{ + tdb_off_t last_ptr, i; + struct list_struct lastrec; + + if (tdb->read_only || tdb->traverse_read) return -1; + + if (((tdb->traverse_write != 0) && (!TDB_DEAD(rec))) || + tdb_write_lock_record(tdb, rec_ptr) == -1) { + /* Someone traversing here: mark it as dead */ + rec->magic = TDB_DEAD_MAGIC; + return tdb_rec_write(tdb, rec_ptr, rec); + } + if (tdb_write_unlock_record(tdb, rec_ptr) != 0) + return -1; + + /* find previous record in hash chain */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) + return -1; + for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) + if (tdb_rec_read(tdb, i, &lastrec) == -1) + return -1; + + /* unlink it: next ptr is at start of record. */ + if (last_ptr == 0) + last_ptr = TDB_HASH_TOP(rec->full_hash); + if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) + return -1; + + /* recover the space */ + if (tdb_free(tdb, rec_ptr, rec) == -1) + return -1; + return 0; +} + +static int tdb_count_dead(struct tdb_context *tdb, uint32_t hash) +{ + int res = 0; + tdb_off_t rec_ptr; + struct list_struct rec; + + /* read in the hash top */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) + return 0; + + while (rec_ptr) { + if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) + return 0; + + if (rec.magic == TDB_DEAD_MAGIC) { + res += 1; + } + rec_ptr = rec.next; + } + return res; +} + +/* + * Purge all DEAD records from a hash chain + */ +static int tdb_purge_dead(struct tdb_context *tdb, uint32_t hash) +{ + int res = -1; + struct list_struct rec; + tdb_off_t rec_ptr; + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + return -1; + } + + /* read in the hash top */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) + goto fail; + + while (rec_ptr) { + tdb_off_t next; + + if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) { + goto fail; + } + + next = rec.next; + + if (rec.magic == TDB_DEAD_MAGIC + && tdb_do_delete(tdb, rec_ptr, &rec) == -1) { + goto fail; + } + rec_ptr = next; + } + res = 0; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return res; +} + +/* delete an entry in the database given a key */ +static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) +{ + tdb_off_t rec_ptr; + struct list_struct rec; + int ret; + + if (tdb->max_dead_records != 0) { + + /* + * Allow for some dead records per hash chain, mainly for + * tdb's with a very high create/delete rate like locking.tdb. + */ + + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + if (tdb_count_dead(tdb, hash) >= tdb->max_dead_records) { + /* + * Don't let the per-chain freelist grow too large, + * delete all existing dead records + */ + tdb_purge_dead(tdb, hash); + } + + if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return -1; + } + + /* + * Just mark the record as dead. + */ + rec.magic = TDB_DEAD_MAGIC; + ret = tdb_rec_write(tdb, rec_ptr, &rec); + } + else { + if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, + &rec))) + return -1; + + ret = tdb_do_delete(tdb, rec_ptr, &rec); + } + + if (ret == 0) { + tdb_increment_seqnum(tdb); + } + + if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); + return ret; +} + +int tdb_delete(struct tdb_context *tdb, TDB_DATA key) +{ + uint32_t hash = tdb->hash_fn(&key); + return tdb_delete_hash(tdb, key, hash); +} + +/* + * See if we have a dead record around with enough space + */ +static tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, + struct list_struct *r, tdb_len_t length) +{ + tdb_off_t rec_ptr; + + /* read in the hash top */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) + return 0; + + /* keep looking until we find the right record */ + while (rec_ptr) { + if (tdb_rec_read(tdb, rec_ptr, r) == -1) + return 0; + + if (TDB_DEAD(r) && r->rec_len >= length) { + /* + * First fit for simple coding, TODO: change to best + * fit + */ + return rec_ptr; + } + rec_ptr = r->next; + } + return 0; +} + +/* store an element in the database, replacing any existing element + with the same key + + return 0 on success, -1 on failure +*/ +int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) +{ + struct list_struct rec; + uint32_t hash; + tdb_off_t rec_ptr; + char *p = NULL; + int ret = -1; + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + /* check for it existing, on insert. */ + if (flag == TDB_INSERT) { + if (tdb_exists_hash(tdb, key, hash)) { + tdb->ecode = TDB_ERR_EXISTS; + goto fail; + } + } else { + /* first try in-place update, on modify or replace. */ + if (tdb_update_hash(tdb, key, hash, dbuf) == 0) { + goto done; + } + if (tdb->ecode == TDB_ERR_NOEXIST && + flag == TDB_MODIFY) { + /* if the record doesn't exist and we are in TDB_MODIFY mode then + we should fail the store */ + goto fail; + } + } + /* reset the error code potentially set by the tdb_update() */ + tdb->ecode = TDB_SUCCESS; + + /* delete any existing record - if it doesn't exist we don't + care. Doing this first reduces fragmentation, and avoids + coalescing with `allocated' block before it's updated. */ + if (flag != TDB_INSERT) + tdb_delete_hash(tdb, key, hash); + + /* Copy key+value *before* allocating free space in case malloc + fails and we are left with a dead spot in the tdb. */ + + if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + + memcpy(p, key.dptr, key.dsize); + if (dbuf.dsize) + memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); + + if (tdb->max_dead_records != 0) { + /* + * Allow for some dead records per hash chain, look if we can + * find one that can hold the new record. We need enough space + * for key, data and tailer. If we find one, we don't have to + * consult the central freelist. + */ + rec_ptr = tdb_find_dead( + tdb, hash, &rec, + key.dsize + dbuf.dsize + sizeof(tdb_off_t)); + + if (rec_ptr != 0) { + rec.key_len = key.dsize; + rec.data_len = dbuf.dsize; + rec.full_hash = hash; + rec.magic = TDB_MAGIC; + if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 + || tdb->methods->tdb_write( + tdb, rec_ptr + sizeof(rec), + p, key.dsize + dbuf.dsize) == -1) { + goto fail; + } + goto done; + } + } + + /* + * We have to allocate some space from the freelist, so this means we + * have to lock it. Use the chance to purge all the DEAD records from + * the hash chain under the freelist lock. + */ + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + goto fail; + } + + if ((tdb->max_dead_records != 0) + && (tdb_purge_dead(tdb, hash) == -1)) { + tdb_unlock(tdb, -1, F_WRLCK); + goto fail; + } + + /* we have to allocate some space */ + rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec); + + tdb_unlock(tdb, -1, F_WRLCK); + + if (rec_ptr == 0) { + goto fail; + } + + /* Read hash top into next ptr */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) + goto fail; + + rec.key_len = key.dsize; + rec.data_len = dbuf.dsize; + rec.full_hash = hash; + rec.magic = TDB_MAGIC; + + /* write out and point the top of the hash chain at it */ + if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 + || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 + || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { + /* Need to tdb_unallocate() here */ + goto fail; + } + + done: + ret = 0; + fail: + if (ret == 0) { + tdb_increment_seqnum(tdb); + } + + SAFE_FREE(p); + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return ret; +} + + +/* Append to an entry. Create if not exist. */ +int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) +{ + uint32_t hash; + TDB_DATA dbuf; + int ret = -1; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + dbuf = tdb_fetch(tdb, key); + + if (dbuf.dptr == NULL) { + dbuf.dptr = (unsigned char *)malloc(new_dbuf.dsize); + } else { + unsigned char *new_dptr = (unsigned char *)realloc(dbuf.dptr, + dbuf.dsize + new_dbuf.dsize); + if (new_dptr == NULL) { + free(dbuf.dptr); + } + dbuf.dptr = new_dptr; + } + + if (dbuf.dptr == NULL) { + tdb->ecode = TDB_ERR_OOM; + goto failed; + } + + memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize); + dbuf.dsize += new_dbuf.dsize; + + ret = tdb_store(tdb, key, dbuf, 0); + +failed: + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + SAFE_FREE(dbuf.dptr); + return ret; +} + + +/* + return the name of the current tdb file + useful for external logging functions +*/ +const char *tdb_name(struct tdb_context *tdb) +{ + return tdb->name; +} + +/* + return the underlying file descriptor being used by tdb, or -1 + useful for external routines that want to check the device/inode + of the fd +*/ +int tdb_fd(struct tdb_context *tdb) +{ + return tdb->fd; +} + +/* + return the current logging function + useful for external tdb routines that wish to log tdb errors +*/ +tdb_log_func tdb_log_fn(struct tdb_context *tdb) +{ + return tdb->log.log_fn; +} + + +/* + get the tdb sequence number. Only makes sense if the writers opened + with TDB_SEQNUM set. Note that this sequence number will wrap quite + quickly, so it should only be used for a 'has something changed' + test, not for code that relies on the count of the number of changes + made. If you want a counter then use a tdb record. + + The aim of this sequence number is to allow for a very lightweight + test of a possible tdb change. +*/ +int tdb_get_seqnum(struct tdb_context *tdb) +{ + tdb_off_t seqnum=0; + + tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); + return seqnum; +} + +int tdb_hash_size(struct tdb_context *tdb) +{ + return tdb->header.hash_size; +} + +size_t tdb_map_size(struct tdb_context *tdb) +{ + return tdb->map_size; +} + +int tdb_get_flags(struct tdb_context *tdb) +{ + return tdb->flags; +} + +void tdb_add_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags |= flags; +} + +void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags &= ~flags; +} + + +/* + enable sequence number handling on an open tdb +*/ +void tdb_enable_seqnum(struct tdb_context *tdb) +{ + tdb->flags |= TDB_SEQNUM; +} + + +/* + add a region of the file to the freelist. Length is the size of the region in bytes, + which includes the free list header that needs to be added + */ +static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) +{ + struct list_struct rec; + if (length <= sizeof(rec)) { + /* the region is not worth adding */ + return 0; + } + if (length + offset > tdb->map_size) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); + return -1; + } + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = length - sizeof(rec); + if (tdb_free(tdb, offset, &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n")); + return -1; + } + return 0; +} + +/* + wipe the entire database, deleting all records. This can be done + very fast by using a global lock. The entire data portion of the + file becomes a single entry in the freelist. + + This code carefully steps around the recovery area, leaving it alone + */ +int tdb_wipe_all(struct tdb_context *tdb) +{ + int i; + tdb_off_t offset = 0; + ssize_t data_len; + tdb_off_t recovery_head; + tdb_len_t recovery_size = 0; + + if (tdb_lockall(tdb) != 0) { + return -1; + } + + /* see if the tdb has a recovery area, and remember its size + if so. We don't want to lose this as otherwise each + tdb_wipe_all() in a transaction will increase the size of + the tdb by the size of the recovery area */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n")); + goto failed; + } + + if (recovery_head != 0) { + struct list_struct rec; + if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); + return -1; + } + recovery_size = rec.rec_len + sizeof(rec); + } + + /* wipe the hashes */ + for (i=0;iheader.hash_size;i++) { + if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); + goto failed; + } + } + + /* wipe the freelist */ + if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); + goto failed; + } + + /* add all the rest of the file to the freelist, possibly leaving a gap + for the recovery area */ + if (recovery_size == 0) { + /* the simple case - the whole file can be used as a freelist */ + data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)); + if (tdb_free_region(tdb, TDB_DATA_START(tdb->header.hash_size), data_len) != 0) { + goto failed; + } + } else { + /* we need to add two freelist entries - one on either + side of the recovery area + + Note that we cannot shift the recovery area during + this operation. Only the transaction.c code may + move the recovery area or we risk subtle data + corruption + */ + data_len = (recovery_head - TDB_DATA_START(tdb->header.hash_size)); + if (tdb_free_region(tdb, TDB_DATA_START(tdb->header.hash_size), data_len) != 0) { + goto failed; + } + /* and the 2nd free list entry after the recovery area - if any */ + data_len = tdb->map_size - (recovery_head+recovery_size); + if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { + goto failed; + } + } + + if (tdb_unlockall(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); + goto failed; + } + + return 0; + +failed: + tdb_unlockall(tdb); + return -1; +} diff --git a/lib/tdb/common/tdb_private.h b/lib/tdb/common/tdb_private.h new file mode 100644 index 0000000000..ffac89ff0e --- /dev/null +++ b/lib/tdb/common/tdb_private.h @@ -0,0 +1,213 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library - private includes + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "system/shmem.h" +#include "system/select.h" +#include "system/wait.h" +#include "tdb.h" + +#ifndef HAVE_GETPAGESIZE +#define getpagesize() 0x2000 +#endif + +typedef uint32_t tdb_len_t; +typedef uint32_t tdb_off_t; + +#ifndef offsetof +#define offsetof(t,f) ((unsigned int)&((t *)0)->f) +#endif + +#define TDB_MAGIC_FOOD "TDB file\n" +#define TDB_VERSION (0x26011967 + 6) +#define TDB_MAGIC (0x26011999U) +#define TDB_FREE_MAGIC (~TDB_MAGIC) +#define TDB_DEAD_MAGIC (0xFEE1DEAD) +#define TDB_RECOVERY_MAGIC (0xf53bc0e7U) +#define TDB_ALIGNMENT 4 +#define DEFAULT_HASH_SIZE 131 +#define FREELIST_TOP (sizeof(struct tdb_header)) +#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) +#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) +#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) +#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) +#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) +#define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t)) +#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) +#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) +#define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) +#define TDB_PAD_BYTE 0x42 +#define TDB_PAD_U32 0x42424242 + +/* NB assumes there is a local variable called "tdb" that is the + * current context, also takes doubly-parenthesized print-style + * argument. */ +#define TDB_LOG(x) tdb->log.log_fn x + +/* lock offsets */ +#define GLOBAL_LOCK 0 +#define ACTIVE_LOCK 4 +#define TRANSACTION_LOCK 8 + +/* free memory if the pointer is valid and zero the pointer */ +#ifndef SAFE_FREE +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) +#endif + +#define BUCKET(hash) ((hash) % tdb->header.hash_size) + +#define DOCONV() (tdb->flags & TDB_CONVERT) +#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) + + +/* the body of the database is made of one list_struct for the free space + plus a separate data list for each hash value */ +struct list_struct { + tdb_off_t next; /* offset of the next record in the list */ + tdb_len_t rec_len; /* total byte length of record */ + tdb_len_t key_len; /* byte length of key */ + tdb_len_t data_len; /* byte length of data */ + uint32_t full_hash; /* the full 32 bit hash of the key */ + uint32_t magic; /* try to catch errors */ + /* the following union is implied: + union { + char record[rec_len]; + struct { + char key[key_len]; + char data[data_len]; + } + uint32_t totalsize; (tailer) + } + */ +}; + + +/* this is stored at the front of every database */ +struct tdb_header { + char magic_food[32]; /* for /etc/magic */ + uint32_t version; /* version of the code */ + uint32_t hash_size; /* number of hash entries */ + tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ + tdb_off_t recovery_start; /* offset of transaction recovery region */ + tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ + tdb_off_t reserved[29]; +}; + +struct tdb_lock_type { + int list; + uint32_t count; + uint32_t ltype; +}; + +struct tdb_traverse_lock { + struct tdb_traverse_lock *next; + uint32_t off; + uint32_t hash; + int lock_rw; +}; + + +struct tdb_methods { + int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); + int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); + void (*next_hash_chain)(struct tdb_context *, uint32_t *); + int (*tdb_oob)(struct tdb_context *, tdb_off_t , int ); + int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); + int (*tdb_brlock)(struct tdb_context *, tdb_off_t , int, int, int, size_t); +}; + +struct tdb_context { + char *name; /* the name of the database */ + void *map_ptr; /* where it is currently mapped */ + int fd; /* open file descriptor for the database */ + tdb_len_t map_size; /* how much space has been mapped */ + int read_only; /* opened read-only */ + int traverse_read; /* read-only traversal */ + int traverse_write; /* read-write traversal */ + struct tdb_lock_type global_lock; + int num_lockrecs; + struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ + enum TDB_ERROR ecode; /* error code for last tdb error */ + struct tdb_header header; /* a cached copy of the header */ + uint32_t flags; /* the flags passed to tdb_open */ + struct tdb_traverse_lock travlocks; /* current traversal locks */ + struct tdb_context *next; /* all tdbs to avoid multiple opens */ + dev_t device; /* uniquely identifies this tdb */ + ino_t inode; /* uniquely identifies this tdb */ + struct tdb_logging_context log; + unsigned int (*hash_fn)(TDB_DATA *key); + int open_flags; /* flags used in the open - needed by reopen */ + unsigned int num_locks; /* number of chain locks held */ + const struct tdb_methods *methods; + struct tdb_transaction *transaction; + int page_size; + int max_dead_records; + bool have_transaction_lock; + volatile sig_atomic_t *interrupt_sig_ptr; +}; + + +/* + internal prototypes +*/ +int tdb_munmap(struct tdb_context *tdb); +void tdb_mmap(struct tdb_context *tdb); +int tdb_lock(struct tdb_context *tdb, int list, int ltype); +int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); +int tdb_unlock(struct tdb_context *tdb, int list, int ltype); +int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); +int tdb_transaction_lock(struct tdb_context *tdb, int ltype); +int tdb_transaction_unlock(struct tdb_context *tdb); +int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len); +int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); +int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); +int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +void *tdb_convert(void *buf, uint32_t size); +int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); +tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec); +int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); +int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); +int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); +int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); +int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec); +unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); +int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, + tdb_off_t offset, tdb_len_t len, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data); +tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, + struct list_struct *rec); +void tdb_io_init(struct tdb_context *tdb); +int tdb_expand(struct tdb_context *tdb, tdb_off_t size); +int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, + struct list_struct *rec); + + diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c new file mode 100644 index 0000000000..7acda640c8 --- /dev/null +++ b/lib/tdb/common/transaction.c @@ -0,0 +1,1119 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* + transaction design: + + - only allow a single transaction at a time per database. This makes + using the transaction API simpler, as otherwise the caller would + have to cope with temporary failures in transactions that conflict + with other current transactions + + - keep the transaction recovery information in the same file as the + database, using a special 'transaction recovery' record pointed at + by the header. This removes the need for extra journal files as + used by some other databases + + - dynamically allocated the transaction recover record, re-using it + for subsequent transactions. If a larger record is needed then + tdb_free() the old record to place it on the normal tdb freelist + before allocating the new record + + - during transactions, keep a linked list of writes all that have + been performed by intercepting all tdb_write() calls. The hooked + transaction versions of tdb_read() and tdb_write() check this + linked list and try to use the elements of the list in preference + to the real database. + + - don't allow any locks to be held when a transaction starts, + otherwise we can end up with deadlock (plus lack of lock nesting + in posix locks would mean the lock is lost) + + - if the caller gains a lock during the transaction but doesn't + release it then fail the commit + + - allow for nested calls to tdb_transaction_start(), re-using the + existing transaction record. If the inner transaction is cancelled + then a subsequent commit will fail + + - keep a mirrored copy of the tdb hash chain heads to allow for the + fast hash heads scan on traverse, updating the mirrored copy in + the transaction version of tdb_write + + - allow callers to mix transaction and non-transaction use of tdb, + although once a transaction is started then an exclusive lock is + gained until the transaction is committed or cancelled + + - the commit stategy involves first saving away all modified data + into a linearised buffer in the transaction recovery area, then + marking the transaction recovery area with a magic value to + indicate a valid recovery record. In total 4 fsync/msync calls are + needed per commit to prevent race conditions. It might be possible + to reduce this to 3 or even 2 with some more work. + + - check for a valid recovery record on open of the tdb, while the + global lock is held. Automatically recover from the transaction + recovery area if needed, then continue with the open as + usual. This allows for smooth crash recovery with no administrator + intervention. + + - if TDB_NOSYNC is passed to flags in tdb_open then transactions are + still available, but no transaction recovery area is used and no + fsync/msync calls are made. + +*/ + + +/* + hold the context of any current transaction +*/ +struct tdb_transaction { + /* we keep a mirrored copy of the tdb hash heads here so + tdb_next_hash_chain() can operate efficiently */ + uint32_t *hash_heads; + + /* the original io methods - used to do IOs to the real db */ + const struct tdb_methods *io_methods; + + /* the list of transaction blocks. When a block is first + written to, it gets created in this list */ + uint8_t **blocks; + uint32_t num_blocks; + uint32_t block_size; /* bytes in each block */ + uint32_t last_block_size; /* number of valid bytes in the last block */ + + /* non-zero when an internal transaction error has + occurred. All write operations will then fail until the + transaction is ended */ + int transaction_error; + + /* when inside a transaction we need to keep track of any + nested tdb_transaction_start() calls, as these are allowed, + but don't create a new transaction */ + int nesting; + + /* old file size before transaction */ + tdb_len_t old_map_size; +}; + + +/* + read while in a transaction. We need to check first if the data is in our list + of transaction elements, then if not do a real read +*/ +static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, + tdb_len_t len, int cv) +{ + uint32_t blk; + + /* break it down into block sized ops */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_read(tdb, off, buf, len2, cv) != 0) { + return -1; + } + len -= len2; + off += len2; + buf = (void *)(len2 + (char *)buf); + } + + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + + /* see if we have it in the block list */ + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + /* nope, do a real read */ + if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { + goto fail; + } + return 0; + } + + /* it is in the block list. Now check for the last block */ + if (blk == tdb->transaction->num_blocks-1) { + if (len > tdb->transaction->last_block_size) { + goto fail; + } + } + + /* now copy it out of this block */ + memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); + if (cv) { + tdb_convert(buf, len); + } + return 0; + +fail: + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%d len=%d\n", off, len)); + tdb->ecode = TDB_ERR_IO; + tdb->transaction->transaction_error = 1; + return -1; +} + + +/* + write while in a transaction +*/ +static int transaction_write(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + uint32_t blk; + + /* if the write is to a hash head, then update the transaction + hash heads */ + if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && + off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) { + uint32_t chain = (off-FREELIST_TOP) / sizeof(tdb_off_t); + memcpy(&tdb->transaction->hash_heads[chain], buf, len); + } + + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write(tdb, off, buf, len2) != 0) { + return -1; + } + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); + } + } + + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk) { + uint8_t **new_blocks; + /* expand the blocks array */ + if (tdb->transaction->blocks == NULL) { + new_blocks = (uint8_t **)malloc( + (blk+1)*sizeof(uint8_t *)); + } else { + new_blocks = (uint8_t **)realloc( + tdb->transaction->blocks, + (blk+1)*sizeof(uint8_t *)); + } + if (new_blocks == NULL) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + memset(&new_blocks[tdb->transaction->num_blocks], 0, + (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); + tdb->transaction->blocks = new_blocks; + tdb->transaction->num_blocks = blk+1; + tdb->transaction->last_block_size = 0; + } + + /* allocate and fill a block? */ + if (tdb->transaction->blocks[blk] == NULL) { + tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); + if (tdb->transaction->blocks[blk] == NULL) { + tdb->ecode = TDB_ERR_OOM; + tdb->transaction->transaction_error = 1; + return -1; + } + if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size; + if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { + len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); + } + if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, + tdb->transaction->blocks[blk], + len2, 0) != 0) { + SAFE_FREE(tdb->transaction->blocks[blk]); + tdb->ecode = TDB_ERR_IO; + goto fail; + } + if (blk == tdb->transaction->num_blocks-1) { + tdb->transaction->last_block_size = len2; + } + } + } + + /* overwrite part of an existing block */ + if (buf == NULL) { + memset(tdb->transaction->blocks[blk] + off, 0, len); + } else { + memcpy(tdb->transaction->blocks[blk] + off, buf, len); + } + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } + } + + return 0; + +fail: + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + (blk*tdb->transaction->block_size) + off, len)); + tdb->transaction->transaction_error = 1; + return -1; +} + + +/* + write while in a transaction - this varient never expands the transaction blocks, it only + updates existing blocks. This means it cannot change the recovery size +*/ +static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + uint32_t blk; + + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write_existing(tdb, off, buf, len2) != 0) { + return -1; + } + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); + } + } + + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + return 0; + } + + if (blk == tdb->transaction->num_blocks-1 && + off + len > tdb->transaction->last_block_size) { + if (off >= tdb->transaction->last_block_size) { + return 0; + } + len = tdb->transaction->last_block_size - off; + } + + /* overwrite part of an existing block */ + memcpy(tdb->transaction->blocks[blk] + off, buf, len); + + return 0; +} + + +/* + accelerated hash chain head search, using the cached hash heads +*/ +static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) +{ + uint32_t h = *chain; + for (;h < tdb->header.hash_size;h++) { + /* the +1 takes account of the freelist */ + if (0 != tdb->transaction->hash_heads[h+1]) { + break; + } + } + (*chain) = h; +} + +/* + out of bounds check during a transaction +*/ +static int transaction_oob(struct tdb_context *tdb, tdb_off_t len, int probe) +{ + if (len <= tdb->map_size) { + return 0; + } + return TDB_ERRCODE(TDB_ERR_IO, -1); +} + +/* + transaction version of tdb_expand(). +*/ +static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, + tdb_off_t addition) +{ + /* add a write to the transaction elements, so subsequent + reads see the zero data */ + if (transaction_write(tdb, size, NULL, addition) != 0) { + return -1; + } + + return 0; +} + +/* + brlock during a transaction - ignore them +*/ +static int transaction_brlock(struct tdb_context *tdb, tdb_off_t offset, + int rw_type, int lck_type, int probe, size_t len) +{ + return 0; +} + +static const struct tdb_methods transaction_methods = { + transaction_read, + transaction_write, + transaction_next_hash_chain, + transaction_oob, + transaction_expand_file, + transaction_brlock +}; + + +/* + start a tdb transaction. No token is returned, as only a single + transaction is allowed to be pending per tdb_context +*/ +int tdb_transaction_start(struct tdb_context *tdb) +{ + /* some sanity checks */ + if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n")); + tdb->ecode = TDB_ERR_EINVAL; + return -1; + } + + /* cope with nested tdb_transaction_start() calls */ + if (tdb->transaction != NULL) { + tdb->transaction->nesting++; + TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", + tdb->transaction->nesting)); + return 0; + } + + if (tdb->num_locks != 0 || tdb->global_lock.count) { + /* the caller must not have any locks when starting a + transaction as otherwise we'll be screwed by lack + of nested locks in posix */ + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n")); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb->travlocks.next != NULL) { + /* you cannot use transactions inside a traverse (although you can use + traverse inside a transaction) as otherwise you can end up with + deadlock */ + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n")); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + tdb->transaction = (struct tdb_transaction *) + calloc(sizeof(struct tdb_transaction), 1); + if (tdb->transaction == NULL) { + tdb->ecode = TDB_ERR_OOM; + return -1; + } + + /* a page at a time seems like a reasonable compromise between compactness and efficiency */ + tdb->transaction->block_size = tdb->page_size; + + /* get the transaction write lock. This is a blocking lock. As + discussed with Volker, there are a number of ways we could + make this async, which we will probably do in the future */ + if (tdb_transaction_lock(tdb, F_WRLCK) == -1) { + SAFE_FREE(tdb->transaction->blocks); + SAFE_FREE(tdb->transaction); + return -1; + } + + /* get a read lock from the freelist to the end of file. This + is upgraded to a write lock during the commit */ + if (tdb_brlock(tdb, FREELIST_TOP, F_RDLCK, F_SETLKW, 0, 0) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n")); + tdb->ecode = TDB_ERR_LOCK; + goto fail; + } + + /* setup a copy of the hash table heads so the hash scan in + traverse can be fast */ + tdb->transaction->hash_heads = (uint32_t *) + calloc(tdb->header.hash_size+1, sizeof(uint32_t)); + if (tdb->transaction->hash_heads == NULL) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads, + TDB_HASHTABLE_SIZE(tdb), 0) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n")); + tdb->ecode = TDB_ERR_IO; + goto fail; + } + + /* make sure we know about any file expansions already done by + anyone else */ + tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); + tdb->transaction->old_map_size = tdb->map_size; + + /* finally hook the io methods, replacing them with + transaction specific methods */ + tdb->transaction->io_methods = tdb->methods; + tdb->methods = &transaction_methods; + + return 0; + +fail: + tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); + tdb_transaction_unlock(tdb); + SAFE_FREE(tdb->transaction->blocks); + SAFE_FREE(tdb->transaction->hash_heads); + SAFE_FREE(tdb->transaction); + return -1; +} + + +/* + cancel the current transaction +*/ +int tdb_transaction_cancel(struct tdb_context *tdb) +{ + int i; + + if (tdb->transaction == NULL) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); + return -1; + } + + if (tdb->transaction->nesting != 0) { + tdb->transaction->transaction_error = 1; + tdb->transaction->nesting--; + return 0; + } + + tdb->map_size = tdb->transaction->old_map_size; + + /* free all the transaction blocks */ + for (i=0;itransaction->num_blocks;i++) { + if (tdb->transaction->blocks[i] != NULL) { + free(tdb->transaction->blocks[i]); + } + } + SAFE_FREE(tdb->transaction->blocks); + + /* remove any global lock created during the transaction */ + if (tdb->global_lock.count != 0) { + tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 4*tdb->header.hash_size); + tdb->global_lock.count = 0; + } + + /* remove any locks created during the transaction */ + if (tdb->num_locks != 0) { + for (i=0;inum_lockrecs;i++) { + tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list, + F_UNLCK,F_SETLKW, 0, 1); + } + tdb->num_locks = 0; + tdb->num_lockrecs = 0; + SAFE_FREE(tdb->lockrecs); + } + + /* restore the normal io methods */ + tdb->methods = tdb->transaction->io_methods; + + tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); + tdb_transaction_unlock(tdb); + SAFE_FREE(tdb->transaction->hash_heads); + SAFE_FREE(tdb->transaction); + + return 0; +} + +/* + sync to disk +*/ +static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) +{ + if (fsync(tdb->fd) != 0) { + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); + return -1; + } +#ifdef HAVE_MMAP + if (tdb->map_ptr) { + tdb_off_t moffset = offset & ~(tdb->page_size-1); + if (msync(moffset + (char *)tdb->map_ptr, + length + (offset - moffset), MS_SYNC) != 0) { + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", + strerror(errno))); + return -1; + } + } +#endif + return 0; +} + + +/* + work out how much space the linearised recovery data will consume +*/ +static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) +{ + tdb_len_t recovery_size = 0; + int i; + + recovery_size = sizeof(uint32_t); + for (i=0;itransaction->num_blocks;i++) { + if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { + break; + } + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + recovery_size += 2*sizeof(tdb_off_t); + if (i == tdb->transaction->num_blocks-1) { + recovery_size += tdb->transaction->last_block_size; + } else { + recovery_size += tdb->transaction->block_size; + } + } + + return recovery_size; +} + +/* + allocate the recovery area, or use an existing recovery area if it is + large enough +*/ +static int tdb_recovery_allocate(struct tdb_context *tdb, + tdb_len_t *recovery_size, + tdb_off_t *recovery_offset, + tdb_len_t *recovery_max_size) +{ + struct list_struct rec; + const struct tdb_methods *methods = tdb->transaction->io_methods; + tdb_off_t recovery_head; + + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); + return -1; + } + + rec.rec_len = 0; + + if (recovery_head != 0 && + methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery record\n")); + return -1; + } + + *recovery_size = tdb_recovery_size(tdb); + + if (recovery_head != 0 && *recovery_size <= rec.rec_len) { + /* it fits in the existing area */ + *recovery_max_size = rec.rec_len; + *recovery_offset = recovery_head; + return 0; + } + + /* we need to free up the old recovery area, then allocate a + new one at the end of the file. Note that we cannot use + tdb_allocate() to allocate the new one as that might return + us an area that is being currently used (as of the start of + the transaction) */ + if (recovery_head != 0) { + if (tdb_free(tdb, recovery_head, &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to free previous recovery area\n")); + return -1; + } + } + + /* the tdb_free() call might have increased the recovery size */ + *recovery_size = tdb_recovery_size(tdb); + + /* round up to a multiple of page size */ + *recovery_max_size = TDB_ALIGN(sizeof(rec) + *recovery_size, tdb->page_size) - sizeof(rec); + *recovery_offset = tdb->map_size; + recovery_head = *recovery_offset; + + if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, + (tdb->map_size - tdb->transaction->old_map_size) + + sizeof(rec) + *recovery_max_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); + return -1; + } + + /* remap the file (if using mmap) */ + methods->tdb_oob(tdb, tdb->map_size + 1, 1); + + /* we have to reset the old map size so that we don't try to expand the file + again in the transaction commit, which would destroy the recovery area */ + tdb->transaction->old_map_size = tdb->map_size; + + /* write the recovery header offset and sync - we can sync without a race here + as the magic ptr in the recovery record has not been set */ + CONVERT(recovery_head); + if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, + &recovery_head, sizeof(tdb_off_t)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); + return -1; + } + if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); + return -1; + } + + return 0; +} + + +/* + setup the recovery data that will be used on a crash during commit +*/ +static int transaction_setup_recovery(struct tdb_context *tdb, + tdb_off_t *magic_offset) +{ + tdb_len_t recovery_size; + unsigned char *data, *p; + const struct tdb_methods *methods = tdb->transaction->io_methods; + struct list_struct *rec; + tdb_off_t recovery_offset, recovery_max_size; + tdb_off_t old_map_size = tdb->transaction->old_map_size; + uint32_t magic, tailer; + int i; + + /* + check that the recovery area has enough space + */ + if (tdb_recovery_allocate(tdb, &recovery_size, + &recovery_offset, &recovery_max_size) == -1) { + return -1; + } + + data = (unsigned char *)malloc(recovery_size + sizeof(*rec)); + if (data == NULL) { + tdb->ecode = TDB_ERR_OOM; + return -1; + } + + rec = (struct list_struct *)data; + memset(rec, 0, sizeof(*rec)); + + rec->magic = 0; + rec->data_len = recovery_size; + rec->rec_len = recovery_max_size; + rec->key_len = old_map_size; + CONVERT(rec); + + /* build the recovery data into a single blob to allow us to do a single + large write, which should be more efficient */ + p = data + sizeof(*rec); + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; + + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (offset >= old_map_size) { + continue; + } + if (offset + length > tdb->transaction->old_map_size) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); + free(data); + tdb->ecode = TDB_ERR_CORRUPT; + return -1; + } + memcpy(p, &offset, 4); + memcpy(p+4, &length, 4); + if (DOCONV()) { + tdb_convert(p, 8); + } + /* the recovery area contains the old data, not the + new data, so we have to call the original tdb_read + method to get it */ + if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } + p += 8 + length; + } + + /* and the tailer */ + tailer = sizeof(*rec) + recovery_max_size; + memcpy(p, &tailer, 4); + CONVERT(p); + + /* write the recovery data to the recovery area */ + if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n")); + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } + if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* as we don't have ordered writes, we have to sync the recovery + data before we update the magic to indicate that the recovery + data is present */ + if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { + free(data); + return -1; + } + + free(data); + + magic = TDB_RECOVERY_MAGIC; + CONVERT(magic); + + *magic_offset = recovery_offset + offsetof(struct list_struct, magic); + + if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* ensure the recovery magic marker is on disk */ + if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { + return -1; + } + + return 0; +} + +/* + commit the current transaction +*/ +int tdb_transaction_commit(struct tdb_context *tdb) +{ + const struct tdb_methods *methods; + tdb_off_t magic_offset = 0; + uint32_t zero = 0; + int i; + + if (tdb->transaction == NULL) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); + return -1; + } + + if (tdb->transaction->transaction_error) { + tdb->ecode = TDB_ERR_IO; + tdb_transaction_cancel(tdb); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n")); + return -1; + } + + + if (tdb->transaction->nesting != 0) { + tdb->transaction->nesting--; + return 0; + } + + /* check for a null transaction */ + if (tdb->transaction->blocks == NULL) { + tdb_transaction_cancel(tdb); + return 0; + } + + methods = tdb->transaction->io_methods; + + /* if there are any locks pending then the caller has not + nested their locks properly, so fail the transaction */ + if (tdb->num_locks || tdb->global_lock.count) { + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: locks pending on commit\n")); + tdb_transaction_cancel(tdb); + return -1; + } + + /* upgrade the main transaction lock region to a write lock */ + if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to upgrade hash locks\n")); + tdb->ecode = TDB_ERR_LOCK; + tdb_transaction_cancel(tdb); + return -1; + } + + /* get the global lock - this prevents new users attaching to the database + during the commit */ + if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: failed to get global lock\n")); + tdb->ecode = TDB_ERR_LOCK; + tdb_transaction_cancel(tdb); + return -1; + } + + if (!(tdb->flags & TDB_NOSYNC)) { + /* write the recovery data to the end of the file */ + if (transaction_setup_recovery(tdb, &magic_offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to setup recovery data\n")); + tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); + tdb_transaction_cancel(tdb); + return -1; + } + } + + /* expand the file to the new size if needed */ + if (tdb->map_size != tdb->transaction->old_map_size) { + if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, + tdb->map_size - + tdb->transaction->old_map_size) == -1) { + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: expansion failed\n")); + tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); + tdb_transaction_cancel(tdb); + return -1; + } + tdb->map_size = tdb->transaction->old_map_size; + methods->tdb_oob(tdb, tdb->map_size + 1, 1); + } + + /* perform all the writes */ + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; + + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); + + /* we've overwritten part of the data and + possibly expanded the file, so we need to + run the crash recovery code */ + tdb->methods = methods; + tdb_transaction_recover(tdb); + + tdb_transaction_cancel(tdb); + tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); + + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); + return -1; + } + SAFE_FREE(tdb->transaction->blocks[i]); + } + + SAFE_FREE(tdb->transaction->blocks); + tdb->transaction->num_blocks = 0; + + if (!(tdb->flags & TDB_NOSYNC)) { + /* ensure the new data is on disk */ + if (transaction_sync(tdb, 0, tdb->map_size) == -1) { + return -1; + } + + /* remove the recovery marker */ + if (methods->tdb_write(tdb, magic_offset, &zero, 4) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to remove recovery magic\n")); + return -1; + } + + /* ensure the recovery marker has been removed on disk */ + if (transaction_sync(tdb, magic_offset, 4) == -1) { + return -1; + } + } + + tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); + + /* + TODO: maybe write to some dummy hdr field, or write to magic + offset without mmap, before the last sync, instead of the + utime() call + */ + + /* on some systems (like Linux 2.6.x) changes via mmap/msync + don't change the mtime of the file, this means the file may + not be backed up (as tdb rounding to block sizes means that + file size changes are quite rare too). The following forces + mtime changes when a transaction completes */ +#ifdef HAVE_UTIME + utime(tdb->name, NULL); +#endif + + /* use a transaction cancel to free memory and remove the + transaction locks */ + tdb_transaction_cancel(tdb); + + return 0; +} + + +/* + recover from an aborted transaction. Must be called with exclusive + database write access already established (including the global + lock to prevent new processes attaching) +*/ +int tdb_transaction_recover(struct tdb_context *tdb) +{ + tdb_off_t recovery_head, recovery_eof; + unsigned char *data, *p; + uint32_t zero = 0; + struct list_struct rec; + + /* find the recovery area */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + if (recovery_head == 0) { + /* we have never allocated a recovery record */ + return 0; + } + + /* read the recovery record */ + if (tdb->methods->tdb_read(tdb, recovery_head, &rec, + sizeof(rec), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + if (rec.magic != TDB_RECOVERY_MAGIC) { + /* there is no valid recovery data */ + return 0; + } + + if (tdb->read_only) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n")); + tdb->ecode = TDB_ERR_CORRUPT; + return -1; + } + + recovery_eof = rec.key_len; + + data = (unsigned char *)malloc(rec.data_len); + if (data == NULL) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); + tdb->ecode = TDB_ERR_OOM; + return -1; + } + + /* read the full recovery data */ + if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, + rec.data_len, 0) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* recover the file data */ + p = data; + while (p+8 < data + rec.data_len) { + uint32_t ofs, len; + if (DOCONV()) { + tdb_convert(p, 8); + } + memcpy(&ofs, p, 4); + memcpy(&len, p+4, 4); + + if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) { + free(data); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %d bytes at offset %d\n", len, ofs)); + tdb->ecode = TDB_ERR_IO; + return -1; + } + p += 8 + len; + } + + free(data); + + if (transaction_sync(tdb, 0, tdb->map_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* if the recovery area is after the recovered eof then remove it */ + if (recovery_eof <= recovery_head) { + if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + } + + /* remove the recovery magic */ + if (tdb_ofs_write(tdb, recovery_head + offsetof(struct list_struct, magic), + &zero) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* reduce the file size to the old size */ + tdb_munmap(tdb); + if (ftruncate(tdb->fd, recovery_eof) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to reduce to recovery size\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + tdb->map_size = recovery_eof; + tdb_mmap(tdb); + + if (transaction_sync(tdb, 0, recovery_eof) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %d byte database\n", + recovery_eof)); + + /* all done */ + return 0; +} diff --git a/lib/tdb/common/traverse.c b/lib/tdb/common/traverse.c new file mode 100644 index 0000000000..69c81e6e98 --- /dev/null +++ b/lib/tdb/common/traverse.c @@ -0,0 +1,348 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ +static int tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock, + struct list_struct *rec) +{ + int want_next = (tlock->off != 0); + + /* Lock each chain from the start one. */ + for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { + if (!tlock->off && tlock->hash != 0) { + /* this is an optimisation for the common case where + the hash chain is empty, which is particularly + common for the use of tdb with ldb, where large + hashes are used. In that case we spend most of our + time in tdb_brlock(), locking empty hash chains. + + To avoid this, we do an unlocked pre-check to see + if the hash chain is empty before starting to look + inside it. If it is empty then we can avoid that + hash chain. If it isn't empty then we can't believe + the value we get back, as we read it without a + lock, so instead we get the lock and re-fetch the + value below. + + Notice that not doing this optimisation on the + first hash chain is critical. We must guarantee + that we have done at least one fcntl lock at the + start of a search to guarantee that memory is + coherent on SMP systems. If records are added by + others during the search then thats OK, and we + could possibly miss those with this trick, but we + could miss them anyway without this trick, so the + semantics don't change. + + With a non-indexed ldb search this trick gains us a + factor of around 80 in speed on a linux 2.6.x + system (testing using ldbtest). + */ + tdb->methods->next_hash_chain(tdb, &tlock->hash); + if (tlock->hash == tdb->header.hash_size) { + continue; + } + } + + if (tdb_lock(tdb, tlock->hash, tlock->lock_rw) == -1) + return -1; + + /* No previous record? Start at top of chain. */ + if (!tlock->off) { + if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->hash), + &tlock->off) == -1) + goto fail; + } else { + /* Otherwise unlock the previous record. */ + if (tdb_unlock_record(tdb, tlock->off) != 0) + goto fail; + } + + if (want_next) { + /* We have offset of old record: grab next */ + if (tdb_rec_read(tdb, tlock->off, rec) == -1) + goto fail; + tlock->off = rec->next; + } + + /* Iterate through chain */ + while( tlock->off) { + tdb_off_t current; + if (tdb_rec_read(tdb, tlock->off, rec) == -1) + goto fail; + + /* Detect infinite loops. From "Shlomi Yaakobovich" . */ + if (tlock->off == rec->next) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n")); + goto fail; + } + + if (!TDB_DEAD(rec)) { + /* Woohoo: we found one! */ + if (tdb_lock_record(tdb, tlock->off) != 0) + goto fail; + return tlock->off; + } + + /* Try to clean dead ones from old traverses */ + current = tlock->off; + tlock->off = rec->next; + if (!(tdb->read_only || tdb->traverse_read) && + tdb_do_delete(tdb, current, rec) != 0) + goto fail; + } + tdb_unlock(tdb, tlock->hash, tlock->lock_rw); + want_next = 0; + } + /* We finished iteration without finding anything */ + return TDB_ERRCODE(TDB_SUCCESS, 0); + + fail: + tlock->off = 0; + if (tdb_unlock(tdb, tlock->hash, tlock->lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n")); + return -1; +} + +/* traverse the entire database - calling fn(tdb, key, data) on each element. + return -1 on error or the record count traversed + if fn is NULL then it is not called + a non-zero return value from fn() indicates that the traversal should stop + */ +static int tdb_traverse_internal(struct tdb_context *tdb, + tdb_traverse_func fn, void *private_data, + struct tdb_traverse_lock *tl) +{ + TDB_DATA key, dbuf; + struct list_struct rec; + int ret, count = 0; + + /* This was in the initializaton, above, but the IRIX compiler + * did not like it. crh + */ + tl->next = tdb->travlocks.next; + + /* fcntl locks don't stack: beware traverse inside traverse */ + tdb->travlocks.next = tl; + + /* tdb_next_lock places locks on the record returned, and its chain */ + while ((ret = tdb_next_lock(tdb, tl, &rec)) > 0) { + count++; + /* now read the full record */ + key.dptr = tdb_alloc_read(tdb, tl->off + sizeof(rec), + rec.key_len + rec.data_len); + if (!key.dptr) { + ret = -1; + if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) + goto out; + if (tdb_unlock_record(tdb, tl->off) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); + goto out; + } + key.dsize = rec.key_len; + dbuf.dptr = key.dptr + rec.key_len; + dbuf.dsize = rec.data_len; + + /* Drop chain lock, call out */ + if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) { + ret = -1; + SAFE_FREE(key.dptr); + goto out; + } + if (fn && fn(tdb, key, dbuf, private_data)) { + /* They want us to terminate traversal */ + ret = count; + if (tdb_unlock_record(tdb, tl->off) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; + ret = -1; + } + SAFE_FREE(key.dptr); + goto out; + } + SAFE_FREE(key.dptr); + } +out: + tdb->travlocks.next = tl->next; + if (ret < 0) + return -1; + else + return count; +} + + +/* + a write style traverse - temporarily marks the db read only +*/ +int tdb_traverse_read(struct tdb_context *tdb, + tdb_traverse_func fn, void *private_data) +{ + struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; + int ret; + bool in_transaction = (tdb->transaction != NULL); + + /* we need to get a read lock on the transaction lock here to + cope with the lock ordering semantics of solaris10 */ + if (!in_transaction) { + if (tdb_transaction_lock(tdb, F_RDLCK)) { + return -1; + } + } + + tdb->traverse_read++; + ret = tdb_traverse_internal(tdb, fn, private_data, &tl); + tdb->traverse_read--; + + if (!in_transaction) { + tdb_transaction_unlock(tdb); + } + + return ret; +} + +/* + a write style traverse - needs to get the transaction lock to + prevent deadlocks + + WARNING: The data buffer given to the callback fn does NOT meet the + alignment restrictions malloc gives you. +*/ +int tdb_traverse(struct tdb_context *tdb, + tdb_traverse_func fn, void *private_data) +{ + struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; + int ret; + bool in_transaction = (tdb->transaction != NULL); + + if (tdb->read_only || tdb->traverse_read) { + return tdb_traverse_read(tdb, fn, private_data); + } + + if (!in_transaction) { + if (tdb_transaction_lock(tdb, F_WRLCK)) { + return -1; + } + } + + tdb->traverse_write++; + ret = tdb_traverse_internal(tdb, fn, private_data, &tl); + tdb->traverse_write--; + + if (!in_transaction) { + tdb_transaction_unlock(tdb); + } + + return ret; +} + + +/* find the first entry in the database and return its key */ +TDB_DATA tdb_firstkey(struct tdb_context *tdb) +{ + TDB_DATA key; + struct list_struct rec; + + /* release any old lock */ + if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) + return tdb_null; + tdb->travlocks.off = tdb->travlocks.hash = 0; + tdb->travlocks.lock_rw = F_RDLCK; + + /* Grab first record: locks chain and returned record. */ + if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) + return tdb_null; + /* now read the key */ + key.dsize = rec.key_len; + key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); + + /* Unlock the hash chain of the record we just read. */ + if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); + return key; +} + +/* find the next entry in the database, returning its key */ +TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) +{ + uint32_t oldhash; + TDB_DATA key = tdb_null; + struct list_struct rec; + unsigned char *k = NULL; + + /* Is locked key the old key? If so, traverse will be reliable. */ + if (tdb->travlocks.off) { + if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw)) + return tdb_null; + if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 + || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), + rec.key_len)) + || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { + /* No, it wasn't: unlock it and start from scratch */ + if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) { + SAFE_FREE(k); + return tdb_null; + } + if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) { + SAFE_FREE(k); + return tdb_null; + } + tdb->travlocks.off = 0; + } + + SAFE_FREE(k); + } + + if (!tdb->travlocks.off) { + /* No previous element: do normal find, and lock record */ + tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); + if (!tdb->travlocks.off) + return tdb_null; + tdb->travlocks.hash = BUCKET(rec.full_hash); + if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); + return tdb_null; + } + } + oldhash = tdb->travlocks.hash; + + /* Grab next record: locks chain and returned record, + unlocks old record */ + if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { + key.dsize = rec.key_len; + key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), + key.dsize); + /* Unlock the chain of this new record */ + if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + } + /* Unlock the chain of old record */ + if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + return key; +} + diff --git a/lib/tdb/config.guess b/lib/tdb/config.guess new file mode 100755 index 0000000000..354dbe175a --- /dev/null +++ b/lib/tdb/config.guess @@ -0,0 +1,1464 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-08-03' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/tdb/config.mk b/lib/tdb/config.mk new file mode 100644 index 0000000000..90c9ba2863 --- /dev/null +++ b/lib/tdb/config.mk @@ -0,0 +1,57 @@ +################################################ +# Start SUBSYSTEM LIBTDB +[LIBRARY::LIBTDB] +OUTPUT_TYPE = STATIC_LIBRARY +CFLAGS = -I$(tdbsrcdir)/include +# +# End SUBSYSTEM ldb +################################################ + +LIBTDB_OBJ_FILES = $(addprefix $(tdbsrcdir)/common/, \ + tdb.o dump.o io.o lock.o \ + open.o traverse.o freelist.o \ + error.o transaction.o) + +################################################ +# Start BINARY tdbtool +[BINARY::tdbtool] +INSTALLDIR = BINDIR +PRIVATE_DEPENDENCIES = \ + LIBTDB +# End BINARY tdbtool +################################################ + +tdbtool_OBJ_FILES = $(tdbsrcdir)/tools/tdbtool.o + +################################################ +# Start BINARY tdbtorture +[BINARY::tdbtorture] +INSTALLDIR = BINDIR +PRIVATE_DEPENDENCIES = \ + LIBTDB +# End BINARY tdbtorture +################################################ + +tdbtorture_OBJ_FILES = $(tdbsrcdir)/tools/tdbtorture.o + +################################################ +# Start BINARY tdbdump +[BINARY::tdbdump] +INSTALLDIR = BINDIR +PRIVATE_DEPENDENCIES = \ + LIBTDB +# End BINARY tdbdump +################################################ + +tdbdump_OBJ_FILES = $(tdbsrcdir)/tools/tdbdump.o + +################################################ +# Start BINARY tdbbackup +[BINARY::tdbbackup] +INSTALLDIR = BINDIR +PRIVATE_DEPENDENCIES = \ + LIBTDB +# End BINARY tdbbackup +################################################ + +tdbbackup_OBJ_FILES = $(tdbsrcdir)/tools/tdbbackup.o diff --git a/lib/tdb/config.sub b/lib/tdb/config.sub new file mode 100755 index 0000000000..23cd6fd75c --- /dev/null +++ b/lib/tdb/config.sub @@ -0,0 +1,1577 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-07-08' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ms1 \ + | msp430 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | ms1-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/lib/tdb/configure.ac b/lib/tdb/configure.ac new file mode 100644 index 0000000000..eaf70d30b4 --- /dev/null +++ b/lib/tdb/configure.ac @@ -0,0 +1,30 @@ +AC_PREREQ(2.50) +AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) +AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) +AC_DEFUN([SMB_ENABLE], [echo -n ""]) +AC_INIT(tdb, 1.1.2) +AC_CONFIG_SRCDIR([common/tdb.c]) +AC_CONFIG_HEADER(include/config.h) +AC_LIBREPLACE_ALL_CHECKS +AC_LD_SONAMEFLAG +AC_LD_PICFLAG +AC_LD_SHLIBEXT +AC_LIBREPLACE_SHLD +AC_LIBREPLACE_SHLD_FLAGS +AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR +m4_include(libtdb.m4) +AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config]) +AC_PATH_PROGS([PYTHON], [python2.6 python2.5 python2.4 python]) + +PYTHON_BUILD_TARGET="build-python" +PYTHON_INSTALL_TARGET="install-python" +PYTHON_CHECK_TARGET="check-python" +AC_SUBST(PYTHON_BUILD_TARGET) +AC_SUBST(PYTHON_INSTALL_TARGET) +AC_SUBST(PYTHON_CHECK_TARGET) +if test -z "$PYTHON_CONFIG"; then + PYTHON_BUILD_TARGET="" + PYTHON_INSTALL_TARGET="" + PYTHON_CHECK_TARGET="" +fi +AC_OUTPUT(Makefile tdb.pc) diff --git a/lib/tdb/docs/README b/lib/tdb/docs/README new file mode 100644 index 0000000000..63fcf5e049 --- /dev/null +++ b/lib/tdb/docs/README @@ -0,0 +1,238 @@ +tdb - a trivial database system +tridge@linuxcare.com December 1999 +================================== + +This is a simple database API. It was inspired by the realisation that +in Samba we have several ad-hoc bits of code that essentially +implement small databases for sharing structures between parts of +Samba. As I was about to add another I realised that a generic +database module was called for to replace all the ad-hoc bits. + +I based the interface on gdbm. I couldn't use gdbm as we need to be +able to have multiple writers to the databases at one time. + +Compilation +----------- + +add HAVE_MMAP=1 to use mmap instead of read/write +add NOLOCK=1 to disable locking code + +Testing +------- + +Compile tdbtest.c and link with gdbm for testing. tdbtest will perform +identical operations via tdb and gdbm then make sure the result is the +same + +Also included is tdbtool, which allows simple database manipulation +on the commandline. + +tdbtest and tdbtool are not built as part of Samba, but are included +for completeness. + +Interface +--------- + +The interface is very similar to gdbm except for the following: + +- different open interface. The tdb_open call is more similar to a + traditional open() +- no tdbm_reorganise() function +- no tdbm_sync() function. No operations are cached in the library anyway +- added a tdb_traverse() function for traversing the whole database +- added transactions support + +A general rule for using tdb is that the caller frees any returned +TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA +return value called p. This is the same as gdbm. + +here is a full list of tdb functions with brief descriptions. + + +---------------------------------------------------------------------- +TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) + + open the database, creating it if necessary + + The open_flags and mode are passed straight to the open call on the database + file. A flags value of O_WRONLY is invalid + + The hash size is advisory, use zero for a default value. + + return is NULL on error + + possible tdb_flags are: + TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open + TDB_INTERNAL - don't use a file, instaed store the data in + memory. The filename is ignored in this case. + TDB_NOLOCK - don't do any locking + TDB_NOMMAP - don't use mmap + TDB_NOSYNC - don't synchronise transactions to disk + +---------------------------------------------------------------------- +TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + tdb_log_func log_fn, + tdb_hash_func hash_fn) + +This is like tdb_open(), but allows you to pass an initial logging and +hash function. Be careful when passing a hash function - all users of +the database must use the same hash function or you will get data +corruption. + + +---------------------------------------------------------------------- +char *tdb_error(TDB_CONTEXT *tdb); + + return a error string for the last tdb error + +---------------------------------------------------------------------- +int tdb_close(TDB_CONTEXT *tdb); + + close a database + +---------------------------------------------------------------------- +int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf); + + update an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1 + +---------------------------------------------------------------------- +TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); + + fetch an entry in the database given a key + if the return value has a null dptr then a error occurred + + caller must free the resulting data + +---------------------------------------------------------------------- +int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); + + check if an entry in the database exists + + note that 1 is returned if the key is found and 0 is returned if not found + this doesn't match the conventions in the rest of this module, but is + compatible with gdbm + +---------------------------------------------------------------------- +int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, + TDB_DATA key, TDB_DATA dbuf, void *state), void *state); + + traverse the entire database - calling fn(tdb, key, data, state) on each + element. + + return -1 on error or the record count traversed + + if fn is NULL then it is not called + + a non-zero return value from fn() indicates that the traversal + should stop. Traversal callbacks may not start transactions. + + WARNING: The data buffer given to the callback fn does NOT meet the + alignment restrictions malloc gives you. + +---------------------------------------------------------------------- +int tdb_traverse_read(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, + TDB_DATA key, TDB_DATA dbuf, void *state), void *state); + + traverse the entire database - calling fn(tdb, key, data, state) on + each element, but marking the database read only during the + traversal, so any write operations will fail. This allows tdb to + use read locks, which increases the parallelism possible during the + traversal. + + return -1 on error or the record count traversed + + if fn is NULL then it is not called + + a non-zero return value from fn() indicates that the traversal + should stop. Traversal callbacks may not start transactions. + +---------------------------------------------------------------------- +TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); + + find the first entry in the database and return its key + + the caller must free the returned data + +---------------------------------------------------------------------- +TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); + + find the next entry in the database, returning its key + + the caller must free the returned data + +---------------------------------------------------------------------- +int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); + + delete an entry in the database given a key + +---------------------------------------------------------------------- +int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); + + store an element in the database, replacing any existing element + with the same key + + If flag==TDB_INSERT then don't overwrite an existing entry + If flag==TDB_MODIFY then don't create a new entry + + return 0 on success, -1 on failure + +---------------------------------------------------------------------- +int tdb_writelock(TDB_CONTEXT *tdb); + + lock the database. If we already have it locked then don't do anything + +---------------------------------------------------------------------- +int tdb_writeunlock(TDB_CONTEXT *tdb); + unlock the database + +---------------------------------------------------------------------- +int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key); + + lock one hash chain. This is meant to be used to reduce locking + contention - it cannot guarantee how many records will be locked + +---------------------------------------------------------------------- +int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key); + + unlock one hash chain + +---------------------------------------------------------------------- +int tdb_transaction_start(TDB_CONTEXT *tdb) + + start a transaction. All operations after the transaction start can + either be committed with tdb_transaction_commit() or cancelled with + tdb_transaction_cancel(). + + If you call tdb_transaction_start() again on the same tdb context + while a transaction is in progress, then the same transaction + buffer is re-used. The number of tdb_transaction_{commit,cancel} + operations must match the number of successful + tdb_transaction_start() calls. + + Note that transactions are by default disk synchronous, and use a + recover area in the database to automatically recover the database + on the next open if the system crashes during a transaction. You + can disable the synchronous transaction recovery setup using the + TDB_NOSYNC flag, which will greatly speed up operations at the risk + of corrupting your database if the system crashes. + + Operations made within a transaction are not visible to other users + of the database until a successful commit. + +---------------------------------------------------------------------- +int tdb_transaction_cancel(TDB_CONTEXT *tdb) + + cancel a current transaction, discarding all write and lock + operations that have been made since the transaction started. + + +---------------------------------------------------------------------- +int tdb_transaction_commit(TDB_CONTEXT *tdb) + + commit a current transaction, updating the database and releasing + the transaction locks. + diff --git a/lib/tdb/docs/tdb.magic b/lib/tdb/docs/tdb.magic new file mode 100644 index 0000000000..f5619e7327 --- /dev/null +++ b/lib/tdb/docs/tdb.magic @@ -0,0 +1,10 @@ +# Magic file(1) information about tdb files. +# +# Install this into /etc/magic or the corresponding location for your +# system, or pass as a -m argument to file(1). + +# You may use and redistribute this file without restriction. + +0 string TDB\ file TDB database +>32 lelong =0x2601196D version 6, little-endian +>>36 lelong x hash size %d bytes diff --git a/lib/tdb/include/tdb.h b/lib/tdb/include/tdb.h new file mode 100644 index 0000000000..0008085de5 --- /dev/null +++ b/lib/tdb/include/tdb.h @@ -0,0 +1,167 @@ +#ifndef __TDB_H__ +#define __TDB_H__ + +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2004 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* flags to tdb_store() */ +#define TDB_REPLACE 1 /* Unused */ +#define TDB_INSERT 2 /* Don't overwrite an existing entry */ +#define TDB_MODIFY 3 /* Don't create an existing entry */ + +/* flags for tdb_open() */ +#define TDB_DEFAULT 0 /* just a readability place holder */ +#define TDB_CLEAR_IF_FIRST 1 +#define TDB_INTERNAL 2 /* don't store on disk */ +#define TDB_NOLOCK 4 /* don't do any locking */ +#define TDB_NOMMAP 8 /* don't use mmap */ +#define TDB_CONVERT 16 /* convert endian (internal use) */ +#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ +#define TDB_NOSYNC 64 /* don't use synchronous transactions */ +#define TDB_SEQNUM 128 /* maintain a sequence number */ +#define TDB_VOLATILE 256 /* Activate the per-hashchain freelist, default 5 */ + +#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) + +/* error codes */ +enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, + TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, + TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY}; + +/* debugging uses one of the following levels */ +enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, + TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; + +typedef struct TDB_DATA { + unsigned char *dptr; + size_t dsize; +} TDB_DATA; + +#ifndef PRINTF_ATTRIBUTE +#if (__GNUC__ >= 3) +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +/* this is the context structure that is returned from a db open */ +typedef struct tdb_context TDB_CONTEXT; + +typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); +typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4); +typedef unsigned int (*tdb_hash_func)(TDB_DATA *key); + +struct tdb_logging_context { + tdb_log_func log_fn; + void *log_private; +}; + +struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode); +struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + const struct tdb_logging_context *log_ctx, + tdb_hash_func hash_fn); +void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); + +int tdb_reopen(struct tdb_context *tdb); +int tdb_reopen_all(int parent_longlived); +void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); +enum TDB_ERROR tdb_error(struct tdb_context *tdb); +const char *tdb_errorstr(struct tdb_context *tdb); +TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); +int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data); +int tdb_delete(struct tdb_context *tdb, TDB_DATA key); +int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); +int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); +int tdb_close(struct tdb_context *tdb); +TDB_DATA tdb_firstkey(struct tdb_context *tdb); +TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); +int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *); +int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *); +int tdb_exists(struct tdb_context *tdb, TDB_DATA key); +int tdb_lockall(struct tdb_context *tdb); +int tdb_lockall_nonblock(struct tdb_context *tdb); +int tdb_unlockall(struct tdb_context *tdb); +int tdb_lockall_read(struct tdb_context *tdb); +int tdb_lockall_read_nonblock(struct tdb_context *tdb); +int tdb_unlockall_read(struct tdb_context *tdb); +int tdb_lockall_mark(struct tdb_context *tdb); +int tdb_lockall_unmark(struct tdb_context *tdb); +const char *tdb_name(struct tdb_context *tdb); +int tdb_fd(struct tdb_context *tdb); +tdb_log_func tdb_log_fn(struct tdb_context *tdb); +void *tdb_get_logging_private(struct tdb_context *tdb); +int tdb_transaction_start(struct tdb_context *tdb); +int tdb_transaction_commit(struct tdb_context *tdb); +int tdb_transaction_cancel(struct tdb_context *tdb); +int tdb_transaction_recover(struct tdb_context *tdb); +int tdb_get_seqnum(struct tdb_context *tdb); +int tdb_hash_size(struct tdb_context *tdb); +size_t tdb_map_size(struct tdb_context *tdb); +int tdb_get_flags(struct tdb_context *tdb); +void tdb_add_flags(struct tdb_context *tdb, unsigned flag); +void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); +void tdb_enable_seqnum(struct tdb_context *tdb); +void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); + +/* Low level locking functions: use with care */ +int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key); + +void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr); + +/* Debug functions. Not used in production. */ +void tdb_dump_all(struct tdb_context *tdb); +int tdb_printfreelist(struct tdb_context *tdb); +int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); +int tdb_wipe_all(struct tdb_context *tdb); +int tdb_freelist_size(struct tdb_context *tdb); + +extern TDB_DATA tdb_null; + +#ifdef __cplusplus +} +#endif + +#endif /* tdb.h */ diff --git a/lib/tdb/install-sh b/lib/tdb/install-sh new file mode 100755 index 0000000000..58719246f0 --- /dev/null +++ b/lib/tdb/install-sh @@ -0,0 +1,238 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +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=: + 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 diff --git a/lib/tdb/libtdb.m4 b/lib/tdb/libtdb.m4 new file mode 100644 index 0000000000..252e0b0be3 --- /dev/null +++ b/lib/tdb/libtdb.m4 @@ -0,0 +1,30 @@ +dnl find the tdb sources. This is meant to work both for +dnl tdb standalone builds, and builds of packages using tdb +tdbdir="" +tdbpaths="$srcdir $srcdir/lib/tdb $srcdir/tdb $srcdir/../tdb $srcdir/../lib/tdb" +for d in $tdbpaths; do + if test -f "$d/common/tdb.c"; then + tdbdir="$d" + AC_SUBST(tdbdir) + break; + fi +done +if test x"$tdbdir" = "x"; then + AC_MSG_ERROR([cannot find tdb source in $tdbpaths]) +fi +TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" +TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o" +AC_SUBST(TDB_OBJ) +AC_SUBST(LIBREPLACEOBJ) + +TDB_LIBS="" +AC_SUBST(TDB_LIBS) + +TDB_CFLAGS="-I$tdbdir/include" +AC_SUBST(TDB_CFLAGS) + +AC_CHECK_FUNCS(mmap pread pwrite getpagesize utime) +AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h) + +AC_HAVE_DECL(pread, [#include ]) +AC_HAVE_DECL(pwrite, [#include ]) diff --git a/lib/tdb/python.mk b/lib/tdb/python.mk new file mode 100644 index 0000000000..12e8217df9 --- /dev/null +++ b/lib/tdb/python.mk @@ -0,0 +1,10 @@ +[PYTHON::swig_tdb] +LIBRARY_REALNAME = _tdb.$(SHLIBEXT) +PUBLIC_DEPENDENCIES = LIBTDB DYNCONFIG + +swig_tdb_OBJ_FILES = $(tdbsrcdir)/tdb_wrap.o + +$(eval $(call python_py_module_template,tdb.py,$(tdbsrcdir)/tdb.py)) + +$(swig_tdb_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) + diff --git a/lib/tdb/python/tdbdump.py b/lib/tdb/python/tdbdump.py new file mode 100644 index 0000000000..d759d771c8 --- /dev/null +++ b/lib/tdb/python/tdbdump.py @@ -0,0 +1,12 @@ +#!/usr/bin/python +# Trivial reimplementation of tdbdump in Python + +import tdb, sys + +if len(sys.argv) < 2: + print "Usage: tdbdump.py " + sys.exit(1) + +db = tdb.Tdb(sys.argv[1]) +for (k, v) in db.iteritems(): + print "{\nkey(%d) = %r\ndata(%d) = %r\n}" % (len(k), k, len(v), v) diff --git a/lib/tdb/python/tests/simple.py b/lib/tdb/python/tests/simple.py new file mode 100644 index 0000000000..7147718c91 --- /dev/null +++ b/lib/tdb/python/tests/simple.py @@ -0,0 +1,152 @@ +#!/usr/bin/python +# Some simple tests for the Python bindings for TDB +# Note that this tests the interface of the Python bindings +# It does not test tdb itself. +# +# Copyright (C) 2007-2008 Jelmer Vernooij +# Published under the GNU LGPLv3 or later + +import tdb +from unittest import TestCase +import os, tempfile + + +class OpenTdbTests(TestCase): + def test_nonexistant_read(self): + self.assertRaises(IOError, tdb.Tdb, "/some/nonexistant/file", 0, tdb.DEFAULT, os.O_RDWR) + + +class SimpleTdbTests(TestCase): + def setUp(self): + super(SimpleTdbTests, self).setUp() + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) + self.assertNotEqual(None, self.tdb) + + def tearDown(self): + del self.tdb + + def test_repr(self): + self.assertTrue(repr(self.tdb).startswith("Tdb('")) + + def test_lockall(self): + self.tdb.lock_all() + + def test_max_dead(self): + self.tdb.max_dead = 20 + + def test_unlockall(self): + self.tdb.lock_all() + self.tdb.unlock_all() + + def test_lockall_read(self): + self.tdb.read_lock_all() + self.tdb.read_unlock_all() + + def test_reopen(self): + self.tdb.reopen() + + def test_store(self): + self.tdb.store("bar", "bla") + self.assertEquals("bla", self.tdb.get("bar")) + + def test_getitem(self): + self.tdb["bar"] = "foo" + self.tdb.reopen() + self.assertEquals("foo", self.tdb["bar"]) + + def test_delete(self): + self.tdb["bar"] = "foo" + del self.tdb["bar"] + self.assertRaises(KeyError, lambda: self.tdb["bar"]) + + def test_contains(self): + self.tdb["bla"] = "bloe" + self.assertTrue("bla" in self.tdb) + + def test_keyerror(self): + self.assertRaises(KeyError, lambda: self.tdb["bla"]) + + def test_hash_size(self): + self.tdb.hash_size + + def test_map_size(self): + self.tdb.map_size + + def test_name(self): + self.tdb.name + + def test_iterator(self): + self.tdb["bla"] = "1" + self.tdb["brainslug"] = "2" + self.assertEquals(["bla", "brainslug"], list(self.tdb)) + + def test_items(self): + self.tdb["bla"] = "1" + self.tdb["brainslug"] = "2" + self.assertEquals([("bla", "1"), ("brainslug", "2")], self.tdb.items()) + + def test_iteritems(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "25" + i = self.tdb.iteritems() + self.assertEquals(set([("bla", "25"), ("bloe", "2")]), + set([i.next(), i.next()])) + + def test_transaction_cancel(self): + self.tdb["bloe"] = "2" + self.tdb.transaction_start() + self.tdb["bloe"] = "1" + self.tdb.transaction_cancel() + self.assertEquals("2", self.tdb["bloe"]) + + def test_transaction_commit(self): + self.tdb["bloe"] = "2" + self.tdb.transaction_start() + self.tdb["bloe"] = "1" + self.tdb.transaction_commit() + self.assertEquals("1", self.tdb["bloe"]) + + def test_iterator(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "hoi" + i = iter(self.tdb) + self.assertEquals(set(["bloe", "bla"]), set([i.next(), i.next()])) + + def test_keys(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "25" + self.assertEquals(["bla", "bloe"], self.tdb.keys()) + + def test_iterkeys(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "25" + i = self.tdb.iterkeys() + self.assertEquals(set(["bloe", "bla"]), set([i.next(), i.next()])) + + def test_values(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "25" + self.assertEquals(["25", "2"], self.tdb.values()) + + def test_itervalues(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "25" + i = self.tdb.itervalues() + self.assertEquals(set(["25", "2"]), set([i.next(), i.next()])) + + def test_clear(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "25" + self.assertEquals(2, len(self.tdb)) + self.tdb.clear() + self.assertEquals(0, len(self.tdb)) + + def test_len(self): + self.assertEquals(0, len(self.tdb)) + self.tdb["entry"] = "value" + self.assertEquals(1, len(self.tdb)) + + +if __name__ == '__main__': + import unittest + unittest.TestProgram() diff --git a/lib/tdb/rules.mk b/lib/tdb/rules.mk new file mode 100644 index 0000000000..7b765625df --- /dev/null +++ b/lib/tdb/rules.mk @@ -0,0 +1,21 @@ +.SUFFIXES: .i _wrap.c + +.i_wrap.c: + $(SWIG) -O -Wall -python -keyword $< + +showflags:: + @echo 'tdb will be compiled with flags:' + @echo ' CFLAGS = $(CFLAGS)' + @echo ' CPPFLAGS = $(CPPFLAGS)' + @echo ' LDFLAGS = $(LDFLAGS)' + @echo ' LIBS = $(LIBS)' + +.SUFFIXES: .c .o + +.c.o: + @echo Compiling $*.c + @mkdir -p `dirname $@` + @$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@ + +distclean:: + rm -f *~ */*~ diff --git a/lib/tdb/tdb.i b/lib/tdb/tdb.i new file mode 100644 index 0000000000..3d8b697732 --- /dev/null +++ b/lib/tdb/tdb.i @@ -0,0 +1,323 @@ +/* + Unix SMB/CIFS implementation. + + Swig interface to tdb. + + Copyright (C) 2004-2006 Tim Potter + Copyright (C) 2007 Jelmer Vernooij + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +%define DOCSTRING +"TDB is a simple key-value database similar to GDBM that supports multiple writers." +%enddef + +%module(docstring=DOCSTRING) tdb + +%{ + +/* This symbol is used in both includes.h and Python.h which causes an + annoying compiler warning. */ + +#ifdef HAVE_FSTAT +#undef HAVE_FSTAT +#endif + +/* Include tdb headers */ +#include +#include +#include +#include + +typedef TDB_CONTEXT tdb; +%} + +/* The tdb functions will crash if a NULL tdb context is passed */ + +%import exception.i +%import stdint.i + +%typemap(check,noblock=1) TDB_CONTEXT* { + if ($1 == NULL) + SWIG_exception(SWIG_ValueError, + "tdb context must be non-NULL"); +} + +/* In and out typemaps for the TDB_DATA structure. This is converted to + and from the Python string type which can contain arbitrary binary + data.. */ + +%typemap(in,noblock=1) TDB_DATA { + if ($input == Py_None) { + $1.dsize = 0; + $1.dptr = NULL; + } else if (!PyString_Check($input)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + $1.dsize = PyString_Size($input); + $1.dptr = (uint8_t *)PyString_AsString($input); + } +} + +%typemap(out,noblock=1) TDB_DATA { + if ($1.dptr == NULL && $1.dsize == 0) { + $result = Py_None; + } else { + $result = PyString_FromStringAndSize((const char *)$1.dptr, $1.dsize); + free($1.dptr); + } +} + +/* Treat a mode_t as an unsigned integer */ +typedef int mode_t; + +/* flags to tdb_store() */ +%constant int REPLACE = TDB_REPLACE; +%constant int INSERT = TDB_INSERT; +%constant int MODIFY = TDB_MODIFY; + +/* flags for tdb_open() */ +%constant int DEFAULT = TDB_DEFAULT; +%constant int CLEAR_IF_FIRST = TDB_CLEAR_IF_FIRST; +%constant int INTERNAL = TDB_INTERNAL; +%constant int NOLOCK = TDB_NOLOCK; +%constant int NOMMAP = TDB_NOMMAP; +%constant int CONVERT = TDB_CONVERT; +%constant int BIGENDIAN = TDB_BIGENDIAN; + +enum TDB_ERROR { + TDB_SUCCESS=0, + TDB_ERR_CORRUPT, + TDB_ERR_IO, + TDB_ERR_LOCK, + TDB_ERR_OOM, + TDB_ERR_EXISTS, + TDB_ERR_NOLOCK, + TDB_ERR_LOCK_TIMEOUT, + TDB_ERR_NOEXIST, + TDB_ERR_EINVAL, + TDB_ERR_RDONLY +}; + +%rename(lock_all) tdb_context::lockall; +%rename(unlock_all) tdb_context::unlockall; + +%rename(read_lock_all) tdb_context::lockall_read; +%rename(read_unlock_all) tdb_context::unlockall_read; + +%typemap(default,noblock=1) int tdb_flags { + $1 = TDB_DEFAULT; +} + +%typemap(default,noblock=1) int flags { + $1 = O_RDWR; +} + +%typemap(default,noblock=1) int hash_size { + $1 = 0; +} + +%typemap(default,noblock=1) mode_t mode { + $1 = 0600; +} + +%typemap(default,noblock=1) int flag { + $1 = TDB_REPLACE; +} + +%rename(Tdb) tdb_context; +%feature("docstring") tdb_context "A TDB file."; +%typemap(out,noblock=1) tdb * { + /* Throw an IOError exception from errno if tdb_open() returns NULL */ + if ($1 == NULL) { + PyErr_SetFromErrno(PyExc_IOError); + SWIG_fail; + } + $result = SWIG_NewPointerObj($1, $1_descriptor, 0); +} + +typedef struct tdb_context { + %extend { + %feature("docstring") tdb "S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600)\n" + "Open a TDB file."; + tdb(const char *name, int hash_size, int tdb_flags, int flags, mode_t mode) { + return tdb_open(name, hash_size, tdb_flags, flags, mode); + } + %feature("docstring") error "S.error() -> int\n" + "Find last error number returned by operation on this TDB."; + enum TDB_ERROR error(); + ~tdb() { tdb_close($self); } + %feature("docstring") close "S.close() -> None\n" + "Close the TDB file."; + int close(); + int append(TDB_DATA key, TDB_DATA new_dbuf); + %feature("docstring") errorstr "S.errorstr() -> errorstring\n" + "Obtain last error message."; + const char *errorstr(); + %rename(get) fetch; + %feature("docstring") fetch "S.fetch(key) -> value\n" + "Fetch a value."; + TDB_DATA fetch(TDB_DATA key); + %feature("docstring") delete "S.delete(key) -> None\n" + "Delete an entry."; + int delete(TDB_DATA key); + %feature("docstring") store "S.store(key, value, flag=TDB_REPLACE) -> None\n" + "Store an entry."; + int store(TDB_DATA key, TDB_DATA dbuf, int flag); + %feature("docstring") exists "S.exists(key) -> bool\n" + "Check whether key exists in this database."; + int exists(TDB_DATA key); + %feature("docstring") firstkey "S.firstkey() -> data\n" + "Return the first key in this database."; + TDB_DATA firstkey(); + %feature("docstring") nextkey "S.nextkey(prev) -> data\n" + "Return the next key in this database."; + TDB_DATA nextkey(TDB_DATA key); + %feature("docstring") lockall "S.lockall() -> bool"; + int lockall(); + %feature("docstring") unlockall "S.unlockall() -> bool"; + int unlockall(); + %feature("docstring") unlockall "S.lockall_read() -> bool"; + int lockall_read(); + %feature("docstring") unlockall "S.unlockall_read() -> bool"; + int unlockall_read(); + %feature("docstring") reopen "S.reopen() -> bool\n" + "Reopen this file."; + int reopen(); + %feature("docstring") transaction_start "S.transaction_start() -> None\n" + "Start a new transaction."; + int transaction_start(); + %feature("docstring") transaction_commit "S.transaction_commit() -> None\n" + "Commit the currently active transaction."; + int transaction_commit(); + %feature("docstring") transaction_cancel "S.transaction_cancel() -> None\n" + "Cancel the currently active transaction."; + int transaction_cancel(); + int transaction_recover(); + %feature("docstring") hash_size "S.hash_size() -> int"; + int hash_size(); + %feature("docstring") map_size "S.map_size() -> int"; + size_t map_size(); + %feature("docstring") get_flags "S.get_flags() -> int"; + int get_flags(); + %feature("docstring") set_max_dead "S.set_max_dead(int) -> None"; + void set_max_dead(int max_dead); + %feature("docstring") name "S.name() -> path\n" \ + "Return filename of this TDB file."; + const char *name(); + } + + %pythoncode { + def __repr__(self): + return "Tdb('%s')" % self.name() + + # Random access to keys, values + def __getitem__(self, key): + result = self.get(key) + if result is None: + raise KeyError, '%s: %s' % (key, self.errorstr()) + return result + + def __setitem__(self, key, item): + if self.store(key, item) == -1: + raise IOError, self.errorstr() + + def __delitem__(self, key): + if not self.exists(key): + raise KeyError, '%s: %s' % (key, self.errorstr()) + self.delete(key) + + def __contains__(self, key): + return self.exists(key) != 0 + + def has_key(self, key): + return self.exists(key) != 0 + + def fetch_uint32(self, key): + data = self.get(key) + if data is None: + return None + import struct + return struct.unpack("" % (self.__class__.__module__, self.__class__.__name__, strthis,) + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 +del types + + +def _swig_setattr_nondynamic_method(set): + def set_attr(self,name,value): + if (name == "thisown"): return self.this.own(value) + if hasattr(self,name) or (name == "this"): + set(self,name,value) + else: + raise AttributeError("You cannot add attributes to %s" % self) + return set_attr + + +REPLACE = _tdb.REPLACE +INSERT = _tdb.INSERT +MODIFY = _tdb.MODIFY +DEFAULT = _tdb.DEFAULT +CLEAR_IF_FIRST = _tdb.CLEAR_IF_FIRST +INTERNAL = _tdb.INTERNAL +NOLOCK = _tdb.NOLOCK +NOMMAP = _tdb.NOMMAP +CONVERT = _tdb.CONVERT +BIGENDIAN = _tdb.BIGENDIAN +TDB_SUCCESS = _tdb.TDB_SUCCESS +TDB_ERR_CORRUPT = _tdb.TDB_ERR_CORRUPT +TDB_ERR_IO = _tdb.TDB_ERR_IO +TDB_ERR_LOCK = _tdb.TDB_ERR_LOCK +TDB_ERR_OOM = _tdb.TDB_ERR_OOM +TDB_ERR_EXISTS = _tdb.TDB_ERR_EXISTS +TDB_ERR_NOLOCK = _tdb.TDB_ERR_NOLOCK +TDB_ERR_LOCK_TIMEOUT = _tdb.TDB_ERR_LOCK_TIMEOUT +TDB_ERR_NOEXIST = _tdb.TDB_ERR_NOEXIST +TDB_ERR_EINVAL = _tdb.TDB_ERR_EINVAL +TDB_ERR_RDONLY = _tdb.TDB_ERR_RDONLY +class Tdb(object): + """A TDB file.""" + thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') + __repr__ = _swig_repr + def __init__(self, *args, **kwargs): + """ + S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600) + Open a TDB file. + """ + _tdb.Tdb_swiginit(self,_tdb.new_Tdb(*args, **kwargs)) + def error(*args, **kwargs): + """ + S.error() -> int + Find last error number returned by operation on this TDB. + """ + return _tdb.Tdb_error(*args, **kwargs) + + __swig_destroy__ = _tdb.delete_Tdb + def close(*args, **kwargs): + """ + S.close() -> None + Close the TDB file. + """ + return _tdb.Tdb_close(*args, **kwargs) + + def errorstr(*args, **kwargs): + """ + S.errorstr() -> errorstring + Obtain last error message. + """ + return _tdb.Tdb_errorstr(*args, **kwargs) + + def get(*args, **kwargs): + """ + S.fetch(key) -> value + Fetch a value. + """ + return _tdb.Tdb_get(*args, **kwargs) + + def delete(*args, **kwargs): + """ + S.delete(key) -> None + Delete an entry. + """ + return _tdb.Tdb_delete(*args, **kwargs) + + def store(*args, **kwargs): + """ + S.store(key, value, flag=TDB_REPLACE) -> None + Store an entry. + """ + return _tdb.Tdb_store(*args, **kwargs) + + def exists(*args, **kwargs): + """ + S.exists(key) -> bool + Check whether key exists in this database. + """ + return _tdb.Tdb_exists(*args, **kwargs) + + def firstkey(*args, **kwargs): + """ + S.firstkey() -> data + Return the first key in this database. + """ + return _tdb.Tdb_firstkey(*args, **kwargs) + + def nextkey(*args, **kwargs): + """ + S.nextkey(prev) -> data + Return the next key in this database. + """ + return _tdb.Tdb_nextkey(*args, **kwargs) + + def lock_all(*args, **kwargs): + """S.lockall() -> bool""" + return _tdb.Tdb_lock_all(*args, **kwargs) + + def unlock_all(*args, **kwargs): + """S.unlockall() -> bool""" + return _tdb.Tdb_unlock_all(*args, **kwargs) + + def reopen(*args, **kwargs): + """ + S.reopen() -> bool + Reopen this file. + """ + return _tdb.Tdb_reopen(*args, **kwargs) + + def transaction_start(*args, **kwargs): + """ + S.transaction_start() -> None + Start a new transaction. + """ + return _tdb.Tdb_transaction_start(*args, **kwargs) + + def transaction_commit(*args, **kwargs): + """ + S.transaction_commit() -> None + Commit the currently active transaction. + """ + return _tdb.Tdb_transaction_commit(*args, **kwargs) + + def transaction_cancel(*args, **kwargs): + """ + S.transaction_cancel() -> None + Cancel the currently active transaction. + """ + return _tdb.Tdb_transaction_cancel(*args, **kwargs) + + def hash_size(*args, **kwargs): + """S.hash_size() -> int""" + return _tdb.Tdb_hash_size(*args, **kwargs) + + def map_size(*args, **kwargs): + """S.map_size() -> int""" + return _tdb.Tdb_map_size(*args, **kwargs) + + def get_flags(*args, **kwargs): + """S.get_flags() -> int""" + return _tdb.Tdb_get_flags(*args, **kwargs) + + def set_max_dead(*args, **kwargs): + """S.set_max_dead(int) -> None""" + return _tdb.Tdb_set_max_dead(*args, **kwargs) + + def name(*args, **kwargs): + """ + S.name() -> path + Return filename of this TDB file. + """ + return _tdb.Tdb_name(*args, **kwargs) + + def __repr__(self): + return "Tdb('%s')" % self.name() + + + def __getitem__(self, key): + result = self.get(key) + if result is None: + raise KeyError, '%s: %s' % (key, self.errorstr()) + return result + + def __setitem__(self, key, item): + if self.store(key, item) == -1: + raise IOError, self.errorstr() + + def __delitem__(self, key): + if not self.exists(key): + raise KeyError, '%s: %s' % (key, self.errorstr()) + self.delete(key) + + def __contains__(self, key): + return self.exists(key) != 0 + + def has_key(self, key): + return self.exists(key) != 0 + + def fetch_uint32(self, key): + data = self.get(key) + if data is None: + return None + import struct + return struct.unpack(" 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +/* Python.h has to appear first */ +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic CAPI SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "4" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the swig runtime code. + In 99.9% of the cases, swig just needs to declare them as 'static'. + + But only do this if is strictly necessary, ie, if you have problems + with your compiler or so. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The swig conversion methods, as ConvertPtr, return and integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old swig versions, you usually write code as: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit as: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + that seems to be the same, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + requires also to SWIG_ConvertPtr to return new result values, as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + swig errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() + + + */ +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *, int *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store information on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* think of this as a c++ template<> or a scheme macro */ +#define SWIG_TypeCheck_Template(comparison, ty) \ + if (ty) { \ + swig_cast_info *iter = ty->cast; \ + while (iter) { \ + if (comparison) { \ + if (iter == ty->cast) return iter; \ + /* Move iter to the top of the linked list */ \ + iter->prev->next = iter->next; \ + if (iter->next) \ + iter->next->prev = iter->prev; \ + iter->next = ty->cast; \ + iter->prev = 0; \ + if (ty->cast) ty->cast->prev = iter; \ + ty->cast = iter; \ + return iter; \ + } \ + iter = iter->next; \ + } \ + } \ + return 0 + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); +} + +/* Same as previous function, except strcmp is replaced with a pointer comparison */ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { + SWIG_TypeCheck_Template(iter->type == from, into); +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +/* Add PyOS_snprintf for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# define PyOS_snprintf _snprintf +# else +# define PyOS_snprintf snprintf +# endif +#endif + +/* A crude PyString_FromFormat implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 + +#ifndef SWIG_PYBUFFER_SIZE +# define SWIG_PYBUFFER_SIZE 1024 +#endif + +static PyObject * +PyString_FromFormat(const char *fmt, ...) { + va_list ap; + char buf[SWIG_PYBUFFER_SIZE * 2]; + int res; + va_start(ap, fmt); + res = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); +} +#endif + +/* Add PyObject_Del for old Pythons */ +#if PY_VERSION_HEX < 0x01060000 +# define PyObject_Del(op) PyMem_DEL((op)) +#endif +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# ifndef PyExc_StopIteration +# define PyExc_StopIteration PyExc_RuntimeError +# endif +# ifndef PyObject_GenericGetAttr +# define PyObject_GenericGetAttr 0 +# endif +#endif +/* Py_NotImplemented is defined in 2.1 and up. */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef Py_NotImplemented +# define Py_NotImplemented PyExc_RuntimeError +# endif +#endif + + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef PyString_AsStringAndSize +# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +# endif +#endif + +/* PySequence_Size for old Pythons */ +#if PY_VERSION_HEX < 0x02000000 +# ifndef PySequence_Size +# define PySequence_Size PySequence_Length +# endif +#endif + + +/* PyBool_FromLong for old Pythons */ +#if PY_VERSION_HEX < 0x02030000 +static +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} +#endif + +/* Py_ssize_t for old Pythons */ +/* This code is as recommended by: */ +/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +# define PY_SSIZE_T_MIN INT_MIN +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyErr_Clear(); + Py_XINCREF(type); + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_SetString(PyExc_RuntimeError, mesg); + } +} + + + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ +# define SWIG_PYTHON_USE_GIL +# endif +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) PySwigClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, (char *) msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, (char*) name, obj); + Py_DECREF(obj); +} + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { +#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +#else + PyObject* o2; + PyObject* o3; + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyTuple_Check(result)) { + o2 = result; + result = PyTuple_New(1); + PyTuple_SET_ITEM(result, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SET_ITEM(o3, 0, obj); + o2 = result; + result = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return result; +#endif +} + +/* Unpack the argument tuple */ + +SWIGINTERN int +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + register Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + register int i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#if PY_VERSION_HEX >= 0x02020000 +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); +#else +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); +#endif + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* How to access Py_None */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef SWIG_PYTHON_NO_BUILD_NONE +# ifndef SWIG_PYTHON_BUILD_NONE +# define SWIG_PYTHON_BUILD_NONE +# endif +# endif +#endif + +#ifdef SWIG_PYTHON_BUILD_NONE +# ifdef Py_None +# undef Py_None +# define Py_None SWIG_Py_None() +# endif +SWIGRUNTIMEINLINE PyObject * +_SWIG_Py_None(void) +{ + PyObject *none = Py_BuildValue((char*)""); + Py_DECREF(none); + return none; +} +SWIGRUNTIME PyObject * +SWIG_Py_None(void) +{ + static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); + return none; +} +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* PySwigClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; +} PySwigClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + PySwigClientData *data = (PySwigClientData *)ty->clientdata; + return data ? data->implicitconv : 0; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME PySwigClientData * +PySwigClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; +#else + data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); +#endif + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O + data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif + } else { + data->delargs = 0; + } + data->implicitconv = 0; + return data; + } +} + +SWIGRUNTIME void +PySwigClientData_Del(PySwigClientData* data) +{ + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== PySwigObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +} PySwigObject; + +SWIGRUNTIME PyObject * +PySwigObject_long(PySwigObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +PySwigObject_format(const char* fmt, PySwigObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { + PyObject *ofmt = PyString_FromString(fmt); + if (ofmt) { + res = PyString_Format(ofmt,args); + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +PySwigObject_oct(PySwigObject *v) +{ + return PySwigObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +PySwigObject_hex(PySwigObject *v) +{ + return PySwigObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +#ifdef METH_NOARGS +PySwigObject_repr(PySwigObject *v) +#else +PySwigObject_repr(PySwigObject *v, PyObject *args) +#endif +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *hex = PySwigObject_hex(v); + PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); + Py_DECREF(hex); + if (v->next) { +#ifdef METH_NOARGS + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); +#else + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); +#endif + PyString_ConcatAndDel(&repr,nrep); + } + return repr; +} + +SWIGRUNTIME int +PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ +#ifdef METH_NOARGS + PyObject *repr = PySwigObject_repr(v); +#else + PyObject *repr = PySwigObject_repr(v, NULL); +#endif + if (repr) { + fputs(PyString_AsString(repr), fp); + Py_DECREF(repr); + return 0; + } else { + return 1; + } +} + +SWIGRUNTIME PyObject * +PySwigObject_str(PySwigObject *v) +{ + char result[SWIG_BUFFER_SIZE]; + return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? + PyString_FromString(result) : 0; +} + +SWIGRUNTIME int +PySwigObject_compare(PySwigObject *v, PySwigObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigObject_Check(PyObject *op) { + return ((op)->ob_type == PySwigObject_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +PySwigObject_dealloc(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *) v; + PyObject *next = sobj->next; + if (sobj->own == SWIG_POINTER_OWN) { + swig_type_info *ty = sobj->ty; + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + if (data->delargs) { + /* we need to create a temporal object to carry the destroy operation */ + PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + Py_XDECREF(res); + } +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); + } +#endif + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +PySwigObject_append(PyObject* v, PyObject* next) +{ + PySwigObject *sobj = (PySwigObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif + if (!PySwigObject_Check(next)) { + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +#ifdef METH_NOARGS +PySwigObject_next(PyObject* v) +#else +PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_disown(PyObject *v) +#else +PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_acquire(PyObject *v) +#else +PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +PySwigObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; + } + else + { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v,args); + } else { + PySwigObject_disown(v,args); + } +#endif + } + return obj; + } +} + +#ifdef METH_O +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#else +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#endif + +#if PY_VERSION_HEX < 0x02020000 +SWIGINTERN PyObject * +PySwigObject_getattr(PySwigObject *sobj,char *name) +{ + return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); +} +#endif + +SWIGRUNTIME PyTypeObject* +_PySwigObject_type(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods PySwigObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + (binaryfunc)0, /*nb_divide*/ + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + (coercion)0, /*nb_coerce*/ + (unaryfunc)PySwigObject_long, /*nb_int*/ + (unaryfunc)PySwigObject_long, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ + (unaryfunc)PySwigObject_oct, /*nb_oct*/ + (unaryfunc)PySwigObject_hex, /*nb_hex*/ +#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ +#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ + 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ +#endif + }; + + static PyTypeObject pyswigobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigObject", /* tp_name */ + sizeof(PySwigObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigObject_dealloc, /* tp_dealloc */ + (printfunc)PySwigObject_print, /* tp_print */ +#if PY_VERSION_HEX < 0x02020000 + (getattrfunc)PySwigObject_getattr, /* tp_getattr */ +#else + (getattrfunc)0, /* tp_getattr */ +#endif + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigObject_compare, /* tp_compare */ + (reprfunc)PySwigObject_repr, /* tp_repr */ + &PySwigObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigObject_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigobject_type = tmp; + pyswigobject_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigobject_type; +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own) +{ + PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} PySwigPacked; + +SWIGRUNTIME int +PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ + char result[SWIG_BUFFER_SIZE]; + fputs("pack, v->size, 0, sizeof(result))) { + fputs("at ", fp); + fputs(result, fp); + } + fputs(v->ty->name,fp); + fputs(">", fp); + return 0; +} + +SWIGRUNTIME PyObject * +PySwigPacked_repr(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return PyString_FromFormat("", result, v->ty->name); + } else { + return PyString_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +PySwigPacked_str(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return PyString_FromFormat("%s%s", result, v->ty->name); + } else { + return PyString_FromString(v->ty->name); + } +} + +SWIGRUNTIME int +PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigPacked_Check(PyObject *op) { + return ((op)->ob_type == _PySwigPacked_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); +} + +SWIGRUNTIME void +PySwigPacked_dealloc(PyObject *v) +{ + if (PySwigPacked_Check(v)) { + PySwigPacked *sobj = (PySwigPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +_PySwigPacked_type(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject pyswigpacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigPacked", /* tp_name */ + sizeof(PySwigPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigPacked_dealloc, /* tp_dealloc */ + (printfunc)PySwigPacked_print, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigPacked_compare, /* tp_compare */ + (reprfunc)PySwigPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigpacked_type = tmp; + pyswigpacked_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigpacked_type; +} + +SWIGRUNTIME PyObject * +PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (PySwigPacked_Check(obj)) { + PySwigPacked *sobj = (PySwigPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIMEINLINE PyObject * +_SWIG_This(void) +{ + return PyString_FromString("this"); +} + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); + return swig_this; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +SWIGRUNTIME PySwigObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (PySwigObject_Check(pyobj)) { + return (PySwigObject *) pyobj; + } else { + PyObject *obj = 0; +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !PySwigObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + PySwigObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (PySwigObject *)obj; + } +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own == SWIG_POINTER_OWN) { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + if (ptr) *ptr = 0; + return SWIG_OK; + } else { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (PySwigObject *)sobj->next; + } else { + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) + *own = *own | sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + int res = SWIG_ERROR; + if (flags & SWIG_POINTER_IMPLICIT_CONV) { + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + } + return res; + } + } +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) { + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) return SWIG_ERROR; + } + if (ty) { + swig_cast_info *tc = SWIG_TypeCheck(desc,ty); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } + } else { + *ptr = vptr; + } + return SWIG_OK; + } +} + +/* Convert a packed value value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, whitout calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) +{ +#if (PY_VERSION_HEX >= 0x02020000) + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } + return inst; +#else +#if (PY_VERSION_HEX >= 0x02010000) + PyObject *inst; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + return (PyObject *) inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } +#ifdef Py_TPFLAGS_HAVE_WEAKREFS + inst->in_weakreflist = NULL; +#endif +#ifdef Py_TPFLAGS_GC + PyObject_GC_Init(inst); +#endif + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif +#endif +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, (char*)"__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { + return NULL; + } else { + PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + PySwigObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { + if (!ptr) { + return SWIG_Py_Void(); + } else { + int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + PyObject *robj = PySwigObject_New(ptr, type, own); + PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; + } +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +#if PY_MAJOR_VERSION < 2 +/* PyModule_AddObject function was introduced in Python 2.0. The following function + is copied out of Python/modsupport.c in python version 2.3.4 */ +SWIGINTERN int +PyModule_AddObject(PyObject *m, char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return SWIG_ERROR; + } + if (!o) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return SWIG_ERROR; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return SWIG_ERROR; + } + if (PyDict_SetItemString(dict, name, o)) + return SWIG_ERROR; + Py_DECREF(o); + return SWIG_OK; +} +#endif + +SWIGRUNTIME void +SWIG_Python_DestroyModule(void *vptr) +{ + swig_module_info *swig_module = (swig_module_info *) vptr; + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + PySwigClientData *data = (PySwigClientData *) ty->clientdata; + if (data) PySwigClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ + + PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + swig_empty_runtime_method_table); + PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = PyString_FromString(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); + } else { + swig_module_info *swig_module = SWIG_Python_GetModule(); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCObject_FromVoidPtr(descriptor, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); + } else { + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + } + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +PySwigObject_GetDesc(PyObject *self) +{ + PySwigObject *v = (PySwigObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : (char*)""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && PySwigObject_Check(obj)) { + const char *otype = (const char *) PySwigObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? PyString_AsString(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + if (flags & SWIG_POINTER_EXCEPTION) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } + } + return result; +} + + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_TDB_DATA swig_types[0] +#define SWIGTYPE_p_char swig_types[1] +#define SWIGTYPE_p_int swig_types[2] +#define SWIGTYPE_p_long_long swig_types[3] +#define SWIGTYPE_p_short swig_types[4] +#define SWIGTYPE_p_signed_char swig_types[5] +#define SWIGTYPE_p_tdb_context swig_types[6] +#define SWIGTYPE_p_unsigned_char swig_types[7] +#define SWIGTYPE_p_unsigned_int swig_types[8] +#define SWIGTYPE_p_unsigned_long_long swig_types[9] +#define SWIGTYPE_p_unsigned_short swig_types[10] +static swig_type_info *swig_types[12]; +static swig_module_info swig_module = {swig_types, 11, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#if (PY_VERSION_HEX <= 0x02000000) +# if !defined(SWIG_PYTHON_CLASSIC) +# error "This python version requires swig to be run with the '-classic' option" +# endif +#endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodern' option" +#endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodernargs' option" +#endif +#ifndef METH_O +# error "This python version requires swig to be run with the '-nofastunpack' option" +#endif +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery + +/*----------------------------------------------- + @(target):= _tdb.so + ------------------------------------------------*/ +#define SWIG_init init_tdb + +#define SWIG_name "_tdb" + +#define SWIGVERSION 0x010335 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + + +/* This symbol is used in both includes.h and Python.h which causes an + annoying compiler warning. */ + +#ifdef HAVE_FSTAT +#undef HAVE_FSTAT +#endif + +/* Include tdb headers */ +#include +#include +#include +#include + +typedef TDB_CONTEXT tdb; + + + #define SWIG_From_long PyInt_FromLong + + +SWIGINTERNINLINE PyObject * +SWIG_From_int (int value) +{ + return SWIG_From_long (value); +} + + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ + if (PyString_Check(obj)) { + char *cstr; Py_ssize_t len; + PyString_AsStringAndSize(obj, &cstr, &len); + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = PyString_AsString(obj); + } + } + if (psize) *psize = len + 1; + return SWIG_OK; + } else { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; + } else if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_long (PyObject *obj, long* val) +{ + if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + long v = PyInt_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { + if (val) *val = (long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERN int +SWIG_AsVal_int (PyObject * obj, int *val) +{ + long v; + int res = SWIG_AsVal_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (int)(v); + } + } + return res; +} + +SWIGINTERN tdb *new_tdb(char const *name,int hash_size,int tdb_flags,int flags,mode_t mode){ + return tdb_open(name, hash_size, tdb_flags, flags, mode); + } +SWIGINTERN void delete_tdb(tdb *self){ tdb_close(self); } + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { + return PyString_FromStringAndSize(carray, (int)(size)); + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + + +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long (unsigned long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLong(value) : PyInt_FromLong((long)(value)); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_size_t (size_t value) +{ + return SWIG_From_unsigned_SS_long ((unsigned long)(value)); +} + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_new_Tdb(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + char *arg1 = (char *) 0 ; + int arg2 ; + int arg3 ; + int arg4 ; + mode_t arg5 ; + tdb *result = 0 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + int val2 ; + int ecode2 = 0 ; + int val3 ; + int ecode3 = 0 ; + int val4 ; + int ecode4 = 0 ; + int val5 ; + int ecode5 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; + char * kwnames[] = { + (char *) "name",(char *) "hash_size",(char *) "tdb_flags",(char *) "flags",(char *) "mode", NULL + }; + + arg2 = 0; + arg3 = TDB_DEFAULT; + arg4 = O_RDWR; + arg5 = 0600; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOOO:new_Tdb",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; + res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Tdb" "', argument " "1"" of type '" "char const *""'"); + } + arg1 = (char *)(buf1); + if (obj1) { + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_Tdb" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + } + if (obj2) { + ecode3 = SWIG_AsVal_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_Tdb" "', argument " "3"" of type '" "int""'"); + } + arg3 = (int)(val3); + } + if (obj3) { + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_Tdb" "', argument " "4"" of type '" "int""'"); + } + arg4 = (int)(val4); + } + if (obj4) { + ecode5 = SWIG_AsVal_int(obj4, &val5); + if (!SWIG_IsOK(ecode5)) { + SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_Tdb" "', argument " "5"" of type '" "mode_t""'"); + } + arg5 = (mode_t)(val5); + } + result = (tdb *)new_tdb((char const *)arg1,arg2,arg3,arg4,arg5); + /* Throw an IOError exception from errno if tdb_open() returns NULL */ + if (result == NULL) { + PyErr_SetFromErrno(PyExc_IOError); + SWIG_fail; + } + resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_tdb_context, 0); + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return resultobj; +fail: + if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_error(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + enum TDB_ERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_error" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (enum TDB_ERROR)tdb_error(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_delete_Tdb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, SWIG_POINTER_DISOWN | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Tdb" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + delete_tdb(arg1); + + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_close(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_close" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_close(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + TDB_DATA arg2 ; + TDB_DATA arg3 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "key",(char *) "new_dbuf", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:Tdb_append",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_append" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); + } + if (obj2 == Py_None) { + (&arg3)->dsize = 0; + (&arg3)->dptr = NULL; + } else if (!PyString_Check(obj2)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg3)->dsize = PyString_Size(obj2); + (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); + } + result = (int)tdb_append(arg1,arg2,arg3); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_errorstr(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_errorstr" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (char *)tdb_errorstr(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + TDB_DATA arg2 ; + TDB_DATA result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "key", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_get",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_get" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); + } + result = tdb_fetch(arg1,arg2); + if ((&result)->dptr == NULL && (&result)->dsize == 0) { + resultobj = Py_None; + } else { + resultobj = PyString_FromStringAndSize((const char *)(&result)->dptr, (&result)->dsize); + free((&result)->dptr); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_delete(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + TDB_DATA arg2 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "key", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_delete",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_delete" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); + } + result = (int)tdb_delete(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_store(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + TDB_DATA arg2 ; + TDB_DATA arg3 ; + int arg4 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + int val4 ; + int ecode4 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "key",(char *) "dbuf",(char *) "flag", NULL + }; + + arg4 = TDB_REPLACE; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:Tdb_store",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_store" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); + } + if (obj2 == Py_None) { + (&arg3)->dsize = 0; + (&arg3)->dptr = NULL; + } else if (!PyString_Check(obj2)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg3)->dsize = PyString_Size(obj2); + (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); + } + if (obj3) { + ecode4 = SWIG_AsVal_int(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Tdb_store" "', argument " "4"" of type '" "int""'"); + } + arg4 = (int)(val4); + } + result = (int)tdb_store(arg1,arg2,arg3,arg4); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_exists(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + TDB_DATA arg2 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "key", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_exists",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_exists" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); + } + result = (int)tdb_exists(arg1,arg2); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_firstkey(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + TDB_DATA result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_firstkey" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = tdb_firstkey(arg1); + if ((&result)->dptr == NULL && (&result)->dsize == 0) { + resultobj = Py_None; + } else { + resultobj = PyString_FromStringAndSize((const char *)(&result)->dptr, (&result)->dsize); + free((&result)->dptr); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_nextkey(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + TDB_DATA arg2 ; + TDB_DATA result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "key", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_nextkey",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_nextkey" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); + } + result = tdb_nextkey(arg1,arg2); + if ((&result)->dptr == NULL && (&result)->dsize == 0) { + resultobj = Py_None; + } else { + resultobj = PyString_FromStringAndSize((const char *)(&result)->dptr, (&result)->dsize); + free((&result)->dptr); + } + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_lock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_lock_all" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_lockall(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_unlock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_unlock_all" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_unlockall(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_read_lock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_read_lock_all" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_lockall_read(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_read_unlock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_read_unlock_all" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_unlockall_read(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_reopen(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_reopen" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_reopen(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_transaction_start(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_start" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_transaction_start(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_transaction_commit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_commit" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_transaction_commit(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_transaction_cancel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_cancel" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_transaction_cancel(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_transaction_recover(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_recover" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_transaction_recover(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_hash_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_hash_size" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_hash_size(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_map_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + size_t result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_map_size" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = tdb_map_size(arg1); + resultobj = SWIG_From_size_t((size_t)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_get_flags(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_get_flags" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (int)tdb_get_flags(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_set_max_dead(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + int arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + int val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "max_dead", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_set_max_dead",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_set_max_dead" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + ecode2 = SWIG_AsVal_int(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tdb_set_max_dead" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + tdb_set_max_dead(arg1,arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Tdb_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + tdb *arg1 = (tdb *) 0 ; + char *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_name" "', argument " "1"" of type '" "tdb *""'"); + } + arg1 = (tdb *)(argp1); + result = (char *)tdb_name(arg1); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *Tdb_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *obj; + if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; + SWIG_TypeNewClientData(SWIGTYPE_p_tdb_context, SWIG_NewClientData(obj)); + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject *Tdb_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + return SWIG_Python_InitShadowInstance(args); +} + +static PyMethodDef SwigMethods[] = { + { (char *)"new_Tdb", (PyCFunction) _wrap_new_Tdb, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600)\n" + "Open a TDB file.\n" + ""}, + { (char *)"Tdb_error", (PyCFunction)_wrap_Tdb_error, METH_O, (char *)"\n" + "S.error() -> int\n" + "Find last error number returned by operation on this TDB.\n" + ""}, + { (char *)"delete_Tdb", (PyCFunction)_wrap_delete_Tdb, METH_O, NULL}, + { (char *)"Tdb_close", (PyCFunction)_wrap_Tdb_close, METH_O, (char *)"\n" + "S.close() -> None\n" + "Close the TDB file.\n" + ""}, + { (char *)"Tdb_append", (PyCFunction) _wrap_Tdb_append, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Tdb_errorstr", (PyCFunction)_wrap_Tdb_errorstr, METH_O, (char *)"\n" + "S.errorstr() -> errorstring\n" + "Obtain last error message.\n" + ""}, + { (char *)"Tdb_get", (PyCFunction) _wrap_Tdb_get, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.fetch(key) -> value\n" + "Fetch a value.\n" + ""}, + { (char *)"Tdb_delete", (PyCFunction) _wrap_Tdb_delete, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.delete(key) -> None\n" + "Delete an entry.\n" + ""}, + { (char *)"Tdb_store", (PyCFunction) _wrap_Tdb_store, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.store(key, value, flag=TDB_REPLACE) -> None\n" + "Store an entry.\n" + ""}, + { (char *)"Tdb_exists", (PyCFunction) _wrap_Tdb_exists, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.exists(key) -> bool\n" + "Check whether key exists in this database.\n" + ""}, + { (char *)"Tdb_firstkey", (PyCFunction)_wrap_Tdb_firstkey, METH_O, (char *)"\n" + "S.firstkey() -> data\n" + "Return the first key in this database.\n" + ""}, + { (char *)"Tdb_nextkey", (PyCFunction) _wrap_Tdb_nextkey, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.nextkey(prev) -> data\n" + "Return the next key in this database.\n" + ""}, + { (char *)"Tdb_lock_all", (PyCFunction)_wrap_Tdb_lock_all, METH_O, (char *)"S.lockall() -> bool"}, + { (char *)"Tdb_unlock_all", (PyCFunction)_wrap_Tdb_unlock_all, METH_O, (char *)"S.unlockall() -> bool"}, + { (char *)"Tdb_read_lock_all", (PyCFunction)_wrap_Tdb_read_lock_all, METH_O, NULL}, + { (char *)"Tdb_read_unlock_all", (PyCFunction)_wrap_Tdb_read_unlock_all, METH_O, NULL}, + { (char *)"Tdb_reopen", (PyCFunction)_wrap_Tdb_reopen, METH_O, (char *)"\n" + "S.reopen() -> bool\n" + "Reopen this file.\n" + ""}, + { (char *)"Tdb_transaction_start", (PyCFunction)_wrap_Tdb_transaction_start, METH_O, (char *)"\n" + "S.transaction_start() -> None\n" + "Start a new transaction.\n" + ""}, + { (char *)"Tdb_transaction_commit", (PyCFunction)_wrap_Tdb_transaction_commit, METH_O, (char *)"\n" + "S.transaction_commit() -> None\n" + "Commit the currently active transaction.\n" + ""}, + { (char *)"Tdb_transaction_cancel", (PyCFunction)_wrap_Tdb_transaction_cancel, METH_O, (char *)"\n" + "S.transaction_cancel() -> None\n" + "Cancel the currently active transaction.\n" + ""}, + { (char *)"Tdb_transaction_recover", (PyCFunction)_wrap_Tdb_transaction_recover, METH_O, NULL}, + { (char *)"Tdb_hash_size", (PyCFunction)_wrap_Tdb_hash_size, METH_O, (char *)"S.hash_size() -> int"}, + { (char *)"Tdb_map_size", (PyCFunction)_wrap_Tdb_map_size, METH_O, (char *)"S.map_size() -> int"}, + { (char *)"Tdb_get_flags", (PyCFunction)_wrap_Tdb_get_flags, METH_O, (char *)"S.get_flags() -> int"}, + { (char *)"Tdb_set_max_dead", (PyCFunction) _wrap_Tdb_set_max_dead, METH_VARARGS | METH_KEYWORDS, (char *)"S.set_max_dead(int) -> None"}, + { (char *)"Tdb_name", (PyCFunction)_wrap_Tdb_name, METH_O, (char *)"\n" + "S.name() -> path\n" + "Return filename of this TDB file.\n" + ""}, + { (char *)"Tdb_swigregister", Tdb_swigregister, METH_VARARGS, NULL}, + { (char *)"Tdb_swiginit", Tdb_swiginit, METH_VARARGS, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_TDB_DATA = {"_p_TDB_DATA", "TDB_DATA *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *|mode_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_tdb_context = {"_p_tdb_context", "struct tdb_context *|tdb *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_TDB_DATA, + &_swigt__p_char, + &_swigt__p_int, + &_swigt__p_long_long, + &_swigt__p_short, + &_swigt__p_signed_char, + &_swigt__p_tdb_context, + &_swigt__p_unsigned_char, + &_swigt__p_unsigned_int, + &_swigt__p_unsigned_long_long, + &_swigt__p_unsigned_short, +}; + +static swig_cast_info _swigc__p_TDB_DATA[] = { {&_swigt__p_TDB_DATA, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_tdb_context[] = { {&_swigt__p_tdb_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_TDB_DATA, + _swigc__p_char, + _swigc__p_int, + _swigc__p_long_long, + _swigc__p_short, + _swigc__p_signed_char, + _swigc__p_tdb_context, + _swigc__p_unsigned_char, + _swigc__p_unsigned_int, + _swigc__p_unsigned_long_long, + _swigc__p_unsigned_short, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found, init; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + init = 1; + } else { + init = 0; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { + return PyString_FromString(""); + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); + return str; + } + + SWIGINTERN int + swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { + PyObject *str = swig_varlink_str(v); + fprintf(fp,"Swig global variables "); + fprintf(fp,"%s\n", PyString_AsString(str)); + Py_DECREF(str); + return 0; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* Number of items in variable part (ob_size) */ + (char *)"swigvarlink", /* Type name (tp_name) */ + sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ + 0, /* Itemsize (tp_itemsize) */ + (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ + (printfunc) swig_varlink_print, /* Print (tp_print) */ + (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ + (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + varlink_type = tmp; + varlink_type.ob_type = &PyType_Type; + type_init = 1; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + strncpy(gv->name,name,size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *_SWIG_globals = 0; + if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); + return _SWIG_globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (c && (c = strstr(c, "swig_ptr: "))) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + strncpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + strncpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIG_init(void) { + PyObject *m, *d; + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + + m = Py_InitModule((char *) SWIG_name, SwigMethods); + d = PyModule_GetDict(m); + + SWIG_InitializeModule(0); + SWIG_InstallConstants(d,swig_const_table); + + + SWIG_Python_SetConstant(d, "REPLACE",SWIG_From_int((int)(TDB_REPLACE))); + SWIG_Python_SetConstant(d, "INSERT",SWIG_From_int((int)(TDB_INSERT))); + SWIG_Python_SetConstant(d, "MODIFY",SWIG_From_int((int)(TDB_MODIFY))); + SWIG_Python_SetConstant(d, "DEFAULT",SWIG_From_int((int)(TDB_DEFAULT))); + SWIG_Python_SetConstant(d, "CLEAR_IF_FIRST",SWIG_From_int((int)(TDB_CLEAR_IF_FIRST))); + SWIG_Python_SetConstant(d, "INTERNAL",SWIG_From_int((int)(TDB_INTERNAL))); + SWIG_Python_SetConstant(d, "NOLOCK",SWIG_From_int((int)(TDB_NOLOCK))); + SWIG_Python_SetConstant(d, "NOMMAP",SWIG_From_int((int)(TDB_NOMMAP))); + SWIG_Python_SetConstant(d, "CONVERT",SWIG_From_int((int)(TDB_CONVERT))); + SWIG_Python_SetConstant(d, "BIGENDIAN",SWIG_From_int((int)(TDB_BIGENDIAN))); + SWIG_Python_SetConstant(d, "TDB_SUCCESS",SWIG_From_int((int)(TDB_SUCCESS))); + SWIG_Python_SetConstant(d, "TDB_ERR_CORRUPT",SWIG_From_int((int)(TDB_ERR_CORRUPT))); + SWIG_Python_SetConstant(d, "TDB_ERR_IO",SWIG_From_int((int)(TDB_ERR_IO))); + SWIG_Python_SetConstant(d, "TDB_ERR_LOCK",SWIG_From_int((int)(TDB_ERR_LOCK))); + SWIG_Python_SetConstant(d, "TDB_ERR_OOM",SWIG_From_int((int)(TDB_ERR_OOM))); + SWIG_Python_SetConstant(d, "TDB_ERR_EXISTS",SWIG_From_int((int)(TDB_ERR_EXISTS))); + SWIG_Python_SetConstant(d, "TDB_ERR_NOLOCK",SWIG_From_int((int)(TDB_ERR_NOLOCK))); + SWIG_Python_SetConstant(d, "TDB_ERR_LOCK_TIMEOUT",SWIG_From_int((int)(TDB_ERR_LOCK_TIMEOUT))); + SWIG_Python_SetConstant(d, "TDB_ERR_NOEXIST",SWIG_From_int((int)(TDB_ERR_NOEXIST))); + SWIG_Python_SetConstant(d, "TDB_ERR_EINVAL",SWIG_From_int((int)(TDB_ERR_EINVAL))); + SWIG_Python_SetConstant(d, "TDB_ERR_RDONLY",SWIG_From_int((int)(TDB_ERR_RDONLY))); +} + diff --git a/lib/tdb/tools/tdbbackup.c b/lib/tdb/tools/tdbbackup.c new file mode 100644 index 0000000000..6f3ca48314 --- /dev/null +++ b/lib/tdb/tools/tdbbackup.c @@ -0,0 +1,300 @@ +/* + Unix SMB/CIFS implementation. + low level tdb backup and restore utility + Copyright (C) Andrew Tridgell 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + + This program is meant for backup/restore of tdb databases. Typical usage would be: + tdbbackup *.tdb + when Samba shuts down cleanly, which will make a backup of all the local databases + to *.bak files. Then on Samba startup you would use: + tdbbackup -v *.tdb + and this will check the databases for corruption and if corruption is detected then + the backup will be restored. + + You may also like to do a backup on a regular basis while Samba is + running, perhaps using cron. + + The reason this program is needed is to cope with power failures + while Samba is running. A power failure could lead to database + corruption and Samba will then not start correctly. + + Note that many of the databases in Samba are transient and thus + don't need to be backed up, so you can optimise the above a little + by only running the backup on the critical databases. + + */ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "tdb.h" + +#ifdef HAVE_GETOPT_H +#include +#endif + +static int failed; + +static char *add_suffix(const char *name, const char *suffix) +{ + char *ret; + int len = strlen(name) + strlen(suffix) + 1; + ret = (char *)malloc(len); + if (!ret) { + fprintf(stderr,"Out of memory!\n"); + exit(1); + } + snprintf(ret, len, "%s%s", name, suffix); + return ret; +} + +static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; + + if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { + fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new)); + failed = 1; + return 1; + } + return 0; +} + + +static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + return 0; +} + +/* + carefully backup a tdb, validating the contents and + only doing the backup if its OK + this function is also used for restore +*/ +static int backup_tdb(const char *old_name, const char *new_name, int hash_size) +{ + TDB_CONTEXT *tdb; + TDB_CONTEXT *tdb_new; + char *tmp_name; + struct stat st; + int count1, count2; + + tmp_name = add_suffix(new_name, ".tmp"); + + /* stat the old tdb to find its permissions */ + if (stat(old_name, &st) != 0) { + perror(old_name); + free(tmp_name); + return 1; + } + + /* open the old tdb */ + tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); + if (!tdb) { + printf("Failed to open %s\n", old_name); + free(tmp_name); + return 1; + } + + /* create the new tdb */ + unlink(tmp_name); + tdb_new = tdb_open(tmp_name, + hash_size ? hash_size : tdb_hash_size(tdb), + TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, + st.st_mode & 0777); + if (!tdb_new) { + perror(tmp_name); + free(tmp_name); + return 1; + } + + /* lock the old tdb */ + if (tdb_lockall(tdb) != 0) { + fprintf(stderr,"Failed to lock %s\n", old_name); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + failed = 0; + + /* traverse and copy */ + count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); + if (count1 < 0 || failed) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* close the old tdb */ + tdb_close(tdb); + + /* close the new tdb and re-open read-only */ + tdb_close(tdb_new); + tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); + if (!tdb_new) { + fprintf(stderr,"failed to reopen %s\n", tmp_name); + unlink(tmp_name); + perror(tmp_name); + free(tmp_name); + return 1; + } + + /* traverse the new tdb to confirm */ + count2 = tdb_traverse(tdb_new, test_fn, NULL); + if (count2 != count1) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* make sure the new tdb has reached stable storage */ + fsync(tdb_fd(tdb_new)); + + /* close the new tdb and rename it to .bak */ + tdb_close(tdb_new); + if (rename(tmp_name, new_name) != 0) { + perror(new_name); + free(tmp_name); + return 1; + } + + free(tmp_name); + + return 0; +} + +/* + verify a tdb and if it is corrupt then restore from *.bak +*/ +static int verify_tdb(const char *fname, const char *bak_name) +{ + TDB_CONTEXT *tdb; + int count = -1; + + /* open the tdb */ + tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); + + /* traverse the tdb, then close it */ + if (tdb) { + count = tdb_traverse(tdb, test_fn, NULL); + tdb_close(tdb); + } + + /* count is < 0 means an error */ + if (count < 0) { + printf("restoring %s\n", fname); + return backup_tdb(bak_name, fname, 0); + } + + printf("%s : %d records\n", fname, count); + + return 0; +} + +/* + see if one file is newer than another +*/ +static int file_newer(const char *fname1, const char *fname2) +{ + struct stat st1, st2; + if (stat(fname1, &st1) != 0) { + return 0; + } + if (stat(fname2, &st2) != 0) { + return 1; + } + return (st1.st_mtime > st2.st_mtime); +} + +static void usage(void) +{ + printf("Usage: tdbbackup [options] \n\n"); + printf(" -h this help message\n"); + printf(" -s suffix set the backup suffix\n"); + printf(" -v verify mode (restore if corrupt)\n"); + printf(" -n hashsize set the new hash size for the backup\n"); +} + + + int main(int argc, char *argv[]) +{ + int i; + int ret = 0; + int c; + int verify = 0; + int hashsize = 0; + const char *suffix = ".bak"; + + while ((c = getopt(argc, argv, "vhs:n:")) != -1) { + switch (c) { + case 'h': + usage(); + exit(0); + case 'v': + verify = 1; + break; + case 's': + suffix = optarg; + break; + case 'n': + hashsize = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) { + usage(); + exit(1); + } + + for (i=0; i. +*/ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "tdb.h" + +static void print_data(TDB_DATA d) +{ + unsigned char *p = (unsigned char *)d.dptr; + int len = d.dsize; + while (len--) { + if (isprint(*p) && !strchr("\"\\", *p)) { + fputc(*p, stdout); + } else { + printf("\\%02X", *p); + } + p++; + } +} + +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("{\n"); + printf("key(%d) = \"", (int)key.dsize); + print_data(key); + printf("\"\n"); + printf("data(%d) = \"", (int)dbuf.dsize); + print_data(dbuf); + printf("\"\n"); + printf("}\n"); + return 0; +} + +static int dump_tdb(const char *fname, const char *keyname) +{ + TDB_CONTEXT *tdb; + TDB_DATA key, value; + + tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); + if (!tdb) { + printf("Failed to open %s\n", fname); + return 1; + } + + if (!keyname) { + tdb_traverse(tdb, traverse_fn, NULL); + } else { + key.dptr = discard_const_p(uint8_t,keyname); + key.dsize = strlen( keyname); + value = tdb_fetch(tdb, key); + if (!value.dptr) { + return 1; + } else { + print_data(value); + free(value.dptr); + } + } + + return 0; +} + +static void usage( void) +{ + printf( "Usage: tdbdump [options] \n\n"); + printf( " -h this help message\n"); + printf( " -k keyname dumps value of keyname\n"); +} + + int main(int argc, char *argv[]) +{ + char *fname, *keyname=NULL; + int c; + + if (argc < 2) { + printf("Usage: tdbdump \n"); + exit(1); + } + + while ((c = getopt( argc, argv, "hk:")) != -1) { + switch (c) { + case 'h': + usage(); + exit( 0); + case 'k': + keyname = optarg; + break; + default: + usage(); + exit( 1); + } + } + + fname = argv[optind]; + + return dump_tdb(fname, keyname); +} diff --git a/lib/tdb/tools/tdbtest.c b/lib/tdb/tools/tdbtest.c new file mode 100644 index 0000000000..416bc50a5b --- /dev/null +++ b/lib/tdb/tools/tdbtest.c @@ -0,0 +1,265 @@ +/* a test program for tdb - the trivial database */ + +#include "replace.h" +#include "tdb.h" +#include "system/filesys.h" +#include "system/time.h" + +#include + + +#define DELETE_PROB 7 +#define STORE_PROB 5 + +static struct tdb_context *db; +static GDBM_FILE gdbm; + +struct timeval tp1,tp2; + +static void _start_timer(void) +{ + gettimeofday(&tp1,NULL); +} + +static double _end_timer(void) +{ + gettimeofday(&tp2,NULL); + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); +} + +static void fatal(const char *why) +{ + perror(why); + exit(1); +} + +#ifdef PRINTF_ATTRIBUTE +static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); +#endif +static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); + fflush(stdout); +} + +static void compare_db(void) +{ + TDB_DATA d, key, nextkey; + datum gd, gkey, gnextkey; + + key = tdb_firstkey(db); + while (key.dptr) { + d = tdb_fetch(db, key); + gkey.dptr = key.dptr; + gkey.dsize = key.dsize; + + gd = gdbm_fetch(gdbm, gkey); + + if (!gd.dptr) fatal("key not in gdbm"); + if (gd.dsize != d.dsize) fatal("data sizes differ"); + if (memcmp(gd.dptr, d.dptr, d.dsize)) { + fatal("data differs"); + } + + nextkey = tdb_nextkey(db, key); + free(key.dptr); + free(d.dptr); + free(gd.dptr); + key = nextkey; + } + + gkey = gdbm_firstkey(gdbm); + while (gkey.dptr) { + gd = gdbm_fetch(gdbm, gkey); + key.dptr = gkey.dptr; + key.dsize = gkey.dsize; + + d = tdb_fetch(db, key); + + if (!d.dptr) fatal("key not in db"); + if (d.dsize != gd.dsize) fatal("data sizes differ"); + if (memcmp(d.dptr, gd.dptr, gd.dsize)) { + fatal("data differs"); + } + + gnextkey = gdbm_nextkey(gdbm, gkey); + free(gkey.dptr); + free(gd.dptr); + free(d.dptr); + gkey = gnextkey; + } +} + +static char *randbuf(int len) +{ + char *buf; + int i; + buf = (char *)malloc(len+1); + + for (i=0;i. +*/ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "tdb.h" + +static int do_command(void); +const char *cmdname; +char *arg1, *arg2; +size_t arg1len, arg2len; +int bIterate = 0; +char *line; +TDB_DATA iterate_kbuf; +char cmdline[1024]; +static int disable_mmap; + +enum commands { + CMD_CREATE_TDB, + CMD_OPEN_TDB, + CMD_ERASE, + CMD_DUMP, + CMD_INSERT, + CMD_MOVE, + CMD_STORE, + CMD_SHOW, + CMD_KEYS, + CMD_HEXKEYS, + CMD_DELETE, + CMD_LIST_HASH_FREE, + CMD_LIST_FREE, + CMD_INFO, + CMD_MMAP, + CMD_SPEED, + CMD_FIRST, + CMD_NEXT, + CMD_SYSTEM, + CMD_QUIT, + CMD_HELP +}; + +typedef struct { + const char *name; + enum commands cmd; +} COMMAND_TABLE; + +COMMAND_TABLE cmd_table[] = { + {"create", CMD_CREATE_TDB}, + {"open", CMD_OPEN_TDB}, + {"erase", CMD_ERASE}, + {"dump", CMD_DUMP}, + {"insert", CMD_INSERT}, + {"move", CMD_MOVE}, + {"store", CMD_STORE}, + {"show", CMD_SHOW}, + {"keys", CMD_KEYS}, + {"hexkeys", CMD_HEXKEYS}, + {"delete", CMD_DELETE}, + {"list", CMD_LIST_HASH_FREE}, + {"free", CMD_LIST_FREE}, + {"info", CMD_INFO}, + {"speed", CMD_SPEED}, + {"mmap", CMD_MMAP}, + {"first", CMD_FIRST}, + {"1", CMD_FIRST}, + {"next", CMD_NEXT}, + {"n", CMD_NEXT}, + {"quit", CMD_QUIT}, + {"q", CMD_QUIT}, + {"!", CMD_SYSTEM}, + {NULL, CMD_HELP} +}; + +struct timeval tp1,tp2; + +static void _start_timer(void) +{ + gettimeofday(&tp1,NULL); +} + +static double _end_timer(void) +{ + gettimeofday(&tp2,NULL); + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); +} + +/* a tdb tool for manipulating a tdb database */ + +static TDB_CONTEXT *tdb; + +static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); + +static void print_asc(const char *buf,int len) +{ + int i; + + /* We're probably printing ASCII strings so don't try to display + the trailing NULL character. */ + + if (buf[len - 1] == 0) + len--; + + for (i=0;i8) printf(" "); + while (n--) printf(" "); + + n = i%16; + if (n > 8) n = 8; + print_asc(&buf[i-(i%16)],n); printf(" "); + n = (i%16) - n; + if (n>0) print_asc(&buf[i-n],n); + printf("\n"); + } +} + +static void help(void) +{ + printf("\n" +"tdbtool: \n" +" create dbname : create a database\n" +" open dbname : open an existing database\n" +" erase : erase the database\n" +" dump : dump the database as strings\n" +" keys : dump the database keys as strings\n" +" hexkeys : dump the database keys as hex values\n" +" info : print summary info about the database\n" +" insert key data : insert a record\n" +" move key file : move a record to a destination tdb\n" +" store key data : store a record (replace)\n" +" show key : show a record by key\n" +" delete key : delete a record by key\n" +" list : print the database hash table and freelist\n" +" free : print the database freelist\n" +" ! command : execute system command\n" +" 1 | first : print the first record\n" +" n | next : print the next record\n" +" q | quit : terminate\n" +" \\n : repeat 'next' command\n" +"\n"); +} + +static void terror(const char *why) +{ + printf("%s\n", why); +} + +static void create_tdb(const char *tdbname) +{ + if (tdb) tdb_close(tdb); + tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST | (disable_mmap?TDB_NOMMAP:0), + O_RDWR | O_CREAT | O_TRUNC, 0600); + if (!tdb) { + printf("Could not create %s: %s\n", tdbname, strerror(errno)); + } +} + +static void open_tdb(const char *tdbname) +{ + if (tdb) tdb_close(tdb); + tdb = tdb_open(tdbname, 0, disable_mmap?TDB_NOMMAP:0, O_RDWR, 0600); + if (!tdb) { + printf("Could not open %s: %s\n", tdbname, strerror(errno)); + } +} + +static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) +{ + TDB_DATA key, dbuf; + + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + dbuf.dptr = (unsigned char *)data; + dbuf.dsize = datalen; + + if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { + terror("insert failed"); + } +} + +static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) +{ + TDB_DATA key, dbuf; + + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); + return; + } + + if ((data == NULL) || (datalen == 0)) { + terror("need data"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + dbuf.dptr = (unsigned char *)data; + dbuf.dsize = datalen; + + printf("Storing key:\n"); + print_rec(tdb, key, dbuf, NULL); + + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { + terror("store failed"); + } +} + +static void show_tdb(char *keyname, size_t keylen) +{ + TDB_DATA key, dbuf; + + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) { + terror("fetch failed"); + return; + } + + print_rec(tdb, key, dbuf, NULL); + + free( dbuf.dptr ); + + return; +} + +static void delete_tdb(char *keyname, size_t keylen) +{ + TDB_DATA key; + + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + + if (tdb_delete(tdb, key) != 0) { + terror("delete failed"); + } +} + +static void move_rec(char *keyname, size_t keylen, char* tdbname) +{ + TDB_DATA key, dbuf; + TDB_CONTEXT *dst_tdb; + + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); + return; + } + + if ( !tdbname ) { + terror("need destination tdb name"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) { + terror("fetch failed"); + return; + } + + print_rec(tdb, key, dbuf, NULL); + + dst_tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600); + if ( !dst_tdb ) { + terror("unable to open destination tdb"); + return; + } + + if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { + terror("failed to move record"); + } + else + printf("record moved\n"); + + tdb_close( dst_tdb ); + + return; +} + +static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("\nkey %d bytes\n", (int)key.dsize); + print_asc((const char *)key.dptr, key.dsize); + printf("\ndata %d bytes\n", (int)dbuf.dsize); + print_data((const char *)dbuf.dptr, dbuf.dsize); + return 0; +} + +static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("key %d bytes: ", (int)key.dsize); + print_asc((const char *)key.dptr, key.dsize); + printf("\n"); + return 0; +} + +static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("key %d bytes\n", (int)key.dsize); + print_data((const char *)key.dptr, key.dsize); + printf("\n"); + return 0; +} + +static int total_bytes; + +static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + total_bytes += dbuf.dsize; + return 0; +} + +static void info_tdb(void) +{ + int count; + total_bytes = 0; + if ((count = tdb_traverse(tdb, traverse_fn, NULL)) == -1) + printf("Error = %s\n", tdb_errorstr(tdb)); + else + printf("%d records totalling %d bytes\n", count, total_bytes); +} + +static void speed_tdb(const char *tlimit) +{ + unsigned timelimit = tlimit?atoi(tlimit):0; + double t; + int ops=0; + if (timelimit == 0) timelimit = 10; + printf("Testing traverse speed for %u seconds\n", timelimit); + _start_timer(); + while ((t=_end_timer()) < timelimit) { + tdb_traverse(tdb, traverse_fn, NULL); + printf("%10.3f ops/sec\r", (++ops)/t); + } + printf("\n"); +} + +static void toggle_mmap(void) +{ + disable_mmap = !disable_mmap; + if (disable_mmap) { + printf("mmap is disabled\n"); + } else { + printf("mmap is enabled\n"); + } +} + +static char *tdb_getline(const char *prompt) +{ + static char thisline[1024]; + char *p; + fputs(prompt, stdout); + thisline[0] = 0; + p = fgets(thisline, sizeof(thisline)-1, stdin); + if (p) p = strchr(p, '\n'); + if (p) *p = 0; + return p?thisline:NULL; +} + +static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, + void *state) +{ + return tdb_delete(the_tdb, key); +} + +static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) +{ + TDB_DATA dbuf; + *pkey = tdb_firstkey(the_tdb); + + dbuf = tdb_fetch(the_tdb, *pkey); + if (!dbuf.dptr) terror("fetch failed"); + else { + print_rec(the_tdb, *pkey, dbuf, NULL); + } +} + +static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) +{ + TDB_DATA dbuf; + *pkey = tdb_nextkey(the_tdb, *pkey); + + dbuf = tdb_fetch(the_tdb, *pkey); + if (!dbuf.dptr) + terror("fetch failed"); + else + print_rec(the_tdb, *pkey, dbuf, NULL); +} + +static int do_command(void) +{ + COMMAND_TABLE *ctp = cmd_table; + enum commands mycmd = CMD_HELP; + int cmd_len; + + if (cmdname && strlen(cmdname) == 0) { + mycmd = CMD_NEXT; + } else { + while (ctp->name) { + cmd_len = strlen(ctp->name); + if (strncmp(ctp->name,cmdname,cmd_len) == 0) { + mycmd = ctp->cmd; + break; + } + ctp++; + } + } + + switch (mycmd) { + case CMD_CREATE_TDB: + bIterate = 0; + create_tdb(arg1); + return 0; + case CMD_OPEN_TDB: + bIterate = 0; + open_tdb(arg1); + return 0; + case CMD_SYSTEM: + /* Shell command */ + system(arg1); + return 0; + case CMD_QUIT: + return 1; + default: + /* all the rest require a open database */ + if (!tdb) { + bIterate = 0; + terror("database not open"); + help(); + return 0; + } + switch (mycmd) { + case CMD_ERASE: + bIterate = 0; + tdb_traverse(tdb, do_delete_fn, NULL); + return 0; + case CMD_DUMP: + bIterate = 0; + tdb_traverse(tdb, print_rec, NULL); + return 0; + case CMD_INSERT: + bIterate = 0; + insert_tdb(arg1, arg1len,arg2,arg2len); + return 0; + case CMD_MOVE: + bIterate = 0; + move_rec(arg1,arg1len,arg2); + return 0; + case CMD_STORE: + bIterate = 0; + store_tdb(arg1,arg1len,arg2,arg2len); + return 0; + case CMD_SHOW: + bIterate = 0; + show_tdb(arg1, arg1len); + return 0; + case CMD_KEYS: + tdb_traverse(tdb, print_key, NULL); + return 0; + case CMD_HEXKEYS: + tdb_traverse(tdb, print_hexkey, NULL); + return 0; + case CMD_DELETE: + bIterate = 0; + delete_tdb(arg1,arg1len); + return 0; + case CMD_LIST_HASH_FREE: + tdb_dump_all(tdb); + return 0; + case CMD_LIST_FREE: + tdb_printfreelist(tdb); + return 0; + case CMD_INFO: + info_tdb(); + return 0; + case CMD_SPEED: + speed_tdb(arg1); + return 0; + case CMD_MMAP: + toggle_mmap(); + return 0; + case CMD_FIRST: + bIterate = 1; + first_record(tdb, &iterate_kbuf); + return 0; + case CMD_NEXT: + if (bIterate) + next_record(tdb, &iterate_kbuf); + return 0; + case CMD_HELP: + help(); + return 0; + case CMD_CREATE_TDB: + case CMD_OPEN_TDB: + case CMD_SYSTEM: + case CMD_QUIT: + /* + * unhandled commands. cases included here to avoid compiler + * warnings. + */ + return 0; + } + } + + return 0; +} + +static char *convert_string(char *instring, size_t *sizep) +{ + size_t length = 0; + char *outp, *inp; + char temp[3]; + + + outp = inp = instring; + + while (*inp) { + if (*inp == '\\') { + inp++; + if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { + temp[0] = *inp++; + temp[1] = '\0'; + if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { + temp[1] = *inp++; + temp[2] = '\0'; + } + *outp++ = (char)strtol((const char *)temp,NULL,16); + } else { + *outp++ = *inp++; + } + } else { + *outp++ = *inp++; + } + length++; + } + *sizep = length; + return instring; +} + +int main(int argc, char *argv[]) +{ + cmdname = ""; + arg1 = NULL; + arg1len = 0; + arg2 = NULL; + arg2len = 0; + + if (argv[1]) { + cmdname = "open"; + arg1 = argv[1]; + do_command(); + cmdname = ""; + arg1 = NULL; + } + + switch (argc) { + case 1: + case 2: + /* Interactive mode */ + while ((cmdname = tdb_getline("tdb> "))) { + arg2 = arg1 = NULL; + if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { + arg1++; + arg2 = arg1; + while (*arg2) { + if (*arg2 == ' ') { + *arg2++ = '\0'; + break; + } + if ((*arg2++ == '\\') && (*arg2 == ' ')) { + arg2++; + } + } + } + if (arg1) arg1 = convert_string(arg1,&arg1len); + if (arg2) arg2 = convert_string(arg2,&arg2len); + if (do_command()) break; + } + break; + case 5: + arg2 = convert_string(argv[4],&arg2len); + case 4: + arg1 = convert_string(argv[3],&arg1len); + case 3: + cmdname = argv[2]; + default: + do_command(); + break; + } + + if (tdb) tdb_close(tdb); + + return 0; +} diff --git a/lib/tdb/tools/tdbtorture.c b/lib/tdb/tools/tdbtorture.c new file mode 100644 index 0000000000..9265cf07aa --- /dev/null +++ b/lib/tdb/tools/tdbtorture.c @@ -0,0 +1,318 @@ +/* this tests tdb by doing lots of ops from several simultaneous + writers - that stresses the locking code. +*/ + +#include "replace.h" +#include "system/time.h" +#include "system/wait.h" +#include "system/filesys.h" +#include "tdb.h" + +#ifdef HAVE_GETOPT_H +#include +#endif + + +#define REOPEN_PROB 30 +#define DELETE_PROB 8 +#define STORE_PROB 4 +#define APPEND_PROB 6 +#define TRANSACTION_PROB 10 +#define LOCKSTORE_PROB 5 +#define TRAVERSE_PROB 20 +#define TRAVERSE_READ_PROB 20 +#define CULL_PROB 100 +#define KEYLEN 3 +#define DATALEN 100 + +static struct tdb_context *db; +static int in_transaction; +static int error_count; + +#ifdef PRINTF_ATTRIBUTE +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); +#endif +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) +{ + va_list ap; + + error_count++; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); + fflush(stdout); +#if 0 + { + char *ptr; + asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); + system(ptr); + free(ptr); + } +#endif +} + +static void fatal(const char *why) +{ + perror(why); + error_count++; +} + +static char *randbuf(int len) +{ + char *buf; + int i; + buf = (char *)malloc(len+1); + + for (i=0;i + + +ldb + + + +

tdb

+ +TDB is a Trivial Database. In concept, it is very much like GDBM, and BSD's DB +except that it allows multiple simultaneous writers and uses locking +internally to keep writers from trampling on each other. TDB is also extremely +small. + +

Discussion and bug reports

+ +tdb does not currently have its own mailing list or bug tracking +system. For now, please use the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +

Download

+ +You can download the latest release either via rsync or git.
+
+To fetch via git see the following guide:
+Using Git for Samba Development
+Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/tdb directory.
+
+To fetch via rsync use these commands: + +
+  rsync -Pavz samba.org::ftp/unpacked/tdb .
+  rsync -Pavz samba.org::ftp/unpacked/libreplace .
+
+ +and build in tdb. It will find the replace library in the directory +above automatically. + + + diff --git a/nss_wrapper/config.m4 b/nss_wrapper/config.m4 deleted file mode 100644 index 9b86b4dbb8..0000000000 --- a/nss_wrapper/config.m4 +++ /dev/null @@ -1,19 +0,0 @@ -AC_ARG_ENABLE(nss-wrapper, -[ --enable-nss-wrapper Turn on nss wrapper library (default=no)]) - -HAVE_NSS_WRAPPER=no - -if eval "test x$developer = xyes"; then - enable_nss_wrapper=yes -fi - -if eval "test x$enable_nss_wrapper = xyes"; then - AC_DEFINE(NSS_WRAPPER,1,[Use nss wrapper library]) - HAVE_NSS_WRAPPER=yes - - # this is only used for samba3 - NSS_WRAPPER_OBJS="../nss_wrapper/nss_wrapper.o" -fi - -AC_SUBST(HAVE_NSS_WRAPPER) -AC_SUBST(NSS_WRAPPER_OBJS) diff --git a/nss_wrapper/config.mk b/nss_wrapper/config.mk deleted file mode 100644 index 015fbe511c..0000000000 --- a/nss_wrapper/config.mk +++ /dev/null @@ -1,7 +0,0 @@ -############################## -# Start SUBSYSTEM NSS_WRAPPER -[SUBSYSTEM::NSS_WRAPPER] -# End SUBSYSTEM NSS_WRAPPER -############################## - -NSS_WRAPPER_OBJ_FILES = $(nsswrappersrcdir)/nss_wrapper.o diff --git a/nss_wrapper/nss_wrapper.c b/nss_wrapper/nss_wrapper.c deleted file mode 100644 index da090832b0..0000000000 --- a/nss_wrapper/nss_wrapper.c +++ /dev/null @@ -1,1130 +0,0 @@ -/* - * Copyright (C) Stefan Metzmacher 2007 - * - * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. - */ - -#ifdef _SAMBA_BUILD_ - -#define NSS_WRAPPER_NOT_REPLACE -#include "../replace/replace.h" -#include "system/passwd.h" -#include "system/filesys.h" - -#else /* _SAMBA_BUILD_ */ - -#error nss_wrapper_only_supported_in_samba_yet - -#endif - -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif - -/* not all systems have _r functions... */ -#ifndef HAVE_GETPWNAM_R -#define getpwnam_r(name, pwdst, buf, buflen, pwdstp) ENOSYS -#endif -#ifndef HAVE_GETPWUID_R -#define getpwuid_r(uid, pwdst, buf, buflen, pwdstp) ENOSYS -#endif -#ifndef HAVE_GETPWENT_R -#define getpwent_r(pwdst, buf, buflen, pwdstp) ENOSYS -#endif -#ifndef HAVE_GETGRNAM_R -#define getgrnam_r(name, grdst, buf, buflen, grdstp) ENOSYS -#endif -#ifndef HAVE_GETGRUID_R -#define getgrgid_r(uid, grdst, buf, buflen, grdstp) ENOSYS -#endif -#ifndef HAVE_GETGRENT_R -#define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS -#endif - -/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support - * for now */ -#define REWRITE_CALLS - -#ifdef REWRITE_CALLS - -#define real_getpwnam getpwnam -#define real_getpwnam_r getpwnam_r -#define real_getpwuid getpwuid -#define real_getpwuid_r getpwuid_r - -#define real_setpwent setpwent -#define real_getpwent getpwent -#define real_getpwent_r getpwent_r -#define real_endpwent endpwent - -/* -#define real_getgrlst getgrlst -#define real_getgrlst_r getgrlst_r -#define real_initgroups_dyn initgroups_dyn -*/ -#define real_initgroups initgroups - -#define real_getgrnam getgrnam -#define real_getgrnam_r getgrnam_r -#define real_getgrgid getgrgid -#define real_getgrgid_r getgrgid_r - -#define real_setgrent setgrent -#define real_getgrent getgrent -#define real_getgrent_r getgrent_r -#define real_endgrent endgrent - -#endif - -#if 0 -# ifdef DEBUG -# define NWRAP_ERROR(args) DEBUG(0, args) -# else -# define NWRAP_ERROR(args) printf args -# endif -#else -#define NWRAP_ERROR(args) -#endif - -#if 0 -# ifdef DEBUG -# define NWRAP_DEBUG(args) DEBUG(0, args) -# else -# define NWRAP_DEBUG(args) printf args -# endif -#else -#define NWRAP_DEBUG(args) -#endif - -#if 0 -# ifdef DEBUG -# define NWRAP_VERBOSE(args) DEBUG(0, args) -# else -# define NWRAP_VERBOSE(args) printf args -# endif -#else -#define NWRAP_VERBOSE(args) -#endif - -struct nwrap_cache { - const char *path; - int fd; - struct stat st; - uint8_t *buf; - void *private_data; - bool (*parse_line)(struct nwrap_cache *, char *line); - void (*unload)(struct nwrap_cache *); -}; - -struct nwrap_pw { - struct nwrap_cache *cache; - - struct passwd *list; - int num; - int idx; -}; - -struct nwrap_cache __nwrap_cache_pw; -struct nwrap_pw nwrap_pw_global; - -static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line); -static void nwrap_pw_unload(struct nwrap_cache *nwrap); - -struct nwrap_gr { - struct nwrap_cache *cache; - - struct group *list; - int num; - int idx; -}; - -struct nwrap_cache __nwrap_cache_gr; -struct nwrap_gr nwrap_gr_global; - -static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line); -static void nwrap_gr_unload(struct nwrap_cache *nwrap); - -static void nwrap_init(void) -{ - static bool initialized; - - if (initialized) return; - initialized = true; - - nwrap_pw_global.cache = &__nwrap_cache_pw; - - nwrap_pw_global.cache->path = getenv("NSS_WRAPPER_PASSWD"); - nwrap_pw_global.cache->fd = -1; - nwrap_pw_global.cache->private_data = &nwrap_pw_global; - nwrap_pw_global.cache->parse_line = nwrap_pw_parse_line; - nwrap_pw_global.cache->unload = nwrap_pw_unload; - - nwrap_gr_global.cache = &__nwrap_cache_gr; - - nwrap_gr_global.cache->path = getenv("NSS_WRAPPER_GROUP"); - nwrap_gr_global.cache->fd = -1; - nwrap_gr_global.cache->private_data = &nwrap_gr_global; - nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line; - nwrap_gr_global.cache->unload = nwrap_gr_unload; -} - -static bool nwrap_enabled(void) -{ - nwrap_init(); - - if (!nwrap_pw_global.cache->path) { - return false; - } - if (nwrap_pw_global.cache->path[0] == '\0') { - return false; - } - if (!nwrap_gr_global.cache->path) { - return false; - } - if (nwrap_gr_global.cache->path[0] == '\0') { - return false; - } - - return true; -} - -static bool nwrap_parse_file(struct nwrap_cache *nwrap) -{ - int ret; - uint8_t *buf = NULL; - char *nline; - - if (nwrap->st.st_size == 0) { - NWRAP_DEBUG(("%s: size == 0\n", - __location__)); - goto done; - } - - if (nwrap->st.st_size > INT32_MAX) { - NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n", - __location__, (unsigned)nwrap->st.st_size)); - goto failed; - } - - ret = lseek(nwrap->fd, 0, SEEK_SET); - if (ret != 0) { - NWRAP_ERROR(("%s: lseek - %d\n",__location__,ret)); - goto failed; - } - - buf = (uint8_t *)malloc(nwrap->st.st_size + 1); - if (!buf) { - NWRAP_ERROR(("%s: malloc failed\n",__location__)); - goto failed; - } - - ret = read(nwrap->fd, buf, nwrap->st.st_size); - if (ret != nwrap->st.st_size) { - NWRAP_ERROR(("%s: read(%u) gave %d\n", - __location__, (unsigned)nwrap->st.st_size, ret)); - goto failed; - } - - buf[nwrap->st.st_size] = '\0'; - - nline = (char *)buf; - while (nline && nline[0]) { - char *line; - char *e; - bool ok; - - line = nline; - nline = NULL; - - e = strchr(line, '\n'); - if (e) { - e[0] = '\0'; - e++; - if (e[0] == '\r') { - e[0] = '\0'; - e++; - } - nline = e; - } - - NWRAP_VERBOSE(("%s:'%s'\n",__location__, line)); - - if (strlen(line) == 0) { - continue; - } - - ok = nwrap->parse_line(nwrap, line); - if (!ok) { - goto failed; - } - } - -done: - nwrap->buf = buf; - return true; - -failed: - if (buf) free(buf); - return false; -} - -static void nwrap_cache_unload(struct nwrap_cache *nwrap) -{ - nwrap->unload(nwrap); - - if (nwrap->buf) free(nwrap->buf); - - nwrap->buf = NULL; -} - -static void nwrap_cache_reload(struct nwrap_cache *nwrap) -{ - struct stat st; - int ret; - bool ok; - bool retried = false; - -reopen: - if (nwrap->fd < 0) { - nwrap->fd = open(nwrap->path, O_RDONLY); - if (nwrap->fd < 0) { - NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n", - __location__, - nwrap->path, nwrap->fd, - strerror(errno))); - return; - } - NWRAP_VERBOSE(("%s: open '%s'\n", __location__, nwrap->path)); - } - - ret = fstat(nwrap->fd, &st); - if (ret != 0) { - NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n", - __location__, - nwrap->path, - ret, strerror(errno))); - return; - } - - if (retried == false && st.st_nlink == 0) { - /* maybe someone has replaced the file... */ - NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n", - __location__, nwrap->path)); - retried = true; - memset(&nwrap->st, 0, sizeof(nwrap->st)); - close(nwrap->fd); - nwrap->fd = -1; - goto reopen; - } - - if (st.st_mtime == nwrap->st.st_mtime) { - NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n", - __location__, (unsigned)st.st_mtime)); - return; - } - NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n", - __location__, (unsigned)st.st_mtime, - (unsigned)nwrap->st.st_mtime)); - - nwrap->st = st; - - nwrap_cache_unload(nwrap); - - ok = nwrap_parse_file(nwrap); - if (!ok) { - NWRAP_ERROR(("%s: failed to reload %s\n", - __location__, nwrap->path)); - nwrap_cache_unload(nwrap); - } - NWRAP_DEBUG(("%s: reloaded %s\n", - __location__, nwrap->path)); -} - -/* - * the caller has to call nwrap_unload() on failure - */ -static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line) -{ - struct nwrap_pw *nwrap_pw; - char *c; - char *p; - char *e; - struct passwd *pw; - size_t list_size; - - nwrap_pw = (struct nwrap_pw *)nwrap->private_data; - - list_size = sizeof(*nwrap_pw->list) * (nwrap_pw->num+1); - pw = (struct passwd *)realloc(nwrap_pw->list, list_size); - if (!pw) { - NWRAP_ERROR(("%s:realloc(%u) failed\n", - __location__, list_size)); - return false; - } - nwrap_pw->list = pw; - - pw = &nwrap_pw->list[nwrap_pw->num]; - - c = line; - - /* name */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - pw->pw_name = c; - c = p; - - NWRAP_VERBOSE(("name[%s]\n", pw->pw_name)); - - /* password */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - pw->pw_passwd = c; - c = p; - - NWRAP_VERBOSE(("password[%s]\n", pw->pw_passwd)); - - /* uid */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - e = NULL; - pw->pw_uid = (uid_t)strtoul(c, &e, 10); - if (c == e) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - if (e == NULL) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - if (e[0] != '\0') { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - c = p; - - NWRAP_VERBOSE(("uid[%u]\n", pw->pw_uid)); - - /* gid */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - e = NULL; - pw->pw_gid = (gid_t)strtoul(c, &e, 10); - if (c == e) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - if (e == NULL) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - if (e[0] != '\0') { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - c = p; - - NWRAP_VERBOSE(("gid[%u]\n", pw->pw_gid)); - - /* gecos */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - pw->pw_gecos = c; - c = p; - - NWRAP_VERBOSE(("gecos[%s]\n", pw->pw_gecos)); - - /* dir */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:'%s'\n",__location__,c)); - return false; - } - *p = '\0'; - p++; - pw->pw_dir = c; - c = p; - - NWRAP_VERBOSE(("dir[%s]\n", pw->pw_dir)); - - /* shell */ - pw->pw_shell = c; - NWRAP_VERBOSE(("shell[%s]\n", pw->pw_shell)); - - NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n", - pw->pw_name, pw->pw_passwd, - pw->pw_uid, pw->pw_gid, - pw->pw_gecos, pw->pw_dir, pw->pw_shell)); - - nwrap_pw->num++; - return true; -} - -static void nwrap_pw_unload(struct nwrap_cache *nwrap) -{ - struct nwrap_pw *nwrap_pw; - nwrap_pw = (struct nwrap_pw *)nwrap->private_data; - - if (nwrap_pw->list) free(nwrap_pw->list); - - nwrap_pw->list = NULL; - nwrap_pw->num = 0; - nwrap_pw->idx = 0; -} - -static int nwrap_pw_copy_r(const struct passwd *src, struct passwd *dst, - char *buf, size_t buflen, struct passwd **dstp) -{ - char *first; - char *last; - off_t ofs; - - first = src->pw_name; - - last = src->pw_shell; - while (*last) last++; - - ofs = PTR_DIFF(last + 1, first); - - if (ofs > buflen) { - return ERANGE; - } - - memcpy(buf, first, ofs); - - ofs = PTR_DIFF(src->pw_name, first); - dst->pw_name = buf + ofs; - ofs = PTR_DIFF(src->pw_passwd, first); - dst->pw_passwd = buf + ofs; - dst->pw_uid = src->pw_uid; - dst->pw_gid = src->pw_gid; - ofs = PTR_DIFF(src->pw_gecos, first); - dst->pw_gecos = buf + ofs; - ofs = PTR_DIFF(src->pw_dir, first); - dst->pw_dir = buf + ofs; - ofs = PTR_DIFF(src->pw_shell, first); - dst->pw_shell = buf + ofs; - - if (dstp) { - *dstp = dst; - } - - return 0; -} - -/* - * the caller has to call nwrap_unload() on failure - */ -static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line) -{ - struct nwrap_gr *nwrap_gr; - char *c; - char *p; - char *e; - struct group *gr; - size_t list_size; - unsigned nummem; - - nwrap_gr = (struct nwrap_gr *)nwrap->private_data; - - list_size = sizeof(*nwrap_gr->list) * (nwrap_gr->num+1); - gr = (struct group *)realloc(nwrap_gr->list, list_size); - if (!gr) { - NWRAP_ERROR(("%s:realloc failed\n",__location__)); - return false; - } - nwrap_gr->list = gr; - - gr = &nwrap_gr->list[nwrap_gr->num]; - - c = line; - - /* name */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - gr->gr_name = c; - c = p; - - NWRAP_VERBOSE(("name[%s]\n", gr->gr_name)); - - /* password */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - gr->gr_passwd = c; - c = p; - - NWRAP_VERBOSE(("password[%s]\n", gr->gr_passwd)); - - /* gid */ - p = strchr(c, ':'); - if (!p) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n", - __location__, line, c)); - return false; - } - *p = '\0'; - p++; - e = NULL; - gr->gr_gid = (gid_t)strtoul(c, &e, 10); - if (c == e) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - if (e == NULL) { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - if (e[0] != '\0') { - NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n", - __location__, line, c, strerror(errno))); - return false; - } - c = p; - - NWRAP_VERBOSE(("gid[%u]\n", gr->gr_gid)); - - /* members */ - gr->gr_mem = (char **)malloc(sizeof(char *)); - if (!gr->gr_mem) { - NWRAP_ERROR(("%s:calloc failed\n",__location__)); - return false; - } - gr->gr_mem[0] = NULL; - - for(nummem=0; p; nummem++) { - char **m; - size_t m_size; - c = p; - p = strchr(c, ','); - if (p) { - *p = '\0'; - p++; - } - - if (strlen(c) == 0) { - break; - } - - m_size = sizeof(char *) * (nummem+2); - m = (char **)realloc(gr->gr_mem, m_size); - if (!m) { - NWRAP_ERROR(("%s:realloc(%u) failed\n", - __location__, m_size)); - return false; - } - gr->gr_mem = m; - gr->gr_mem[nummem] = c; - gr->gr_mem[nummem+1] = NULL; - - NWRAP_VERBOSE(("member[%u]: '%s'\n", nummem, gr->gr_mem[nummem])); - } - - NWRAP_DEBUG(("add group[%s:%s:%u:] with %u members\n", - gr->gr_name, gr->gr_passwd, gr->gr_gid, nummem)); - - nwrap_gr->num++; - return true; -} - -static void nwrap_gr_unload(struct nwrap_cache *nwrap) -{ - int i; - struct nwrap_gr *nwrap_gr; - nwrap_gr = (struct nwrap_gr *)nwrap->private_data; - - if (nwrap_gr->list) { - for (i=0; i < nwrap_gr->num; i++) { - if (nwrap_gr->list[i].gr_mem) { - free(nwrap_gr->list[i].gr_mem); - } - } - free(nwrap_gr->list); - } - - nwrap_gr->list = NULL; - nwrap_gr->num = 0; - nwrap_gr->idx = 0; -} - -static int nwrap_gr_copy_r(const struct group *src, struct group *dst, - char *buf, size_t buflen, struct group **dstp) -{ - char *first; - char **lastm; - char *last; - off_t ofsb; - off_t ofsm; - off_t ofs; - unsigned i; - - first = src->gr_name; - - lastm = src->gr_mem; - while (*lastm) lastm++; - - last = *lastm; - while (*last) last++; - - ofsb = PTR_DIFF(last + 1, first); - ofsm = PTR_DIFF(lastm + 1, src->gr_mem); - - if ((ofsb + ofsm) > buflen) { - return ERANGE; - } - - memcpy(buf, first, ofsb); - memcpy(buf + ofsb, src->gr_mem, ofsm); - - ofs = PTR_DIFF(src->gr_name, first); - dst->gr_name = buf + ofs; - ofs = PTR_DIFF(src->gr_passwd, first); - dst->gr_passwd = buf + ofs; - dst->gr_gid = src->gr_gid; - - dst->gr_mem = (char **)(buf + ofsb); - for (i=0; src->gr_mem[i]; i++) { - ofs = PTR_DIFF(src->gr_mem[i], first); - dst->gr_mem[i] = buf + ofs; - } - - if (dstp) { - *dstp = dst; - } - - return 0; -} - -/* user functions */ -_PUBLIC_ struct passwd *nwrap_getpwnam(const char *name) -{ - int i; - - if (!nwrap_enabled()) { - return real_getpwnam(name); - } - - nwrap_cache_reload(nwrap_pw_global.cache); - - for (i=0; i= nwrap_pw_global.num) { - errno = ENOENT; - return NULL; - } - - pw = &nwrap_pw_global.list[nwrap_pw_global.idx++]; - - NWRAP_VERBOSE(("%s: return user[%s] uid[%u]\n", - __location__, pw->pw_name, pw->pw_uid)); - - return pw; -} - -_PUBLIC_ int nwrap_getpwent_r(struct passwd *pwdst, char *buf, - size_t buflen, struct passwd **pwdstp) -{ - struct passwd *pw; - - if (!nwrap_enabled()) { -#ifdef SOLARIS_GETPWENT_R - pw = real_getpwent_r(pwdst, buf, buflen); - if (!pw) { - if (errno == 0) { - return ENOENT; - } - return errno; - } - if (pwdstp) { - *pwdstp = pw; - } - return 0; -#else - return real_getpwent_r(pwdst, buf, buflen, pwdstp); -#endif - } - - pw = nwrap_getpwent(); - if (!pw) { - if (errno == 0) { - return ENOENT; - } - return errno; - } - - return nwrap_pw_copy_r(pw, pwdst, buf, buflen, pwdstp); -} - -_PUBLIC_ void nwrap_endpwent(void) -{ - if (!nwrap_enabled()) { - real_endpwent(); - } - - nwrap_pw_global.idx = 0; -} - -/* misc functions */ -_PUBLIC_ int nwrap_initgroups(const char *user, gid_t group) -{ - if (!nwrap_enabled()) { - return real_initgroups(user, group); - } - - /* TODO: maybe we should also fake this... */ - return EPERM; -} - -/* group functions */ -_PUBLIC_ struct group *nwrap_getgrnam(const char *name) -{ - int i; - - if (!nwrap_enabled()) { - return real_getgrnam(name); - } - - nwrap_cache_reload(nwrap_gr_global.cache); - - for (i=0; i= nwrap_gr_global.num) { - errno = ENOENT; - return NULL; - } - - gr = &nwrap_gr_global.list[nwrap_gr_global.idx++]; - - NWRAP_VERBOSE(("%s: return group[%s] gid[%u]\n", - __location__, gr->gr_name, gr->gr_gid)); - - return gr; -} - -_PUBLIC_ int nwrap_getgrent_r(struct group *grdst, char *buf, - size_t buflen, struct group **grdstp) -{ - struct group *gr; - - if (!nwrap_enabled()) { -#ifdef SOLARIS_GETGRENT_R - gr = real_getgrent_r(grdst, buf, buflen); - if (!gr) { - if (errno == 0) { - return ENOENT; - } - return errno; - } - if (grdstp) { - *grdstp = gr; - } - return 0; -#else - return real_getgrent_r(grdst, buf, buflen, grdstp); -#endif - } - - gr = nwrap_getgrent(); - if (!gr) { - if (errno == 0) { - return ENOENT; - } - return errno; - } - - return nwrap_gr_copy_r(gr, grdst, buf, buflen, grdstp); -} - -_PUBLIC_ void nwrap_endgrent(void) -{ - if (!nwrap_enabled()) { - real_endgrent(); - } - - nwrap_gr_global.idx = 0; -} diff --git a/nss_wrapper/nss_wrapper.h b/nss_wrapper/nss_wrapper.h deleted file mode 100644 index 35a47348a8..0000000000 --- a/nss_wrapper/nss_wrapper.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) Stefan Metzmacher 2007 - * - * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. - */ - -#ifndef __NSS_WRAPPER_H__ -#define __NSS_WRAPPER_H__ - -struct passwd *nwrap_getpwnam(const char *name); -int nwrap_getpwnam_r(const char *name, struct passwd *pwbuf, - char *buf, size_t buflen, struct passwd **pwbufp); -struct passwd *nwrap_getpwuid(uid_t uid); -int nwrap_getpwuid_r(uid_t uid, struct passwd *pwbuf, - char *buf, size_t buflen, struct passwd **pwbufp); -void nwrap_setpwent(void); -struct passwd *nwrap_getpwent(void); -int nwrap_getpwent_r(struct passwd *pwbuf, char *buf, - size_t buflen, struct passwd **pwbufp); -void nwrap_endpwent(void); -int nwrap_initgroups(const char *user, gid_t group); -struct group *nwrap_getgrnam(const char *name); -int nwrap_getgrnam_r(const char *name, struct group *gbuf, - char *buf, size_t buflen, struct group **gbufp); -struct group *nwrap_getgrgid(gid_t gid); -int nwrap_getgrgid_r(gid_t gid, struct group *gbuf, - char *buf, size_t buflen, struct group **gbufp); -void nwrap_setgrent(void); -struct group *nwrap_getgrent(void); -int nwrap_getgrent_r(struct group *gbuf, char *buf, - size_t buflen, struct group **gbufp); -void nwrap_endgrent(void); - -#ifdef NSS_WRAPPER_REPLACE - -#ifdef getpwnam -#undef getpwnam -#endif -#define getpwnam nwrap_getpwnam - -#ifdef getpwnam_r -#undef getpwnam_r -#endif -#define getpwnam_r nwrap_getpwnam_r - -#ifdef getpwuid -#undef getpwuid -#endif -#define getpwuid nwrap_getpwuid - -#ifdef getpwuid_r -#undef getpwuid_r -#endif -#define getpwuid_r nwrap_getpwuid_r - -#ifdef setpwent -#undef setpwent -#endif -#define setpwent nwrap_setpwent - -#ifdef getpwent -#undef getpwent -#endif -#define getpwent nwrap_getpwent - -#ifdef getpwent_r -#undef getpwent_r -#endif -#define getpwent_r nwrap_getpwent_r - -#ifdef endpwent -#undef endpwent -#endif -#define endpwent nwrap_endpwent - -#ifdef getgrlst -#undef getgrlst -#endif -#define getgrlst __none_nwrap_getgrlst - -#ifdef getgrlst_r -#undef getgrlst_r -#endif -#define getgrlst_r __none_nwrap_getgrlst_r - -#ifdef initgroups_dyn -#undef initgroups_dyn -#endif -#define initgroups_dyn __none_nwrap_initgroups_dyn - -#ifdef initgroups -#undef initgroups -#endif -#define initgroups nwrap_initgroups - -#ifdef getgrnam -#undef getgrnam -#endif -#define getgrnam nwrap_getgrnam - -#ifdef getgrnam_r -#undef getgrnam_r -#endif -#define getgrnam_r nwrap_getgrnam_r - -#ifdef getgrgid -#undef getgrgid -#endif -#define getgrgid nwrap_getgrgid - -#ifdef getgrgid_r -#undef getgrgid_r -#endif -#define getgrgid_r nwrap_getgrgid_r - -#ifdef setgrent -#undef setgrent -#endif -#define setgrent nwrap_setgrent - -#ifdef getgrent -#undef getgrent -#endif -#define getgrent nwrap_getgrent - -#ifdef getgrent_r -#undef getgrent_r -#endif -#define getgrent_r nwrap_getgrent_r - -#ifdef endgrent -#undef endgrent -#endif -#define endgrent nwrap_endgrent - -#endif /* NSS_WRAPPER_REPLACE */ - -#endif /* __NSS_WRAPPER_H__ */ diff --git a/nss_wrapper/nss_wrapper.pl b/nss_wrapper/nss_wrapper.pl deleted file mode 100644 index b1c9be5365..0000000000 --- a/nss_wrapper/nss_wrapper.pl +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/perl -# - -use strict; - -use Getopt::Long; -use Cwd qw(abs_path); - -my $opt_help = 0; -my $opt_path = undef; -my $opt_action = undef; -my $opt_type = undef; -my $opt_name = undef; - -my $passwdfn = undef; -my $groupfn = undef; -my $actionfn = undef; - -sub passwd_add($$); -sub passwd_delete($$); -sub group_add($$); -sub group_delete($$); - -my $result = GetOptions( - 'help|h|?' => \$opt_help, - 'path=s' => \$opt_path, - 'action=s' => \$opt_action, - 'type=s' => \$opt_type, - 'name=s' => \$opt_name -); - -sub usage($;$) -{ - my ($ret, $msg) = @_; - - print $msg."\n\n" if defined($msg); - - print "usage: - - --help|-h|-? Show this help. - - --path Path of the 'passwd' or 'group' file. - - --type Only 'passwd' is supported yet, - but 'group' and maybe 'member' will be added - in future. - - --action 'add' or 'delete'. - - --name The name of the object. -"; - exit($ret); -} - -usage(1) if (not $result); - -usage(0) if ($opt_help); - -if (not defined($opt_path)) { - usage(1, "missing: --path "); -} -if ($opt_path eq "" or $opt_path eq "/") { - usage(1, "invalid: --path : '$opt_path'"); -} -my $opt_fullpath = abs_path($opt_path); -if (not defined($opt_fullpath)) { - usage(1, "invalid: --path : '$opt_path'"); -} - - -if (not defined($opt_action)) { - usage(1, "missing: --action [add|delete]"); -} -if ($opt_action eq "add") { - $passwdfn = \&passwd_add; - $groupfn = \&group_add; -} elsif ($opt_action eq "delete") { - $passwdfn = \&passwd_delete; - $groupfn = \&group_delete; -} else { - usage(1, "invalid: --action [add|delete]: '$opt_action'"); -} - -if (not defined($opt_type)) { - usage(1, "missing: --type [passwd|group]"); -} -if ($opt_type eq "passwd") { - $actionfn = $passwdfn; -} elsif ($opt_type eq "group") { - $actionfn = $groupfn; -} else { - usage(1, "invalid: --type [passwd|group]: '$opt_type'") -} - -if (not defined($opt_name)) { - usage(1, "missing: --name "); -} -if ($opt_name eq "") { - usage(1, "invalid: --name "); -} - -exit $actionfn->($opt_fullpath, $opt_name); - -sub passwd_add_entry($$); - -sub passwd_load($) -{ - my ($path) = @_; - my @lines; - my $passwd = undef; - - open(PWD, "<$path") or die("Unable to open '$path' for read"); - @lines = ; - close(PWD); - - $passwd->{array} = (); - $passwd->{name} = {}; - $passwd->{uid} = {}; - $passwd->{path} = $path; - - foreach my $line (@lines) { - passwd_add_entry($passwd, $line); - } - - return $passwd; -} - -sub passwd_lookup_name($$) -{ - my ($passwd, $name) = @_; - - return undef unless defined($passwd->{name}{$name}); - - return $passwd->{name}{$name}; -} - -sub passwd_lookup_uid($$) -{ - my ($passwd, $uid) = @_; - - return undef unless defined($passwd->{uid}{$uid}); - - return $passwd->{uid}{$uid}; -} - -sub passwd_get_free_uid($) -{ - my ($passwd) = @_; - my $uid = 1000; - - while (passwd_lookup_uid($passwd, $uid)) { - $uid++; - } - - return $uid; -} - -sub passwd_add_entry($$) -{ - my ($passwd, $str) = @_; - - chomp $str; - my @e = split(':', $str); - - push(@{$passwd->{array}}, \@e); - $passwd->{name}{$e[0]} = \@e; - $passwd->{uid}{$e[2]} = \@e; -} - -sub passwd_remove_entry($$) -{ - my ($passwd, $eref) = @_; - - for(my $i; defined($passwd->{array}[$i]); $i++) { - if ($eref == $passwd->{array}[$i]) { - $passwd->{array}[$i] = undef; - } - } - - delete $passwd->{name}{${$eref}[0]}; - delete $passwd->{uid}{${$eref}[2]}; -} - -sub passwd_save($) -{ - my ($passwd) = @_; - my @lines = (); - my $path = $passwd->{path}; - my $tmppath = $path.$$; - - foreach my $eref (@{$passwd->{array}}) { - next unless defined($eref); - - my $line = join(':', @{$eref}); - push(@lines, $line); - } - - open(PWD, ">$tmppath") or die("Unable to open '$tmppath' for write"); - print PWD join("\n", @lines)."\n"; - close(PWD); - rename($tmppath, $path) or die("Unable to rename $tmppath => $path"); -} - -sub passwd_add($$) -{ - my ($path, $name) = @_; - - #print "passwd_add: '$name' in '$path'\n"; - - my $passwd = passwd_load($path); - - my $e = passwd_lookup_name($passwd, $name); - die("account[$name] already exists in '$path'") if defined($e); - - my $uid = passwd_get_free_uid($passwd); - my $gid = 65534;# nogroup gid - - my $pwent = $name.":x:".$uid.":".$gid.":".$name." gecos:/nodir:/bin/false"; - - passwd_add_entry($passwd, $pwent); - - passwd_save($passwd); - - return 0; -} - -sub passwd_delete($$) -{ - my ($path, $name) = @_; - - #print "passwd_delete: '$name' in '$path'\n"; - - my $passwd = passwd_load($path); - - my $e = passwd_lookup_name($passwd, $name); - die("account[$name] does not exists in '$path'") unless defined($e); - - passwd_remove_entry($passwd, $e); - - passwd_save($passwd); - - return 0; -} - -sub group_add($$) -{ - my ($path, $name) = @_; - - #print "group_add: '$name' in '$path'\n"; - - die("group_add: not implemented yet!"); - - return 0; -} - -sub group_delete($$) -{ - my ($path, $name) = @_; - - #print "group_delete: '$name' in '$path'\n"; - - die("group_delete: not implemented yet!"); - - return 0; -} diff --git a/popt/CHANGES b/popt/CHANGES deleted file mode 100644 index db16a5fdd0..0000000000 --- a/popt/CHANGES +++ /dev/null @@ -1,46 +0,0 @@ -1.5 -> 1.6 - - add ability to perform callbacks for every, not just first, match. - -1.3 -> 1.5 - - heavy dose of const's - - poptParseArgvString() now NULL terminates the list - -1.2.3 -> 1.3 - - added support for single - - - misc bug fixes - - portability improvements - -1.2.2 -> 1.2.3 - - fixed memset() in help message generation (Dale Hawkins) - - added extern "C" stuff to popt.h for C++ compilers (Dale Hawkins) - - const'ified poptParseArgvString (Jeff Garzik) - -1.2.1 -> 1.2.2 - - fixed bug in chaind alias happens which seems to have only - affected --triggers in rpm - - added POPT_ARG_VAL - - popt.3 installed by default - -1.2 -> 1.2.1 - - added POPT_ARG_INTL_DOMAIN (Elliot Lee) - - updated Makefile's to be more GNUish (Elliot Lee) - -1.1 -> 1.2 - - added popt.3 man page (Robert Lynch) - - don't use mmap anymore (its lack of portability isn't worth the - trouble) - - added test script - - added support for exec - - removed support for *_POPT_ALIASES env variable -- it was a bad - idea - - reorganized into multiple source files - - added automatic help generation, POPT_AUTOHELP - - added table callbacks - - added table inclusion - - updated man page for new features - - added test scripts - -1.0 -> 1.1 - - moved to autoconf (Fred Fish) - - added STRERROR replacement (Norbert Warmuth) - - added const keywords (Bruce Perens) diff --git a/popt/COPYING b/popt/COPYING deleted file mode 100644 index b4c7ca876c..0000000000 --- a/popt/COPYING +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 1998 Red Hat Software - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in 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: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -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 -X CONSORTIUM 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. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. diff --git a/popt/README b/popt/README deleted file mode 100644 index 0b5205bfdd..0000000000 --- a/popt/README +++ /dev/null @@ -1,18 +0,0 @@ -This is the popt command line option parsing library. While it is similiar -to getopt(3), it contains a number of enhancements, including: - - 1) popt is fully reentrant - 2) popt can parse arbitrary argv[] style arrays while - getopt(2) makes this quite difficult - 3) popt allows users to alias command line arguments - 4) popt provides convience functions for parsing strings - into argv[] style arrays - -popt is used by rpm, the Red Hat install program, and many other Red Hat -utilities, all of which provide excellent examples of how to use popt. -Complete documentation on popt is available in popt.ps (included in this -tarball), which is excerpted with permission from the book "Linux -Application Development" by Michael K. Johnson and Erik Troan (availble -from Addison Wesley in May, 1998). - -Comments on popt should be addressed to ewt@redhat.com. diff --git a/popt/config.mk b/popt/config.mk deleted file mode 100644 index 04cc2c7ea5..0000000000 --- a/popt/config.mk +++ /dev/null @@ -1,5 +0,0 @@ -[SUBSYSTEM::LIBPOPT] -CFLAGS = -I$(poptsrcdir) - -LIBPOPT_OBJ_FILES = $(addprefix $(poptsrcdir)/, findme.o popt.o poptconfig.o popthelp.o poptparse.o) - diff --git a/popt/dummy.in b/popt/dummy.in deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/popt/findme.c b/popt/findme.c deleted file mode 100644 index b28981ba1f..0000000000 --- a/popt/findme.c +++ /dev/null @@ -1,50 +0,0 @@ -/** \ingroup popt - * \file popt/findme.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" -#include "findme.h" - -const char * findProgramPath(const char * argv0) { - char * path = getenv("PATH"); - char * pathbuf; - char * start, * chptr; - char * buf; - - if (argv0 == NULL) return NULL; /* XXX can't happen */ - /* If there is a / in the argv[0], it has to be an absolute path */ - if (strchr(argv0, '/')) - return xstrdup(argv0); - - if (path == NULL) return NULL; - - start = pathbuf = (char *)alloca(strlen(path) + 1); - buf = (char *)malloc(strlen(path) + strlen(argv0) + sizeof("/")); - if (buf == NULL) return NULL; /* XXX can't happen */ - strcpy(pathbuf, path); - - chptr = NULL; - /*@-branchstate@*/ - do { - if ((chptr = strchr(start, ':'))) - *chptr = '\0'; - sprintf(buf, "%s/%s", start, argv0); - - if (!access(buf, X_OK)) - return buf; - - if (chptr) - start = chptr + 1; - else - start = NULL; - } while (start && *start); - /*@=branchstate@*/ - - free(buf); - - return NULL; -} diff --git a/popt/findme.h b/popt/findme.h deleted file mode 100644 index a016b867ea..0000000000 --- a/popt/findme.h +++ /dev/null @@ -1,20 +0,0 @@ -/** \ingroup popt - * \file popt/findme.h - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_FINDME -#define H_FINDME - -/** - * Return absolute path to executable by searching PATH. - * @param argv0 name of executable - * @return (malloc'd) absolute path to executable (or NULL) - */ -/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0) - /*@*/; - -#endif diff --git a/popt/libpopt.m4 b/popt/libpopt.m4 deleted file mode 100644 index 79980d1d6b..0000000000 --- a/popt/libpopt.m4 +++ /dev/null @@ -1,43 +0,0 @@ -dnl Check to see if we should use the included popt - -INCLUDED_POPT=auto -AC_ARG_WITH(included-popt, -[ --with-included-popt use bundled popt library, not from system], -[ INCLUDED_POPT=$withval ]) - -AC_SUBST(POPT_LIBS) -AC_SUBST(POPT_CFLAGS) - -if test x"$INCLUDED_POPT" != x"yes"; then - AC_CHECK_HEADERS(popt.h) - AC_CHECK_LIB(popt, poptGetContext, [ POPT_LIBS="-lpopt" ]) - if test x"$ac_cv_header_popt_h" = x"no" -o x"$ac_cv_lib_popt_poptGetContext" = x"no"; then - INCLUDED_POPT=yes - POPT_CFLAGS="" - else - INCLUDED_POPT=no - fi -fi - -AC_MSG_CHECKING(whether to use included popt) -AC_MSG_RESULT($INCLUDED_POPT) -if test x"$INCLUDED_POPT" != x"no"; then - dnl find the popt sources. This is meant to work both for - dnl popt standalone builds, and builds of packages using popt - poptdir="" - poptpaths="$srcdir $srcdir/lib/popt $srcdir/popt $srcdir/../popt" - for d in $poptpaths; do - if test -f "$d/popt.c"; then - poptdir="$d" - POPT_CFLAGS="-I$d" - AC_SUBST(poptdir) - break - fi - done - if test x"$poptdir" = "x"; then - AC_MSG_ERROR([cannot find popt source in $poptpaths]) - fi - POPT_OBJ="popt.o findme.o poptconfig.o popthelp.o poptparse.o" - AC_SUBST(POPT_OBJ) - AC_CHECK_HEADERS([float.h alloca.h]) -fi diff --git a/popt/popt.c b/popt/popt.c deleted file mode 100644 index d9e8411b9f..0000000000 --- a/popt/popt.c +++ /dev/null @@ -1,1249 +0,0 @@ -/** \ingroup popt - * \file popt/popt.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist */ - -#undef MYDEBUG - -#include "system.h" - -#if HAVE_FLOAT_H -#include -#endif -#include - -#include "findme.h" -#include "poptint.h" - -#ifdef MYDEBUG -/*@unchecked@*/ -int _popt_debug = 0; -#endif - -#ifndef HAVE_STRERROR -static char * strerror(int errno) { - extern int sys_nerr; - extern char * sys_errlist[]; - - if ((0 <= errno) && (errno < sys_nerr)) - return sys_errlist[errno]; - else - return POPT_("unknown errno"); -} -#endif - -#ifdef MYDEBUG -/*@unused@*/ static void prtcon(const char *msg, poptContext con) -{ - if (msg) fprintf(stderr, "%s", msg); - fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n", - con, con->os, - (con->os->nextCharArg ? con->os->nextCharArg : ""), - (con->os->nextArg ? con->os->nextArg : ""), - con->os->next, - (con->os->argv && con->os->argv[con->os->next] - ? con->os->argv[con->os->next] : "")); -} -#endif - -void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) -{ - con->execPath = (const char *)_free(con->execPath); - con->execPath = xstrdup(path); - con->execAbsolute = allowAbsolute; - /*@-nullstate@*/ /* LCL: con->execPath can be NULL? */ - return; - /*@=nullstate@*/ -} - -static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - if (opt->arg == NULL) continue; /* XXX program error. */ - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - /* Recurse on included sub-tables. */ - invokeCallbacksPRE(con, (const struct poptOption *)opt->arg); - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && - (opt->argInfo & POPT_CBFLAG_PRE)) - { /*@-castfcnptr@*/ - poptCallbackType cb = (poptCallbackType)opt->arg; - /*@=castfcnptr@*/ - /* Perform callback. */ - /*@-moduncon -noeffectuncon @*/ - cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip); - /*@=moduncon =noeffectuncon @*/ - } - } -} - -static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - if (opt->arg == NULL) continue; /* XXX program error. */ - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - /* Recurse on included sub-tables. */ - invokeCallbacksPOST(con, (const struct poptOption *)opt->arg); - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && - (opt->argInfo & POPT_CBFLAG_POST)) - { /*@-castfcnptr@*/ - poptCallbackType cb = (poptCallbackType)opt->arg; - /*@=castfcnptr@*/ - /* Perform callback. */ - /*@-moduncon -noeffectuncon @*/ - cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip); - /*@=moduncon =noeffectuncon @*/ - } - } -} - -static void invokeCallbacksOPTION(poptContext con, - const struct poptOption * opt, - const struct poptOption * myOpt, - /*@null@*/ const void * myData, int shorty) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - const struct poptOption * cbopt = NULL; - - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - /* Recurse on included sub-tables. */ - if (opt->arg != NULL) /* XXX program error */ - invokeCallbacksOPTION(con, (const struct poptOption *)opt->arg, - myOpt, myData, shorty); - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK && - !(opt->argInfo & POPT_CBFLAG_SKIPOPTION)) { - /* Save callback info. */ - cbopt = opt; - } else if (cbopt != NULL && - ((myOpt->shortName && opt->shortName && shorty && - myOpt->shortName == opt->shortName) || - (myOpt->longName && opt->longName && - /*@-nullpass@*/ /* LCL: opt->longName != NULL */ - !strcmp(myOpt->longName, opt->longName))) - /*@=nullpass@*/ - ) - { /*@-castfcnptr@*/ - poptCallbackType cb = (poptCallbackType)cbopt->arg; - /*@=castfcnptr@*/ - const void * cbData = (cbopt->descrip ? cbopt->descrip : myData); - /* Perform callback. */ - if (cb != NULL) { /* XXX program error */ - /*@-moduncon -noeffectuncon @*/ - cb(con, POPT_CALLBACK_REASON_OPTION, myOpt, - con->os->nextArg, cbData); - /*@=moduncon =noeffectuncon @*/ - } - /* Terminate (unless explcitly continuing). */ - if (!(cbopt->argInfo & POPT_CBFLAG_CONTINUE)) - return; - } - } -} - -poptContext poptGetContext(const char * name, int argc, const char ** argv, - const struct poptOption * options, int flags) -{ - poptContext con = (poptContext)malloc(sizeof(*con)); - - if (con == NULL) return NULL; /* XXX can't happen */ - memset(con, 0, sizeof(*con)); - - con->os = con->optionStack; - con->os->argc = argc; - /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ - con->os->argv = argv; - /*@=dependenttrans =assignexpose@*/ - con->os->argb = NULL; - - if (!(flags & POPT_CONTEXT_KEEP_FIRST)) - con->os->next = 1; /* skip argv[0] */ - - con->leftovers = (const char **)calloc( (argc + 1), - sizeof(*con->leftovers) ); - /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ - con->options = options; - /*@=dependenttrans =assignexpose@*/ - con->aliases = NULL; - con->numAliases = 0; - con->flags = flags; - con->execs = NULL; - con->numExecs = 0; - con->finalArgvAlloced = argc * 2; - con->finalArgv = (const char **)calloc( con->finalArgvAlloced, - sizeof(*con->finalArgv) ); - con->execAbsolute = 1; - con->arg_strip = NULL; - - if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) - con->flags |= POPT_CONTEXT_POSIXMEHARDER; - - if (name) { - char * t = (char *)malloc(strlen(name) + 1); - if (t) con->appName = strcpy(t, name); - } - - /*@-internalglobs@*/ - invokeCallbacksPRE(con, con->options); - /*@=internalglobs@*/ - - return con; -} - -static void cleanOSE(/*@special@*/ struct optionStackEntry *os) - /*@uses os @*/ - /*@releases os->nextArg, os->argv, os->argb @*/ - /*@modifies os @*/ -{ - os->nextArg = (const char *)_free(os->nextArg); - os->argv = (const char **)_free(os->argv); - os->argb = (pbm_set *)PBM_FREE(os->argb); -} - -/*@-boundswrite@*/ -void poptResetContext(poptContext con) -{ - int i; - - if (con == NULL) return; - while (con->os > con->optionStack) { - cleanOSE(con->os--); - } - con->os->argb = (pbm_set *)PBM_FREE(con->os->argb); - con->os->currAlias = NULL; - con->os->nextCharArg = NULL; - con->os->nextArg = NULL; - con->os->next = 1; /* skip argv[0] */ - - con->numLeftovers = 0; - con->nextLeftover = 0; - con->restLeftover = 0; - con->doExec = NULL; - - if (con->finalArgv != NULL) - for (i = 0; i < con->finalArgvCount; i++) { - /*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */ - con->finalArgv[i] = (const char *)_free(con->finalArgv[i]); - /*@=unqualifiedtrans@*/ - } - - con->finalArgvCount = 0; - con->arg_strip = ( pbm_set *)PBM_FREE(con->arg_strip); - /*@-nullstate@*/ /* FIX: con->finalArgv != NULL */ - return; - /*@=nullstate@*/ -} -/*@=boundswrite@*/ - -/* Only one of longName, shortName should be set, not both. */ -/*@-boundswrite@*/ -static int handleExec(/*@special@*/ poptContext con, - /*@null@*/ const char * longName, char shortName) - /*@uses con->execs, con->numExecs, con->flags, con->doExec, - con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/ - /*@modifies con @*/ -{ - poptItem item; - int i; - - if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */ - return 0; - - for (i = con->numExecs - 1; i >= 0; i--) { - item = con->execs + i; - if (longName && !(item->option.longName && - !strcmp(longName, item->option.longName))) - continue; - else if (shortName != item->option.shortName) - continue; - break; - } - if (i < 0) return 0; - - - if (con->flags & POPT_CONTEXT_NO_EXEC) - return 1; - - if (con->doExec == NULL) { - con->doExec = con->execs + i; - return 1; - } - - /* We already have an exec to do; remember this option for next - time 'round */ - if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { - con->finalArgvAlloced += 10; - con->finalArgv = (const char **)realloc(con->finalArgv, - sizeof(*con->finalArgv) * con->finalArgvAlloced); - } - - i = con->finalArgvCount++; - if (con->finalArgv != NULL) /* XXX can't happen */ - { char *s = (char *)malloc((longName ? strlen(longName) : 0) + 3); - if (s != NULL) { /* XXX can't happen */ - if (longName) - sprintf(s, "--%s", longName); - else - sprintf(s, "-%c", shortName); - con->finalArgv[i] = s; - } else - con->finalArgv[i] = NULL; - } - - /*@-nullstate@*/ /* FIX: con->finalArgv[] == NULL */ - return 1; - /*@=nullstate@*/ -} -/*@=boundswrite@*/ - -/* Only one of longName, shortName may be set at a time */ -static int handleAlias(/*@special@*/ poptContext con, - /*@null@*/ const char * longName, char shortName, - /*@exposed@*/ /*@null@*/ const char * nextCharArg) - /*@uses con->aliases, con->numAliases, con->optionStack, con->os, - con->os->currAlias, con->os->currAlias->option.longName @*/ - /*@modifies con @*/ -{ - poptItem item = con->os->currAlias; - int rc; - int i; - - if (item) { - if (longName && (item->option.longName && - !strcmp(longName, item->option.longName))) - return 0; - if (shortName && shortName == item->option.shortName) - return 0; - } - - if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */ - return 0; - - for (i = con->numAliases - 1; i >= 0; i--) { - item = con->aliases + i; - if (longName && !(item->option.longName && - !strcmp(longName, item->option.longName))) - continue; - else if (shortName != item->option.shortName) - continue; - break; - } - if (i < 0) return 0; - - if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) - return POPT_ERROR_OPTSTOODEEP; - -/*@-boundsread@*/ - if (nextCharArg && *nextCharArg) - con->os->nextCharArg = nextCharArg; -/*@=boundsread@*/ - - con->os++; - con->os->next = 0; - con->os->stuffed = 0; - con->os->nextArg = NULL; - con->os->nextCharArg = NULL; - con->os->currAlias = con->aliases + i; - rc = poptDupArgv(con->os->currAlias->argc, con->os->currAlias->argv, - &con->os->argc, &con->os->argv); - con->os->argb = NULL; - - return (rc ? rc : 1); -} - -/*@-bounds -boundswrite @*/ -static int execCommand(poptContext con) - /*@globals internalState @*/ - /*@modifies internalState @*/ -{ - poptItem item = con->doExec; - const char ** argv; - int argc = 0; - int rc; - - if (item == NULL) /*XXX can't happen*/ - return POPT_ERROR_NOARG; - - if (item->argv == NULL || item->argc < 1 || - (!con->execAbsolute && strchr(item->argv[0], '/'))) - return POPT_ERROR_NOARG; - - argv = (const char **)malloc( - sizeof(*argv) * (6 + item->argc + con->numLeftovers + con->finalArgvCount)); - if (argv == NULL) return POPT_ERROR_MALLOC; /* XXX can't happen */ - - if (!strchr(item->argv[0], '/') && con->execPath) { - char *s = (char *)alloca( - strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/")); - sprintf(s, "%s/%s", con->execPath, item->argv[0]); - argv[argc] = s; - } else { - argv[argc] = findProgramPath(item->argv[0]); - } - if (argv[argc++] == NULL) return POPT_ERROR_NOARG; - - if (item->argc > 1) { - memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); - argc += (item->argc - 1); - } - - if (con->finalArgv != NULL && con->finalArgvCount > 0) { - memcpy(argv + argc, con->finalArgv, - sizeof(*argv) * con->finalArgvCount); - argc += con->finalArgvCount; - } - - if (con->leftovers != NULL && con->numLeftovers > 0) { -#if 0 - argv[argc++] = "--"; -#endif - memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers); - argc += con->numLeftovers; - } - - argv[argc] = NULL; - -#ifdef __hpux - rc = setresuid(getuid(), getuid(),-1); - if (rc) return POPT_ERROR_ERRNO; -#else -/* - * XXX " ... on BSD systems setuid() should be preferred over setreuid()" - * XXX sez' Timur Bakeyev - * XXX from Norbert Warmuth - */ -#if defined(HAVE_SETUID) - rc = setuid(getuid()); - if (rc) return POPT_ERROR_ERRNO; -#elif defined (HAVE_SETREUID) - rc = setreuid(getuid(), getuid()); /*hlauer: not portable to hpux9.01 */ - if (rc) return POPT_ERROR_ERRNO; -#else - ; /* Can't drop privileges */ -#endif -#endif - - if (argv[0] == NULL) - return POPT_ERROR_NOARG; - -#ifdef MYDEBUG -if (_popt_debug) - { const char ** avp; - fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc); - for (avp = argv; *avp; avp++) - fprintf(stderr, " '%s'", *avp); - fprintf(stderr, "\n"); - } -#endif - - rc = execvp(argv[0], (char *const *)argv); - /* notreached */ - if (rc) { - return POPT_ERROR_ERRNO; - } - - return 0; -} -/*@=bounds =boundswrite @*/ - -/*@-boundswrite@*/ -/*@observer@*/ /*@null@*/ static const struct poptOption * -findOption(const struct poptOption * opt, /*@null@*/ const char * longName, - char shortName, - /*@null@*/ /*@out@*/ poptCallbackType * callback, - /*@null@*/ /*@out@*/ const void ** callbackData, - int singleDash) - /*@modifies *callback, *callbackData */ -{ - const struct poptOption * cb = NULL; - - /* This happens when a single - is given */ - if (singleDash && !shortName && (longName && *longName == '\0')) - shortName = '-'; - - for (; opt->longName || opt->shortName || opt->arg; opt++) { - - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - const struct poptOption * opt2; - - /* Recurse on included sub-tables. */ - if (opt->arg == NULL) continue; /* XXX program error */ - opt2 = findOption((const struct poptOption *)opt->arg, longName, - shortName, callback, - callbackData, singleDash); - if (opt2 == NULL) continue; - /* Sub-table data will be inheirited if no data yet. */ - if (!(callback && *callback)) return opt2; - if (!(callbackData && *callbackData == NULL)) return opt2; - /*@-observertrans -dependenttrans @*/ - *callbackData = opt->descrip; - /*@=observertrans =dependenttrans @*/ - return opt2; - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) { - cb = opt; - } else if (longName && opt->longName && - (!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) && - /*@-nullpass@*/ /* LCL: opt->longName != NULL */ - !strcmp(longName, opt->longName)) - /*@=nullpass@*/ - { - break; - } else if (shortName && shortName == opt->shortName) { - break; - } - } - - if (!opt->longName && !opt->shortName) - return NULL; - /*@-modobserver -mods @*/ - if (callback) *callback = NULL; - if (callbackData) *callbackData = NULL; - if (cb) { - if (callback) - /*@-castfcnptr@*/ - *callback = (poptCallbackType)cb->arg; - /*@=castfcnptr@*/ - if (!(cb->argInfo & POPT_CBFLAG_INC_DATA)) { - if (callbackData) - /*@-observertrans@*/ /* FIX: typedef double indirection. */ - *callbackData = cb->descrip; - /*@=observertrans@*/ - } - } - /*@=modobserver =mods @*/ - - return opt; -} -/*@=boundswrite@*/ - -static const char * findNextArg(/*@special@*/ poptContext con, - unsigned argx, int delete_arg) - /*@uses con->optionStack, con->os, - con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ - /*@modifies con @*/ -{ - struct optionStackEntry * os = con->os; - const char * arg; - - do { - int i; - arg = NULL; - while (os->next == os->argc && os > con->optionStack) os--; - if (os->next == os->argc && os == con->optionStack) break; - if (os->argv != NULL) - for (i = os->next; i < os->argc; i++) { - /*@-sizeoftype@*/ - if (os->argb && PBM_ISSET(i, os->argb)) - /*@innercontinue@*/ continue; - if (*os->argv[i] == '-') - /*@innercontinue@*/ continue; - if (--argx > 0) - /*@innercontinue@*/ continue; - arg = os->argv[i]; - if (delete_arg) { - if (os->argb == NULL) os->argb = (pbm_set *)PBM_ALLOC(os->argc); - if (os->argb != NULL) /* XXX can't happen */ - PBM_SET(i, os->argb); - } - /*@innerbreak@*/ break; - /*@=sizeoftype@*/ - } - if (os > con->optionStack) os--; - } while (arg == NULL); - return arg; -} - -/*@-boundswrite@*/ -static /*@only@*/ /*@null@*/ const char * -expandNextArg(/*@special@*/ poptContext con, const char * s) - /*@uses con->optionStack, con->os, - con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ - /*@modifies con @*/ -{ - const char * a = NULL; - size_t alen; - char *t, *te; - size_t tn = strlen(s) + 1; - char c; - - te = t = (char *)malloc(tn);; - if (t == NULL) return NULL; /* XXX can't happen */ - while ((c = *s++) != '\0') { - switch (c) { -#if 0 /* XXX can't do this */ - case '\\': /* escape */ - c = *s++; - /*@switchbreak@*/ break; -#endif - case '!': - if (!(s[0] == '#' && s[1] == ':' && s[2] == '+')) - /*@switchbreak@*/ break; - /* XXX Make sure that findNextArg deletes only next arg. */ - if (a == NULL) { - if ((a = findNextArg(con, 1, 1)) == NULL) - /*@switchbreak@*/ break; - } - s += 3; - - alen = strlen(a); - tn += alen; - *te = '\0'; - t = (char *)realloc(t, tn); - te = t + strlen(t); - strncpy(te, a, alen); te += alen; - continue; - /*@notreached@*/ /*@switchbreak@*/ break; - default: - /*@switchbreak@*/ break; - } - *te++ = c; - } - *te = '\0'; - t = (char *)realloc(t, strlen(t) + 1); /* XXX memory leak, hard to plug */ - return t; -} -/*@=boundswrite@*/ - -static void poptStripArg(/*@special@*/ poptContext con, int which) - /*@uses con->arg_strip, con->optionStack @*/ - /*@defines con->arg_strip @*/ - /*@modifies con @*/ -{ - /*@-sizeoftype@*/ - if (con->arg_strip == NULL) - con->arg_strip = (pbm_set *)PBM_ALLOC(con->optionStack[0].argc); - if (con->arg_strip != NULL) /* XXX can't happen */ - PBM_SET(which, con->arg_strip); - /*@=sizeoftype@*/ - /*@-compdef@*/ /* LCL: con->arg_strip udefined? */ - return; - /*@=compdef@*/ -} - -int poptSaveLong(long * arg, int argInfo, long aLong) -{ - /* XXX Check alignment, may fail on funky platforms. */ - if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) - return POPT_ERROR_NULLARG; - - if (argInfo & POPT_ARGFLAG_NOT) - aLong = ~aLong; - switch (argInfo & POPT_ARGFLAG_LOGICALOPS) { - case 0: - *arg = aLong; - break; - case POPT_ARGFLAG_OR: - *arg |= aLong; - break; - case POPT_ARGFLAG_AND: - *arg &= aLong; - break; - case POPT_ARGFLAG_XOR: - *arg ^= aLong; - break; - default: - return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) -{ - /* XXX Check alignment, may fail on funky platforms. */ - if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) - return POPT_ERROR_NULLARG; - - if (argInfo & POPT_ARGFLAG_NOT) - aLong = ~aLong; - switch (argInfo & POPT_ARGFLAG_LOGICALOPS) { - case 0: - *arg = aLong; - break; - case POPT_ARGFLAG_OR: - *arg |= aLong; - break; - case POPT_ARGFLAG_AND: - *arg &= aLong; - break; - case POPT_ARGFLAG_XOR: - *arg ^= aLong; - break; - default: - return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -/*@-boundswrite@*/ -/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ -int poptGetNextOpt(poptContext con) -{ - const struct poptOption * opt = NULL; - int done = 0; - - if (con == NULL) - return -1; - while (!done) { - const char * origOptString = NULL; - poptCallbackType cb = NULL; - const void * cbData = NULL; - const char * longArg = NULL; - int canstrip = 0; - int shorty = 0; - - while (!con->os->nextCharArg && con->os->next == con->os->argc - && con->os > con->optionStack) { - cleanOSE(con->os--); - } - if (!con->os->nextCharArg && con->os->next == con->os->argc) { - /*@-internalglobs@*/ - invokeCallbacksPOST(con, con->options); - /*@=internalglobs@*/ - if (con->doExec) return execCommand(con); - return -1; - } - - /* Process next long option */ - if (!con->os->nextCharArg) { - char * localOptString, * optString; - int thisopt; - - /*@-sizeoftype@*/ - if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { - con->os->next++; - continue; - } - /*@=sizeoftype@*/ - thisopt = con->os->next; - if (con->os->argv != NULL) /* XXX can't happen */ - origOptString = con->os->argv[con->os->next++]; - - if (origOptString == NULL) /* XXX can't happen */ - return POPT_ERROR_BADOPT; - - if (con->restLeftover || *origOptString != '-') { - if (con->flags & POPT_CONTEXT_POSIXMEHARDER) - con->restLeftover = 1; - if (con->flags & POPT_CONTEXT_ARG_OPTS) { - con->os->nextArg = xstrdup(origOptString); - return 0; - } - if (con->leftovers != NULL) /* XXX can't happen */ - con->leftovers[con->numLeftovers++] = origOptString; - continue; - } - - /* Make a copy we can hack at */ - localOptString = optString = - strcpy((char *)alloca(strlen(origOptString) + 1), - origOptString); - - if (optString[0] == '\0') - return POPT_ERROR_BADOPT; - - if (optString[1] == '-' && !optString[2]) { - con->restLeftover = 1; - continue; - } else { - char *oe; - int singleDash; - - optString++; - if (*optString == '-') - singleDash = 0, optString++; - else - singleDash = 1; - - /* XXX aliases with arg substitution need "--alias=arg" */ - if (handleAlias(con, optString, '\0', NULL)) - continue; - - if (handleExec(con, optString, '\0')) - continue; - - /* Check for "--long=arg" option. */ - for (oe = optString; *oe && *oe != '='; oe++) - {}; - if (*oe == '=') { - *oe++ = '\0'; - /* XXX longArg is mapped back to persistent storage. */ - longArg = origOptString + (oe - localOptString); - } - - opt = findOption(con->options, optString, '\0', &cb, &cbData, - singleDash); - if (!opt && !singleDash) - return POPT_ERROR_BADOPT; - } - - if (!opt) { - con->os->nextCharArg = origOptString + 1; - } else { - if (con->os == con->optionStack && - opt->argInfo & POPT_ARGFLAG_STRIP) - { - canstrip = 1; - poptStripArg(con, thisopt); - } - shorty = 0; - } - } - - /* Process next short option */ - /*@-branchstate@*/ /* FIX: W2DO? */ - if (con->os->nextCharArg) { - origOptString = con->os->nextCharArg; - - con->os->nextCharArg = NULL; - - if (handleAlias(con, NULL, *origOptString, origOptString + 1)) - continue; - - if (handleExec(con, NULL, *origOptString)) { - /* Restore rest of short options for further processing */ - origOptString++; - if (*origOptString != '\0') - con->os->nextCharArg = origOptString; - continue; - } - - opt = findOption(con->options, NULL, *origOptString, &cb, - &cbData, 0); - if (!opt) - return POPT_ERROR_BADOPT; - shorty = 1; - - origOptString++; - if (*origOptString != '\0') - con->os->nextCharArg = origOptString; - } - /*@=branchstate@*/ - - if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */ - if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) { - if (poptSaveInt((int *)opt->arg, opt->argInfo, 1L)) - return POPT_ERROR_BADOPERATION; - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) { - if (opt->arg) { - if (poptSaveInt((int *)opt->arg, opt->argInfo, (long)opt->val)) - return POPT_ERROR_BADOPERATION; - } - } else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { - con->os->nextArg = (const char *)_free(con->os->nextArg); - /*@-usedef@*/ /* FIX: W2DO? */ - if (longArg) { - /*@=usedef@*/ - longArg = expandNextArg(con, longArg); - con->os->nextArg = longArg; - } else if (con->os->nextCharArg) { - longArg = expandNextArg(con, con->os->nextCharArg); - con->os->nextArg = longArg; - con->os->nextCharArg = NULL; - } else { - while (con->os->next == con->os->argc && - con->os > con->optionStack) { - cleanOSE(con->os--); - } - if (con->os->next == con->os->argc) { - if (!(opt->argInfo & POPT_ARGFLAG_OPTIONAL)) - /*@-compdef@*/ /* FIX: con->os->argv not defined */ - return POPT_ERROR_NOARG; - /*@=compdef@*/ - con->os->nextArg = NULL; - } else { - - /* - * Make sure this isn't part of a short arg or the - * result of an alias expansion. - */ - if (con->os == con->optionStack && - (opt->argInfo & POPT_ARGFLAG_STRIP) && - canstrip) { - poptStripArg(con, con->os->next); - } - - if (con->os->argv != NULL) { /* XXX can't happen */ - /* XXX watchout: subtle side-effects live here. */ - longArg = con->os->argv[con->os->next++]; - longArg = expandNextArg(con, longArg); - con->os->nextArg = longArg; - } - } - } - longArg = NULL; - - if (opt->arg) { - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_STRING: - /* XXX memory leak, hard to plug */ - *((const char **) opt->arg) = (con->os->nextArg) - ? xstrdup(con->os->nextArg) : NULL; - /*@switchbreak@*/ break; - - case POPT_ARG_INT: - case POPT_ARG_LONG: - { long aLong = 0; - char *end; - - if (con->os->nextArg) { - aLong = strtol(con->os->nextArg, &end, 0); - if (!(end && *end == '\0')) - return POPT_ERROR_BADNUMBER; - } - - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { - if (aLong == LONG_MIN || aLong == LONG_MAX) - return POPT_ERROR_OVERFLOW; - if (poptSaveLong((long *)opt->arg, opt->argInfo, aLong)) - return POPT_ERROR_BADOPERATION; - } else { - if (aLong > INT_MAX || aLong < INT_MIN) - return POPT_ERROR_OVERFLOW; - if (poptSaveInt((int *)opt->arg, opt->argInfo, aLong)) - return POPT_ERROR_BADOPERATION; - } - } /*@switchbreak@*/ break; - - case POPT_ARG_FLOAT: - case POPT_ARG_DOUBLE: - { double aDouble = 0.0; - char *end; - - if (con->os->nextArg) { - /*@-mods@*/ - int saveerrno = errno; - errno = 0; - aDouble = strtod(con->os->nextArg, &end); - if (errno == ERANGE) - return POPT_ERROR_OVERFLOW; - errno = saveerrno; - /*@=mods@*/ - if (*end != '\0') - return POPT_ERROR_BADNUMBER; - } - - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_DOUBLE) { - *((double *) opt->arg) = aDouble; - } else { -#ifndef _ABS -#define _ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a)) -#endif - if ((_ABS(aDouble) - FLT_MAX) > DBL_EPSILON) - return POPT_ERROR_OVERFLOW; - if ((FLT_MIN - _ABS(aDouble)) > DBL_EPSILON) - return POPT_ERROR_OVERFLOW; - *((float *) opt->arg) = aDouble; - } - } /*@switchbreak@*/ break; - default: - fprintf(stdout, - POPT_("option type (%d) not implemented in popt\n"), - (opt->argInfo & POPT_ARG_MASK)); - exit(EXIT_FAILURE); - /*@notreached@*/ /*@switchbreak@*/ break; - } - } - } - - if (cb) { - /*@-internalglobs@*/ - invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); - /*@=internalglobs@*/ - } else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)) - done = 1; - - if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { - con->finalArgvAlloced += 10; - con->finalArgv = (const char **)realloc(con->finalArgv, - sizeof(*con->finalArgv) * con->finalArgvAlloced); - } - - if (con->finalArgv != NULL) - { char *s = (char *)malloc( - (opt->longName ? strlen(opt->longName) : 0) + 3); - if (s != NULL) { /* XXX can't happen */ - if (opt->longName) - sprintf(s, "%s%s", - ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), - opt->longName); - else - sprintf(s, "-%c", opt->shortName); - con->finalArgv[con->finalArgvCount++] = s; - } else - con->finalArgv[con->finalArgvCount++] = NULL; - } - - if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) - /*@-ifempty@*/ ; /*@=ifempty@*/ - else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) - /*@-ifempty@*/ ; /*@=ifempty@*/ - else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { - if (con->finalArgv != NULL && con->os->nextArg) - con->finalArgv[con->finalArgvCount++] = - /*@-nullpass@*/ /* LCL: con->os->nextArg != NULL */ - xstrdup(con->os->nextArg); - /*@=nullpass@*/ - } - } - - return (opt ? opt->val : -1); /* XXX can't happen */ -} -/*@=boundswrite@*/ - -const char * poptGetOptArg(poptContext con) -{ - const char * ret = NULL; - /*@-branchstate@*/ - if (con) { - ret = con->os->nextArg; - con->os->nextArg = NULL; - } - /*@=branchstate@*/ - return ret; -} - -const char * poptGetArg(poptContext con) -{ - const char * ret = NULL; - if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) - ret = con->leftovers[con->nextLeftover++]; - return ret; -} - -const char * poptPeekArg(poptContext con) -{ - const char * ret = NULL; - if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) - ret = con->leftovers[con->nextLeftover]; - return ret; -} - -/*@-boundswrite@*/ -const char ** poptGetArgs(poptContext con) -{ - if (con == NULL || - con->leftovers == NULL || con->numLeftovers == con->nextLeftover) - return NULL; - - /* some apps like [like RPM ;-) ] need this NULL terminated */ - con->leftovers[con->numLeftovers] = NULL; - - /*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */ - return (con->leftovers + con->nextLeftover); - /*@=nullret =nullstate @*/ -} -/*@=boundswrite@*/ - -poptContext poptFreeContext(poptContext con) -{ - poptItem item; - int i; - - if (con == NULL) return con; - poptResetContext(con); - con->os->argb = (pbm_set *)_free(con->os->argb); - - if (con->aliases != NULL) - for (i = 0; i < con->numAliases; i++) { - item = con->aliases + i; - /*@-modobserver -observertrans -dependenttrans@*/ - item->option.longName = (const char *)_free(item->option.longName); - item->option.descrip = (const char *)_free(item->option.descrip); - item->option.argDescrip = (const char *)_free(item->option.argDescrip); - /*@=modobserver =observertrans =dependenttrans@*/ - item->argv = (const char **)_free(item->argv); - } - con->aliases = (poptItem)_free(con->aliases); - - if (con->execs != NULL) - for (i = 0; i < con->numExecs; i++) { - item = con->execs + i; - /*@-modobserver -observertrans -dependenttrans@*/ - item->option.longName = (const char *)_free(item->option.longName); - item->option.descrip = (const char *)_free(item->option.descrip); - item->option.argDescrip = (const char *)_free(item->option.argDescrip); - /*@=modobserver =observertrans =dependenttrans@*/ - item->argv = (const char **)_free(item->argv); - } - con->execs = (poptItem)_free(con->execs); - - con->leftovers = (const char **)_free(con->leftovers); - con->finalArgv = (const char **)_free(con->finalArgv); - con->appName = (const char *)_free(con->appName); - con->otherHelp = (const char *)_free(con->otherHelp); - con->execPath = (const char *)_free(con->execPath); - con->arg_strip = (pbm_set *)PBM_FREE(con->arg_strip); - - con = (poptContext)_free(con); - return con; -} - -int poptAddAlias(poptContext con, struct poptAlias alias, - /*@unused@*/ int flags) -{ - poptItem item = (poptItem)alloca(sizeof(*item)); - memset(item, 0, sizeof(*item)); - item->option.longName = alias.longName; - item->option.shortName = alias.shortName; - item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; - item->option.arg = 0; - item->option.val = 0; - item->option.descrip = NULL; - item->option.argDescrip = NULL; - item->argc = alias.argc; - item->argv = alias.argv; - return poptAddItem(con, item, 0); -} - -/*@-boundswrite@*/ -/*@-mustmod@*/ /* LCL: con not modified? */ -int poptAddItem(poptContext con, poptItem newItem, int flags) -{ - poptItem * items, item; - int * nitems; - - switch (flags) { - case 1: - items = &con->execs; - nitems = &con->numExecs; - break; - case 0: - items = &con->aliases; - nitems = &con->numAliases; - break; - default: - return 1; - /*@notreached@*/ break; - } - - *items = (poptItem)realloc((*items), ((*nitems) + 1) * sizeof(**items)); - if ((*items) == NULL) - return 1; - - item = (*items) + (*nitems); - - item->option.longName = - (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL); - item->option.shortName = newItem->option.shortName; - item->option.argInfo = newItem->option.argInfo; - item->option.arg = newItem->option.arg; - item->option.val = newItem->option.val; - item->option.descrip = - (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL); - item->option.argDescrip = - (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL); - item->argc = newItem->argc; - item->argv = newItem->argv; - - (*nitems)++; - - return 0; -} -/*@=mustmod@*/ -/*@=boundswrite@*/ - -const char * poptBadOption(poptContext con, int flags) -{ - struct optionStackEntry * os = NULL; - - if (con != NULL) - os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os; - - /*@-nullderef@*/ /* LCL: os->argv != NULL */ - return (os && os->argv ? os->argv[os->next - 1] : NULL); - /*@=nullderef@*/ -} - -const char *poptStrerror(const int error) -{ - switch (error) { - case POPT_ERROR_NOARG: - return POPT_("missing argument"); - case POPT_ERROR_BADOPT: - return POPT_("unknown option"); - case POPT_ERROR_BADOPERATION: - return POPT_("mutually exclusive logical operations requested"); - case POPT_ERROR_NULLARG: - return POPT_("opt->arg should not be NULL"); - case POPT_ERROR_OPTSTOODEEP: - return POPT_("aliases nested too deeply"); - case POPT_ERROR_BADQUOTE: - return POPT_("error in parameter quoting"); - case POPT_ERROR_BADNUMBER: - return POPT_("invalid numeric value"); - case POPT_ERROR_OVERFLOW: - return POPT_("number too large or too small"); - case POPT_ERROR_MALLOC: - return POPT_("memory allocation failed"); - case POPT_ERROR_ERRNO: - return strerror(errno); - default: - return POPT_("unknown error"); - } -} - -int poptStuffArgs(poptContext con, const char ** argv) -{ - int argc; - int rc; - - if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) - return POPT_ERROR_OPTSTOODEEP; - - for (argc = 0; argv[argc]; argc++) - {}; - - con->os++; - con->os->next = 0; - con->os->nextArg = NULL; - con->os->nextCharArg = NULL; - con->os->currAlias = NULL; - rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv); - con->os->argb = NULL; - con->os->stuffed = 1; - - return rc; -} - -const char * poptGetInvocationName(poptContext con) -{ - return (con->os->argv ? con->os->argv[0] : ""); -} - -/*@-boundswrite@*/ -int poptStrippedArgv(poptContext con, int argc, char ** argv) -{ - int numargs = argc; - int j = 1; - int i; - - /*@-sizeoftype@*/ - if (con->arg_strip) - for (i = 1; i < argc; i++) { - if (PBM_ISSET(i, con->arg_strip)) - numargs--; - } - - for (i = 1; i < argc; i++) { - if (con->arg_strip && PBM_ISSET(i, con->arg_strip)) - continue; - argv[j] = (j < numargs) ? argv[i] : NULL; - j++; - } - /*@=sizeoftype@*/ - - return numargs; -} -/*@=boundswrite@*/ diff --git a/popt/popt.h b/popt/popt.h deleted file mode 100644 index 08701d73b5..0000000000 --- a/popt/popt.h +++ /dev/null @@ -1,545 +0,0 @@ -/** \file popt/popt.h - * \ingroup popt - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_POPT -#define H_POPT - -#include /* for FILE * */ - -#define POPT_OPTION_DEPTH 10 - -/** \ingroup popt - * \name Arg type identifiers - */ -/*@{*/ -#define POPT_ARG_NONE 0 /*!< no arg */ -#define POPT_ARG_STRING 1 /*!< arg will be saved as string */ -#define POPT_ARG_INT 2 /*!< arg will be converted to int */ -#define POPT_ARG_LONG 3 /*!< arg will be converted to long */ -#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */ -#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be - set first in table; arg points - to callback, descrip points to - callback data to pass */ -#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain - for this table and any - included tables; arg points - to the domain string */ -#define POPT_ARG_VAL 7 /*!< arg should take value val */ -#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */ -#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */ - -#define POPT_ARG_MASK 0x0000FFFF -/*@}*/ - -/** \ingroup popt - * \name Arg modifiers - */ -/*@{*/ -#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */ -#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */ -#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */ -#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */ - -#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */ -#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */ -#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */ -#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */ -#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */ -#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */ -#define POPT_ARGFLAG_LOGICALOPS \ - (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) - -#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) - /*!< set arg bit(s) */ -#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND) - /*!< clear arg bit(s) */ - -#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */ - -/*@}*/ - -/** \ingroup popt - * \name Callback modifiers - */ -/*@{*/ -#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */ -#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */ -#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line, - not the subtable */ -#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */ -#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */ -/*@}*/ - -/** \ingroup popt - * \name Error return values - */ -/*@{*/ -#define POPT_ERROR_NOARG -10 /*!< missing argument */ -#define POPT_ERROR_BADOPT -11 /*!< unknown option */ -#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */ -#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */ -#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */ -#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */ -#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */ -#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */ -#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */ -#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */ -/*@}*/ - -/** \ingroup popt - * \name poptBadOption() flags - */ -/*@{*/ -#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */ -/*@}*/ - -/** \ingroup popt - * \name poptGetContext() flags - */ -/*@{*/ -#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */ -#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */ -#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */ -#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */ -/*@}*/ - -/** \ingroup popt - */ -struct poptOption { -/*@observer@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be '\0' */ - int argInfo; -/*@shared@*/ /*@null@*/ - void * arg; /*!< depends on argInfo */ - int val; /*!< 0 means don't return, just update flag */ -/*@observer@*/ /*@null@*/ - const char * descrip; /*!< description for autohelp -- may be NULL */ -/*@observer@*/ /*@null@*/ - const char * argDescrip; /*!< argument description for autohelp */ -}; - -/** \ingroup popt - * A popt alias argument for poptAddAlias(). - */ -struct poptAlias { -/*@owned@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be '\0' */ - int argc; -/*@owned@*/ - const char ** argv; /*!< must be free()able */ -}; - -/** \ingroup popt - * A popt alias or exec argument for poptAddItem(). - */ -/*@-exporttype@*/ -typedef struct poptItem_s { - struct poptOption option; /*!< alias/exec name(s) and description. */ - int argc; /*!< (alias) no. of args. */ -/*@owned@*/ - const char ** argv; /*!< (alias) args, must be free()able. */ -} * poptItem; -/*@=exporttype@*/ - -/** \ingroup popt - * \name Auto-generated help/usage - */ -/*@{*/ - -/** - * Empty table marker to enable displaying popt alias/exec options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptAliasOptions[]; -/*@=exportvar@*/ -#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ - 0, "Options implemented via popt alias/exec:", NULL }, - -/** - * Auto help table options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptHelpOptions[]; -/*@=exportvar@*/ -#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ - 0, "Help options:", NULL }, - -#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } -/*@}*/ - -/** \ingroup popt - */ -/*@-exporttype@*/ -typedef /*@abstract@*/ struct poptContext_s * poptContext; -/*@=exporttype@*/ - -/** \ingroup popt - */ -#ifndef __cplusplus -/*@-exporttype -typeuse@*/ -typedef struct poptOption * poptOption; -/*@=exporttype =typeuse@*/ -#endif - -/*@-exportconst@*/ -enum poptCallbackReason { - POPT_CALLBACK_REASON_PRE = 0, - POPT_CALLBACK_REASON_POST = 1, - POPT_CALLBACK_REASON_OPTION = 2 -}; -/*@=exportconst@*/ - -#ifdef __cplusplus -extern "C" { -#endif -/*@-type@*/ - -/** \ingroup popt - * Table callback prototype. - * @param con context - * @param reason reason for callback - * @param opt option that triggered callback - * @param arg @todo Document. - * @param data @todo Document. - */ -typedef void (*poptCallbackType) (poptContext con, - enum poptCallbackReason reason, - /*@null@*/ const struct poptOption * opt, - /*@null@*/ const char * arg, - /*@null@*/ const void * data) - /*@*/; - -/** \ingroup popt - * Initialize popt context. - * @param name context name (usually argv[0] program name) - * @param argc no. of arguments - * @param argv argument array - * @param options address of popt option table - * @param flags or'd POPT_CONTEXT_* bits - * @return initialized popt context - */ -/*@only@*/ /*@null@*/ poptContext poptGetContext( - /*@dependent@*/ /*@keep@*/ const char * name, - int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, - /*@dependent@*/ /*@keep@*/ const struct poptOption * options, - int flags) - /*@*/; - -/** \ingroup popt - * Reinitialize popt context. - * @param con context - */ -/*@unused@*/ -void poptResetContext(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return value of next option found. - * @param con context - * @return next option val, -1 on last item, POPT_ERROR_* on error - */ -int poptGetNextOpt(/*@null@*/poptContext con) - /*@globals fileSystem, internalState @*/ - /*@modifies con, fileSystem, internalState @*/; - -/** \ingroup popt - * Return next option argument (if any). - * @param con context - * @return option argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return next argument. - * @param con context - * @return next argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Peek at current argument. - * @param con context - * @return current argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con) - /*@*/; - -/** \ingroup popt - * Return remaining arguments. - * @param con context - * @return argument array, NULL terminated - */ -/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return the option which caused the most recent error. - * @param con context - * @param flags - * @return offending option - */ -/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags) - /*@*/; - -/** \ingroup popt - * Destroy context. - * @param con context - * @return NULL always - */ -/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Add arguments to context. - * @param con context - * @param argv argument array, NULL terminated - * @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure - */ -int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias to context. - * @todo Pass alias by reference, not value. - * @deprecated Use poptAddItem instead. - * @param con context - * @param alias alias to add - * @param flags (unused) - * @return 0 on success - */ -/*@unused@*/ -int poptAddAlias(poptContext con, struct poptAlias alias, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias/exec item to context. - * @param con context - * @param newItem alias/exec item to add - * @param flags 0 for alias, 1 for exec - * @return 0 on success - */ -int poptAddItem(poptContext con, poptItem newItem, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Read configuration file. - * @param con context - * @param fn file name to read - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -int poptReadConfigFile(poptContext con, const char * fn) - /*@globals fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - fileSystem, internalState @*/; - -/** \ingroup popt - * Read default configuration from /etc/popt and $HOME/.popt. - * @param con context - * @param useEnv (unused) - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) - /*@globals fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - fileSystem, internalState @*/; - -/** \ingroup popt - * Duplicate an argument array. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param argc no. of arguments - * @param argv argument array - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - * @return 0 on success, POPT_ERROR_NOARG on failure - */ -int poptDupArgv(int argc, /*@null@*/ const char **argv, - /*@null@*/ /*@out@*/ int * argcPtr, - /*@null@*/ /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parse a string into an argument array. - * The parse allows ', ", and \ quoting, but ' is treated the same as " and - * both may include \ quotes. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param s string to parse - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - */ -int poptParseArgvString(const char * s, - /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parses an input configuration file and returns an string that is a - * command line. For use with popt. You must free the return value when done. - * - * Given the file: -\verbatim -# this line is ignored - # this one too -aaa - bbb - ccc -bla=bla - -this_is = fdsafdas - bad_line= - reall bad line - reall bad line = again -5555= 55555 - test = with lots of spaces -\endverbatim -* -* The result is: -\verbatim ---aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" -\endverbatim -* -* Passing this to poptParseArgvString() yields an argv of: -\verbatim -'--aaa' -'--bbb' -'--ccc' -'--bla=bla' -'--this_is=fdsafdas' -'--5555=55555' -'--test=with lots of spaces' -\endverbatim - * - * @bug NULL is returned if file line is too long. - * @bug Silently ignores invalid lines. - * - * @param fp file handle to read - * @param *argstrp return string of options (malloc'd) - * @param flags unused - * @return 0 on success - * @see poptParseArgvString - */ -/*@-fcnuse@*/ -int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, *argstrp, fileSystem @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return formatted error string for popt failure. - * @param error popt error - * @return error string - */ -/*@observer@*/ const char* poptStrerror(const int error) - /*@*/; - -/** \ingroup popt - * Limit search for executables. - * @param con context - * @param path single path to search for executables - * @param allowAbsolute absolute paths only? - */ -void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) - /*@modifies con @*/; - -/** \ingroup popt - * Print detailed description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/; - -/** \ingroup popt - * Print terse description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/; - -/** \ingroup popt - * Provide text to replace default "[OPTION...]" in help/usage output. - * @param con context - * @param text replacement text - */ -/*@-fcnuse@*/ -void poptSetOtherOptionHelp(poptContext con, const char * text) - /*@modifies con @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return argv[0] from context. - * @param con context - * @return argv[0] - */ -/*@-fcnuse@*/ -/*@observer@*/ const char * poptGetInvocationName(poptContext con) - /*@*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Shuffle argv pointers to remove stripped args, returns new argc. - * @param con context - * @param argc no. of args - * @param argv arg vector - * @return new argc - */ -/*@-fcnuse@*/ -int poptStrippedArgv(poptContext con, int argc, char ** argv) - /*@modifies *argv @*/; -/*@=fcnuse@*/ - -/** - * Save a long, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveLong(/*@null@*/ long * arg, int argInfo, long aLong) - /*@modifies *arg @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/** - * Save an integer, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong) - /*@modifies *arg @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/*@=type@*/ -#ifdef __cplusplus -} -#endif - -#endif diff --git a/popt/poptconfig.c b/popt/poptconfig.c deleted file mode 100644 index 837828ccf9..0000000000 --- a/popt/poptconfig.c +++ /dev/null @@ -1,190 +0,0 @@ -/** \ingroup popt - * \file popt/poptconfig.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" -#include "poptint.h" - -/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ -static void configLine(poptContext con, char * line) - /*@modifies con @*/ -{ - /*@-type@*/ - int nameLength = strlen(con->appName); - /*@=type@*/ - const char * entryType; - const char * opt; - poptItem item = (poptItem)alloca(sizeof(*item)); - int i, j; - -/*@-boundswrite@*/ - memset(item, 0, sizeof(*item)); - - /*@-type@*/ - if (strncmp(line, con->appName, nameLength)) return; - /*@=type@*/ - - line += nameLength; - if (*line == '\0' || !isspace(*line)) return; - - while (*line != '\0' && isspace(*line)) line++; - entryType = line; - while (*line == '\0' || !isspace(*line)) line++; - *line++ = '\0'; - - while (*line != '\0' && isspace(*line)) line++; - if (*line == '\0') return; - opt = line; - while (*line == '\0' || !isspace(*line)) line++; - *line++ = '\0'; - - while (*line != '\0' && isspace(*line)) line++; - if (*line == '\0') return; - - /*@-temptrans@*/ /* FIX: line alias is saved */ - if (opt[0] == '-' && opt[1] == '-') - item->option.longName = opt + 2; - else if (opt[0] == '-' && opt[2] == '\0') - item->option.shortName = opt[1]; - /*@=temptrans@*/ - - if (poptParseArgvString(line, &item->argc, &item->argv)) return; - - /*@-modobserver@*/ - item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; - for (i = 0, j = 0; i < item->argc; i++, j++) { - const char * f; - if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { - f = item->argv[i] + sizeof("--POPTdesc="); - if (f[0] == '$' && f[1] == '"') f++; - item->option.descrip = f; - item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; - j--; - } else - if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { - f = item->argv[i] + sizeof("--POPTargs="); - if (f[0] == '$' && f[1] == '"') f++; - item->option.argDescrip = f; - item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; - item->option.argInfo |= POPT_ARG_STRING; - j--; - } else - if (j != i) - item->argv[j] = item->argv[i]; - } - if (j != i) { - item->argv[j] = NULL; - item->argc = j; - } - /*@=modobserver@*/ -/*@=boundswrite@*/ - - /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ - if (!strcmp(entryType, "alias")) - (void) poptAddItem(con, item, 0); - else if (!strcmp(entryType, "exec")) - (void) poptAddItem(con, item, 1); - /*@=nullstate@*/ -} -/*@=compmempass@*/ - -int poptReadConfigFile(poptContext con, const char * fn) -{ - const char * file, * chptr, * end; - char * buf; -/*@dependent@*/ char * dst; - int fd, rc; - off_t fileLength; - - fd = open(fn, O_RDONLY); - if (fd < 0) - return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO); - - fileLength = lseek(fd, 0, SEEK_END); - if (fileLength == -1 || lseek(fd, 0, 0) == -1) { - rc = errno; - (void) close(fd); - /*@-mods@*/ - errno = rc; - /*@=mods@*/ - return POPT_ERROR_ERRNO; - } - - file = (const char *)alloca(fileLength + 1); - if (read(fd, (char *)file, fileLength) != fileLength) { - rc = errno; - (void) close(fd); - /*@-mods@*/ - errno = rc; - /*@=mods@*/ - return POPT_ERROR_ERRNO; - } - if (close(fd) == -1) - return POPT_ERROR_ERRNO; - -/*@-boundswrite@*/ - dst = buf = (char *)alloca(fileLength + 1); - - chptr = file; - end = (file + fileLength); - /*@-infloops@*/ /* LCL: can't detect chptr++ */ - while (chptr < end) { - switch (*chptr) { - case '\n': - *dst = '\0'; - dst = buf; - while (*dst && isspace(*dst)) dst++; - if (*dst && *dst != '#') - configLine(con, dst); - chptr++; - /*@switchbreak@*/ break; - case '\\': - *dst++ = *chptr++; - if (chptr < end) { - if (*chptr == '\n') - dst--, chptr++; - /* \ at the end of a line does not insert a \n */ - else - *dst++ = *chptr++; - } - /*@switchbreak@*/ break; - default: - *dst++ = *chptr++; - /*@switchbreak@*/ break; - } - } - /*@=infloops@*/ -/*@=boundswrite@*/ - - return 0; -} - -int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) -{ - char * fn, * home; - int rc; - - /*@-type@*/ - if (!con->appName) return 0; - /*@=type@*/ - - rc = poptReadConfigFile(con, "/etc/popt"); - if (rc) return rc; -#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) - if (getuid() != geteuid()) return 0; -#endif - - if ((home = getenv("HOME"))) { - fn = (char *)alloca(strlen(home) + 20); - strcpy(fn, home); - strcat(fn, "/.popt"); - rc = poptReadConfigFile(con, fn); - if (rc) return rc; - } - - return 0; -} diff --git a/popt/popthelp.c b/popt/popthelp.c deleted file mode 100644 index e965ff6168..0000000000 --- a/popt/popthelp.c +++ /dev/null @@ -1,740 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - -/*@-type@*/ -/** \ingroup popt - * \file popt/popthelp.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" -#include "poptint.h" - -/** - * Display arguments. - * @param con context - * @param foo (unused) - * @param key option(s) - * @param arg (unused) - * @param data (unused) - */ -static void displayArgs(poptContext con, - /*@unused@*/ enum poptCallbackReason foo, - struct poptOption * key, - /*@unused@*/ const char * arg, /*@unused@*/ void * data) - /*@globals fileSystem@*/ - /*@modifies fileSystem@*/ -{ - if (key->shortName == '?') - poptPrintHelp(con, stdout, 0); - else - poptPrintUsage(con, stdout, 0); - exit(0); -} - -#ifdef NOTYET -/*@unchecked@*/ -static int show_option_defaults = 0; -#endif - -/** - * Empty table marker to enable displaying popt alias/exec options. - */ -/*@observer@*/ /*@unchecked@*/ -struct poptOption poptAliasOptions[] = { - POPT_TABLEEND -}; - -/** - * Auto help table options. - */ -/*@-castfcnptr@*/ -/*@observer@*/ /*@unchecked@*/ -struct poptOption poptHelpOptions[] = { - { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL }, - { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL }, - { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL }, -#ifdef NOTYET - { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0, - N_("Display option defaults in message"), NULL }, -#endif - POPT_TABLEEND -} ; -/*@=castfcnptr@*/ - -/** - * @param table option(s) - */ -/*@observer@*/ /*@null@*/ static const char * -getTableTranslationDomain(/*@null@*/ const struct poptOption *table) - /*@*/ -{ - const struct poptOption *opt; - - if (table != NULL) - for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { - if (opt->argInfo == POPT_ARG_INTL_DOMAIN) - return (char *)opt->arg; - } - return NULL; -} - -/** - * @param opt option(s) - * @param translation_domain translation domain - */ -/*@observer@*/ /*@null@*/ static const char * -getArgDescrip(const struct poptOption * opt, - /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ - /*@null@*/ const char * translation_domain) - /*@=paramuse@*/ - /*@*/ -{ - if (!(opt->argInfo & POPT_ARG_MASK)) return NULL; - - if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2)) - if (opt->argDescrip) return POPT_(opt->argDescrip); - - if (opt->argDescrip) return D_(translation_domain, opt->argDescrip); - - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_NONE: return POPT_("NONE"); -#ifdef DYING - case POPT_ARG_VAL: return POPT_("VAL"); -#else - case POPT_ARG_VAL: return NULL; -#endif - case POPT_ARG_INT: return POPT_("INT"); - case POPT_ARG_LONG: return POPT_("LONG"); - case POPT_ARG_STRING: return POPT_("STRING"); - case POPT_ARG_FLOAT: return POPT_("FLOAT"); - case POPT_ARG_DOUBLE: return POPT_("DOUBLE"); - default: return POPT_("ARG"); - } -} - -/** - * Display default value for an option. - * @param lineLength - * @param opt option(s) - * @param translation_domain translation domain - * @return - */ -static /*@only@*/ /*@null@*/ char * -singleOptionDefaultValue(int lineLength, - const struct poptOption * opt, - /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ - /*@null@*/ const char * translation_domain) - /*@=paramuse@*/ - /*@*/ -{ - const char * defstr = D_(translation_domain, "default"); - char * le = (char *)malloc(4*lineLength + 1); - char * l = le; - - if (le == NULL) return NULL; /* XXX can't happen */ -/*@-boundswrite@*/ - *le = '\0'; - *le++ = '('; - strcpy(le, defstr); le += strlen(le); - *le++ = ':'; - *le++ = ' '; - if (opt->arg) /* XXX programmer error */ - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_VAL: - case POPT_ARG_INT: - { long aLong = *((int *)opt->arg); - le += sprintf(le, "%ld", aLong); - } break; - case POPT_ARG_LONG: - { long aLong = *((long *)opt->arg); - le += sprintf(le, "%ld", aLong); - } break; - case POPT_ARG_FLOAT: - { double aDouble = *((float *)opt->arg); - le += sprintf(le, "%g", aDouble); - } break; - case POPT_ARG_DOUBLE: - { double aDouble = *((double *)opt->arg); - le += sprintf(le, "%g", aDouble); - } break; - case POPT_ARG_STRING: - { const char * s = *(const char **)opt->arg; - if (s == NULL) { - strcpy(le, "null"); le += strlen(le); - } else { - size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")"); - *le++ = '"'; - strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le); - if (slen < strlen(s)) { - strcpy(le, "..."); le += strlen(le); - } - *le++ = '"'; - } - } break; - case POPT_ARG_NONE: - default: - l = (char *)_free(l); - return NULL; - /*@notreached@*/ break; - } - *le++ = ')'; - *le = '\0'; -/*@=boundswrite@*/ - - return l; -} - -/** - * Display help text for an option. - * @param fp output file handle - * @param maxLeftCol - * @param opt option(s) - * @param translation_domain translation domain - */ -static void singleOptionHelp(FILE * fp, int maxLeftCol, - const struct poptOption * opt, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - int indentLength = maxLeftCol + 5; - int lineLength = 79 - indentLength; - const char * help = D_(translation_domain, opt->descrip); - const char * argDescrip = getArgDescrip(opt, translation_domain); - int helpLength; - char * defs = NULL; - char * left; - int nb = maxLeftCol + 1; - - /* Make sure there's more than enough room in target buffer. */ - if (opt->longName) nb += strlen(opt->longName); - if (argDescrip) nb += strlen(argDescrip); - -/*@-boundswrite@*/ - left = (char *)malloc(nb); - if (left == NULL) return; /* XXX can't happen */ - left[0] = '\0'; - left[maxLeftCol] = '\0'; - - if (opt->longName && opt->shortName) - sprintf(left, "-%c, %s%s", opt->shortName, - ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), - opt->longName); - else if (opt->shortName != '\0') - sprintf(left, "-%c", opt->shortName); - else if (opt->longName) - sprintf(left, "%s%s", - ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), - opt->longName); - if (!*left) goto out; - - if (argDescrip) { - char * le = left + strlen(left); - - if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) - *le++ = '['; - - /* Choose type of output */ - /*@-branchstate@*/ - if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) { - defs = singleOptionDefaultValue(lineLength, opt, translation_domain); - if (defs) { - char * t = (char *)malloc((help ? strlen(help) : 0) + - strlen(defs) + sizeof(" ")); - if (t) { - char * te = t; - *te = '\0'; - if (help) { - strcpy(te, help); te += strlen(te); - } - *te++ = ' '; - strcpy(te, defs); - defs = (char *)_free(defs); - } - defs = t; - } - } - /*@=branchstate@*/ - - if (opt->argDescrip == NULL) { - switch (opt->argInfo & POPT_ARG_MASK) { - case POPT_ARG_NONE: - break; - case POPT_ARG_VAL: -#ifdef NOTNOW /* XXX pug ugly nerdy output */ - { long aLong = opt->val; - int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS); - int negate = (opt->argInfo & POPT_ARGFLAG_NOT); - - /* Don't bother displaying typical values */ - if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L)) - break; - *le++ = '['; - switch (ops) { - case POPT_ARGFLAG_OR: - *le++ = '|'; - /*@innerbreak@*/ break; - case POPT_ARGFLAG_AND: - *le++ = '&'; - /*@innerbreak@*/ break; - case POPT_ARGFLAG_XOR: - *le++ = '^'; - /*@innerbreak@*/ break; - default: - /*@innerbreak@*/ break; - } - *le++ = '='; - if (negate) *le++ = '~'; - /*@-formatconst@*/ - le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong); - /*@=formatconst@*/ - *le++ = ']'; - } -#endif - break; - case POPT_ARG_INT: - case POPT_ARG_LONG: - case POPT_ARG_FLOAT: - case POPT_ARG_DOUBLE: - case POPT_ARG_STRING: - *le++ = '='; - strcpy(le, argDescrip); le += strlen(le); - break; - default: - break; - } - } else { - *le++ = '='; - strcpy(le, argDescrip); le += strlen(le); - } - if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) - *le++ = ']'; - *le = '\0'; - } -/*@=boundswrite@*/ - - if (help) - fprintf(fp," %-*s ", maxLeftCol, left); - else { - fprintf(fp," %s\n", left); - goto out; - } - - left = (char *)_free(left); - if (defs) { - help = defs; defs = NULL; - } - - helpLength = strlen(help); -/*@-boundsread@*/ - while (helpLength > lineLength) { - const char * ch; - char format[16]; - - ch = help + lineLength - 1; - while (ch > help && !isspace(*ch)) ch--; - if (ch == help) break; /* give up */ - while (ch > (help + 1) && isspace(*ch)) ch--; - ch++; - - sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength); - /*@-formatconst@*/ - fprintf(fp, format, help, " "); - /*@=formatconst@*/ - help = ch; - while (isspace(*help) && *help) help++; - helpLength = strlen(help); - } -/*@=boundsread@*/ - - if (helpLength) fprintf(fp, "%s\n", help); - -out: - /*@-dependenttrans@*/ - defs = (char *)_free(defs); - /*@=dependenttrans@*/ - left = (char *)_free(left); -} - -/** - * @param opt option(s) - * @param translation_domain translation domain - */ -static int maxArgWidth(const struct poptOption * opt, - /*@null@*/ const char * translation_domain) - /*@*/ -{ - int max = 0; - int len = 0; - const char * s; - - if (opt != NULL) - while (opt->longName || opt->shortName || opt->arg) { - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - if (opt->arg) /* XXX program error */ - len = maxArgWidth((const struct poptOption *)opt->arg, translation_domain); - if (len > max) max = len; - } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { - len = sizeof(" ")-1; - if (opt->shortName != '\0') len += sizeof("-X")-1; - if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1; - if (opt->longName) { - len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH) - ? sizeof("-")-1 : sizeof("--")-1); - len += strlen(opt->longName); - } - - s = getArgDescrip(opt, translation_domain); - if (s) - len += sizeof("=")-1 + strlen(s); - if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1; - if (len > max) max = len; - } - - opt++; - } - - return max; -} - -/** - * Display popt alias and exec help. - * @param fp output file handle - * @param items alias/exec array - * @param nitems no. of alias/exec entries - * @param left - * @param translation_domain translation domain - */ -static void itemHelp(FILE * fp, - /*@null@*/ poptItem items, int nitems, int left, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - poptItem item; - int i; - - if (items != NULL) - for (i = 0, item = items; i < nitems; i++, item++) { - const struct poptOption * opt; - opt = &item->option; - if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) - singleOptionHelp(fp, left, opt, translation_domain); - } -} - -/** - * Display help text for a table of options. - * @param con context - * @param fp output file handle - * @param table option(s) - * @param left - * @param translation_domain translation domain - */ -static void singleTableHelp(poptContext con, FILE * fp, - /*@null@*/ const struct poptOption * table, int left, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - const struct poptOption * opt; - const char *sub_transdom; - - if (table == poptAliasOptions) { - itemHelp(fp, con->aliases, con->numAliases, left, NULL); - itemHelp(fp, con->execs, con->numExecs, left, NULL); - return; - } - - if (table != NULL) - for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { - if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) - singleOptionHelp(fp, left, opt, translation_domain); - } - - if (table != NULL) - for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { - if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE) - continue; - sub_transdom = getTableTranslationDomain( - (const struct poptOption *)opt->arg); - if (sub_transdom == NULL) - sub_transdom = translation_domain; - - if (opt->descrip) - fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip)); - - singleTableHelp(con, fp, (const struct poptOption *)opt->arg, left, sub_transdom); - } -} - -/** - * @param con context - * @param fp output file handle - */ -static int showHelpIntro(poptContext con, FILE * fp) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - int len = 6; - const char * fn; - - fprintf(fp, POPT_("Usage:")); - if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) { -/*@-boundsread@*/ - /*@-nullderef@*/ /* LCL: wazzup? */ - fn = con->optionStack->argv[0]; - /*@=nullderef@*/ -/*@=boundsread@*/ - if (fn == NULL) return len; - if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1; - fprintf(fp, " %s", fn); - len += strlen(fn) + 1; - } - - return len; -} - -void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) -{ - int leftColWidth; - - (void) showHelpIntro(con, fp); - if (con->otherHelp) - fprintf(fp, " %s\n", con->otherHelp); - else - fprintf(fp, " %s\n", POPT_("[OPTION...]")); - - leftColWidth = maxArgWidth(con->options, NULL); - singleTableHelp(con, fp, con->options, leftColWidth, NULL); -} - -/** - * @param fp output file handle - * @param cursor - * @param opt option(s) - * @param translation_domain translation domain - */ -static int singleOptionUsage(FILE * fp, int cursor, - const struct poptOption * opt, - /*@null@*/ const char *translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - int len = 4; - char shortStr[2] = { '\0', '\0' }; - const char * item = shortStr; - const char * argDescrip = getArgDescrip(opt, translation_domain); - - if (opt->shortName != '\0' && opt->longName != NULL) { - len += 2; - if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; - len += strlen(opt->longName); - } else if (opt->shortName != '\0') { - len++; - shortStr[0] = opt->shortName; - shortStr[1] = '\0'; - } else if (opt->longName) { - len += strlen(opt->longName); - if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; - item = opt->longName; - } - - if (len == 4) return cursor; - - if (argDescrip) - len += strlen(argDescrip) + 1; - - if ((cursor + len) > 79) { - fprintf(fp, "\n "); - cursor = 7; - } - - if (opt->longName && opt->shortName) { - fprintf(fp, " [-%c|-%s%s%s%s]", - opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"), - opt->longName, - (argDescrip ? " " : ""), - (argDescrip ? argDescrip : "")); - } else { - fprintf(fp, " [-%s%s%s%s]", - ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"), - item, - (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""), - (argDescrip ? argDescrip : "")); - } - - return cursor + len + 1; -} - -/** - * Display popt alias and exec usage. - * @param fp output file handle - * @param cursor - * @param item alias/exec array - * @param nitems no. of ara/exec entries - * @param translation_domain translation domain - */ -static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies *fp, fileSystem @*/ -{ - int i; - - /*@-branchstate@*/ /* FIX: W2DO? */ - if (item != NULL) - for (i = 0; i < nitems; i++, item++) { - const struct poptOption * opt; - opt = &item->option; - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { - translation_domain = (const char *)opt->arg; - } else if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { - cursor = singleOptionUsage(fp, cursor, opt, translation_domain); - } - } - /*@=branchstate@*/ - - return cursor; -} - -/** - * Keep track of option tables already processed. - */ -typedef struct poptDone_s { - int nopts; - int maxopts; - const void ** opts; -} * poptDone; - -/** - * Display usage text for a table of options. - * @param con context - * @param fp output file handle - * @param cursor - * @param opt option(s) - * @param translation_domain translation domain - * @param done tables already processed - * @return - */ -static int singleTableUsage(poptContext con, FILE * fp, int cursor, - /*@null@*/ const struct poptOption * opt, - /*@null@*/ const char * translation_domain, - /*@null@*/ poptDone done) - /*@globals fileSystem @*/ - /*@modifies *fp, done, fileSystem @*/ -{ - /*@-branchstate@*/ /* FIX: W2DO? */ - if (opt != NULL) - for (; (opt->longName || opt->shortName || opt->arg) ; opt++) { - if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { - translation_domain = (const char *)opt->arg; - } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - if (done) { - int i = 0; - for (i = 0; i < done->nopts; i++) { -/*@-boundsread@*/ - const void * that = done->opts[i]; -/*@=boundsread@*/ - if (that == NULL || that != opt->arg) - /*@innercontinue@*/ continue; - /*@innerbreak@*/ break; - } - /* Skip if this table has already been processed. */ - if (opt->arg == NULL || i < done->nopts) - continue; -/*@-boundswrite@*/ - if (done->nopts < done->maxopts) - done->opts[done->nopts++] = (const void *) opt->arg; -/*@=boundswrite@*/ - } - cursor = singleTableUsage(con, fp, cursor, (const struct poptOption *)opt->arg, - translation_domain, done); - } else if ((opt->longName || opt->shortName) && - !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { - cursor = singleOptionUsage(fp, cursor, opt, translation_domain); - } - } - /*@=branchstate@*/ - - return cursor; -} - -/** - * Return concatenated short options for display. - * @todo Sub-tables should be recursed. - * @param opt option(s) - * @param fp output file handle - * @retval str concatenation of short options - * @return length of display string - */ -static int showShortOptions(const struct poptOption * opt, FILE * fp, - /*@null@*/ char * str) - /*@globals fileSystem @*/ - /*@modifies *str, *fp, fileSystem @*/ - /*@requires maxRead(str) >= 0 @*/ -{ - /* bufsize larger then the ascii set, lazy alloca on top level call. */ - char * s = (str != NULL ? str : (char *)memset(alloca(300), 0, 300)); - int len = 0; - -/*@-boundswrite@*/ - if (opt != NULL) - for (; (opt->longName || opt->shortName || opt->arg); opt++) { - if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK)) - s[strlen(s)] = opt->shortName; - else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) - if (opt->arg) /* XXX program error */ - len = showShortOptions( - (const struct poptOption *)opt->arg, fp, s); - } -/*@=boundswrite@*/ - - /* On return to top level, print the short options, return print length. */ - if (s == str && *s != '\0') { - fprintf(fp, " [-%s]", s); - len = strlen(s) + sizeof(" [-]")-1; - } - return len; -} - -void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) -{ - poptDone done = (poptDone)memset(alloca(sizeof(*done)), 0, sizeof(*done)); - int cursor; - - done->nopts = 0; - done->maxopts = 64; - cursor = done->maxopts * sizeof(*done->opts); -/*@-boundswrite@*/ - done->opts = (const void **)memset(alloca(cursor), 0, cursor); - done->opts[done->nopts++] = (const void *) con->options; -/*@=boundswrite@*/ - - cursor = showHelpIntro(con, fp); - cursor += showShortOptions(con->options, fp, NULL); - cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done); - cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL); - cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL); - - if (con->otherHelp) { - cursor += strlen(con->otherHelp) + 1; - if (cursor > 79) fprintf(fp, "\n "); - fprintf(fp, " %s", con->otherHelp); - } - - fprintf(fp, "\n"); -} - -void poptSetOtherOptionHelp(poptContext con, const char * text) -{ - con->otherHelp = (const char *)_free(con->otherHelp); - con->otherHelp = xstrdup(text); -} -/*@=type@*/ diff --git a/popt/poptint.h b/popt/poptint.h deleted file mode 100644 index 5d308efe96..0000000000 --- a/popt/poptint.h +++ /dev/null @@ -1,116 +0,0 @@ -/** \ingroup popt - * \file popt/poptint.h - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_POPTINT -#define H_POPTINT - -/** - * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL. - * @param p memory to free - * @retval NULL always - */ -/*@unused@*/ static inline /*@null@*/ void * -_free(/*@only@*/ /*@null@*/ const void * p) - /*@modifies p @*/ -{ - if (p != NULL) free((void *)p); - return NULL; -} - -/* Bit mask macros. */ -/*@-exporttype -redef @*/ -typedef unsigned int __pbm_bits; -/*@=exporttype =redef @*/ -#define __PBM_NBITS (8 * sizeof (__pbm_bits)) -#define __PBM_IX(d) ((d) / __PBM_NBITS) -#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS)) -/*@-exporttype -redef @*/ -typedef struct { - __pbm_bits bits[1]; -} pbm_set; -/*@=exporttype =redef @*/ -#define __PBM_BITS(set) ((set)->bits) - -#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits)) -#define PBM_FREE(s) _free(s); -#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d)) -#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d)) -#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0) - -struct optionStackEntry { - int argc; -/*@only@*/ /*@null@*/ - const char ** argv; -/*@only@*/ /*@null@*/ - pbm_set * argb; - int next; -/*@only@*/ /*@null@*/ - const char * nextArg; -/*@observer@*/ /*@null@*/ - const char * nextCharArg; -/*@dependent@*/ /*@null@*/ - poptItem currAlias; - int stuffed; -}; - -struct poptContext_s { - struct optionStackEntry optionStack[POPT_OPTION_DEPTH]; -/*@dependent@*/ - struct optionStackEntry * os; -/*@owned@*/ /*@null@*/ - const char ** leftovers; - int numLeftovers; - int nextLeftover; -/*@keep@*/ - const struct poptOption * options; - int restLeftover; -/*@only@*/ /*@null@*/ - const char * appName; -/*@only@*/ /*@null@*/ - poptItem aliases; - int numAliases; - int flags; -/*@owned@*/ /*@null@*/ - poptItem execs; - int numExecs; -/*@only@*/ /*@null@*/ - const char ** finalArgv; - int finalArgvCount; - int finalArgvAlloced; -/*@dependent@*/ /*@null@*/ - poptItem doExec; -/*@only@*/ - const char * execPath; - int execAbsolute; -/*@only@*/ - const char * otherHelp; -/*@null@*/ - pbm_set * arg_strip; -}; - -#ifdef HAVE_LIBINTL_H -#include -#endif - -#if defined(HAVE_GETTEXT) && !defined(__LCLINT__) -#define _(foo) gettext(foo) -#else -#define _(foo) foo -#endif - -#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) -#define D_(dom, str) dgettext(dom, str) -#define POPT_(foo) D_("popt", foo) -#else -#define D_(dom, str) str -#define POPT_(foo) foo -#endif - -#define N_(foo) foo - -#endif diff --git a/popt/poptparse.c b/popt/poptparse.c deleted file mode 100644 index b03deef085..0000000000 --- a/popt/poptparse.c +++ /dev/null @@ -1,227 +0,0 @@ -/** \ingroup popt - * \file popt/poptparse.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" - -#define POPT_ARGV_ARRAY_GROW_DELTA 5 - -/*@-boundswrite@*/ -int poptDupArgv(int argc, const char **argv, - int * argcPtr, const char *** argvPtr) -{ - size_t nb = (argc + 1) * sizeof(*argv); - const char ** argv2; - char * dst; - int i; - - if (argc <= 0 || argv == NULL) /* XXX can't happen */ - return POPT_ERROR_NOARG; - for (i = 0; i < argc; i++) { - if (argv[i] == NULL) - return POPT_ERROR_NOARG; - nb += strlen(argv[i]) + 1; - } - - dst = (char *)malloc(nb); - if (dst == NULL) /* XXX can't happen */ - return POPT_ERROR_MALLOC; - argv2 = (const char **) dst; - dst += (argc + 1) * sizeof(*argv); - - /*@-branchstate@*/ - for (i = 0; i < argc; i++) { - argv2[i] = dst; - dst += strlen(strcpy(dst, argv[i])) + 1; - } - /*@=branchstate@*/ - argv2[argc] = NULL; - - if (argvPtr) { - *argvPtr = argv2; - } else { - free(argv2); - argv2 = NULL; - } - if (argcPtr) - *argcPtr = argc; - return 0; -} -/*@=boundswrite@*/ - -/*@-bounds@*/ -int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) -{ - const char * src; - char quote = '\0'; - int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; - const char ** argv = (const char **)malloc(sizeof(*argv) * argvAlloced); - int argc = 0; - int buflen = strlen(s) + 1; - char * buf = (char*)memset(alloca(buflen), 0, buflen); - int rc = POPT_ERROR_MALLOC; - - if (argv == NULL) return rc; - argv[argc] = buf; - - for (src = s; *src != '\0'; src++) { - if (quote == *src) { - quote = '\0'; - } else if (quote != '\0') { - if (*src == '\\') { - src++; - if (!*src) { - rc = POPT_ERROR_BADQUOTE; - goto exit; - } - if (*src != quote) *buf++ = '\\'; - } - *buf++ = *src; - } else if (isspace(*src)) { - if (*argv[argc] != '\0') { - buf++, argc++; - if (argc == argvAlloced) { - argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; - argv = (const char **)realloc(argv, sizeof(*argv) * argvAlloced); - if (argv == NULL) goto exit; - } - argv[argc] = buf; - } - } else switch (*src) { - case '"': - case '\'': - quote = *src; - /*@switchbreak@*/ break; - case '\\': - src++; - if (!*src) { - rc = POPT_ERROR_BADQUOTE; - goto exit; - } - /*@fallthrough@*/ - default: - *buf++ = *src; - /*@switchbreak@*/ break; - } - } - - if (strlen(argv[argc])) { - argc++, buf++; - } - - rc = poptDupArgv(argc, argv, argcPtr, argvPtr); - -exit: - if (argv) free(argv); - return rc; -} -/*@=bounds@*/ - -/* still in the dev stage. - * return values, perhaps 1== file erro - * 2== line to long - * 3== umm.... more? - */ -int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags) -{ - char line[999]; - char * argstr; - char * p; - char * q; - char * x; - int t; - int argvlen = 0; - size_t maxlinelen = sizeof(line); - size_t linelen; - int maxargvlen = 480; - int linenum = 0; - - *argstrp = NULL; - - /* | this_is = our_line - * p q x - */ - - if (fp == NULL) - return POPT_ERROR_NULLARG; - - argstr = (char *)calloc(maxargvlen, sizeof(*argstr)); - if (argstr == NULL) return POPT_ERROR_MALLOC; - - while (fgets(line, (int)maxlinelen, fp) != NULL) { - linenum++; - p = line; - - /* loop until first non-space char or EOL */ - while( *p != '\0' && isspace(*p) ) - p++; - - linelen = strlen(p); - if (linelen >= maxlinelen-1) - return POPT_ERROR_OVERFLOW; /* XXX line too long */ - - if (*p == '\0' || *p == '\n') continue; /* line is empty */ - if (*p == '#') continue; /* comment line */ - - q = p; - - while (*q != '\0' && (!isspace(*q)) && *q != '=') - q++; - - if (isspace(*q)) { - /* a space after the name, find next non space */ - *q++='\0'; - while( *q != '\0' && isspace((int)*q) ) q++; - } - if (*q == '\0') { - /* single command line option (ie, no name=val, just name) */ - q[-1] = '\0'; /* kill off newline from fgets() call */ - argvlen += (t = q - p) + (sizeof(" --")-1); - if (argvlen >= maxargvlen) { - maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = (char *)realloc(argstr, maxargvlen); - if (argstr == NULL) return POPT_ERROR_MALLOC; - } - strcat(argstr, " --"); - strcat(argstr, p); - continue; - } - if (*q != '=') - continue; /* XXX for now, silently ignore bogus line */ - - /* *q is an equal sign. */ - *q++ = '\0'; - - /* find next non-space letter of value */ - while (*q != '\0' && isspace(*q)) - q++; - if (*q == '\0') - continue; /* XXX silently ignore missing value */ - - /* now, loop and strip all ending whitespace */ - x = p + linelen; - while (isspace(*--x)) - *x = 0; /* null out last char if space (including fgets() NL) */ - - /* rest of line accept */ - t = x - p; - argvlen += t + (sizeof("' --='")-1); - if (argvlen >= maxargvlen) { - maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = (char *)realloc(argstr, maxargvlen); - if (argstr == NULL) return POPT_ERROR_MALLOC; - } - strcat(argstr, " --"); - strcat(argstr, p); - strcat(argstr, "=\""); - strcat(argstr, q); - strcat(argstr, "\""); - } - - *argstrp = argstr; - return 0; -} diff --git a/popt/samba.m4 b/popt/samba.m4 deleted file mode 100644 index 9ee77dfa13..0000000000 --- a/popt/samba.m4 +++ /dev/null @@ -1,8 +0,0 @@ -m4_include(../popt/libpopt.m4) - -if test x"$POPT_OBJ" = "x"; then - SMB_EXT_LIB(LIBPOPT, [${POPT_LIBS}]) -else - SMB_INCLUDE_MK(../popt/config.mk) -fi - diff --git a/popt/system.h b/popt/system.h deleted file mode 100644 index 1d1b9dae88..0000000000 --- a/popt/system.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined (__GLIBC__) && defined(__LCLINT__) -/*@-declundef@*/ -/*@unchecked@*/ -extern __const __int32_t *__ctype_tolower; -/*@unchecked@*/ -extern __const __int32_t *__ctype_toupper; -/*@=declundef@*/ -#endif - -#include - -#include -#include -#include - -#if HAVE_MCHECK_H -#include -#endif - -#include -#include -#include - -#if HAVE_UNISTD_H -#include -#endif - -#ifdef __NeXT -/* access macros are not declared in non posix mode in unistd.h - - don't try to use posix on NeXTstep 3.3 ! */ -#include -#endif - -#if defined(__LCLINT__) -/*@-declundef -incondefs -redecl@*/ /* LCL: missing annotation */ -/*@only@*/ void * alloca (size_t __size) - /*@ensures MaxSet(result) == (__size - 1) @*/ - /*@*/; -/*@=declundef =incondefs =redecl@*/ -#endif - -/* AIX requires this to be the first thing in the file. */ -#ifndef __GNUC__ -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX -#pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -#elif defined(__GNUC__) && defined(__STRICT_ANSI__) -#define alloca __builtin_alloca -#endif - -/*@-redecl -redef@*/ -/*@mayexit@*/ /*@only@*/ char * xstrdup (const char *str) - /*@*/; -/*@=redecl =redef@*/ - -#if HAVE_MCHECK_H && defined(__GNUC__) -#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL) -#define xstrdup(_str) (strcpy((malloc(strlen(_str)+1) ? : vmefail()), (_str))) -#else -#define xstrdup(_str) strdup(_str) -#endif /* HAVE_MCHECK_H && defined(__GNUC__) */ - - -#include "popt.h" diff --git a/replace/.checker_innocent b/replace/.checker_innocent deleted file mode 100644 index e619176540..0000000000 --- a/replace/.checker_innocent +++ /dev/null @@ -1,4 +0,0 @@ ->>>MISTAKE21_create_files_6a9e68ada99a97cb ->>>MISTAKE21_os2_delete_9b2bfa7f38711d09 ->>>MISTAKE21_os2_delete_2fcc29aaa99a97cb ->>>SECURITY2_os2_delete_9b2bfa7f1c9396ca diff --git a/replace/Makefile.in b/replace/Makefile.in deleted file mode 100644 index c989835a8d..0000000000 --- a/replace/Makefile.in +++ /dev/null @@ -1,63 +0,0 @@ -#!gmake -# -CC = @CC@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -includedir = @includedir@ -libdir = @libdir@ -VPATH = @libreplacedir@ -srcdir = @srcdir@ -builddir = @builddir@ -INSTALL = @INSTALL@ -LIBS = @LIBS@ - -.PHONY: test all showflags install installcheck clean distclean realdistclean - -CFLAGS=-I. @CFLAGS@ -LDFLAGS=@LDFLAGS@ - -OBJS = @LIBREPLACEOBJ@ - -all: showflags libreplace.a testsuite - -showflags: - @echo 'libreplace will be compiled with flags:' - @echo ' CC = $(CC)' - @echo ' CFLAGS = $(CFLAGS)' - @echo ' LDFLAGS= $(LDFLAGS)' - @echo ' LIBS = $(LIBS)' - -install: all - mkdir -p $(libdir) - $(INSTALL) libreplace.a $(libdir) - -libreplace.a: $(OBJS) - ar -rcsv $@ $(OBJS) - -test: all - ./testsuite - -installcheck: install test - -TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o test/getifaddrs.o - -testsuite: libreplace.a $(TEST_OBJS) - $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) $(LIBS) - -.c.o: - @echo Compiling $*.c - @mkdir -p `dirname $@` - @$(CC) $(CFLAGS) -c $< -o $@ - -clean: - rm -f *.o test/*.o *.a testsuite - rm -f testfile.dat - -distclean: clean - rm -f *~ */*~ - rm -f config.log config.status config.h config.cache - rm -f Makefile - -realdistclean: distclean - rm -f configure config.h.in diff --git a/replace/README b/replace/README deleted file mode 100644 index 4d94317c4b..0000000000 --- a/replace/README +++ /dev/null @@ -1,113 +0,0 @@ -This subsystem ensures that we can always use a certain core set of -functions and types, that are either provided by the OS or by replacement -functions / definitions in this subsystem. The aim is to try to stick -to POSIX functions in here as much as possible. Convenience functions -that are available on no platform at all belong in other subsystems -(such as LIBUTIL). - -The following functions are guaranteed: - -ftruncate -strlcpy -strlcat -mktime -rename -initgroups -memmove -strdup -setlinebuf -vsyslog -timegm -setenv -unsetenv -strndup -strnlen -waitpid -seteuid -setegid -asprintf -snprintf -vasprintf -vsnprintf -opendir -readdir -telldir -seekdir -closedir -dlopen -dlclose -dlsym -dlerror -chroot -bzero -strerror -errno -mkdtemp -mkstemp (a secure one!) -pread -pwrite -getpass -readline (the library) -inet_ntoa -inet_ntop -inet_pton -inet_aton -strtoll -strtoull -socketpair -strptime -getaddrinfo -freeaddrinfo -getnameinfo -gai_strerror -getifaddrs -freeifaddrs -utime -utimes - -Types: -bool -socklen_t -uint_t -uint{8,16,32,64}_t -int{8,16,32,64}_t -intptr_t - -Constants: -PATH_NAME_MAX -UINT{16,32,64}_MAX -INT32_MAX -RTLD_LAZY -HOST_NAME_MAX -UINT16_MAX -UINT32_MAX -UINT64_MAX -CHAR_BIT - -Macros: -va_copy -__FUNCTION__ -__FILE__ -__LINE__ -__LINESTR__ -__location__ -__STRING -__STRINGSTRING -MIN -MAX -QSORT_CAST -ZERO_STRUCT -ZERO_STRUCTP -ZERO_STRUCTPN -ZERO_ARRAY -ARRAY_SIZE -PTR_DIFF - -Headers: -stdint.h -stdbool.h - -Prerequisites: -memset (for bzero) -syslog (for vsyslog) -mktemp (for mkstemp and mkdtemp) diff --git a/replace/aclocal.m4 b/replace/aclocal.m4 deleted file mode 100644 index 5605e476ba..0000000000 --- a/replace/aclocal.m4 +++ /dev/null @@ -1 +0,0 @@ -m4_include(libreplace.m4) diff --git a/replace/autoconf-2.60.m4 b/replace/autoconf-2.60.m4 deleted file mode 100644 index acdcd38efe..0000000000 --- a/replace/autoconf-2.60.m4 +++ /dev/null @@ -1,210 +0,0 @@ -# AC_GNU_SOURCE -# -------------- -AC_DEFUN([AC_GNU_SOURCE], -[AH_VERBATIM([_GNU_SOURCE], -[/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif])dnl -AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl -AC_BEFORE([$0], [AC_RUN_IFELSE])dnl -AC_DEFINE([_GNU_SOURCE]) -]) - -# _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST, -# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE) -# -------------------------------------------------------------- -# Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99') -# by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails, -# try again with each compiler option in the space-separated OPTION-LIST; if one -# helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE, -# else ACTION-IF-UNAVAILABLE. -AC_DEFUN([_AC_C_STD_TRY], -[AC_MSG_CHECKING([for $CC option to accept ISO ]m4_translit($1, [c], [C])) -AC_CACHE_VAL(ac_cv_prog_cc_$1, -[ac_cv_prog_cc_$1=no -ac_save_CC=$CC -AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])]) -for ac_arg in '' $4 -do - CC="$ac_save_CC $ac_arg" - _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg]) - test "x$ac_cv_prog_cc_$1" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC -])# AC_CACHE_VAL -case "x$ac_cv_prog_cc_$1" in - x) - AC_MSG_RESULT([none needed]) ;; - xno) - AC_MSG_RESULT([unsupported]) ;; - *) - CC="$CC $ac_cv_prog_cc_$1" - AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;; -esac -AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6]) -])# _AC_C_STD_TRY - -# _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE]) -# ---------------------------------------------------------------- -# If the C compiler is not in ISO C99 mode by default, try to add an -# option to output variable CC to make it so. This macro tries -# various options that select ISO C99 on some system or another. It -# considers the compiler to be in ISO C99 mode if it handles mixed -# code and declarations, _Bool, inline and restrict. -AC_DEFUN([_AC_PROG_CC_C99], -[_AC_C_STD_TRY([c99], -[[#include -#include -#include -#include -#include - -struct incomplete_array -{ - int datasize; - double data[]; -}; - -struct named_init { - int number; - const wchar_t *name; - double average; -}; - -typedef const char *ccp; - -static inline int -test_restrict(ccp restrict text) -{ - // See if C++-style comments work. - // Iterate through items via the restricted pointer. - // Also check for declarations in for loops. - for (unsigned int i = 0; *(text+i) != '\0'; ++i) - continue; - return 0; -} - -// Check varargs and va_copy work. -static void -test_varargs(const char *format, ...) -{ - va_list args; - va_start(args, format); - va_list args_copy; - va_copy(args_copy, args); - - const char *str; - int number; - float fnumber; - - while (*format) - { - switch (*format++) - { - case 's': // string - str = va_arg(args_copy, const char *); - break; - case 'd': // int - number = va_arg(args_copy, int); - break; - case 'f': // float - fnumber = (float) va_arg(args_copy, double); - break; - default: - break; - } - } - va_end(args_copy); - va_end(args); -} -]], -[[ - // Check bool and long long datatypes. - _Bool success = false; - long long int bignum = -1234567890LL; - unsigned long long int ubignum = 1234567890uLL; - - // Check restrict. - if (test_restrict("String literal") != 0) - success = true; - char *restrict newvar = "Another string"; - - // Check varargs. - test_varargs("s, d' f .", "string", 65, 34.234); - - // Check incomplete arrays work. - struct incomplete_array *ia = - malloc(sizeof(struct incomplete_array) + (sizeof(double) * 10)); - ia->datasize = 10; - for (int i = 0; i < ia->datasize; ++i) - ia->data[i] = (double) i * 1.234; - - // Check named initialisers. - struct named_init ni = { - .number = 34, - .name = L"Test wide string", - .average = 543.34343, - }; - - ni.number = 58; - - int dynamic_array[ni.number]; - dynamic_array[43] = 543; - - // work around unused variable warnings - return bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'; -]], -dnl Try -dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999) -dnl AIX -qlanglvl=extc99 (unused restrictive mode: -qlanglvl=stdc99) -dnl Intel ICC -c99 -dnl IRIX -c99 -dnl Solaris (unused because it causes the compiler to assume C99 semantics for -dnl library functions, and this is invalid before Solaris 10: -xc99) -dnl Tru64 -c99 -dnl with extended modes being tried first. -[[-std=gnu99 -c99 -qlanglvl=extc99]], [$1], [$2])[]dnl -])# _AC_PROG_CC_C99 - -# AC_PROG_CC_C99 -# -------------- -AC_DEFUN([AC_PROG_CC_C99], -[ AC_REQUIRE([AC_PROG_CC])dnl - _AC_PROG_CC_C99 -]) - -# AC_USE_SYSTEM_EXTENSIONS -# ------------------------ -# Enable extensions on systems that normally disable them, -# typically due to standards-conformance issues. -AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS], -[ - AC_BEFORE([$0], [AC_COMPILE_IFELSE]) - AC_BEFORE([$0], [AC_RUN_IFELSE]) - - AC_REQUIRE([AC_GNU_SOURCE]) - AC_REQUIRE([AC_AIX]) - AC_REQUIRE([AC_MINIX]) - - AH_VERBATIM([__EXTENSIONS__], -[/* Enable extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif]) - AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], - [ac_cv_safe_to_define___extensions__], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([ -# define __EXTENSIONS__ 1 - AC_INCLUDES_DEFAULT])], - [ac_cv_safe_to_define___extensions__=yes], - [ac_cv_safe_to_define___extensions__=no])]) - test $ac_cv_safe_to_define___extensions__ = yes && - AC_DEFINE([__EXTENSIONS__]) - AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) -]) diff --git a/replace/autogen.sh b/replace/autogen.sh deleted file mode 100755 index d46a4279f3..0000000000 --- a/replace/autogen.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f configure config.h.in - -autoheader || exit 1 -autoconf || exit 1 - -rm -rf autom4te.cache - -echo "Now run ./configure and then make." -exit 0 - diff --git a/replace/config.guess b/replace/config.guess deleted file mode 100755 index 354dbe175a..0000000000 --- a/replace/config.guess +++ /dev/null @@ -1,1464 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-08-03' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/replace/config.sub b/replace/config.sub deleted file mode 100755 index 23cd6fd75c..0000000000 --- a/replace/config.sub +++ /dev/null @@ -1,1577 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-07-08' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ms1 \ - | msp430 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | ms1-* \ - | msp430-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - m32c-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/replace/configure.ac b/replace/configure.ac deleted file mode 100644 index 81997e09b7..0000000000 --- a/replace/configure.ac +++ /dev/null @@ -1,30 +0,0 @@ -AC_PREREQ(2.50) -AC_INIT(replace.c) -AC_CONFIG_SRCDIR([replace.c]) -AC_CONFIG_HEADER(config.h) - -CFLAGS="$CFLAGS -I$srcdir" - -AC_LIBREPLACE_ALL_CHECKS -AC_LIBREPLACE_NETWORK_CHECKS - -if test "$ac_cv_prog_gcc" = yes; then - CFLAGS="$CFLAGS -Wall" - CFLAGS="$CFLAGS -W" - CFLAGS="$CFLAGS -Wshadow" - CFLAGS="$CFLAGS -Wstrict-prototypes" - CFLAGS="$CFLAGS -Wpointer-arith" - CFLAGS="$CFLAGS -Wcast-qual" - CFLAGS="$CFLAGS -Wcast-align" - CFLAGS="$CFLAGS -Wwrite-strings" - CFLAGS="$CFLAGS -Werror-implicit-function-declaration" - CFLAGS="$CFLAGS -Wformat=2" - CFLAGS="$CFLAGS -Wno-format-y2k" -fi - -LIBS="${LIBREPLACE_NETWORK_LIBS}" -AC_SUBST(LIBS) - -AC_SUBST(LDFLAGS) - -AC_OUTPUT(Makefile) diff --git a/replace/dlfcn.c b/replace/dlfcn.c deleted file mode 100644 index 3b109d7e40..0000000000 --- a/replace/dlfcn.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba system utilities - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jeremy Allison 1998-2002 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#ifdef HAVE_DL_H -#include -#endif - -#ifndef HAVE_DLOPEN -#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS -void *rep_dlopen(const char *name, unsigned int flags) -#else -void *rep_dlopen(const char *name, int flags) -#endif -{ -#ifdef HAVE_SHL_LOAD - if (name == NULL) - return PROG_HANDLE; - return (void *)shl_load(name, flags, 0); -#else - return NULL; -#endif -} -#endif - -#ifndef HAVE_DLSYM -void *rep_dlsym(void *handle, const char *symbol) -{ -#ifdef HAVE_SHL_FINDSYM - void *sym_addr; - if (!shl_findsym((shl_t *)&handle, symbol, TYPE_UNDEFINED, &sym_addr)) - return sym_addr; -#endif - return NULL; -} -#endif - -#ifndef HAVE_DLERROR -char *rep_dlerror(void) -{ - return "dynamic loading of objects not supported on this platform"; -} -#endif - -#ifndef HAVE_DLCLOSE -int rep_dlclose(void *handle) -{ -#ifdef HAVE_SHL_CLOSE - return shl_unload((shl_t)handle); -#else - return 0; -#endif -} -#endif diff --git a/replace/dlfcn.m4 b/replace/dlfcn.m4 deleted file mode 100644 index 42f56f26be..0000000000 --- a/replace/dlfcn.m4 +++ /dev/null @@ -1,31 +0,0 @@ -dnl dummies provided by dlfcn.c if not available -save_LIBS="$LIBS" -LIBS="" - -libreplace_cv_dlfcn=no -AC_SEARCH_LIBS(dlopen, dl) - -AC_CHECK_HEADERS(dlfcn.h) -AC_CHECK_FUNCS([dlopen dlsym dlerror dlclose],[],[libreplace_cv_dlfcn=yes]) - -libreplace_cv_shl=no -AC_SEARCH_LIBS(shl_load, sl) -AC_CHECK_HEADERS(dl.h) -AC_CHECK_FUNCS([shl_load shl_unload shl_findsym],[],[libreplace_cv_shl=yes]) - -AC_VERIFY_C_PROTOTYPE([void *dlopen(const char* filename, unsigned int flags)], - [ - return 0; - ],[ - AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsigned int flags]) - ],[],[ - #include - ]) - -if test x"${libreplace_cv_dlfcn}" = x"yes";then - LIBREPLACEOBJ="${LIBREPLACEOBJ} dlfcn.o" -fi - -LIBDL="$LIBS" -AC_SUBST(LIBDL) -LIBS="$save_LIBS" diff --git a/replace/getaddrinfo.c b/replace/getaddrinfo.c deleted file mode 100644 index c5cd52be93..0000000000 --- a/replace/getaddrinfo.c +++ /dev/null @@ -1,497 +0,0 @@ -/* -PostgreSQL Database Management System -(formerly known as Postgres, then as Postgres95) - -Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group - -Portions Copyright (c) 1994, The Regents of the University of California - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without a written agreement -is hereby granted, provided that the above copyright notice and this paragraph -and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING -LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS -TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - -*/ - -/*------------------------------------------------------------------------- - * - * getaddrinfo.c - * Support getaddrinfo() on platforms that don't have it. - * - * We also supply getnameinfo() here, assuming that the platform will have - * it if and only if it has getaddrinfo(). If this proves false on some - * platform, we'll need to split this file and provide a separate configure - * test for getnameinfo(). - * - * Copyright (c) 2003-2007, PostgreSQL Global Development Group - * - * Copyright (C) 2007 Jeremy Allison. - * Modified to return multiple IPv4 addresses for Samba. - * - *------------------------------------------------------------------------- - */ - -#include "replace.h" -#include "system/network.h" - -#ifndef SMB_MALLOC -#define SMB_MALLOC(s) malloc(s) -#endif - -#ifndef SMB_STRDUP -#define SMB_STRDUP(s) strdup(s) -#endif - -static int check_hostent_err(struct hostent *hp) -{ - if (!hp) { - switch (h_errno) { - case HOST_NOT_FOUND: - case NO_DATA: - return EAI_NONAME; - case TRY_AGAIN: - return EAI_AGAIN; - case NO_RECOVERY: - default: - return EAI_FAIL; - } - } - if (!hp->h_name || hp->h_addrtype != AF_INET) { - return EAI_FAIL; - } - return 0; -} - -static char *canon_name_from_hostent(struct hostent *hp, - int *perr) -{ - char *ret = NULL; - - *perr = check_hostent_err(hp); - if (*perr) { - return NULL; - } - ret = SMB_STRDUP(hp->h_name); - if (!ret) { - *perr = EAI_MEMORY; - } - return ret; -} - -static char *get_my_canon_name(int *perr) -{ - char name[HOST_NAME_MAX+1]; - - if (gethostname(name, HOST_NAME_MAX) == -1) { - *perr = EAI_FAIL; - return NULL; - } - /* Ensure null termination. */ - name[HOST_NAME_MAX] = '\0'; - return canon_name_from_hostent(gethostbyname(name), perr); -} - -static char *get_canon_name_from_addr(struct in_addr ip, - int *perr) -{ - return canon_name_from_hostent( - gethostbyaddr(&ip, sizeof(ip), AF_INET), - perr); -} - -static struct addrinfo *alloc_entry(const struct addrinfo *hints, - struct in_addr ip, - unsigned short port) -{ - struct sockaddr_in *psin = NULL; - struct addrinfo *ai = SMB_MALLOC(sizeof(*ai)); - - if (!ai) { - return NULL; - } - memset(ai, '\0', sizeof(*ai)); - - psin = SMB_MALLOC(sizeof(*psin)); - if (!psin) { - free(ai); - return NULL; - } - - memset(psin, '\0', sizeof(*psin)); - - psin->sin_family = AF_INET; - psin->sin_port = htons(port); - psin->sin_addr = ip; - - ai->ai_flags = 0; - ai->ai_family = AF_INET; - ai->ai_socktype = hints->ai_socktype; - ai->ai_protocol = hints->ai_protocol; - ai->ai_addrlen = sizeof(*psin); - ai->ai_addr = (struct sockaddr *) psin; - ai->ai_canonname = NULL; - ai->ai_next = NULL; - - return ai; -} - -/* - * get address info for a single ipv4 address. - * - * Bugs: - servname can only be a number, not text. - */ - -static int getaddr_info_single_addr(const char *service, - uint32_t addr, - const struct addrinfo *hints, - struct addrinfo **res) -{ - - struct addrinfo *ai = NULL; - struct in_addr ip; - unsigned short port = 0; - - if (service) { - port = (unsigned short)atoi(service); - } - ip.s_addr = htonl(addr); - - ai = alloc_entry(hints, ip, port); - if (!ai) { - return EAI_MEMORY; - } - - /* If we're asked for the canonical name, - * make sure it returns correctly. */ - if (!(hints->ai_flags & AI_NUMERICSERV) && - hints->ai_flags & AI_CANONNAME) { - int err; - if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) { - ai->ai_canonname = get_my_canon_name(&err); - } else { - ai->ai_canonname = - get_canon_name_from_addr(ip,&err); - } - if (ai->ai_canonname == NULL) { - freeaddrinfo(ai); - return err; - } - } - - *res = ai; - return 0; -} - -/* - * get address info for multiple ipv4 addresses. - * - * Bugs: - servname can only be a number, not text. - */ - -static int getaddr_info_name(const char *node, - const char *service, - const struct addrinfo *hints, - struct addrinfo **res) -{ - struct addrinfo *listp = NULL, *prevp = NULL; - char **pptr = NULL; - int err; - struct hostent *hp = NULL; - unsigned short port = 0; - - if (service) { - port = (unsigned short)atoi(service); - } - - hp = gethostbyname(node); - err = check_hostent_err(hp); - if (err) { - return err; - } - - for(pptr = hp->h_addr_list; *pptr; pptr++) { - struct in_addr ip = *(struct in_addr *)*pptr; - struct addrinfo *ai = alloc_entry(hints, ip, port); - - if (!ai) { - freeaddrinfo(listp); - return EAI_MEMORY; - } - - if (!listp) { - listp = ai; - prevp = ai; - ai->ai_canonname = SMB_STRDUP(hp->h_name); - if (!ai->ai_canonname) { - freeaddrinfo(listp); - return EAI_MEMORY; - } - } else { - prevp->ai_next = ai; - prevp = ai; - } - } - *res = listp; - return 0; -} - -/* - * get address info for ipv4 sockets. - * - * Bugs: - servname can only be a number, not text. - */ - -int rep_getaddrinfo(const char *node, - const char *service, - const struct addrinfo * hintp, - struct addrinfo ** res) -{ - struct addrinfo hints; - - /* Setup the hints struct. */ - if (hintp == NULL) { - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - } else { - memcpy(&hints, hintp, sizeof(hints)); - } - - if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) { - return EAI_FAMILY; - } - - if (hints.ai_socktype == 0) { - hints.ai_socktype = SOCK_STREAM; - } - - if (!node && !service) { - return EAI_NONAME; - } - - if (node) { - if (node[0] == '\0') { - return getaddr_info_single_addr(service, - INADDR_ANY, - &hints, - res); - } else if (hints.ai_flags & AI_NUMERICHOST) { - struct in_addr ip; - if (!inet_aton(node, &ip)) { - return EAI_FAIL; - } - return getaddr_info_single_addr(service, - ntohl(ip.s_addr), - &hints, - res); - } else { - return getaddr_info_name(node, - service, - &hints, - res); - } - } else if (hints.ai_flags & AI_PASSIVE) { - return getaddr_info_single_addr(service, - INADDR_ANY, - &hints, - res); - } - return getaddr_info_single_addr(service, - INADDR_LOOPBACK, - &hints, - res); -} - - -void rep_freeaddrinfo(struct addrinfo *res) -{ - struct addrinfo *next = NULL; - - for (;res; res = next) { - next = res->ai_next; - if (res->ai_canonname) { - free(res->ai_canonname); - } - if (res->ai_addr) { - free(res->ai_addr); - } - free(res); - } -} - - -const char *rep_gai_strerror(int errcode) -{ -#ifdef HAVE_HSTRERROR - int hcode; - - switch (errcode) - { - case EAI_NONAME: - hcode = HOST_NOT_FOUND; - break; - case EAI_AGAIN: - hcode = TRY_AGAIN; - break; - case EAI_FAIL: - default: - hcode = NO_RECOVERY; - break; - } - - return hstrerror(hcode); -#else /* !HAVE_HSTRERROR */ - - switch (errcode) - { - case EAI_NONAME: - return "Unknown host"; - case EAI_AGAIN: - return "Host name lookup failure"; -#ifdef EAI_BADFLAGS - case EAI_BADFLAGS: - return "Invalid argument"; -#endif -#ifdef EAI_FAMILY - case EAI_FAMILY: - return "Address family not supported"; -#endif -#ifdef EAI_MEMORY - case EAI_MEMORY: - return "Not enough memory"; -#endif -#ifdef EAI_NODATA - case EAI_NODATA: - return "No host data of that type was found"; -#endif -#ifdef EAI_SERVICE - case EAI_SERVICE: - return "Class type not found"; -#endif -#ifdef EAI_SOCKTYPE - case EAI_SOCKTYPE: - return "Socket type not supported"; -#endif - default: - return "Unknown server error"; - } -#endif /* HAVE_HSTRERROR */ -} - -static int gethostnameinfo(const struct sockaddr *sa, - char *node, - size_t nodelen, - int flags) -{ - int ret = -1; - char *p = NULL; - - if (!(flags & NI_NUMERICHOST)) { - struct hostent *hp = gethostbyaddr( - &((struct sockaddr_in *)sa)->sin_addr, - sizeof(struct in_addr), - sa->sa_family); - ret = check_hostent_err(hp); - if (ret == 0) { - /* Name looked up successfully. */ - ret = snprintf(node, nodelen, "%s", hp->h_name); - if (ret < 0 || (size_t)ret >= nodelen) { - return EAI_MEMORY; - } - if (flags & NI_NOFQDN) { - p = strchr(node,'.'); - if (p) { - *p = '\0'; - } - } - return 0; - } - - if (flags & NI_NAMEREQD) { - /* If we require a name and didn't get one, - * automatically fail. */ - return ret; - } - /* Otherwise just fall into the numeric host code... */ - } - p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); - ret = snprintf(node, nodelen, "%s", p); - if (ret < 0 || (size_t)ret >= nodelen) { - return EAI_MEMORY; - } - return 0; -} - -static int getservicenameinfo(const struct sockaddr *sa, - char *service, - size_t servicelen, - int flags) -{ - int ret = -1; - int port = ntohs(((struct sockaddr_in *)sa)->sin_port); - - if (!(flags & NI_NUMERICSERV)) { - struct servent *se = getservbyport( - port, - (flags & NI_DGRAM) ? "udp" : "tcp"); - if (se && se->s_name) { - /* Service name looked up successfully. */ - ret = snprintf(service, servicelen, "%s", se->s_name); - if (ret < 0 || (size_t)ret >= servicelen) { - return EAI_MEMORY; - } - return 0; - } - /* Otherwise just fall into the numeric service code... */ - } - ret = snprintf(service, servicelen, "%d", port); - if (ret < 0 || (size_t)ret >= servicelen) { - return EAI_MEMORY; - } - return 0; -} - -/* - * Convert an ipv4 address to a hostname. - * - * Bugs: - No IPv6 support. - */ -int rep_getnameinfo(const struct sockaddr *sa, socklen_t salen, - char *node, size_t nodelen, - char *service, size_t servicelen, int flags) -{ - - /* Invalid arguments. */ - if (sa == NULL || (node == NULL && service == NULL)) { - return EAI_FAIL; - } - - if (sa->sa_family != AF_INET) { - return EAI_FAIL; - } - - if (salen < sizeof(struct sockaddr_in)) { - return EAI_FAIL; - } - - if (node) { - return gethostnameinfo(sa, node, nodelen, flags); - } - - if (service) { - return getservicenameinfo(sa, service, servicelen, flags); - } - return 0; -} diff --git a/replace/getaddrinfo.h b/replace/getaddrinfo.h deleted file mode 100644 index dddd699b62..0000000000 --- a/replace/getaddrinfo.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -PostgreSQL Database Management System -(formerly known as Postgres, then as Postgres95) - -Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group - -Portions Copyright (c) 1994, The Regents of the University of California - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without a written agreement -is hereby granted, provided that the above copyright notice and this paragraph -and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING -LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS -TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - -*/ - -/*------------------------------------------------------------------------- - * - * getaddrinfo.h - * Support getaddrinfo() on platforms that don't have it. - * - * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, - * whether or not the library routine getaddrinfo() can be found. This - * policy is needed because on some platforms a manually installed libbind.a - * may provide getaddrinfo(), yet the system headers may not provide the - * struct definitions needed to call it. To avoid conflict with the libbind - * definition in such cases, we rename our routines to pg_xxx() via macros. - * - -in lib/replace we use rep_xxx() - - * This code will also work on platforms where struct addrinfo is defined - * in the system headers but no getaddrinfo() can be located. - * - * Copyright (c) 2003-2007, PostgreSQL Global Development Group - * - *------------------------------------------------------------------------- - */ -#ifndef GETADDRINFO_H -#define GETADDRINFO_H - -#ifndef HAVE_GETADDRINFO - -/* Rename private copies per comments above */ -#ifdef getaddrinfo -#undef getaddrinfo -#endif -#define getaddrinfo rep_getaddrinfo -#define HAVE_GETADDRINFO - -#ifdef freeaddrinfo -#undef freeaddrinfo -#endif -#define freeaddrinfo rep_freeaddrinfo -#define HAVE_FREEADDRINFO - -#ifdef gai_strerror -#undef gai_strerror -#endif -#define gai_strerror rep_gai_strerror -#define HAVE_GAI_STRERROR - -#ifdef getnameinfo -#undef getnameinfo -#endif -#define getnameinfo rep_getnameinfo -#define HAVE_GETNAMEINFO - -extern int rep_getaddrinfo(const char *node, const char *service, - const struct addrinfo * hints, struct addrinfo ** res); -extern void rep_freeaddrinfo(struct addrinfo * res); -extern const char *rep_gai_strerror(int errcode); -extern int rep_getnameinfo(const struct sockaddr * sa, socklen_t salen, - char *node, size_t nodelen, - char *service, size_t servicelen, int flags); -#endif /* HAVE_GETADDRINFO */ - -#endif /* GETADDRINFO_H */ diff --git a/replace/getifaddrs.c b/replace/getifaddrs.c deleted file mode 100644 index f6f0ec080c..0000000000 --- a/replace/getifaddrs.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Andrew Tridgell 1998 - Copyright (C) Jeremy Allison 2007 - Copyright (C) Jelmer Vernooij 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#define SOCKET_WRAPPER_NOT_REPLACE - -#include "replace.h" -#include "system/network.h" - -#include -#include -#include - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#ifndef SIOCGIFCONF -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif -#endif - -#ifdef HAVE_IFACE_GETIFADDRS -#define _FOUND_IFACE_ANY -#else - -void rep_freeifaddrs(struct ifaddrs *ifp) -{ - if (ifp != NULL) { - free(ifp->ifa_name); - free(ifp->ifa_addr); - free(ifp->ifa_netmask); - free(ifp->ifa_dstaddr); - freeifaddrs(ifp->ifa_next); - free(ifp); - } -} - -static struct sockaddr *sockaddr_dup(struct sockaddr *sa) -{ - struct sockaddr *ret; - socklen_t socklen; -#ifdef HAVE_SOCKADDR_SA_LEN - socklen = sa->sa_len; -#else - socklen = sizeof(struct sockaddr_storage); -#endif - ret = calloc(1, socklen); - if (ret == NULL) - return NULL; - memcpy(ret, sa, socklen); - return ret; -} -#endif - -#if HAVE_IFACE_IFCONF - -/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 - V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. - - It probably also works on any BSD style system. */ - -int rep_getifaddrs(struct ifaddrs **ifap) -{ - struct ifconf ifc; - char buff[8192]; - int fd, i, n; - struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; - struct ifaddrs *curif; - struct ifaddrs *lastif = NULL; - - *ifap = NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - - n = ifc.ifc_len / sizeof(struct ifreq); - - /* Loop through interfaces, looking for given IP address */ - for (i=n-1; i>=0; i--) { - if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) == -1) { - freeifaddrs(*ifap); - return -1; - } - - curif = calloc(1, sizeof(struct ifaddrs)); - curif->ifa_name = strdup(ifr[i].ifr_name); - curif->ifa_flags = ifr[i].ifr_flags; - curif->ifa_dstaddr = NULL; - curif->ifa_data = NULL; - curif->ifa_next = NULL; - - curif->ifa_addr = NULL; - if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != -1) { - curif->ifa_addr = sockaddr_dup(&ifr[i].ifr_addr); - } - - curif->ifa_netmask = NULL; - if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != -1) { - curif->ifa_netmask = sockaddr_dup(&ifr[i].ifr_addr); - } - - if (lastif == NULL) { - *ifap = curif; - } else { - lastif->ifa_next = curif; - } - lastif = curif; - } - - close(fd); - - return 0; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFCONF */ -#ifdef HAVE_IFACE_IFREQ - -#ifndef I_STR -#include -#endif - -/**************************************************************************** -this should cover most of the streams based systems -Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code -****************************************************************************/ -int rep_getifaddrs(struct ifaddrs **ifap) -{ - struct ifreq ifreq; - struct strioctl strioctl; - char buff[8192]; - int fd, i, n; - struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; - struct ifaddrs *curif; - struct ifaddrs *lastif = NULL; - - *ifap = NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - strioctl.ic_cmd = SIOCGIFCONF; - strioctl.ic_dp = buff; - strioctl.ic_len = sizeof(buff); - if (ioctl(fd, I_STR, &strioctl) < 0) { - close(fd); - return -1; - } - - /* we can ignore the possible sizeof(int) here as the resulting - number of interface structures won't change */ - n = strioctl.ic_len / sizeof(struct ifreq); - - /* we will assume that the kernel returns the length as an int - at the start of the buffer if the offered size is a - multiple of the structure size plus an int */ - if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { - ifr = (struct ifreq *)(buff + sizeof(int)); - } else { - ifr = (struct ifreq *)buff; - } - - /* Loop through interfaces */ - - for (i = 0; iifa_next = curif; - } - - strioctl.ic_cmd = SIOCGIFFLAGS; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - freeifaddrs(*ifap); - return -1; - } - - curif->ifa_flags = ifreq.ifr_flags; - - strioctl.ic_cmd = SIOCGIFADDR; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - freeifaddrs(*ifap); - return -1; - } - - curif->ifa_name = strdup(ifreq.ifr_name); - curif->ifa_addr = sockaddr_dup(&ifreq.ifr_addr); - curif->ifa_dstaddr = NULL; - curif->ifa_data = NULL; - curif->ifa_next = NULL; - curif->ifa_netmask = NULL; - - strioctl.ic_cmd = SIOCGIFNETMASK; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - freeifaddrs(*ifap); - return -1; - } - - curif->ifa_netmask = sockaddr_dup(&ifreq.ifr_addr); - - lastif = curif; - } - - close(fd); - - return 0; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFREQ */ -#ifdef HAVE_IFACE_AIX - -/**************************************************************************** -this one is for AIX (tested on 4.2) -****************************************************************************/ -int rep_getifaddrs(struct ifaddrs **ifap) -{ - char buff[8192]; - int fd, i; - struct ifconf ifc; - struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; - struct ifaddrs *curif; - struct ifaddrs *lastif = NULL; - - *ifap = NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - - /* Loop through interfaces */ - i = ifc.ifc_len; - - while (i > 0) { - uint_t inc; - - inc = ifr->ifr_addr.sa_len; - - if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { - freeaddrinfo(*ifap); - return -1; - } - - curif = calloc(1, sizeof(struct ifaddrs)); - if (lastif == NULL) { - *ifap = curif; - } else { - lastif->ifa_next = curif; - } - - curif->ifa_name = strdup(ifr->ifr_name); - curif->ifa_addr = sockaddr_dup(&ifr->ifr_addr); - curif->ifa_dstaddr = NULL; - curif->ifa_data = NULL; - curif->ifa_netmask = NULL; - curif->ifa_next = NULL; - - if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { - freeaddrinfo(*ifap); - return -1; - } - - curif->ifa_flags = ifr->ifr_flags; - - if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { - freeaddrinfo(*ifap); - return -1; - } - - curif->ifa_netmask = sockaddr_dup(&ifr->ifr_addr); - - lastif = curif; - - next: - /* - * Patch from Archie Cobbs (archie@whistle.com). The - * addresses in the SIOCGIFCONF interface list have a - * minimum size. Usually this doesn't matter, but if - * your machine has tunnel interfaces, etc. that have - * a zero length "link address", this does matter. */ - - if (inc < sizeof(ifr->ifr_addr)) - inc = sizeof(ifr->ifr_addr); - inc += IFNAMSIZ; - - ifr = (struct ifreq*) (((char*) ifr) + inc); - i -= inc; - } - - close(fd); - return 0; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_AIX */ -#ifndef _FOUND_IFACE_ANY -int rep_getifaddrs(struct ifaddrs **ifap) -{ - errno = ENOSYS; - return -1; -} -#endif diff --git a/replace/getpass.c b/replace/getpass.c deleted file mode 100644 index 0be618fc91..0000000000 --- a/replace/getpass.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Copyright (C) 1992-1998 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public License as -published by the Free Software Foundation; either version 3 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, see . */ - -/* Modified to use with samba by Jeremy Allison, 8th July 1995. */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "system/terminal.h" -#include "system/passwd.h" - -/* - * Define additional missing types - */ -#ifndef HAVE_SIG_ATOMIC_T_TYPE -typedef int sig_atomic_t; -#endif - -#ifndef SIGCLD -#define SIGCLD SIGCHLD -#endif - -#ifndef SIGNAL_CAST -#define SIGNAL_CAST (RETSIGTYPE (*)(int)) -#endif - -#ifdef SYSV_TERMIO - -/* SYSTEM V TERMIO HANDLING */ - -static struct termio t; - -#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) -#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) - -#ifndef TCSAFLUSH -#define TCSAFLUSH 1 -#endif - -#ifndef TCSANOW -#define TCSANOW 0 -#endif - -static int tcgetattr(int fd, struct termio *_t) -{ - return ioctl(fd, TCGETA, _t); -} - -static int tcsetattr(int fd, int flags, struct termio *_t) -{ - if(flags & TCSAFLUSH) - ioctl(fd, TCFLSH, TCIOFLUSH); - return ioctl(fd, TCSETS, _t); -} - -#elif !defined(TCSAFLUSH) - -/* BSD TERMIO HANDLING */ - -static struct sgttyb t; - -#define ECHO_IS_ON(t) ((t).sg_flags & ECHO) -#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO) - -#define TCSAFLUSH 1 -#define TCSANOW 0 - -static int tcgetattr(int fd, struct sgttyb *_t) -{ - return ioctl(fd, TIOCGETP, (char *)_t); -} - -static int tcsetattr(int fd, int flags, struct sgttyb *_t) -{ - return ioctl(fd, TIOCSETP, (char *)_t); -} - -#else /* POSIX TERMIO HANDLING */ -#define ECHO_IS_ON(t) ((t).c_lflag & ECHO) -#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO) -#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO) - -static struct termios t; -#endif /* SYSV_TERMIO */ - -static void catch_signal(int signum,void (*handler)(int )) -{ -#ifdef HAVE_SIGACTION - struct sigaction act; - struct sigaction oldact; - - memset(&act, 0, sizeof(act)); - - act.sa_handler = handler; -#ifdef SA_RESTART - /* - * We *want* SIGALRM to interrupt a system call. - */ - if(signum != SIGALRM) - act.sa_flags = SA_RESTART; -#endif - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask,signum); - sigaction(signum,&act,&oldact); -#else /* !HAVE_SIGACTION */ - /* FIXME: need to handle sigvec and systems with broken signal() */ - signal(signum, handler); -#endif -} - -static sig_atomic_t gotintr; -static int in_fd = -1; - -/*************************************************************** - Signal function to tell us were ^C'ed. -****************************************************************/ - -static void gotintr_sig(void) -{ - gotintr = 1; - if (in_fd != -1) - close(in_fd); /* Safe way to force a return. */ - in_fd = -1; -} - -char *rep_getpass(const char *prompt) -{ - FILE *in, *out; - int echo_off; - static char buf[256]; - static size_t bufsize = sizeof(buf); - size_t nread; - - /* Catch problematic signals */ - catch_signal(SIGINT, SIGNAL_CAST gotintr_sig); - - /* Try to write to and read from the terminal if we can. - If we can't open the terminal, use stderr and stdin. */ - - in = fopen ("/dev/tty", "w+"); - if (in == NULL) { - in = stdin; - out = stderr; - } else { - out = in; - } - - setvbuf(in, NULL, _IONBF, 0); - - /* Turn echoing off if it is on now. */ - - if (tcgetattr (fileno (in), &t) == 0) { - if (ECHO_IS_ON(t)) { - TURN_ECHO_OFF(t); - echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0; - TURN_ECHO_ON(t); - } else { - echo_off = 0; - } - } else { - echo_off = 0; - } - - /* Write the prompt. */ - fputs(prompt, out); - fflush(out); - - /* Read the password. */ - buf[0] = 0; - if (!gotintr) { - in_fd = fileno(in); - if (fgets(buf, bufsize, in) == NULL) { - buf[0] = 0; - } - } - nread = strlen(buf); - if (nread) { - if (buf[nread - 1] == '\n') - buf[nread - 1] = '\0'; - } - - /* Restore echoing. */ - if (echo_off) { - if (gotintr && in_fd == -1) { - in = fopen ("/dev/tty", "w+"); - } - if (in != NULL) - tcsetattr (fileno (in), TCSANOW, &t); - } - - fprintf(out, "\n"); - fflush(out); - - if (in && in != stdin) /* We opened the terminal; now close it. */ - fclose(in); - - /* Catch problematic signals */ - catch_signal(SIGINT, SIGNAL_CAST SIG_DFL); - - if (gotintr) { - printf("Interupted by signal.\n"); - fflush(stdout); - exit(1); - } - return buf; -} diff --git a/replace/getpass.m4 b/replace/getpass.m4 deleted file mode 100644 index b93817f9d3..0000000000 --- a/replace/getpass.m4 +++ /dev/null @@ -1,24 +0,0 @@ -AC_CHECK_FUNC(getpass, libreplace_cv_HAVE_GETPASS=yes) -AC_CHECK_FUNC(getpassphrase, libreplace_cv_HAVE_GETPASSPHRASE=yes) -if test x"$libreplace_cv_HAVE_GETPASS" = x"yes" -a x"$libreplace_cv_HAVE_GETPASSPHRASE" = x"yes"; then - AC_DEFINE(REPLACE_GETPASS_BY_GETPASSPHRASE, 1, [getpass returns <9 chars where getpassphrase returns <265 chars]) - AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) - LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" -else - -AC_CACHE_CHECK([whether getpass should be replaced],libreplace_cv_REPLACE_GETPASS,[ -SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I$libreplacedir/" -AC_TRY_COMPILE([ -#include "confdefs.h" -#define NO_CONFIG_H -#include "$libreplacedir/getpass.c" -],[],libreplace_cv_REPLACE_GETPASS=yes,libreplace_cv_REPLACE_GETPASS=no) -CPPFLAGS="$SAVE_CPPFLAGS" -]) -if test x"$libreplace_cv_REPLACE_GETPASS" = x"yes"; then - AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) - LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" -fi - -fi diff --git a/replace/inet_aton.c b/replace/inet_aton.c deleted file mode 100644 index c6b3bb11a7..0000000000 --- a/replace/inet_aton.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * replacement functions - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/network.h" - -/** - * We know that we have inet_pton from earlier libreplace checks. - */ -int rep_inet_aton(const char *src, struct in_addr *dst) -{ - return (inet_pton(AF_INET, src, dst) > 0) ? 1 : 0; -} diff --git a/replace/inet_ntoa.c b/replace/inet_ntoa.c deleted file mode 100644 index e3b80ebef8..0000000000 --- a/replace/inet_ntoa.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * replacement routines for broken systems - * Copyright (C) Andrew Tridgell 2003 - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/network.h" - -/** - * NOTE: this is not thread safe, but it can't be, either - * since it returns a pointer to static memory. - */ -char *rep_inet_ntoa(struct in_addr ip) -{ - uint8_t *p = (uint8_t *)&ip.s_addr; - static char buf[18]; - slprintf(buf, 17, "%d.%d.%d.%d", - (int)p[0], (int)p[1], (int)p[2], (int)p[3]); - return buf; -} diff --git a/replace/inet_ntop.c b/replace/inet_ntop.c deleted file mode 100644 index fb3d8e90c8..0000000000 --- a/replace/inet_ntop.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 1996-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#include "replace.h" -#include "system/network.h" - -#define NS_INT16SZ 2 -#define NS_IN6ADDRSZ 16 - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static const char *inet_ntop4(const unsigned char *src, char *dst, - socklen_t size); - -#ifdef AF_INET6 -static const char *inet_ntop6(const unsigned char *src, char *dst, - socklen_t size); -#endif - -/* char * - * isc_net_ntop(af, src, dst, size) - * convert a network format address to presentation format. - * return: - * pointer to presentation format address (`dst'), or NULL (see errno). - * author: - * Paul Vixie, 1996. - */ -const char * -rep_inet_ntop(int af, const void *src, char *dst, socklen_t size) -{ - switch (af) { - case AF_INET: - return (inet_ntop4(src, dst, size)); -#ifdef AF_INET6 - case AF_INET6: - return (inet_ntop6(src, dst, size)); -#endif - default: - errno = EAFNOSUPPORT; - return (NULL); - } - /* NOTREACHED */ -} - -/* const char * - * inet_ntop4(src, dst, size) - * format an IPv4 address - * return: - * `dst' (as a const) - * notes: - * (1) uses no statics - * (2) takes a unsigned char* not an in_addr as input - * author: - * Paul Vixie, 1996. - */ -static const char * -inet_ntop4(const unsigned char *src, char *dst, socklen_t size) -{ - static const char *fmt = "%u.%u.%u.%u"; - char tmp[sizeof "255.255.255.255"]; - size_t len; - - len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); - if (len >= size) { - errno = ENOSPC; - return (NULL); - } - memcpy(dst, tmp, len + 1); - - return (dst); -} - -/* const char * - * isc_inet_ntop6(src, dst, size) - * convert IPv6 binary address into presentation (printable) format - * author: - * Paul Vixie, 1996. - */ -#ifdef AF_INET6 -static const char * -inet_ntop6(const unsigned char *src, char *dst, socklen_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; - struct { int base, len; } best, cur; - unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; - int i, inc; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < NS_IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - best.len = 0; - cur.base = -1; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - if (words[i] == 0) { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) - *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) - return (NULL); - tp += strlen(tp); - break; - } - inc = snprintf(tp, 5, "%x", words[i]); - if (inc >= 5) { - abort(); - } - tp += inc; - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { - errno = ENOSPC; - return (NULL); - } - memcpy(dst, tmp, tp - tmp); - return (dst); -} -#endif /* AF_INET6 */ diff --git a/replace/inet_pton.c b/replace/inet_pton.c deleted file mode 100644 index 80e4865ef4..0000000000 --- a/replace/inet_pton.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 1996-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "replace.h" -#include "system/network.h" - -#define NS_INT16SZ 2 -#define NS_INADDRSZ 4 -#define NS_IN6ADDRSZ 16 - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static int inet_pton4(const char *src, unsigned char *dst); -#ifdef AF_INET6 -static int inet_pton6(const char *src, unsigned char *dst); -#endif - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * author: - * Paul Vixie, 1996. - */ -int -rep_inet_pton(int af, - const char *src, - void *dst) -{ - switch (af) { - case AF_INET: - return (inet_pton4(src, dst)); -#ifdef AF_INET6 - case AF_INET6: - return (inet_pton6(src, dst)); -#endif - default: - errno = EAFNOSUPPORT; - return (-1); - } - /* NOTREACHED */ -} - -/* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton4(src, dst) - const char *src; - unsigned char *dst; -{ - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[NS_INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr(digits, ch)) != NULL) { - unsigned int new = *tp * 10 + (pch - digits); - - if (new > 255) - return (0); - *tp = new; - if (! saw_digit) { - if (++octets > 4) - return (0); - saw_digit = 1; - } - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } else - return (0); - } - if (octets < 4) - return (0); - memcpy(dst, tmp, NS_INADDRSZ); - return (1); -} - -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -#ifdef AF_INET6 -static int -inet_pton6(src, dst) - const char *src; - unsigned char *dst; -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - unsigned int val; - - memset((tp = tmp), '\0', NS_IN6ADDRSZ); - endp = tp + NS_IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (val > 0xffff) - return (0); - saw_xdigit = 1; - continue; - } - if (ch == ':') { - curtok = src; - if (!saw_xdigit) { - if (colonp) - return (0); - colonp = tp; - continue; - } - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += NS_INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if (saw_xdigit) { - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = tp - colonp; - int i; - - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) - return (0); - memcpy(dst, tmp, NS_IN6ADDRSZ); - return (1); -} -#endif diff --git a/replace/install-sh b/replace/install-sh deleted file mode 100755 index 58719246f0..0000000000 --- a/replace/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -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=: - 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 diff --git a/replace/libreplace.m4 b/replace/libreplace.m4 deleted file mode 100644 index 71fa041672..0000000000 --- a/replace/libreplace.m4 +++ /dev/null @@ -1,303 +0,0 @@ -AC_DEFUN_ONCE(AC_LIBREPLACE_LOCATION_CHECKS, -[ -echo "LIBREPLACE_LOCATION_CHECKS: START" - -dnl find the libreplace sources. This is meant to work both for -dnl libreplace standalone builds, and builds of packages using libreplace -libreplacedir="" -libreplacepaths="$srcdir $srcdir/lib/replace $srcdir/libreplace $srcdir/../libreplace $srcdir/../replace" -for d in $libreplacepaths; do - if test -f "$d/replace.c"; then - libreplacedir="$d" - AC_SUBST(libreplacedir) - break; - fi -done -if test x"$libreplacedir" = "x"; then - AC_MSG_ERROR([cannot find libreplace in $libreplacepaths]) -fi -LIBREPLACEOBJ="replace.o" -AC_SUBST(LIBREPLACEOBJ) - -AC_CANONICAL_BUILD -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -echo "LIBREPLACE_LOCATION_CHECKS: END" -]) dnl end AC_LIBREPLACE_LOCATION_CHECKS - - -AC_DEFUN_ONCE(AC_LIBREPLACE_BROKEN_CHECKS, -[ -echo "LIBREPLACE_BROKEN_CHECKS: START" - -dnl find the libreplace sources. This is meant to work both for -dnl libreplace standalone builds, and builds of packages using libreplace -libreplacedir="" -for d in "$srcdir" "$srcdir/lib/replace" "$srcdir/libreplace" "$srcdir/../libreplace" "$srcdir/../replace"; do - if test -f "$d/replace.c"; then - libreplacedir="$d" - AC_SUBST(libreplacedir) - break; - fi -done -LIBREPLACEOBJ="replace.o" -AC_SUBST(LIBREPLACEOBJ) - -LIBREPLACEOBJ="${LIBREPLACEOBJ} snprintf.o" - -AC_TYPE_SIGNAL -AC_TYPE_UID_T -AC_TYPE_MODE_T -AC_TYPE_OFF_T -AC_TYPE_SIZE_T -AC_TYPE_PID_T -AC_STRUCT_ST_RDEV -AC_CHECK_TYPE(ino_t,unsigned) -AC_CHECK_TYPE(loff_t,off_t) -AC_CHECK_TYPE(offset_t,loff_t) - -AC_FUNC_MEMCMP - -AC_CHECK_FUNCS(pipe strftime srandom random srand rand usleep setbuffer lstat getpgrp) - -AC_CHECK_HEADERS(stdbool.h stdint.h sys/select.h) -AC_CHECK_HEADERS(setjmp.h) - -LIBREPLACE_PROVIDE_HEADER([stdint.h]) -LIBREPLACE_PROVIDE_HEADER([stdbool.h]) - -AC_CHECK_TYPE(bool, -[AC_DEFINE(HAVE_BOOL, 1, [Whether the bool type is available])],, -[ -AC_INCLUDES_DEFAULT -#ifdef HAVE_STDBOOL_H -#include -#endif] -) - -AC_CHECK_TYPE(_Bool, -[AC_DEFINE(HAVE__Bool, 1, [Whether the _Bool type is available])],, -[ -AC_INCLUDES_DEFAULT -#ifdef HAVE_STDBOOL_H -#include -#endif] -) - -AC_CACHE_CHECK([for working mmap],libreplace_cv_HAVE_MMAP,[ -AC_TRY_RUN([#include "$libreplacedir/test/shared_mmap.c"], - libreplace_cv_HAVE_MMAP=yes,libreplace_cv_HAVE_MMAP=no,libreplace_cv_HAVE_MMAP=cross)]) -if test x"$libreplace_cv_HAVE_MMAP" = x"yes"; then - AC_DEFINE(HAVE_MMAP,1,[Whether mmap works]) -fi - - -AC_CHECK_HEADERS(sys/syslog.h syslog.h) -AC_CHECK_HEADERS(sys/time.h time.h) -AC_CHECK_HEADERS(stdarg.h vararg.h) -AC_CHECK_HEADERS(sys/mount.h mntent.h) -AC_CHECK_HEADERS(stropts.h) - -AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) -AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) -AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup) -AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp) -AC_CHECK_FUNCS(isatty) -AC_HAVE_DECL(setresuid, [#include ]) -AC_HAVE_DECL(setresgid, [#include ]) -AC_HAVE_DECL(errno, [#include ]) - -AC_CACHE_CHECK([for secure mkstemp],libreplace_cv_HAVE_SECURE_MKSTEMP,[ -AC_TRY_RUN([#include -#include -#include -#include -main() { - struct stat st; - char tpl[20]="/tmp/test.XXXXXX"; - int fd = mkstemp(tpl); - if (fd == -1) exit(1); - unlink(tpl); - if (fstat(fd, &st) != 0) exit(1); - if ((st.st_mode & 0777) != 0600) exit(1); - exit(0); -}], -libreplace_cv_HAVE_SECURE_MKSTEMP=yes, -libreplace_cv_HAVE_SECURE_MKSTEMP=no, -libreplace_cv_HAVE_SECURE_MKSTEMP=cross)]) -if test x"$libreplace_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then - AC_DEFINE(HAVE_SECURE_MKSTEMP,1,[Whether mkstemp is secure]) -fi - -dnl Provided by snprintf.c: -AC_CHECK_HEADERS(stdio.h strings.h) -AC_CHECK_DECLS([snprintf, vsnprintf, asprintf, vasprintf]) -AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf) - -AC_CACHE_CHECK([for C99 vsnprintf],libreplace_cv_HAVE_C99_VSNPRINTF,[ -AC_TRY_RUN([ -#include -#include -#include -#include -void foo(const char *format, ...) { - va_list ap; - int len; - char buf[20]; - long long l = 1234567890; - l *= 100; - - va_start(ap, format); - len = vsnprintf(buf, 0, format, ap); - va_end(ap); - if (len != 5) exit(1); - - va_start(ap, format); - len = vsnprintf(0, 0, format, ap); - va_end(ap); - if (len != 5) exit(2); - - if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(3); - - if (snprintf(buf, 20, "%lld", l) != 12 || strcmp(buf, "123456789000") != 0) exit(4); - if (snprintf(buf, 20, "%zu", 123456789) != 9 || strcmp(buf, "123456789") != 0) exit(5); - if (snprintf(buf, 20, "%2\$d %1\$d", 3, 4) != 3 || strcmp(buf, "4 3") != 0) exit(6); - if (snprintf(buf, 20, "%s", 0) < 3) exit(7); - - exit(0); -} -main() { foo("hello"); } -], -libreplace_cv_HAVE_C99_VSNPRINTF=yes,libreplace_cv_HAVE_C99_VSNPRINTF=no,libreplace_cv_HAVE_C99_VSNPRINTF=cross)]) -if test x"$libreplace_cv_HAVE_C99_VSNPRINTF" = x"yes"; then - AC_DEFINE(HAVE_C99_VSNPRINTF,1,[Whether there is a C99 compliant vsnprintf]) -fi - - -dnl VA_COPY -AC_CACHE_CHECK([for va_copy],libreplace_cv_HAVE_VA_COPY,[ -AC_TRY_LINK([#include -va_list ap1,ap2;], [va_copy(ap1,ap2);], -libreplace_cv_HAVE_VA_COPY=yes,libreplace_cv_HAVE_VA_COPY=no)]) -if test x"$libreplace_cv_HAVE_VA_COPY" = x"yes"; then - AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available]) -fi - -if test x"$libreplace_cv_HAVE_VA_COPY" != x"yes"; then -AC_CACHE_CHECK([for __va_copy],libreplace_cv_HAVE___VA_COPY,[ -AC_TRY_LINK([#include -va_list ap1,ap2;], [__va_copy(ap1,ap2);], -libreplace_cv_HAVE___VA_COPY=yes,libreplace_cv_HAVE___VA_COPY=no)]) -if test x"$libreplace_cv_HAVE___VA_COPY" = x"yes"; then - AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available]) -fi -fi - -dnl __FUNCTION__ macro -AC_CACHE_CHECK([for __FUNCTION__ macro],libreplace_cv_HAVE_FUNCTION_MACRO,[ -AC_TRY_COMPILE([#include ], [printf("%s\n", __FUNCTION__);], -libreplace_cv_HAVE_FUNCTION_MACRO=yes,libreplace_cv_HAVE_FUNCTION_MACRO=no)]) -if test x"$libreplace_cv_HAVE_FUNCTION_MACRO" = x"yes"; then - AC_DEFINE(HAVE_FUNCTION_MACRO,1,[Whether there is a __FUNCTION__ macro]) -else - dnl __func__ macro - AC_CACHE_CHECK([for __func__ macro],libreplace_cv_HAVE_func_MACRO,[ - AC_TRY_COMPILE([#include ], [printf("%s\n", __func__);], - libreplace_cv_HAVE_func_MACRO=yes,libreplace_cv_HAVE_func_MACRO=no)]) - if test x"$libreplace_cv_HAVE_func_MACRO" = x"yes"; then - AC_DEFINE(HAVE_func_MACRO,1,[Whether there is a __func__ macro]) - fi -fi - -AC_CHECK_HEADERS([sys/param.h limits.h]) - -AC_CHECK_TYPE(comparison_fn_t, -[AC_DEFINE(HAVE_COMPARISON_FN_T, 1,[Whether or not we have comparison_fn_t])]) - -AC_HAVE_DECL(setenv, [#include ]) -AC_CHECK_FUNCS(setenv unsetenv) - -AC_CHECK_FUNCS(strnlen) -AC_CHECK_FUNCS(strtoull __strtoull strtouq strtoll __strtoll strtoq) - -# this test disabled as we don't actually need __VA_ARGS__ yet -AC_TRY_CPP([ -#define eprintf(...) fprintf(stderr, __VA_ARGS__) -eprintf("bla", "bar"); -], AC_DEFINE(HAVE__VA_ARGS__MACRO, 1, [Whether the __VA_ARGS__ macro is available])) - - -AC_CACHE_CHECK([for sig_atomic_t type],libreplace_cv_sig_atomic_t, [ - AC_TRY_COMPILE([ -#include -#if STDC_HEADERS -#include -#include -#endif -#include ],[sig_atomic_t i = 0], - libreplace_cv_sig_atomic_t=yes,libreplace_cv_sig_atomic_t=no)]) -if test x"$libreplace_cv_sig_atomic_t" = x"yes"; then - AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE,1,[Whether we have the atomic_t variable type]) -fi - - -AC_CACHE_CHECK([for O_DIRECT flag to open(2)],libreplace_cv_HAVE_OPEN_O_DIRECT,[ -AC_TRY_COMPILE([ -#include -#ifdef HAVE_FCNTL_H -#include -#endif], -[int fd = open("/dev/null", O_DIRECT);], -libreplace_cv_HAVE_OPEN_O_DIRECT=yes,libreplace_cv_HAVE_OPEN_O_DIRECT=no)]) -if test x"$libreplace_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then - AC_DEFINE(HAVE_OPEN_O_DIRECT,1,[Whether the open(2) accepts O_DIRECT]) -fi - - -dnl Check if the C compiler understands volatile (it should, being ANSI). -AC_CACHE_CHECK([that the C compiler understands volatile],libreplace_cv_volatile, [ - AC_TRY_COMPILE([#include ],[volatile int i = 0], - libreplace_cv_volatile=yes,libreplace_cv_volatile=no)]) -if test x"$libreplace_cv_volatile" = x"yes"; then - AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile]) -fi - -m4_include(system/config.m4) - -m4_include(dlfcn.m4) -m4_include(getpass.m4) -m4_include(strptime.m4) -m4_include(win32.m4) -m4_include(timegm.m4) -m4_include(repdir.m4) - -AC_CHECK_FUNCS([syslog printf memset memcpy],,[AC_MSG_ERROR([Required function not found])]) - -echo "LIBREPLACE_BROKEN_CHECKS: END" -]) dnl end AC_LIBREPLACE_BROKEN_CHECKS - -AC_DEFUN_ONCE(AC__LIBREPLACE_ALL_CHECKS_START, -[ -#LIBREPLACE_ALL_CHECKS: START" -]) -AC_DEFUN_ONCE(AC__LIBREPLACE_ALL_CHECKS_END, -[ -#LIBREPLACE_ALL_CHECKS: END" -]) -m4_define(AC_LIBREPLACE_ALL_CHECKS, -[ -AC__LIBREPLACE_ALL_CHECKS_START -AC_LIBREPLACE_LOCATION_CHECKS -AC_LIBREPLACE_CC_CHECKS -AC_LIBREPLACE_BROKEN_CHECKS -AC__LIBREPLACE_ALL_CHECKS_END -CFLAGS="$CFLAGS -I$libreplacedir" -]) - -m4_include(libreplace_cc.m4) -m4_include(libreplace_ld.m4) -m4_include(libreplace_network.m4) -m4_include(libreplace_macros.m4) - -m4_ifndef([AC_USE_SYSTEM_EXTENSIONS],[m4_include(autoconf-2.60.m4)]) diff --git a/replace/libreplace_cc.m4 b/replace/libreplace_cc.m4 deleted file mode 100644 index 30c63f2f05..0000000000 --- a/replace/libreplace_cc.m4 +++ /dev/null @@ -1,182 +0,0 @@ - -AC_DEFUN_ONCE(AC__LIBREPLACE_ONLY_CC_CHECKS_START, -[ -echo "LIBREPLACE_CC_CHECKS: START" -]) - -AC_DEFUN_ONCE(AC__LIBREPLACE_ONLY_CC_CHECKS_END, -[ -echo "LIBREPLACE_CC_CHECKS: END" -]) - -dnl -dnl -dnl AC_LIBREPLACE_CC_CHECKS -dnl -dnl Note: we need to use m4_define instead of AC_DEFUN because -dnl of the ordering of tests -dnl -dnl -m4_define(AC_LIBREPLACE_CC_CHECKS, -[ -AC__LIBREPLACE_ONLY_CC_CHECKS_START - -dnl stop the C89 attempt by autoconf - if autoconf detects -Ae it will enable it -dnl which conflicts with C99 on HPUX -ac_cv_prog_cc_Ae=no - -savedCFLAGS=$CFLAGS -AC_PROG_CC -CFLAGS=$savedCFLAGS - -dnl don't try for C99 if we are using gcc, as otherwise we -dnl lose immediate structure constants -if test x"$GCC" != x"yes" ; then -AC_PROG_CC_C99 -fi - -if test x"$GCC" = x"yes" ; then - AC_MSG_CHECKING([for version of gcc]) - GCC_VERSION=`$CC -dumpversion` - AC_MSG_RESULT(${GCC_VERSION}) -fi -AC_USE_SYSTEM_EXTENSIONS -AC_C_BIGENDIAN -AC_C_INLINE -LIBREPLACE_C99_STRUCT_INIT([],[AC_MSG_WARN([c99 structure initializer are not supported])]) - -AC_PROG_INSTALL - -AC_ISC_POSIX -AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) - -AC_SYS_LARGEFILE - -dnl Add #include for broken IRIX header files -case "$host_os" in - *irix6*) AC_ADD_INCLUDE() - ;; - *hpux*) - # mmap on HPUX is completely broken... - AC_DEFINE(MMAP_BLACKLIST, 1, [Whether MMAP is broken]) - if test "`uname -r`" = "B.11.00" -o "`uname -r`" = "B.11.11"; then - AC_MSG_WARN([Enabling HPUX 11.00/11.11 header bug workaround]) - CFLAGS="$CFLAGS -Dpread=pread64 -Dpwrite=pwrite64" - fi - if test "`uname -r`" = "B.11.23"; then - AC_MSG_WARN([Enabling HPUX 11.23 machine/sys/getppdp.h bug workaround]) - CFLAGS="$CFLAGS -D_MACHINE_SYS_GETPPDP_INCLUDED" - fi - ;; - *aix*) - AC_DEFINE(BROKEN_STRNDUP, 1, [Whether strndup is broken]) - AC_DEFINE(BROKEN_STRNLEN, 1, [Whether strnlen is broken]) - if test "${GCC}" != "yes"; then - ## for funky AIX compiler using strncpy() - CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" - fi - ;; - *osf*) - # this brings in socklen_t - AC_N_DEFINE(_XOPEN_SOURCE,600) - AC_N_DEFINE(_OSF_SOURCE) - ;; - # - # VOS may need to have POSIX support and System V compatibility enabled. - # - *vos*) - case "$CFLAGS" in - *-D_POSIX_C_SOURCE*);; - *) - CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112L" - AC_DEFINE(_POSIX_C_SOURCE, 200112L, [Whether to enable POSIX support]) - ;; - esac - case "$CFLAGS" in - *-D_SYSV*|*-D_SVID_SOURCE*);; - *) - CFLAGS="$CFLAGS -D_SYSV" - AC_DEFINE(_SYSV, 1, [Whether to enable System V compatibility]) - ;; - esac - ;; -esac - - - -AC_CHECK_HEADERS([standards.h]) - -# Solaris needs HAVE_LONG_LONG defined -AC_CHECK_TYPES(long long) - -AC_CHECK_SIZEOF(int) -AC_CHECK_SIZEOF(char) -AC_CHECK_SIZEOF(short) -AC_CHECK_SIZEOF(long) -AC_CHECK_SIZEOF(long long) - -AC_CHECK_TYPE(uint_t, unsigned int) -AC_CHECK_TYPE(int8_t, char) -AC_CHECK_TYPE(uint8_t, unsigned char) -AC_CHECK_TYPE(int16_t, short) -AC_CHECK_TYPE(uint16_t, unsigned short) - -if test $ac_cv_sizeof_int -eq 4 ; then -AC_CHECK_TYPE(int32_t, int) -AC_CHECK_TYPE(uint32_t, unsigned int) -elif test $ac_cv_size_long -eq 4 ; then -AC_CHECK_TYPE(int32_t, long) -AC_CHECK_TYPE(uint32_t, unsigned long) -else -AC_MSG_ERROR([LIBREPLACE no 32-bit type found]) -fi - -AC_CHECK_TYPE(int64_t, long long) -AC_CHECK_TYPE(uint64_t, unsigned long long) - -AC_CHECK_TYPE(size_t, unsigned int) -AC_CHECK_TYPE(ssize_t, int) - -AC_CHECK_SIZEOF(off_t) -AC_CHECK_SIZEOF(size_t) -AC_CHECK_SIZEOF(ssize_t) - -AC_CHECK_TYPE(intptr_t, long long) -AC_CHECK_TYPE(uintptr_t, unsigned long long) -AC_CHECK_TYPE(ptrdiff_t, unsigned long long) - -if test x"$ac_cv_type_long_long" != x"yes";then - AC_MSG_ERROR([LIBREPLACE needs type 'long long']) -fi -if test $ac_cv_sizeof_long_long -lt 8;then - AC_MSG_ERROR([LIBREPLACE needs sizeof(long long) >= 8]) -fi - -############################################ -# check if the compiler can do immediate structures -AC_SUBST(libreplace_cv_immediate_structures) -AC_CACHE_CHECK([for immediate structures],libreplace_cv_immediate_structures,[ - AC_TRY_COMPILE([ - #include - ],[ - typedef struct {unsigned x;} FOOBAR; - #define X_FOOBAR(x) ((FOOBAR) { x }) - #define FOO_ONE X_FOOBAR(1) - FOOBAR f = FOO_ONE; - static const struct { - FOOBAR y; - } f2[] = { - {FOO_ONE} - }; - static const FOOBAR f3[] = {FOO_ONE}; - ], - libreplace_cv_immediate_structures=yes, - libreplace_cv_immediate_structures=no, - libreplace_cv_immediate_structures=cross) -]) -if test x"$libreplace_cv_immediate_structures" = x"yes"; then - AC_DEFINE(HAVE_IMMEDIATE_STRUCTURES,1,[Whether the compiler supports immediate structures]) -fi - -AC__LIBREPLACE_ONLY_CC_CHECKS_END -]) dnl end AC_LIBREPLACE_CC_CHECKS diff --git a/replace/libreplace_ld.m4 b/replace/libreplace_ld.m4 deleted file mode 100644 index 81bde46219..0000000000 --- a/replace/libreplace_ld.m4 +++ /dev/null @@ -1,319 +0,0 @@ -# -# This offers a nice overview how to build shared libraries on all platforms -# http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html -# - -AC_DEFUN([AC_LIBREPLACE_STLD], -[ - AC_PATH_PROG(PROG_AR, ar) - - STLD=${PROG_AR} - - AC_SUBST(STLD) -]) - -AC_DEFUN([AC_LIBREPLACE_STLD_FLAGS], -[ - STLD_FLAGS="-rcs" - AC_SUBST(STLD_FLAGS) -]) - -AC_DEFUN([AC_LD_EXPORT_DYNAMIC], -[ -saved_LDFLAGS="$LDFLAGS" -if AC_TRY_COMMAND([${CC-cc} $CFLAGS -Wl,--version 2>&1 | grep "GNU ld" >/dev/null]); then - LD_EXPORT_DYNAMIC="-Wl,-export-dynamic" -else - case "$host_os" in - hpux* ) - LD_EXPORT_DYNAMIC="-Wl,-E" - ;; - *) - LD_EXPORT_DYNAMIC="" - ;; - esac -fi -AC_SUBST(LD_EXPORT_DYNAMIC) -LDFLAGS="$saved_LDFLAGS" -]) - -AC_DEFUN([AC_LD_PICFLAG], -[ -case "$host_os" in - *linux*) - PICFLAG="-fPIC" - ;; - *solaris*) - if test "${GCC}" = "yes"; then - PICFLAG="-fPIC" - else - PICFLAG="-KPIC" - fi - ;; - *sunos*) - PICFLAG="-KPIC" # Is this correct for SunOS - ;; - *netbsd* | *freebsd* | *dragonfly* ) - PICFLAG="-fPIC -DPIC" - ;; - *openbsd*) - PICFLAG="-fPIC" - ;; - *irix*) - if test "${GCC}" = "yes"; then - PICFLAG="-fPIC" - else - PICFLAG="-KPIC" - fi - ;; - *aix*) - # as AIX code is always position independent... - PICFLAG="-O2" - ;; - *hpux*) - if test $ac_cv_prog_cc_Ae = yes; then - PICFLAG="+z +ESnolit" - elif test "${GCC}" = "yes"; then - PICFLAG="-fPIC" - fi - if test "$host_cpu" = "ia64"; then - PICFLAG="+z" - fi - ;; - *osf*) - PICFLAG="-fPIC" - ;; - *unixware*) - PICFLAG="-KPIC" - ;; - *darwin*) - PICFLAG="-fno-common" - ;; -esac -AC_SUBST(PICFLAG) -]) - -AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_LINKER], -[ - LD_SHLIB_LINKER="${CC}" - - case "$host_os" in - *irix*) - LD_SHLIB_LINKER="${PROG_LD}" - ;; - esac - - AC_SUBST(LD_SHLIB_LINKER) -]) - -AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_FLAGS], -[ - LD_SHLIB_FLAGS="-shared" - - case "$host_os" in - *linux*) - LD_SHLIB_FLAGS="-shared -Wl,-Bsymbolic" - ;; - *solaris*) - LD_SHLIB_FLAGS="-G" - if test "${GCC}" = "no"; then - ## ${CFLAGS} added for building 64-bit shared - ## libs using Sun's Compiler - LD_SHLIB_FLAGS="-G \${CFLAGS}" - fi - ;; - *sunos*) - LD_SHLIB_FLAGS="-G" - ;; - *irix*) - LD_SHLIB_FLAGS="-shared" - ;; - *aix*) - LD_SHLIB_FLAGS="-Wl,-G,-bexpall,-bbigtoc" - ;; - *hpux*) - if test "${GCC}" = "yes"; then - LD_SHLIB_FLAGS="-shared" - else - LD_SHLIB_FLAGS="-b" - fi - ;; - *osf*) - LD_SHLIB_FLAGS="-shared" - ;; - *darwin*) - LD_SHLIB_FLAGS="-dynamiclib -Wl,-search_paths_first" - ;; - esac - - AC_SUBST(LD_SHLIB_FLAGS) -]) - -AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_DISALLOW_UNDEF_FLAG], -[ - LD_SHLIB_DISALLOW_UNDEF_FLAG="" - - # - # TODO: enforce error not only warnings - # - # NOTE: -Wl,--no-allow-shlib-undefined isn't what we want... - # as it bails out on broken system libraries - # - case "$host_os" in - *osf*) - LD_SHLIB_DISALLOW_UNDEF_FLAG="-warning_unresolved" - ;; - *darwin*) - LD_SHLIB_DISALLOW_UNDEF_FLAG="-undefined error" - ;; - esac - - AC_SUBST(LD_SHLIB_DISALLOW_UNDEF_FLAG) -]) - -AC_DEFUN([AC_LIBREPLACE_SHLD], -[ - AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_LINKER]) - SHLD="$LD_SHLIB_LINKER" - AC_SUBST(SHLD) -]) - -AC_DEFUN([AC_LIBREPLACE_SHLD_FLAGS], -[ - AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_FLAGS]) - AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_DISALLOW_UNDEF_FLAG]) - SHLD_FLAGS="$LD_SHLIB_FLAGS $LD_SHLIB_DISALLOW_UNDEF_FLAG" - AC_SUBST(SHLD_FLAGS) -]) - -AC_DEFUN([AC_LD_SHLIBEXT], -[ - SHLIBEXT="so" - case "$host_os" in - *hpux*) - if test "$host_cpu" = "ia64"; then - SHLIBEXT="so" - else - SHLIBEXT="sl" - fi - ;; - *darwin*) - SHLIBEXT="dylib" - ;; - esac - AC_SUBST(SHLIBEXT) -]) - -AC_DEFUN([AC_LD_SONAMEFLAG], -[ - AC_SUBST(SONAMEFLAG) - SONAMEFLAG="" - case "$host_os" in - *linux*) - SONAMEFLAG="-Wl,-soname=" - ;; - *solaris*) - SONAMEFLAG="-h " - if test "${GCC}" = "yes"; then - SONAMEFLAG="-Wl,-soname=" - fi - ;; - *sunos*) - SONAMEFLAG="-Wl,-h," - ;; - *netbsd* | *freebsd* | *dragonfly* ) - SONAMEFLAG="-Wl,-soname," - ;; - *openbsd*) - SONAMEFLAG="-Wl,-soname," - ;; - *irix*) - SONAMEFLAG="-Wl,-soname," - ;; - *hpux*) - SONAMEFLAG="-Wl,+h," - ;; - *osf*) - SONAMEFLAG="-Wl,-soname," - ;; - *unixware*) - SONAMEFLAG="-Wl,-soname," - ;; - *darwin*) - SONAMEFLAG="#" - ;; - *aix*) - # Not supported - SONAMEFLAG="#" - ;; - esac -]) - -AC_DEFUN([AC_LIBREPLACE_MDLD], -[ - AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_LINKER]) - MDLD="$LD_SHLIB_LINKER" - AC_SUBST(MDLD) -]) - -AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], -[ - LD_ALLOW_SHLIB_UNDEF_FLAG="" - - case "$host_os" in - *linux*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" - ;; - *osf*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,\"*\"" - ;; - *darwin*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" - ;; - *aix*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-bnoentry" - ;; - esac - - AC_SUBST(LD_SHLIB_ALLOW_UNDEF_FLAG) -]) - -AC_DEFUN([AC_LIBREPLACE_MDLD_FLAGS], -[ - AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_FLAGS]) - AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG]) - MDLD_FLAGS="$LD_SHLIB_FLAGS $LD_SHLIB_ALLOW_UNDEF_FLAG" - AC_SUBST(MDLD_FLAGS) -]) - -AC_DEFUN([AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR], -[ - case "$host_os" in - *linux*) - LIB_PATH_VAR=LD_LIBRARY_PATH - ;; - *netbsd*) - LIB_PATH_VAR=LD_LIBRARY_PATH - ;; - *solaris*) - LIB_PATH_VAR=LD_LIBRARY_PATH - ;; - *hpux*) - LIB_PATH_VAR=SHLIB_PATH - ;; - *osf*) - LIB_PATH_VAR=LD_LIBRARY_PATH - ;; - *aix*) - LIB_PATH_VAR=LIB_PATH - ;; - *irix*) - LIB_PATH_VAR=LD_LIBRARY_PATH - ;; - *darwin*) - LIB_PATH_VAR=DYLD_LIBRARY_PATH - ;; - esac - - AC_SUBST(LIB_PATH_VAR) -]) diff --git a/replace/libreplace_macros.m4 b/replace/libreplace_macros.m4 deleted file mode 100644 index 1856eacf66..0000000000 --- a/replace/libreplace_macros.m4 +++ /dev/null @@ -1,332 +0,0 @@ -# -# This is a collection of useful autoconf macros -# - -############################################ -# Check if the compiler handles c99 struct initialization, and if not try -AC99 and -c99 flags -# Usage: LIBREPLACE_C99_STRUCT_INIT(success-action,failure-action) -# changes CFLAGS to add -AC99 or -c99 if needed -AC_DEFUN([LIBREPLACE_C99_STRUCT_INIT], -[ -saved_CFLAGS="$CFLAGS"; -c99_init=no -if test x"$c99_init" = x"no"; then - AC_MSG_CHECKING(for C99 designated initializers) - CFLAGS="$saved_CFLAGS"; - AC_TRY_COMPILE([#include ], - [ struct foo {int x;char y;}; - struct foo bar = { .y = 'X', .x = 1 }; - ], - [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) -fi -if test x"$c99_init" = x"no"; then - AC_MSG_CHECKING(for C99 designated initializers with -AC99) - CFLAGS="$saved_CFLAGS -AC99"; - AC_TRY_COMPILE([#include ], - [ struct foo {int x;char y;}; - struct foo bar = { .y = 'X', .x = 1 }; - ], - [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) -fi -if test x"$c99_init" = x"no"; then - AC_MSG_CHECKING(for C99 designated initializers with -qlanglvl=extc99) - CFLAGS="$saved_CFLAGS -qlanglvl=extc99"; - AC_TRY_COMPILE([#include ], - [ struct foo {int x;char y;}; - struct foo bar = { .y = 'X', .x = 1 }; - ], - [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) -fi -if test x"$c99_init" = x"no"; then - AC_MSG_CHECKING(for C99 designated initializers with -qlanglvl=stdc99) - CFLAGS="$saved_CFLAGS -qlanglvl=stdc99"; - AC_TRY_COMPILE([#include ], - [ struct foo {int x;char y;}; - struct foo bar = { .y = 'X', .x = 1 }; - ], - [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) -fi -if test x"$c99_init" = x"no"; then - AC_MSG_CHECKING(for C99 designated initializers with -c99) - CFLAGS="$saved_CFLAGS -c99" - AC_TRY_COMPILE([#include ], - [ struct foo {int x;char y;}; - struct foo bar = { .y = 'X', .x = 1 }; - ], - [AC_MSG_RESULT(yes); c99_init=yes],[AC_MSG_RESULT(no)]) -fi - -if test "`uname`" = "HP-UX"; then - if test "$ac_cv_c_compiler_gnu" = no; then - # special override for broken HP-UX compiler - I can't find a way to test - # this properly (its a compiler bug) - CFLAGS="$CFLAGS -AC99"; - c99_init=yes; - fi -fi - -if test x"$c99_init" = x"yes"; then - saved_CFLAGS="" - $1 -else - CFLAGS="$saved_CFLAGS" - saved_CFLAGS="" - $2 -fi -]) - -dnl AC_PROG_CC_FLAG(flag) -AC_DEFUN(AC_PROG_CC_FLAG, -[AC_CACHE_CHECK(whether ${CC-cc} accepts -$1, ac_cv_prog_cc_$1, -[echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -$1 -c conftest.c 2>&1`"; then - ac_cv_prog_cc_$1=yes -else - ac_cv_prog_cc_$1=no -fi -rm -f conftest* -])]) - -dnl see if a declaration exists for a function or variable -dnl defines HAVE_function_DECL if it exists -dnl AC_HAVE_DECL(var, includes) -AC_DEFUN(AC_HAVE_DECL, -[ - AC_CACHE_CHECK([for $1 declaration],ac_cv_have_$1_decl,[ - AC_TRY_COMPILE([$2],[int i = (int)$1], - ac_cv_have_$1_decl=yes,ac_cv_have_$1_decl=no)]) - if test x"$ac_cv_have_$1_decl" = x"yes"; then - AC_DEFINE([HAVE_]translit([$1], [a-z], [A-Z])[_DECL],1,[Whether $1() is available]) - fi -]) - - -# AC_CHECK_LIB_EXT(LIBRARY, [EXT_LIBS], [FUNCTION], -# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], -# [ADD-ACTION-IF-FOUND],[OTHER-LIBRARIES]) -# ------------------------------------------------------ -# -# Use a cache variable name containing both the library and function name, -# because the test really is for library $1 defining function $3, not -# just for library $1. Separate tests with the same $1 and different $3s -# may have different results. -# -# Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3]) -# is asking for trouble, since AC_CHECK_LIB($lib, fun) would give -# ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence -# the AS_LITERAL_IF indirection. -# -# FIXME: This macro is extremely suspicious. It DEFINEs unconditionally, -# whatever the FUNCTION, in addition to not being a *S macro. Note -# that the cache does depend upon the function we are looking for. -# -# It is on purpose we used `ac_check_lib_ext_save_LIBS' and not just -# `ac_save_LIBS': there are many macros which don't want to see `LIBS' -# changed but still want to use AC_CHECK_LIB_EXT, so they save `LIBS'. -# And ``ac_save_LIBS' is too tempting a name, so let's leave them some -# freedom. -AC_DEFUN([AC_CHECK_LIB_EXT], -[ -AH_CHECK_LIB_EXT([$1]) -ac_check_lib_ext_save_LIBS=$LIBS -LIBS="-l$1 $$2 $7 $LIBS" -AS_LITERAL_IF([$1], - [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1])], - [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1''])])dnl - -m4_ifval([$3], - [ - AH_CHECK_FUNC_EXT([$3]) - AS_LITERAL_IF([$1], - [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1_$3])], - [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1''_$3])])dnl - AC_CACHE_CHECK([for $3 in -l$1], ac_Lib_func, - [AC_TRY_LINK_FUNC($3, - [AS_VAR_SET(ac_Lib_func, yes); - AS_VAR_SET(ac_Lib_ext, yes)], - [AS_VAR_SET(ac_Lib_func, no); - AS_VAR_SET(ac_Lib_ext, no)]) - ]) - AS_IF([test AS_VAR_GET(ac_Lib_func) = yes], - [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$3))])dnl - AS_VAR_POPDEF([ac_Lib_func])dnl - ],[ - AC_CACHE_CHECK([for -l$1], ac_Lib_ext, - [AC_TRY_LINK_FUNC([main], - [AS_VAR_SET(ac_Lib_ext, yes)], - [AS_VAR_SET(ac_Lib_ext, no)]) - ]) - ]) -LIBS=$ac_check_lib_ext_save_LIBS - -AS_IF([test AS_VAR_GET(ac_Lib_ext) = yes], - [m4_default([$4], - [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1)) - case "$$2" in - *-l$1*) - ;; - *) - $2="-l$1 $$2" - ;; - esac]) - [$6] - ], - [$5])dnl -AS_VAR_POPDEF([ac_Lib_ext])dnl -])# AC_CHECK_LIB_EXT - -# AH_CHECK_LIB_EXT(LIBNAME) -# --------------------- -m4_define([AH_CHECK_LIB_EXT], -[AH_TEMPLATE(AS_TR_CPP(HAVE_LIB$1), - [Define to 1 if you have the `]$1[' library (-l]$1[).])]) - -dnl AC_SEARCH_LIBS_EXT(FUNCTION, SEARCH-LIBS, EXT_LIBS, -dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], -dnl [OTHER-LIBRARIES]) -dnl -------------------------------------------------------- -dnl Search for a library defining FUNC, if it's not already available. -AC_DEFUN([AC_SEARCH_LIBS_EXT], -[AC_CACHE_CHECK([for library containing $1], [ac_cv_search_ext_$1], -[ -ac_func_search_ext_save_LIBS=$LIBS -ac_cv_search_ext_$1=no -AC_LINK_IFELSE([AC_LANG_CALL([], [$1])], - [ac_cv_search_ext_$1="none required"]) -if test "$ac_cv_search_ext_$1" = no; then - for ac_lib in $2; do - LIBS="-l$ac_lib $$3 $6 $ac_func_search_save_ext_LIBS" - AC_LINK_IFELSE([AC_LANG_CALL([], [$1])], - [ac_cv_search_ext_$1="-l$ac_lib" -break]) - done -fi -LIBS=$ac_func_search_ext_save_LIBS]) -AS_IF([test "$ac_cv_search_ext_$1" != no], - [test "$ac_cv_search_ext_$1" = "none required" || $3="$ac_cv_search_ext_$1 $$3" - $4], - [$5])dnl -]) - -dnl check for a function in a $LIBS and $OTHER_LIBS libraries variable. -dnl AC_CHECK_FUNC_EXT(func,OTHER_LIBS,IF-TRUE,IF-FALSE) -AC_DEFUN([AC_CHECK_FUNC_EXT], -[ - AH_CHECK_FUNC_EXT($1) - ac_check_func_ext_save_LIBS=$LIBS - LIBS="$2 $LIBS" - AS_VAR_PUSHDEF([ac_var], [ac_cv_func_ext_$1])dnl - AC_CACHE_CHECK([for $1], ac_var, - [AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([$1])], - [AS_VAR_SET(ac_var, yes)], - [AS_VAR_SET(ac_var, no)])]) - LIBS=$ac_check_func_ext_save_LIBS - AS_IF([test AS_VAR_GET(ac_var) = yes], - [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) $3], - [$4])dnl -AS_VAR_POPDEF([ac_var])dnl -])# AC_CHECK_FUNC - -# AH_CHECK_FUNC_EXT(FUNCNAME) -# --------------------- -m4_define([AH_CHECK_FUNC_EXT], -[AH_TEMPLATE(AS_TR_CPP(HAVE_$1), - [Define to 1 if you have the `]$1[' function.])]) - -dnl Define an AC_DEFINE with ifndef guard. -dnl AC_N_DEFINE(VARIABLE [, VALUE]) -AC_DEFUN([AC_N_DEFINE], -[ -AH_VERBATIM([$1], [ -#ifndef $1 -# undef $1 -#endif -]) - - cat >>confdefs.h <<\EOF -#ifndef $1 -[#define] $1 m4_if($#, 1, 1, [$2]) -#endif -EOF -]) - -dnl Add an #include -dnl AC_ADD_INCLUDE(VARIABLE) -define(AC_ADD_INCLUDE, -[cat >> confdefs.h <<\EOF -[#include] $1 -EOF -]) - -dnl remove an #include -dnl AC_REMOVE_INCLUDE(VARIABLE) -define(AC_REMOVE_INCLUDE, -[ -grep -v '[#include] $1' confdefs.h >confdefs.h.tmp -cat confdefs.h.tmp > confdefs.h -rm confdefs.h.tmp -]) - -dnl remove an #define -dnl AC_REMOVE_DEFINE(VARIABLE) -define(AC_REMOVE_DEFINE, -[ -grep -v '[#define] $1 ' confdefs.h |grep -v '[#define] $1[$]'>confdefs.h.tmp -cat confdefs.h.tmp > confdefs.h -rm confdefs.h.tmp -]) - -dnl AS_HELP_STRING is not available in autoconf 2.57, and AC_HELP_STRING is deprecated -dnl in autoconf 2.59, so define AS_HELP_STRING to be AC_HELP_STRING unless it is already -dnl defined. -m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))]) - -dnl check if the prototype in the header matches the given one -dnl AC_VERIFY_C_PROTOTYPE(prototype,functionbody,[IF-TRUE].[IF-FALSE],[extraheaders]) -AC_DEFUN(AC_VERIFY_C_PROTOTYPE, -[AC_CACHE_CHECK([for prototype $1], AS_TR_SH([ac_cv_c_prototype_$1]), - AC_COMPILE_IFELSE([AC_LANG_SOURCE([ - AC_INCLUDES_DEFAULT - $5 - $1 - { - $2 - } - ])],[ - AS_TR_SH([ac_cv_c_prototype_$1])=yes - ],[ - AS_TR_SH([ac_cv_c_prototype_$1])=no - ]) -) -AS_IF([test $AS_TR_SH([ac_cv_c_prototype_$1]) = yes],[$3],[$4]) -]) - -AC_DEFUN(LIBREPLACE_PROVIDE_HEADER, -[AC_CHECK_HEADER([$1], - [ AC_CONFIG_COMMANDS(rm-$1, [rm -f $libreplacedir/$1], [libreplacedir=$libreplacedir]) ], - [ AC_CONFIG_COMMANDS(mk-$1, [echo "#include \"replace.h\"" > $libreplacedir/$1], [libreplacedir=$libreplacedir]) ] - ) -]) - -dnl AC_HAVE_TYPE(TYPE,INCLUDES) -AC_DEFUN([AC_HAVE_TYPE], [ -AC_REQUIRE([AC_HEADER_STDC]) -cv=`echo "$1" | sed 'y%./+- %__p__%'` -AC_MSG_CHECKING(for $1) -AC_CACHE_VAL([ac_cv_type_$cv], -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -AC_INCLUDES_DEFAULT -$2]], -[[$1 foo;]])], -[eval "ac_cv_type_$cv=yes"], -[eval "ac_cv_type_$cv=no"]))dnl -ac_foo=`eval echo \\$ac_cv_type_$cv` -AC_MSG_RESULT($ac_foo) -if test "$ac_foo" = yes; then - ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'` -if false; then - AC_CHECK_TYPES($1) -fi - AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1']) -fi -]) diff --git a/replace/libreplace_network.m4 b/replace/libreplace_network.m4 deleted file mode 100644 index 4edb55c03a..0000000000 --- a/replace/libreplace_network.m4 +++ /dev/null @@ -1,377 +0,0 @@ -AC_DEFUN_ONCE(AC_LIBREPLACE_NETWORK_CHECKS, -[ -echo "LIBREPLACE_NETWORK_CHECKS: START" - -AC_DEFINE(LIBREPLACE_NETWORK_CHECKS, 1, [LIBREPLACE_NETWORK_CHECKS were used]) -LIBREPLACE_NETWORK_OBJS="" -LIBREPLACE_NETWORK_LIBS="" - -AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h) -AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) -AC_CHECK_HEADERS(sys/sockio.h sys/un.h) - -dnl we need to check that net/if.h really can be used, to cope with hpux -dnl where including it always fails -AC_CACHE_CHECK([for usable net/if.h],libreplace_cv_USABLE_NET_IF_H,[ - AC_COMPILE_IFELSE([AC_LANG_SOURCE([ - AC_INCLUDES_DEFAULT - #if HAVE_SYS_SOCKET_H - # include - #endif - #include - int main(void) {return 0;}])], - [libreplace_cv_USABLE_NET_IF_H=yes], - [libreplace_cv_USABLE_NET_IF_H=no] - ) -]) -if test x"$libreplace_cv_USABLE_NET_IF_H" = x"yes";then - AC_DEFINE(HAVE_NET_IF_H, 1, usability of net/if.h) -fi - -AC_HAVE_TYPE([socklen_t],[#include ]) -AC_HAVE_TYPE([sa_family_t],[#include ]) -AC_HAVE_TYPE([struct addrinfo], [#include ]) -AC_HAVE_TYPE([struct sockaddr], [#include ]) -AC_HAVE_TYPE([struct sockaddr_storage], [ -#include -#include -#include -]) -AC_HAVE_TYPE([struct sockaddr_in6], [ -#include -#include -#include -]) - -if test x"$ac_cv_type_struct_sockaddr_storage" = x"yes"; then -AC_CHECK_MEMBER(struct sockaddr_storage.ss_family, - AC_DEFINE(HAVE_SS_FAMILY, 1, [Defined if struct sockaddr_storage has ss_family field]),, - [ -#include -#include -#include - ]) - -if test x"$ac_cv_member_struct_sockaddr_storage_ss_family" != x"yes"; then -AC_CHECK_MEMBER(struct sockaddr_storage.__ss_family, - AC_DEFINE(HAVE___SS_FAMILY, 1, [Defined if struct sockaddr_storage has __ss_family field]),, - [ -#include -#include -#include - ]) -fi -fi - -AC_CACHE_CHECK([for sin_len in sock],libreplace_cv_HAVE_SOCK_SIN_LEN,[ - AC_TRY_COMPILE( - [ -#include -#include -#include - ],[ -struct sockaddr_in sock; sock.sin_len = sizeof(sock); - ],[ - libreplace_cv_HAVE_SOCK_SIN_LEN=yes - ],[ - libreplace_cv_HAVE_SOCK_SIN_LEN=no - ]) -]) -if test x"$libreplace_cv_HAVE_SOCK_SIN_LEN" = x"yes"; then - AC_DEFINE(HAVE_SOCK_SIN_LEN,1,[Whether the sockaddr_in struct has a sin_len property]) -fi - -############################################ -# check for unix domain sockets -AC_CACHE_CHECK([for unix domain sockets],libreplace_cv_HAVE_UNIXSOCKET,[ - AC_TRY_COMPILE([ -#include -#include -#include -#include -#include - ],[ -struct sockaddr_un sunaddr; -sunaddr.sun_family = AF_UNIX; - ],[ - libreplace_cv_HAVE_UNIXSOCKET=yes - ],[ - libreplace_cv_HAVE_UNIXSOCKET=no - ]) -]) -if test x"$libreplace_cv_HAVE_UNIXSOCKET" = x"yes"; then - AC_DEFINE(HAVE_UNIXSOCKET,1,[If we need to build with unixscoket support]) -fi - -dnl The following test is roughl taken from the cvs sources. -dnl -dnl If we can't find connect, try looking in -lsocket, -lnsl, and -linet. -dnl The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has -dnl libsocket.so which has a bad implementation of gethostbyname (it -dnl only looks in /etc/hosts), so we only look for -lsocket if we need -dnl it. -AC_CHECK_FUNCS(connect) -if test x"$ac_cv_func_connect" = x"no"; then - AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, connect) - AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, connect) - AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, connect) - AC_CHECK_LIB_EXT(inet, LIBREPLACE_NETWORK_LIBS, connect) - dnl We can't just call AC_CHECK_FUNCS(connect) here, - dnl because the value has been cached. - if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" || - test x"$ac_cv_lib_ext_nsl_connect" = x"yes" || - test x"$ac_cv_lib_ext_socket_connect" = x"yes" || - test x"$ac_cv_lib_ext_inet_connect" = x"yes" - then - AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()]) - fi -fi - -AC_CHECK_FUNCS(gethostbyname) -if test x"$ac_cv_func_gethostbyname" = x"no"; then - AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, gethostbyname) - AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, gethostbyname) - AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, gethostbyname) - dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here, - dnl because the value has been cached. - if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" = x"yes" || - test x"$ac_cv_lib_ext_nsl_gethostbyname" = x"yes" || - test x"$ac_cv_lib_ext_socket_gethostbyname" = x"yes" - then - AC_DEFINE(HAVE_GETHOSTBYNAME,1, - [Whether the system has gethostbyname()]) - fi -fi - -dnl HP-UX has if_nametoindex in -lipv6 -AC_CHECK_FUNCS(if_nametoindex) -if test x"$ac_cv_func_if_nametoindex" = x"no"; then - AC_CHECK_LIB_EXT(ipv6, LIBREPLACE_NETWORK_LIBS, if_nametoindex) - dnl We can't just call AC_CHECK_FUNCS(if_nametoindex) here, - dnl because the value has been cached. - if test x"$ac_cv_lib_ext_ipv6_if_nametoindex" = x"yes" - then - AC_DEFINE(HAVE_IF_NAMETOINDEX, 1, - [Whether the system has if_nametoindex()]) - fi -fi - -# The following tests need LIBS="${LIBREPLACE_NETWORK_LIBS}" -old_LIBS=$LIBS -LIBS="${LIBREPLACE_NETWORK_LIBS}" -SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I$libreplacedir" - -AC_CHECK_FUNCS(socketpair,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} socketpair.o"]) - -AC_CACHE_CHECK([for broken inet_ntoa],libreplace_cv_REPLACE_INET_NTOA,[ -AC_TRY_RUN([ -#include -#include -#include -#include -#ifdef HAVE_ARPA_INET_H -#include -#endif -main() { struct in_addr ip; ip.s_addr = 0x12345678; -if (strcmp(inet_ntoa(ip),"18.52.86.120") && - strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } -exit(1);}], - libreplace_cv_REPLACE_INET_NTOA=yes,libreplace_cv_REPLACE_INET_NTOA=no,libreplace_cv_REPLACE_INET_NTOA=cross)]) - -AC_CHECK_FUNCS(inet_ntoa,[],[libreplace_cv_REPLACE_INET_NTOA=yes]) -if test x"$libreplace_cv_REPLACE_INET_NTOA" = x"yes"; then - AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced]) - LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_ntoa.o" -fi - -AC_CHECK_FUNCS(inet_aton,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_aton.o"]) - -AC_CHECK_FUNCS(inet_ntop,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_ntop.o"]) - -AC_CHECK_FUNCS(inet_pton,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} inet_pton.o"]) - -dnl test for getaddrinfo/getnameinfo -AC_CACHE_CHECK([for getaddrinfo],libreplace_cv_HAVE_GETADDRINFO,[ -AC_TRY_LINK([ -#include -#if STDC_HEADERS -#include -#include -#endif -#include -#include ], -[ -struct sockaddr sa; -struct addrinfo *ai = NULL; -int ret = getaddrinfo(NULL, NULL, NULL, &ai); -if (ret != 0) { - const char *es = gai_strerror(ret); -} -freeaddrinfo(ai); -ret = getnameinfo(&sa, sizeof(sa), - NULL, 0, - NULL, 0, 0); - -], -libreplace_cv_HAVE_GETADDRINFO=yes,libreplace_cv_HAVE_GETADDRINFO=no)]) -if test x"$libreplace_cv_HAVE_GETADDRINFO" = x"yes"; then - AC_DEFINE(HAVE_GETADDRINFO,1,[Whether the system has getaddrinfo]) - AC_DEFINE(HAVE_GETNAMEINFO,1,[Whether the system has getnameinfo]) - AC_DEFINE(HAVE_FREEADDRINFO,1,[Whether the system has freeaddrinfo]) - AC_DEFINE(HAVE_GAI_STRERROR,1,[Whether the system has gai_strerror]) -else - LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} getaddrinfo.o" -fi - -AC_CHECK_HEADERS([ifaddrs.h]) - -dnl Used when getifaddrs is not available -AC_CHECK_MEMBERS([struct sockaddr.sa_len], - [AC_DEFINE(HAVE_SOCKADDR_SA_LEN, 1, [Whether struct sockaddr has a sa_len member])], - [], - [#include ]) - -dnl test for getifaddrs and freeifaddrs -AC_CACHE_CHECK([for getifaddrs and freeifaddrs],libreplace_cv_HAVE_GETIFADDRS,[ -AC_TRY_COMPILE([ -#include -#if STDC_HEADERS -#include -#include -#endif -#include -#include -#include -#include -#include ], -[ -struct ifaddrs *ifp = NULL; -int ret = getifaddrs (&ifp); -freeifaddrs(ifp); -], -libreplace_cv_HAVE_GETIFADDRS=yes,libreplace_cv_HAVE_GETIFADDRS=no)]) -if test x"$libreplace_cv_HAVE_GETIFADDRS" = x"yes"; then - AC_DEFINE(HAVE_GETIFADDRS,1,[Whether the system has getifaddrs]) - AC_DEFINE(HAVE_FREEIFADDRS,1,[Whether the system has freeifaddrs]) - AC_DEFINE(HAVE_STRUCT_IFADDRS,1,[Whether struct ifaddrs is available]) -fi - -################## -# look for a method of finding the list of network interfaces -iface=no; -AC_CACHE_CHECK([for iface getifaddrs],libreplace_cv_HAVE_IFACE_GETIFADDRS,[ -AC_TRY_RUN([ -#define HAVE_IFACE_GETIFADDRS 1 -#define NO_CONFIG_H 1 -#define AUTOCONF_TEST 1 -#define SOCKET_WRAPPER_NOT_REPLACE -#include "$libreplacedir/replace.c" -#include "$libreplacedir/inet_ntop.c" -#include "$libreplacedir/snprintf.c" -#include "$libreplacedir/getifaddrs.c" -#define getifaddrs_test main -#include "$libreplacedir/test/getifaddrs.c"], - libreplace_cv_HAVE_IFACE_GETIFADDRS=yes,libreplace_cv_HAVE_IFACE_GETIFADDRS=no,libreplace_cv_HAVE_IFACE_GETIFADDRS=cross)]) -if test x"$libreplace_cv_HAVE_IFACE_GETIFADDRS" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_GETIFADDRS,1,[Whether iface getifaddrs is available]) -else - LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} getifaddrs.o" -fi - - -if test $iface = no; then -AC_CACHE_CHECK([for iface AIX],libreplace_cv_HAVE_IFACE_AIX,[ -AC_TRY_RUN([ -#define HAVE_IFACE_AIX 1 -#define NO_CONFIG_H 1 -#define AUTOCONF_TEST 1 -#undef _XOPEN_SOURCE_EXTENDED -#define SOCKET_WRAPPER_NOT_REPLACE -#include "$libreplacedir/replace.c" -#include "$libreplacedir/inet_ntop.c" -#include "$libreplacedir/snprintf.c" -#include "$libreplacedir/getifaddrs.c" -#define getifaddrs_test main -#include "$libreplacedir/test/getifaddrs.c"], - libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)]) -if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available]) -fi -fi - - -if test $iface = no; then -AC_CACHE_CHECK([for iface ifconf],libreplace_cv_HAVE_IFACE_IFCONF,[ -AC_TRY_RUN([ -#define HAVE_IFACE_IFCONF 1 -#define NO_CONFIG_H 1 -#define AUTOCONF_TEST 1 -#define SOCKET_WRAPPER_NOT_REPLACE -#include "$libreplacedir/replace.c" -#include "$libreplacedir/inet_ntop.c" -#include "$libreplacedir/snprintf.c" -#include "$libreplacedir/getifaddrs.c" -#define getifaddrs_test main -#include "$libreplacedir/test/getifaddrs.c"], - libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)]) -if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available]) -fi -fi - -if test $iface = no; then -AC_CACHE_CHECK([for iface ifreq],libreplace_cv_HAVE_IFACE_IFREQ,[ -AC_TRY_RUN([ -#define HAVE_IFACE_IFREQ 1 -#define NO_CONFIG_H 1 -#define AUTOCONF_TEST 1 -#define SOCKET_WRAPPER_NOT_REPLACE -#include "$libreplacedir/replace.c" -#include "$libreplacedir/inet_ntop.c" -#include "$libreplacedir/snprintf.c" -#include "$libreplacedir/getifaddrs.c" -#define getifaddrs_test main -#include "$libreplacedir/test/getifaddrs.c"], - libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)]) -if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available]) -fi -fi - -dnl test for ipv6 -AC_CACHE_CHECK([for ipv6 support],libreplace_cv_HAVE_IPV6,[ - AC_TRY_LINK([ -#include /* for NULL */ -#include -#include -#include - ], - [ -struct sockaddr_storage sa_store; -struct addrinfo *ai = NULL; -struct in6_addr in6addr; -int idx = if_nametoindex("iface1"); -int s = socket(AF_INET6, SOCK_STREAM, 0); -int ret = getaddrinfo(NULL, NULL, NULL, &ai); -if (ret != 0) { - const char *es = gai_strerror(ret); -} -freeaddrinfo(ai); - ],[ - libreplace_cv_HAVE_IPV6=yes - ],[ - libreplace_cv_HAVE_IPV6=no - ]) -]) -if test x"$libreplace_cv_HAVE_IPV6" = x"yes"; then - AC_DEFINE(HAVE_IPV6,1,[Whether the system has IPv6 support]) -fi - -LIBS=$old_LIBS -CPPFLAGS="$SAVE_CPPFLAGS" - -LIBREPLACEOBJ="${LIBREPLACEOBJ} ${LIBREPLACE_NETWORK_OBJS}" - -echo "LIBREPLACE_NETWORK_CHECKS: END" -]) dnl end AC_LIBREPLACE_NETWORK_CHECKS diff --git a/replace/repdir.m4 b/replace/repdir.m4 deleted file mode 100644 index f53a4c2974..0000000000 --- a/replace/repdir.m4 +++ /dev/null @@ -1,78 +0,0 @@ -AC_CACHE_CHECK([for broken readdir],libreplace_cv_READDIR_NEEDED,[ - AC_TRY_RUN([ -#define test_readdir_os2_delete main -#include "$libreplacedir/test/os2_delete.c"], - [libreplace_cv_READDIR_NEEDED=no], - [libreplace_cv_READDIR_NEEDED=yes], - [libreplace_cv_READDIR_NEEDED="assuming not"]) -]) - -# -# try to replace with getdirentries() if needed -# -if test x"$libreplace_cv_READDIR_NEEDED" = x"yes"; then -AC_CHECK_FUNCS(getdirentries) -AC_VERIFY_C_PROTOTYPE([long telldir(const DIR *dir)], - [ - return 0; - ],[ - AC_DEFINE(TELLDIR_TAKES_CONST_DIR, 1, [Whether telldir takes a const pointer]) - ],[],[ - #include - ]) - -AC_VERIFY_C_PROTOTYPE([int seekdir(DIR *dir, long ofs)], - [ - return 0; - ],[ - AC_DEFINE(SEEKDIR_RETURNS_INT, 1, [Whether seekdir returns an int]) - ],[],[ - #include - ]) -AC_CACHE_CHECK([for replacing readdir using getdirentries()],libreplace_cv_READDIR_GETDIRENTRIES,[ - AC_TRY_RUN([ -#define _LIBREPLACE_REPLACE_H -#include "$libreplacedir/repdir_getdirentries.c" -#define test_readdir_os2_delete main -#include "$libreplacedir/test/os2_delete.c"], - [libreplace_cv_READDIR_GETDIRENTRIES=yes], - [libreplace_cv_READDIR_GETDIRENTRIES=no]) -]) -fi -if test x"$libreplace_cv_READDIR_GETDIRENTRIES" = x"yes"; then - AC_DEFINE(REPLACE_READDIR,1,[replace readdir]) - AC_DEFINE(REPLACE_READDIR_GETDIRENTRIES,1,[replace readdir using getdirentries()]) - LIBREPLACEOBJ="${LIBREPLACEOBJ} repdir_getdirentries.o" - libreplace_cv_READDIR_NEEDED=no -fi - -# -# try to replace with getdents() if needed -# -if test x"$libreplace_cv_READDIR_NEEDED" = x"yes"; then -AC_CHECK_FUNCS(getdents) -AC_CACHE_CHECK([for replacing readdir using getdents()],libreplace_cv_READDIR_GETDENTS,[ - AC_TRY_RUN([ -#define _LIBREPLACE_REPLACE_H -#error _donot_use_getdents_replacement_anymore -#include "$libreplacedir/repdir_getdents.c" -#define test_readdir_os2_delete main -#include "$libreplacedir/test/os2_delete.c"], - [libreplace_cv_READDIR_GETDENTS=yes], - [libreplace_cv_READDIR_GETDENTS=no]) -]) -fi -if test x"$libreplace_cv_READDIR_GETDENTS" = x"yes"; then - AC_DEFINE(REPLACE_READDIR,1,[replace readdir]) - AC_DEFINE(REPLACE_READDIR_GETDENTS,1,[replace readdir using getdents()]) - LIBREPLACEOBJ="${LIBREPLACEOBJ} repdir_getdents.o" - libreplace_cv_READDIR_NEEDED=no -fi - -AC_MSG_CHECKING([a usable readdir()]) -if test x"$libreplace_cv_READDIR_NEEDED" = x"yes"; then - AC_MSG_RESULT(no) - AC_MSG_WARN([the provided readdir() is broken]) -else - AC_MSG_RESULT(yes) -fi diff --git a/replace/repdir_getdents.c b/replace/repdir_getdents.c deleted file mode 100644 index afc634a796..0000000000 --- a/replace/repdir_getdents.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -/* - a replacement for opendir/readdir/telldir/seekdir/closedir for BSD systems - - This is needed because the existing directory handling in FreeBSD - and OpenBSD (and possibly NetBSD) doesn't correctly handle unlink() - on files in a directory where telldir() has been used. On a block - boundary it will occasionally miss a file when seekdir() is used to - return to a position previously recorded with telldir(). - - This also fixes a severe performance and memory usage problem with - telldir() on BSD systems. Each call to telldir() in BSD adds an - entry to a linked list, and those entries are cleaned up on - closedir(). This means with a large directory closedir() can take an - arbitrary amount of time, causing network timeouts as millions of - telldir() entries are freed - - Note! This replacement code is not portable. It relies on getdents() - always leaving the file descriptor at a seek offset that is a - multiple of DIR_BUF_SIZE. If the code detects that this doesn't - happen then it will abort(). It also does not handle directories - with offsets larger than can be stored in a long, - - This code is available under other free software licenses as - well. Contact the author. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#define DIR_BUF_BITS 9 -#define DIR_BUF_SIZE (1<fd = open(dname, O_RDONLY); - if (d->fd == -1) { - free(d); - return NULL; - } - if (fstat(d->fd, &sb) < 0) { - close(d->fd); - free(d); - return NULL; - } - if (!S_ISDIR(sb.st_mode)) { - close(d->fd); - free(d); - errno = ENOTDIR; - return NULL; - } - d->ofs = 0; - d->seekpos = 0; - d->nbytes = 0; - return (DIR *)d; -} - -struct dirent *readdir(DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - struct dirent *de; - - if (d->ofs >= d->nbytes) { - d->seekpos = lseek(d->fd, 0, SEEK_CUR); - d->nbytes = getdents(d->fd, d->buf, DIR_BUF_SIZE); - d->ofs = 0; - } - if (d->ofs >= d->nbytes) { - return NULL; - } - de = (struct dirent *)&d->buf[d->ofs]; - d->ofs += de->d_reclen; - return de; -} - -long telldir(DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - if (d->ofs >= d->nbytes) { - d->seekpos = lseek(d->fd, 0, SEEK_CUR); - d->ofs = 0; - d->nbytes = 0; - } - /* this relies on seekpos always being a multiple of - DIR_BUF_SIZE. Is that always true on BSD systems? */ - if (d->seekpos & (DIR_BUF_SIZE-1)) { - abort(); - } - return d->seekpos + d->ofs; -} - -void seekdir(DIR *dir, long ofs) -{ - struct dir_buf *d = (struct dir_buf *)dir; - d->seekpos = lseek(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET); - d->nbytes = getdents(d->fd, d->buf, DIR_BUF_SIZE); - d->ofs = 0; - while (d->ofs < (ofs & (DIR_BUF_SIZE-1))) { - if (readdir(dir) == NULL) break; - } -} - -void rewinddir(DIR *dir) -{ - seekdir(dir, 0); -} - -int closedir(DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - int r = close(d->fd); - if (r != 0) { - return r; - } - free(d); - return 0; -} - -#ifndef dirfd -/* darn, this is a macro on some systems. */ -int dirfd(DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - return d->fd; -} -#endif diff --git a/replace/repdir_getdirentries.c b/replace/repdir_getdirentries.c deleted file mode 100644 index 197e5931fc..0000000000 --- a/replace/repdir_getdirentries.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -/* - a replacement for opendir/readdir/telldir/seekdir/closedir for BSD - systems using getdirentries - - This is needed because the existing directory handling in FreeBSD - and OpenBSD (and possibly NetBSD) doesn't correctly handle unlink() - on files in a directory where telldir() has been used. On a block - boundary it will occasionally miss a file when seekdir() is used to - return to a position previously recorded with telldir(). - - This also fixes a severe performance and memory usage problem with - telldir() on BSD systems. Each call to telldir() in BSD adds an - entry to a linked list, and those entries are cleaned up on - closedir(). This means with a large directory closedir() can take an - arbitrary amount of time, causing network timeouts as millions of - telldir() entries are freed - - Note! This replacement code is not portable. It relies on - getdirentries() always leaving the file descriptor at a seek offset - that is a multiple of DIR_BUF_SIZE. If the code detects that this - doesn't happen then it will abort(). It also does not handle - directories with offsets larger than can be stored in a long, - - This code is available under other free software licenses as - well. Contact the author. -*/ - -#include "replace.h" -#include -#include -#include -#include -#include -#include -#include - -#define DIR_BUF_BITS 9 -#define DIR_BUF_SIZE (1<fd = open(dname, O_RDONLY); - if (d->fd == -1) { - free(d); - return NULL; - } - if (fstat(d->fd, &sb) < 0) { - close(d->fd); - free(d); - return NULL; - } - if (!S_ISDIR(sb.st_mode)) { - close(d->fd); - free(d); - errno = ENOTDIR; - return NULL; - } - d->ofs = 0; - d->seekpos = 0; - d->nbytes = 0; - return (DIR *)d; -} - -struct dirent *readdir(DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - struct dirent *de; - - if (d->ofs >= d->nbytes) { - long pos; - d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos); - d->seekpos = pos; - d->ofs = 0; - } - if (d->ofs >= d->nbytes) { - return NULL; - } - de = (struct dirent *)&d->buf[d->ofs]; - d->ofs += de->d_reclen; - return de; -} - -#ifdef TELLDIR_TAKES_CONST_DIR -long telldir(const DIR *dir) -#else -long telldir(DIR *dir) -#endif -{ - struct dir_buf *d = (struct dir_buf *)dir; - if (d->ofs >= d->nbytes) { - d->seekpos = lseek(d->fd, 0, SEEK_CUR); - d->ofs = 0; - d->nbytes = 0; - } - /* this relies on seekpos always being a multiple of - DIR_BUF_SIZE. Is that always true on BSD systems? */ - if (d->seekpos & (DIR_BUF_SIZE-1)) { - abort(); - } - return d->seekpos + d->ofs; -} - -#ifdef SEEKDIR_RETURNS_INT -int seekdir(DIR *dir, long ofs) -#else -void seekdir(DIR *dir, long ofs) -#endif -{ - struct dir_buf *d = (struct dir_buf *)dir; - long pos; - d->seekpos = lseek(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET); - d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos); - d->ofs = 0; - while (d->ofs < (ofs & (DIR_BUF_SIZE-1))) { - if (readdir(dir) == NULL) break; - } -#ifdef SEEKDIR_RETURNS_INT - return -1; -#endif -} - -void rewinddir(DIR *dir) -{ - seekdir(dir, 0); -} - -int closedir(DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - int r = close(d->fd); - if (r != 0) { - return r; - } - free(d); - return 0; -} - -#ifndef dirfd -/* darn, this is a macro on some systems. */ -int dirfd(DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - return d->fd; -} -#endif - - diff --git a/replace/replace.c b/replace/replace.c deleted file mode 100644 index 98d799b07e..0000000000 --- a/replace/replace.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - Unix SMB/CIFS implementation. - replacement routines for broken systems - Copyright (C) Andrew Tridgell 1992-1998 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" - -#include "system/filesys.h" -#include "system/time.h" -#include "system/passwd.h" -#include "system/syslog.h" -#include "system/locale.h" -#include "system/wait.h" - -void replace_dummy(void); -void replace_dummy(void) {} - -#ifndef HAVE_FTRUNCATE - /******************************************************************* -ftruncate for operating systems that don't have it -********************************************************************/ -int rep_ftruncate(int f, off_t l) -{ -#ifdef HAVE_CHSIZE - return chsize(f,l); -#elif defined(F_FREESP) - struct flock fl; - - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = l; - fl.l_type = F_WRLCK; - return fcntl(f, F_FREESP, &fl); -#else -#error "you must have a ftruncate function" -#endif -} -#endif /* HAVE_FTRUNCATE */ - - -#ifndef HAVE_STRLCPY -/* like strncpy but does not 0 fill the buffer and always null - terminates. bufsize is the size of the destination buffer */ -size_t rep_strlcpy(char *d, const char *s, size_t bufsize) -{ - size_t len = strlen(s); - size_t ret = len; - if (bufsize <= 0) return 0; - if (len >= bufsize) len = bufsize-1; - memcpy(d, s, len); - d[len] = 0; - return ret; -} -#endif - -#ifndef HAVE_STRLCAT -/* like strncat but does not 0 fill the buffer and always null - terminates. bufsize is the length of the buffer, which should - be one more than the maximum resulting string length */ -size_t rep_strlcat(char *d, const char *s, size_t bufsize) -{ - size_t len1 = strlen(d); - size_t len2 = strlen(s); - size_t ret = len1 + len2; - - if (len1+len2 >= bufsize) { - if (bufsize < (len1+1)) { - return ret; - } - len2 = bufsize - (len1+1); - } - if (len2 > 0) { - memcpy(d+len1, s, len2); - d[len1+len2] = 0; - } - return ret; -} -#endif - -#ifndef HAVE_MKTIME -/******************************************************************* -a mktime() replacement for those who don't have it - contributed by -C.A. Lademann -Corrections by richard.kettlewell@kewill.com -********************************************************************/ - -#define MINUTE 60 -#define HOUR 60*MINUTE -#define DAY 24*HOUR -#define YEAR 365*DAY -time_t rep_mktime(struct tm *t) -{ - struct tm *u; - time_t epoch = 0; - int n; - int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - y, m, i; - - if(t->tm_year < 70) - return((time_t)-1); - - n = t->tm_year + 1900 - 1; - epoch = (t->tm_year - 70) * YEAR + - ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY; - - y = t->tm_year + 1900; - m = 0; - - for(i = 0; i < t->tm_mon; i++) { - epoch += mon [m] * DAY; - if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) - epoch += DAY; - - if(++m > 11) { - m = 0; - y++; - } - } - - epoch += (t->tm_mday - 1) * DAY; - epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; - - if((u = localtime(&epoch)) != NULL) { - t->tm_sec = u->tm_sec; - t->tm_min = u->tm_min; - t->tm_hour = u->tm_hour; - t->tm_mday = u->tm_mday; - t->tm_mon = u->tm_mon; - t->tm_year = u->tm_year; - t->tm_wday = u->tm_wday; - t->tm_yday = u->tm_yday; - t->tm_isdst = u->tm_isdst; - } - - return(epoch); -} -#endif /* !HAVE_MKTIME */ - - -#ifndef HAVE_INITGROUPS -/**************************************************************************** - some systems don't have an initgroups call -****************************************************************************/ -int rep_initgroups(char *name, gid_t id) -{ -#ifndef HAVE_SETGROUPS - /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ - errno = ENOSYS; - return -1; -#else /* HAVE_SETGROUPS */ - -#include - - gid_t *grouplst = NULL; - int max_gr = NGROUPS_MAX; - int ret; - int i,j; - struct group *g; - char *gr; - - if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) { - errno = ENOMEM; - return -1; - } - - grouplst[0] = id; - i = 1; - while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) { - if (g->gr_gid == id) - continue; - j = 0; - gr = g->gr_mem[0]; - while (gr && (*gr != (char)NULL)) { - if (strcmp(name,gr) == 0) { - grouplst[i] = g->gr_gid; - i++; - gr = (char *)NULL; - break; - } - gr = g->gr_mem[++j]; - } - } - endgrent(); - ret = setgroups(i, grouplst); - free(grouplst); - return ret; -#endif /* HAVE_SETGROUPS */ -} -#endif /* HAVE_INITGROUPS */ - - -#if (defined(SecureWare) && defined(SCO)) -/* This is needed due to needing the nap() function but we don't want - to include the Xenix libraries since that will break other things... - BTW: system call # 0x0c28 is the same as calling nap() */ -long nap(long milliseconds) { - return syscall(0x0c28, milliseconds); - } -#endif - - -#ifndef HAVE_MEMMOVE -/******************************************************************* -safely copies memory, ensuring no overlap problems. -this is only used if the machine does not have its own memmove(). -this is not the fastest algorithm in town, but it will do for our -needs. -********************************************************************/ -void *rep_memmove(void *dest,const void *src,int size) -{ - unsigned long d,s; - int i; - if (dest==src || !size) return(dest); - - d = (unsigned long)dest; - s = (unsigned long)src; - - if ((d >= (s+size)) || (s >= (d+size))) { - /* no overlap */ - memcpy(dest,src,size); - return(dest); - } - - if (d < s) { - /* we can forward copy */ - if (s-d >= sizeof(int) && - !(s%sizeof(int)) && - !(d%sizeof(int)) && - !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=0;i= sizeof(int) && - !(s%sizeof(int)) && - !(d%sizeof(int)) && - !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=size-1;i>=0;i--) idest[i] = isrc[i]; - } else { - /* simplest */ - char *cdest = (char *)dest; - char *csrc = (char *)src; - for (i=size-1;i>=0;i--) cdest[i] = csrc[i]; - } - } - return(dest); -} -#endif /* HAVE_MEMMOVE */ - -#ifndef HAVE_STRDUP -/**************************************************************************** -duplicate a string -****************************************************************************/ -char *rep_strdup(const char *s) -{ - size_t len; - char *ret; - - if (!s) return(NULL); - - len = strlen(s)+1; - ret = (char *)malloc(len); - if (!ret) return(NULL); - memcpy(ret,s,len); - return(ret); -} -#endif /* HAVE_STRDUP */ - -#ifndef HAVE_SETLINEBUF -void rep_setlinebuf(FILE *stream) -{ - setvbuf(stream, (char *)NULL, _IOLBF, 0); -} -#endif /* HAVE_SETLINEBUF */ - -#ifndef HAVE_VSYSLOG -#ifdef HAVE_SYSLOG -void rep_vsyslog (int facility_priority, const char *format, va_list arglist) -{ - char *msg = NULL; - vasprintf(&msg, format, arglist); - if (!msg) - return; - syslog(facility_priority, "%s", msg); - free(msg); -} -#endif /* HAVE_SYSLOG */ -#endif /* HAVE_VSYSLOG */ - -#ifndef HAVE_STRNLEN -/** - Some platforms don't have strnlen -**/ - size_t rep_strnlen(const char *s, size_t max) -{ - size_t len; - - for (len = 0; len < max; len++) { - if (s[len] == '\0') { - break; - } - } - return len; -} -#endif - -#ifndef HAVE_STRNDUP -/** - Some platforms don't have strndup. -**/ -char *rep_strndup(const char *s, size_t n) -{ - char *ret; - - n = strnlen(s, n); - ret = malloc(n+1); - if (!ret) - return NULL; - memcpy(ret, s, n); - ret[n] = 0; - - return ret; -} -#endif - -#ifndef HAVE_WAITPID -int rep_waitpid(pid_t pid,int *status,int options) -{ - return wait4(pid, status, options, NULL); -} -#endif - -#ifndef HAVE_SETEUID -int rep_seteuid(uid_t euid) -{ -#ifdef HAVE_SETRESUID - return setresuid(-1, euid, -1); -#else -# error "You need a seteuid function" -#endif -} -#endif - -#ifndef HAVE_SETEGID -int rep_setegid(gid_t egid) -{ -#ifdef HAVE_SETRESGID - return setresgid(-1, egid, -1); -#else -# error "You need a setegid function" -#endif -} -#endif - -/******************************************************************* -os/2 also doesn't have chroot -********************************************************************/ -#ifndef HAVE_CHROOT -int rep_chroot(const char *dname) -{ - errno = ENOSYS; - return -1; -} -#endif - -/***************************************************************** - Possibly replace mkstemp if it is broken. -*****************************************************************/ - -#ifndef HAVE_SECURE_MKSTEMP -int rep_mkstemp(char *template) -{ - /* have a reasonable go at emulating it. Hope that - the system mktemp() isn't completly hopeless */ - char *p = mktemp(template); - if (!p) - return -1; - return open(p, O_CREAT|O_EXCL|O_RDWR, 0600); -} -#endif - -#ifndef HAVE_MKDTEMP -char *rep_mkdtemp(char *template) -{ - char *dname; - - if ((dname = mktemp(template))) { - if (mkdir(dname, 0700) >= 0) { - return dname; - } - } - - return NULL; -} -#endif - -/***************************************************************** - Watch out: this is not thread safe. -*****************************************************************/ - -#ifndef HAVE_PREAD -ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) -{ - if (lseek(__fd, __offset, SEEK_SET) != __offset) { - return -1; - } - return read(__fd, __buf, __nbytes); -} -#endif - -/***************************************************************** - Watch out: this is not thread safe. -*****************************************************************/ - -#ifndef HAVE_PWRITE -ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) -{ - if (lseek(__fd, __offset, SEEK_SET) != __offset) { - return -1; - } - return write(__fd, __buf, __nbytes); -} -#endif - -#ifndef HAVE_STRCASESTR -char *rep_strcasestr(const char *haystack, const char *needle) -{ - const char *s; - size_t nlen = strlen(needle); - for (s=haystack;*s;s++) { - if (toupper(*needle) == toupper(*s) && - strncasecmp(s, needle, nlen) == 0) { - return (char *)((uintptr_t)s); - } - } - return NULL; -} -#endif - -#ifndef HAVE_STRTOK_R -/* based on GLIBC version, copyright Free Software Foundation */ -char *rep_strtok_r(char *s, const char *delim, char **save_ptr) -{ - char *token; - - if (s == NULL) s = *save_ptr; - - s += strspn(s, delim); - if (*s == '\0') { - *save_ptr = s; - return NULL; - } - - token = s; - s = strpbrk(token, delim); - if (s == NULL) { - *save_ptr = token + strlen(token); - } else { - *s = '\0'; - *save_ptr = s + 1; - } - - return token; -} -#endif - -#ifndef HAVE_STRTOLL -long long int rep_strtoll(const char *str, char **endptr, int base) -{ -#ifdef HAVE_STRTOQ - return strtoq(str, endptr, base); -#elif defined(HAVE___STRTOLL) - return __strtoll(str, endptr, base); -#elif SIZEOF_LONG == SIZEOF_LONG_LONG - return (long long int) strtol(str, endptr, base); -#else -# error "You need a strtoll function" -#endif -} -#endif - - -#ifndef HAVE_STRTOULL -unsigned long long int rep_strtoull(const char *str, char **endptr, int base) -{ -#ifdef HAVE_STRTOUQ - return strtouq(str, endptr, base); -#elif defined(HAVE___STRTOULL) - return __strtoull(str, endptr, base); -#elif SIZEOF_LONG == SIZEOF_LONG_LONG - return (unsigned long long int) strtoul(str, endptr, base); -#else -# error "You need a strtoull function" -#endif -} -#endif - -#ifndef HAVE_SETENV -int rep_setenv(const char *name, const char *value, int overwrite) -{ - char *p; - size_t l1, l2; - int ret; - - if (!overwrite && getenv(name)) { - return 0; - } - - l1 = strlen(name); - l2 = strlen(value); - - p = malloc(l1+l2+2); - if (p == NULL) { - return -1; - } - memcpy(p, name, l1); - p[l1] = '='; - memcpy(p+l1+1, value, l2); - p[l1+l2+1] = 0; - - ret = putenv(p); - if (ret != 0) { - free(p); - } - - return ret; -} -#endif - -#ifndef HAVE_UNSETENV -int rep_unsetenv(const char *name) -{ - extern char **environ; - size_t len = strlen(name); - size_t i, count; - - if (environ == NULL || getenv(name) == NULL) { - return 0; - } - - for (i=0;environ[i];i++) /* noop */ ; - - count=i; - - for (i=0;i -#endif - -#ifdef HAVE_STRING_H -#include -#endif - -#ifdef HAVE_STRINGS_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#if STDC_HEADERS -#include -#include -#endif - -#ifndef HAVE_STRERROR -extern char *sys_errlist[]; -#define strerror(i) sys_errlist[i] -#endif - -#ifndef HAVE_ERRNO_DECL -extern int errno; -#endif - -#ifndef HAVE_STRDUP -#define strdup rep_strdup -char *rep_strdup(const char *s); -#endif - -#ifndef HAVE_MEMMOVE -#define memmove rep_memmove -void *rep_memmove(void *dest,const void *src,int size); -#endif - -#ifndef HAVE_MKTIME -#define mktime rep_mktime -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_TIMEGM -#define timegm rep_timegm -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_UTIME -#define utime rep_utime -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_UTIMES -#define utimes rep_utimes -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_STRLCPY -#define strlcpy rep_strlcpy -size_t rep_strlcpy(char *d, const char *s, size_t bufsize); -#endif - -#ifndef HAVE_STRLCAT -#define strlcat rep_strlcat -size_t rep_strlcat(char *d, const char *s, size_t bufsize); -#endif - -#if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP)) -#undef HAVE_STRNDUP -#define strndup rep_strndup -char *rep_strndup(const char *s, size_t n); -#endif - -#if (defined(BROKEN_STRNLEN) || !defined(HAVE_STRNLEN)) -#undef HAVE_STRNLEN -#define strnlen rep_strnlen -size_t rep_strnlen(const char *s, size_t n); -#endif - -#ifndef HAVE_SETENV -#define setenv rep_setenv -int rep_setenv(const char *name, const char *value, int overwrite); -#else -#ifndef HAVE_SETENV_DECL -int setenv(const char *name, const char *value, int overwrite); -#endif -#endif - -#ifndef HAVE_UNSETENV -#define unsetenv rep_unsetenv -int rep_unsetenv(const char *name); -#endif - -#ifndef HAVE_SETEUID -#define seteuid rep_seteuid -int rep_seteuid(uid_t); -#endif - -#ifndef HAVE_SETEGID -#define setegid rep_setegid -int rep_setegid(gid_t); -#endif - -#ifndef HAVE_SETLINEBUF -#define setlinebuf rep_setlinebuf -void rep_setlinebuf(FILE *); -#endif - -#ifndef HAVE_STRCASESTR -#define strcasestr rep_strcasestr -char *rep_strcasestr(const char *haystack, const char *needle); -#endif - -#ifndef HAVE_STRTOK_R -#define strtok_r rep_strtok_r -char *rep_strtok_r(char *s, const char *delim, char **save_ptr); -#endif - -#ifndef HAVE_STRTOLL -#define strtoll rep_strtoll -long long int rep_strtoll(const char *str, char **endptr, int base); -#endif - -#ifndef HAVE_STRTOULL -#define strtoull rep_strtoull -unsigned long long int rep_strtoull(const char *str, char **endptr, int base); -#endif - -#ifndef HAVE_FTRUNCATE -#define ftruncate rep_ftruncate -int rep_ftruncate(int,off_t); -#endif - -#ifndef HAVE_INITGROUPS -#define initgroups rep_initgroups -int rep_initgroups(char *name, gid_t id); -#endif - -#if !defined(HAVE_BZERO) && defined(HAVE_MEMSET) -#define bzero(a,b) memset((a),'\0',(b)) -#endif - -#ifndef HAVE_DLERROR -#define dlerror rep_dlerror -char *rep_dlerror(void); -#endif - -#ifndef HAVE_DLOPEN -#define dlopen rep_dlopen -#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS -void *rep_dlopen(const char *name, unsigned int flags); -#else -void *rep_dlopen(const char *name, int flags); -#endif -#endif - -#ifndef HAVE_DLSYM -#define dlsym rep_dlsym -void *rep_dlsym(void *handle, const char *symbol); -#endif - -#ifndef HAVE_DLCLOSE -#define dlclose rep_dlclose -int rep_dlclose(void *handle); -#endif - -#ifndef HAVE_SOCKETPAIR -#define socketpair rep_socketpair -/* prototype is in system/network.h */ -#endif - -#ifndef PRINTF_ATTRIBUTE -#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -#ifndef _DEPRECATED_ -#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif - -#ifndef HAVE_VASPRINTF -#define vasprintf rep_vasprintf -int rep_vasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); -#endif - -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define snprintf rep_snprintf -int rep_snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4); -#endif - -#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define vsnprintf rep_vsnprintf -int rep_vsnprintf(char *,size_t ,const char *, va_list ap) PRINTF_ATTRIBUTE(3,0); -#endif - -#ifndef HAVE_ASPRINTF -#define asprintf rep_asprintf -int rep_asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); -#endif - -#ifndef HAVE_VSYSLOG -#ifdef HAVE_SYSLOG -#define vsyslog rep_vsyslog -void rep_vsyslog (int facility_priority, const char *format, va_list arglist) PRINTF_ATTRIBUTE(2,0); -#endif -#endif - -/* we used to use these fns, but now we have good replacements - for snprintf and vsnprintf */ -#define slprintf snprintf - - -#ifndef HAVE_VA_COPY -#undef va_copy -#ifdef HAVE___VA_COPY -#define va_copy(dest, src) __va_copy(dest, src) -#else -#define va_copy(dest, src) (dest) = (src) -#endif -#endif - -#ifndef HAVE_VOLATILE -#define volatile -#endif - -#ifndef HAVE_COMPARISON_FN_T -typedef int (*comparison_fn_t)(const void *, const void *); -#endif - -#ifdef REPLACE_STRPTIME -#define strptime rep_strptime -struct tm; -char *rep_strptime(const char *buf, const char *format, struct tm *tm); -#endif - -/* Load header file for dynamic linking stuff */ -#ifdef HAVE_DLFCN_H -#include -#endif - -#ifndef RTLD_LAZY -#define RTLD_LAZY 0 -#endif -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#ifndef HAVE_SECURE_MKSTEMP -#define mkstemp(path) rep_mkstemp(path) -int rep_mkstemp(char *temp); -#endif - -#ifndef HAVE_MKDTEMP -#define mkdtemp rep_mkdtemp -char *rep_mkdtemp(char *template); -#endif - -#ifndef HAVE_PREAD -#define pread rep_pread -ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); -#endif - -#ifndef HAVE_PWRITE -#define pwrite rep_pwrite -ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); -#endif - -#if !defined(HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) -#define inet_ntoa rep_inet_ntoa -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_INET_PTON -#define inet_pton rep_inet_pton -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_INET_NTOP -#define inet_ntop rep_inet_ntop -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_INET_ATON -#define inet_aton rep_inet_aton -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_CONNECT -#define connect rep_connect -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_GETHOSTBYNAME -#define gethostbyname rep_gethostbyname -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_GETIFADDRS -#define getifaddrs rep_getifaddrs -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_FREEIFADDRS -#define freeifaddrs rep_freeifaddrs -/* prototype is in "system/network.h" */ -#endif - -#ifdef HAVE_LIMITS_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -/* The extra casts work around common compiler bugs. */ -#define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) -/* The outer cast is needed to work around a bug in Cray C 5.0.3.0. - It is necessary at least when t == time_t. */ -#define _TYPE_MINIMUM(t) ((t) (_TYPE_SIGNED (t) \ - ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) -#define _TYPE_MAXIMUM(t) ((t) (~ (t) 0 - _TYPE_MINIMUM (t))) - -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 255 -#endif - -/* - * Some older systems seem not to have MAXHOSTNAMELEN - * defined. - */ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN HOST_NAME_MAX -#endif - -#ifndef UINT16_MAX -#define UINT16_MAX 65535 -#endif - -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#ifndef UINT64_MAX -#define UINT64_MAX ((uint64_t)-1) -#endif - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -#ifndef INT32_MAX -#define INT32_MAX _TYPE_MAXIMUM(int32_t) -#endif - -#ifdef HAVE_STDBOOL_H -#include -#endif - -#if !defined(HAVE_BOOL) -#ifdef HAVE__Bool -#define bool _Bool -#else -typedef int bool; -#endif -#endif - -/* - * to prevent from doing a redefine of 'bool' - * - * IRIX, HPUX, MacOS 10 and Solaris need BOOL_DEFINED - * Tru64 needs _BOOL_EXISTS - * AIX needs _BOOL,_TRUE,_FALSE - */ -#ifndef BOOL_DEFINED -#define BOOL_DEFINED -#endif -#ifndef _BOOL_EXISTS -#define _BOOL_EXISTS -#endif -#ifndef _BOOL -#define _BOOL -#endif - -#ifndef __bool_true_false_are_defined -#define __bool_true_false_are_defined -#endif - -#ifndef true -#define true (1) -#endif -#ifndef false -#define false (0) -#endif - -#ifndef _TRUE -#define _TRUE true -#endif -#ifndef _FALSE -#define _FALSE false -#endif - -#ifndef HAVE_FUNCTION_MACRO -#ifdef HAVE_func_MACRO -#define __FUNCTION__ __func__ -#else -#define __FUNCTION__ ("") -#endif -#endif - - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -#if !defined(HAVE_VOLATILE) -#define volatile -#endif - -/** - this is a warning hack. The idea is to use this everywhere that we - get the "discarding const" warning from gcc. That doesn't actually - fix the problem of course, but it means that when we do get to - cleaning them up we can do it by searching the code for - discard_const. - - It also means that other error types aren't as swamped by the noise - of hundreds of const warnings, so we are more likely to notice when - we get new errors. - - Please only add more uses of this macro when you find it - _really_ hard to fix const warnings. Our aim is to eventually use - this function in only a very few places. - - Also, please call this via the discard_const_p() macro interface, as that - makes the return type safe. -*/ -#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) - -/** Type-safe version of discard_const */ -#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) - -#ifndef __STRING -#define __STRING(x) #x -#endif - -#ifndef __STRINGSTRING -#define __STRINGSTRING(x) __STRING(x) -#endif - -#ifndef __LINESTR__ -#define __LINESTR__ __STRINGSTRING(__LINE__) -#endif - -#ifndef __location__ -#define __location__ __FILE__ ":" __LINESTR__ -#endif - -/** - * zero a structure - */ -#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) - -/** - * zero a structure given a pointer to the structure - */ -#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) - -/** - * zero a structure given a pointer to the structure - no zero check - */ -#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x))) - -/* zero an array - note that sizeof(array) must work - ie. it must not be a - pointer */ -#define ZERO_ARRAY(x) memset((char *)(x), 0, sizeof(x)) - -/** - * work out how many elements there are in a static array - */ -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - -/** - * pointer difference macro - */ -#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) - -#if MMAP_BLACKLIST -#undef HAVE_MMAP -#endif - -#ifdef __COMPAR_FN_T -#define QSORT_CAST (__compar_fn_t) -#endif - -#ifndef QSORT_CAST -#define QSORT_CAST (int (*)(const void *, const void *)) -#endif - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -#ifndef MAX_DNS_NAME_LENGTH -#define MAX_DNS_NAME_LENGTH 256 /* Actually 255 but +1 for terminating null. */ -#endif - -#endif /* _LIBREPLACE_REPLACE_H */ diff --git a/replace/samba.m4 b/replace/samba.m4 deleted file mode 100644 index 07c4d38887..0000000000 --- a/replace/samba.m4 +++ /dev/null @@ -1,35 +0,0 @@ -AC_LIBREPLACE_BROKEN_CHECKS -AC_LIBREPLACE_NETWORK_CHECKS - -SMB_EXT_LIB(LIBREPLACE_EXT, [${LIBDL}]) -SMB_ENABLE(LIBREPLACE_EXT) - -SMB_EXT_LIB(LIBREPLACE_NETWORK, [${LIBREPLACE_NETWORK_LIBS}]) -SMB_ENABLE(LIBREPLACE_NETWORK) - -# remove leading ./ -LIBREPLACE_DIR=`echo ${libreplacedir} |sed -e 's/^\.\///g'` - -# remove leading srcdir .. we are looking for the relative -# path within the samba source tree or wherever libreplace is. -# We need to make sure the object is not forced to end up in -# the source directory because we might be using a separate -# build directory. -LIBREPLACE_DIR=`echo ${LIBREPLACE_DIR} | sed -e "s|^$srcdir/||g"` - -LIBREPLACE_OBJS="" -for obj in ${LIBREPLACEOBJ}; do - LIBREPLACE_OBJS="${LIBREPLACE_OBJS} ${LIBREPLACE_DIR}/${obj}" -done - -SMB_SUBSYSTEM(LIBREPLACE, - [${LIBREPLACE_OBJS}], - [LIBREPLACE_EXT LIBREPLACE_NETWORK], - [-Ilib/replace]) - -LIBREPLACE_HOSTCC_OBJS=`echo ${LIBREPLACE_OBJS} |sed -e 's/\.o/\.ho/g'` - -SMB_SUBSYSTEM(LIBREPLACE_HOSTCC, - [${LIBREPLACE_HOSTCC_OBJS}], - [], - [-Ilib/replace]) diff --git a/replace/snprintf.c b/replace/snprintf.c deleted file mode 100644 index c54d721ce5..0000000000 --- a/replace/snprintf.c +++ /dev/null @@ -1,1530 +0,0 @@ -/* - * NOTE: If you change this file, please merge it into rsync, samba, etc. - */ - -/* - * Copyright Patrick Powell 1995 - * This code is based on code written by Patrick Powell (papowell@astart.com) - * It may be used for any purpose as long as this notice remains intact - * on all source code distributions - */ - -/************************************************************** - * 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 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 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 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. - * Unfortunately, unsigned formats simply didn't work. - * - * Michael Elkins 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. - * - * Andrew Tridgell (tridge@samba.org) Oct 1998 - * fixed handling of %.0f - * added test for HAVE_LONG_DOUBLE - * - * tridge@samba.org, idra@samba.org, April 2001 - * got rid of fcvt code (twas buggy and made testing harder) - * added C99 semantics - * - * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 - * actually print args for %g and %e - * - * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 - * Since includes.h isn't included here, VA_COPY has to be defined here. I don't - * see any include file that is guaranteed to be here, so I'm defining it - * locally. Fixes AIX and Solaris builds. - * - * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 - * put the ifdef for HAVE_VA_COPY in one place rather than in lots of - * functions - * - * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 - * Fix usage of va_list passed as an arg. Use __va_copy before using it - * when it exists. - * - * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 - * Fix incorrect zpadlen handling in fmtfp. - * Thanks to Ollie Oldham for spotting it. - * few mods to make it easier to compile the tests. - * addedd the "Ollie" test to the floating point ones. - * - * Martin Pool (mbp@samba.org) April 2003 - * Remove NO_CONFIG_H so that the test case can be built within a source - * tree with less trouble. - * Remove unnecessary SAFE_FREE() definition. - * - * Martin Pool (mbp@samba.org) May 2003 - * Put in a prototype for dummy_snprintf() to quiet compiler warnings. - * - * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even - * if the C library has some snprintf functions already. - * - * Darren Tucker (dtucker@zip.com.au) 2005 - * Fix bug allowing read overruns of the source string with "%.*s" - * Usually harmless unless the read runs outside the process' allocation - * (eg if your malloc does guard pages) in which case it will segfault. - * From OpenSSH. Also added test for same. - * - * Simo Sorce (idra@samba.org) Jan 2006 - * - * Add support for position independent parameters - * fix fmtstr now it conforms to sprintf wrt min.max - * - **************************************************************/ - -#include "replace.h" -#include "system/locale.h" - -#ifdef TEST_SNPRINTF /* need math library headers for testing */ - -/* In test mode, we pretend that this system doesn't have any snprintf - * functions, regardless of what config.h says. */ -# undef HAVE_SNPRINTF -# undef HAVE_VSNPRINTF -# undef HAVE_C99_VSNPRINTF -# undef HAVE_ASPRINTF -# undef HAVE_VASPRINTF -# include -#endif /* TEST_SNPRINTF */ - -#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) -/* only include stdio.h if we are not re-defining snprintf or vsnprintf */ -#include - /* make the compiler happy with an empty file */ - void dummy_snprintf(void); - void dummy_snprintf(void) {} -#endif /* HAVE_SNPRINTF, etc */ - -/* yes this really must be a ||. Don't muck with this (tridge) */ -#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - -#ifdef HAVE_LONG_DOUBLE -#define LDOUBLE long double -#else -#define LDOUBLE double -#endif - -#ifdef HAVE_LONG_LONG -#define LLONG long long -#else -#define LLONG long -#endif - -#ifndef VA_COPY -#ifdef HAVE_VA_COPY -#define VA_COPY(dest, src) va_copy(dest, src) -#else -#ifdef HAVE___VA_COPY -#define VA_COPY(dest, src) __va_copy(dest, src) -#else -#define VA_COPY(dest, src) (dest) = (src) -#endif -#endif - -/* - * 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_CHAR 1 -#define DP_C_SHORT 2 -#define DP_C_LONG 3 -#define DP_C_LDOUBLE 4 -#define DP_C_LLONG 5 -#define DP_C_SIZET 6 - -/* Chunk types */ -#define CNK_FMT_STR 0 -#define CNK_INT 1 -#define CNK_OCTAL 2 -#define CNK_UINT 3 -#define CNK_HEX 4 -#define CNK_FLOAT 5 -#define CNK_CHAR 6 -#define CNK_STRING 7 -#define CNK_PTR 8 -#define CNK_NUM 9 -#define CNK_PRCNT 10 - -#define char_to_int(p) ((p)- '0') -#ifndef MAX -#define MAX(p,q) (((p) >= (q)) ? (p) : (q)) -#endif - -struct pr_chunk { - int type; /* chunk type */ - int num; /* parameter number */ - int min; - int max; - int flags; - int cflags; - int start; - int len; - LLONG value; - LDOUBLE fvalue; - char *strvalue; - void *pnum; - struct pr_chunk *min_star; - struct pr_chunk *max_star; - struct pr_chunk *next; -}; - -struct pr_chunk_x { - struct pr_chunk **chunks; - int num; -}; - -static int dopr(char *buffer, size_t maxlen, const char *format, - va_list args_in); -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, - LLONG value, int base, int min, int max, int flags); -static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags); -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); -static struct pr_chunk *new_chunk(void); -static int add_cnk_list_entry(struct pr_chunk_x **list, - int max_num, struct pr_chunk *chunk); - -static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) -{ - char ch; - int state; - int pflag; - int pnum; - int pfirst; - size_t currlen; - va_list args; - const char *base; - struct pr_chunk *chunks = NULL; - struct pr_chunk *cnk = NULL; - struct pr_chunk_x *clist = NULL; - int max_pos; - int ret = -1; - - VA_COPY(args, args_in); - - state = DP_S_DEFAULT; - pfirst = 1; - pflag = 0; - pnum = 0; - - max_pos = 0; - base = format; - ch = *format++; - - /* retrieve the string structure as chunks */ - while (state != DP_S_DONE) { - if (ch == '\0') - state = DP_S_DONE; - - switch(state) { - case DP_S_DEFAULT: - - if (cnk) { - cnk->next = new_chunk(); - cnk = cnk->next; - } else { - cnk = new_chunk(); - } - if (!cnk) goto done; - if (!chunks) chunks = cnk; - - if (ch == '%') { - state = DP_S_FLAGS; - ch = *format++; - } else { - cnk->type = CNK_FMT_STR; - cnk->start = format - base -1; - while ((ch != '\0') && (ch != '%')) ch = *format++; - cnk->len = format - base - cnk->start -1; - } - break; - case DP_S_FLAGS: - switch (ch) { - case '-': - cnk->flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - cnk->flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - cnk->flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - cnk->flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - cnk->flags |= DP_F_ZERO; - ch = *format++; - break; - case 'I': - /* internationalization not supported yet */ - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) { - cnk->min = 10 * cnk->min + char_to_int (ch); - ch = *format++; - } else if (ch == '$') { - if (!pfirst && !pflag) { - /* parameters must be all positioned or none */ - goto done; - } - if (pfirst) { - pfirst = 0; - pflag = 1; - } - if (cnk->min == 0) /* what ?? */ - goto done; - cnk->num = cnk->min; - cnk->min = 0; - ch = *format++; - } else if (ch == '*') { - if (pfirst) pfirst = 0; - cnk->min_star = new_chunk(); - if (!cnk->min_star) /* out of memory :-( */ - goto done; - cnk->min_star->type = CNK_INT; - if (pflag) { - int num; - ch = *format++; - if (!isdigit((unsigned char)ch)) { - /* parameters must be all positioned or none */ - goto done; - } - for (num = 0; isdigit((unsigned char)ch); ch = *format++) { - num = 10 * num + char_to_int(ch); - } - cnk->min_star->num = num; - if (ch != '$') /* what ?? */ - goto done; - } else { - cnk->min_star->num = ++pnum; - } - max_pos = add_cnk_list_entry(&clist, max_pos, cnk->min_star); - if (max_pos == 0) /* out of memory :-( */ - goto done; - ch = *format++; - state = DP_S_DOT; - } else { - if (pfirst) pfirst = 0; - 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 (cnk->max < 0) - cnk->max = 0; - cnk->max = 10 * cnk->max + char_to_int (ch); - ch = *format++; - } else if (ch == '$') { - if (!pfirst && !pflag) { - /* parameters must be all positioned or none */ - goto done; - } - if (cnk->max <= 0) /* what ?? */ - goto done; - cnk->num = cnk->max; - cnk->max = -1; - ch = *format++; - } else if (ch == '*') { - cnk->max_star = new_chunk(); - if (!cnk->max_star) /* out of memory :-( */ - goto done; - cnk->max_star->type = CNK_INT; - if (pflag) { - int num; - ch = *format++; - if (!isdigit((unsigned char)ch)) { - /* parameters must be all positioned or none */ - goto done; - } - for (num = 0; isdigit((unsigned char)ch); ch = *format++) { - num = 10 * num + char_to_int(ch); - } - cnk->max_star->num = num; - if (ch != '$') /* what ?? */ - goto done; - } else { - cnk->max_star->num = ++pnum; - } - max_pos = add_cnk_list_entry(&clist, max_pos, cnk->max_star); - if (max_pos == 0) /* out of memory :-( */ - goto done; - - ch = *format++; - state = DP_S_MOD; - } else { - state = DP_S_MOD; - } - break; - case DP_S_MOD: - switch (ch) { - case 'h': - cnk->cflags = DP_C_SHORT; - ch = *format++; - if (ch == 'h') { - cnk->cflags = DP_C_CHAR; - ch = *format++; - } - break; - case 'l': - cnk->cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { /* It's a long long */ - cnk->cflags = DP_C_LLONG; - ch = *format++; - } - break; - case 'L': - cnk->cflags = DP_C_LDOUBLE; - ch = *format++; - break; - case 'z': - cnk->cflags = DP_C_SIZET; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - if (cnk->num == 0) cnk->num = ++pnum; - max_pos = add_cnk_list_entry(&clist, max_pos, cnk); - if (max_pos == 0) /* out of memory :-( */ - goto done; - - switch (ch) { - case 'd': - case 'i': - cnk->type = CNK_INT; - break; - case 'o': - cnk->type = CNK_OCTAL; - cnk->flags |= DP_F_UNSIGNED; - break; - case 'u': - cnk->type = CNK_UINT; - cnk->flags |= DP_F_UNSIGNED; - break; - case 'X': - cnk->flags |= DP_F_UP; - case 'x': - cnk->type = CNK_HEX; - cnk->flags |= DP_F_UNSIGNED; - break; - case 'A': - /* hex float not supported yet */ - case 'E': - case 'G': - case 'F': - cnk->flags |= DP_F_UP; - case 'a': - /* hex float not supported yet */ - case 'e': - case 'f': - case 'g': - cnk->type = CNK_FLOAT; - break; - case 'c': - cnk->type = CNK_CHAR; - break; - case 's': - cnk->type = CNK_STRING; - break; - case 'p': - cnk->type = CNK_PTR; - break; - case 'n': - cnk->type = CNK_NUM; - break; - case '%': - cnk->type = CNK_PRCNT; - break; - default: - /* Unknown, bail out*/ - goto done; - } - ch = *format++; - state = DP_S_DEFAULT; - break; - case DP_S_DONE: - break; - default: - /* hmm? */ - break; /* some picky compilers need this */ - } - } - - /* retrieve the format arguments */ - for (pnum = 0; pnum < max_pos; pnum++) { - int i; - - if (clist[pnum].num == 0) { - /* ignoring a parameter should not be permitted - * all parameters must be matched at least once - * BUT seem some system ignore this rule ... - * at least my glibc based system does --SSS - */ -#ifdef DEBUG_SNPRINTF - printf("parameter at position %d not used\n", pnum+1); -#endif - /* eat the parameter */ - va_arg (args, int); - continue; - } - for (i = 1; i < clist[pnum].num; i++) { - if (clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) { - /* nooo noo no! - * all the references to a parameter - * must be of the same type - */ - goto done; - } - } - cnk = clist[pnum].chunks[0]; - switch (cnk->type) { - case CNK_INT: - if (cnk->cflags == DP_C_SHORT) - cnk->value = va_arg (args, int); - else if (cnk->cflags == DP_C_LONG) - cnk->value = va_arg (args, long int); - else if (cnk->cflags == DP_C_LLONG) - cnk->value = va_arg (args, LLONG); - else if (cnk->cflags == DP_C_SIZET) - cnk->value = va_arg (args, ssize_t); - else - cnk->value = va_arg (args, int); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->value = cnk->value; - } - break; - - case CNK_OCTAL: - case CNK_UINT: - case CNK_HEX: - if (cnk->cflags == DP_C_SHORT) - cnk->value = va_arg (args, unsigned int); - else if (cnk->cflags == DP_C_LONG) - cnk->value = (unsigned long int)va_arg (args, unsigned long int); - else if (cnk->cflags == DP_C_LLONG) - cnk->value = (LLONG)va_arg (args, unsigned LLONG); - else if (cnk->cflags == DP_C_SIZET) - cnk->value = (size_t)va_arg (args, size_t); - else - cnk->value = (unsigned int)va_arg (args, unsigned int); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->value = cnk->value; - } - break; - - case CNK_FLOAT: - if (cnk->cflags == DP_C_LDOUBLE) - cnk->fvalue = va_arg (args, LDOUBLE); - else - cnk->fvalue = va_arg (args, double); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->fvalue = cnk->fvalue; - } - break; - - case CNK_CHAR: - cnk->value = va_arg (args, int); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->value = cnk->value; - } - break; - - case CNK_STRING: - cnk->strvalue = va_arg (args, char *); - if (!cnk->strvalue) cnk->strvalue = "(NULL)"; - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->strvalue = cnk->strvalue; - } - break; - - case CNK_PTR: - cnk->strvalue = va_arg (args, void *); - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->strvalue = cnk->strvalue; - } - break; - - case CNK_NUM: - if (cnk->cflags == DP_C_CHAR) - cnk->pnum = va_arg (args, char *); - else if (cnk->cflags == DP_C_SHORT) - cnk->pnum = va_arg (args, short int *); - else if (cnk->cflags == DP_C_LONG) - cnk->pnum = va_arg (args, long int *); - else if (cnk->cflags == DP_C_LLONG) - cnk->pnum = va_arg (args, LLONG *); - else if (cnk->cflags == DP_C_SIZET) - cnk->pnum = va_arg (args, ssize_t *); - else - cnk->pnum = va_arg (args, int *); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->pnum = cnk->pnum; - } - break; - - case CNK_PRCNT: - break; - - default: - /* what ?? */ - goto done; - } - } - /* print out the actual string from chunks */ - currlen = 0; - cnk = chunks; - while (cnk) { - int len, min, max; - - if (cnk->min_star) min = cnk->min_star->value; - else min = cnk->min; - if (cnk->max_star) max = cnk->max_star->value; - else max = cnk->max; - - switch (cnk->type) { - - case CNK_FMT_STR: - if (maxlen != 0 && maxlen > currlen) { - if (maxlen > (currlen + cnk->len)) len = cnk->len; - else len = maxlen - currlen; - - memcpy(&(buffer[currlen]), &(base[cnk->start]), len); - } - currlen += cnk->len; - - break; - - case CNK_INT: - case CNK_UINT: - fmtint (buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags); - break; - - case CNK_OCTAL: - fmtint (buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags); - break; - - case CNK_HEX: - fmtint (buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags); - break; - - case CNK_FLOAT: - fmtfp (buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags); - break; - - case CNK_CHAR: - dopr_outch (buffer, &currlen, maxlen, cnk->value); - break; - - case CNK_STRING: - if (max == -1) { - max = strlen(cnk->strvalue); - } - fmtstr (buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max); - break; - - case CNK_PTR: - fmtint (buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags); - break; - - case CNK_NUM: - if (cnk->cflags == DP_C_CHAR) - *((char *)(cnk->pnum)) = (char)currlen; - else if (cnk->cflags == DP_C_SHORT) - *((short int *)(cnk->pnum)) = (short int)currlen; - else if (cnk->cflags == DP_C_LONG) - *((long int *)(cnk->pnum)) = (long int)currlen; - else if (cnk->cflags == DP_C_LLONG) - *((LLONG *)(cnk->pnum)) = (LLONG)currlen; - else if (cnk->cflags == DP_C_SIZET) - *((ssize_t *)(cnk->pnum)) = (ssize_t)currlen; - else - *((int *)(cnk->pnum)) = (int)currlen; - break; - - case CNK_PRCNT: - dopr_outch (buffer, &currlen, maxlen, '%'); - break; - - default: - /* what ?? */ - goto done; - } - cnk = cnk->next; - } - if (maxlen != 0) { - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else if (maxlen > 0) - buffer[maxlen - 1] = '\0'; - } - ret = currlen; - -done: - va_end(args); - - while (chunks) { - cnk = chunks->next; - free(chunks); - chunks = cnk; - } - if (clist) { - for (pnum = 0; pnum < max_pos; pnum++) { - if (clist[pnum].chunks) free(clist[pnum].chunks); - } - free(clist); - } - return ret; -} - -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; - -#ifdef DEBUG_SNPRINTF - printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); -#endif - if (value == 0) { - value = ""; - } - - for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - } - while (*value && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, *value++); - ++cnt; - } - while (padlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - } -} - -/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ - -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags) -{ - int signvalue = 0; - unsigned LLONG 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 - printf("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 LDOUBLE abs_val(LDOUBLE value) -{ - LDOUBLE result = value; - - if (value < 0) - result = -value; - - return result; -} - -static LDOUBLE POW10(int exp) -{ - LDOUBLE result = 1; - - while (exp) { - result *= 10; - exp--; - } - - return result; -} - -static LLONG ROUND(LDOUBLE value) -{ - LLONG intpart; - - intpart = (LLONG)value; - value = value - intpart; - if (value >= 0.5) intpart++; - - return intpart; -} - -/* a replacement for modf that doesn't need the math library. Should - be portable, but slow */ -static double my_modf(double x0, double *iptr) -{ - int i; - LLONG l=0; - double x = x0; - double f = 1.0; - - for (i=0;i<100;i++) { - l = (long)x; - if (l <= (x+1) && l >= (x-1)) break; - x *= 0.1; - f *= 10.0; - } - - if (i == 100) { - /* yikes! the number is beyond what we can handle. What do we do? */ - (*iptr) = 0; - return 0; - } - - if (i != 0) { - double i2; - double ret; - - ret = my_modf(x0-l*f, &i2); - (*iptr) = l*f + i2; - return ret; - } - - (*iptr) = l; - return x - (*iptr); -} - - -static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags) -{ - int signvalue = 0; - double ufvalue; - char iconvert[311]; - char fconvert[311]; - int iplace = 0; - int fplace = 0; - int padlen = 0; /* amount to pad */ - int zpadlen = 0; - int caps = 0; - int idx; - double intpart; - double fracpart; - double temp; - - /* - * 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 - -#if 0 - if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ -#endif - - /* - * 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 - */ - - temp = ufvalue; - my_modf(temp, &intpart); - - fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); - - if (fracpart >= POW10(max)) { - intpart++; - fracpart -= POW10(max); - } - - - /* Convert integer part */ - do { - temp = intpart*0.1; - my_modf(temp, &intpart); - idx = (int) ((temp -intpart +0.05)* 10.0); - /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ - /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ - iconvert[iplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; - } while (intpart && (iplace < 311)); - if (iplace == 311) iplace--; - iconvert[iplace] = 0; - - /* Convert fractional part */ - if (fracpart) - { - do { - temp = fracpart*0.1; - my_modf(temp, &fracpart); - idx = (int) ((temp -fracpart +0.05)* 10.0); - /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ - /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ - fconvert[fplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; - } while(fracpart && (fplace < 311)); - if (fplace == 311) 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]); - -#ifdef DEBUG_SNPRINTF - printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); -#endif - - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - if (max > 0) { - dopr_outch (buffer, currlen, maxlen, '.'); - - while (zpadlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - - while (fplace > 0) - dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); - } - - 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; - } - (*currlen)++; -} - -static struct pr_chunk *new_chunk(void) { - struct pr_chunk *new_c = (struct pr_chunk *)malloc(sizeof(struct pr_chunk)); - - if (!new_c) - return NULL; - - new_c->type = 0; - new_c->num = 0; - new_c->min = 0; - new_c->min_star = NULL; - new_c->max = -1; - new_c->max_star = NULL; - new_c->flags = 0; - new_c->cflags = 0; - new_c->start = 0; - new_c->len = 0; - new_c->value = 0; - new_c->fvalue = 0; - new_c->strvalue = NULL; - new_c->pnum = NULL; - new_c->next = NULL; - - return new_c; -} - -static int add_cnk_list_entry(struct pr_chunk_x **list, - int max_num, struct pr_chunk *chunk) { - struct pr_chunk_x *l; - struct pr_chunk **c; - int max; - int cnum; - int i, pos; - - if (chunk->num > max_num) { - max = chunk->num; - - if (*list == NULL) { - l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max); - pos = 0; - } else { - l = (struct pr_chunk_x *)realloc(*list, sizeof(struct pr_chunk_x) * max); - pos = max_num; - } - if (l == NULL) { - for (i = 0; i < max; i++) { - if ((*list)[i].chunks) free((*list)[i].chunks); - } - return 0; - } - for (i = pos; i < max; i++) { - l[i].chunks = NULL; - l[i].num = 0; - } - } else { - l = *list; - max = max_num; - } - - i = chunk->num - 1; - cnum = l[i].num + 1; - if (l[i].chunks == NULL) { - c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum); - } else { - c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum); - } - if (c == NULL) { - for (i = 0; i < max; i++) { - if (l[i].chunks) free(l[i].chunks); - } - return 0; - } - c[l[i].num] = chunk; - l[i].chunks = c; - l[i].num = cnum; - - *list = l; - return max; -} - - int vsnprintf (char *str, size_t count, const char *fmt, va_list args) -{ - return dopr(str, count, fmt, args); -} -#endif - -/* yes this really must be a ||. Don't muck with this (tridge) - * - * The logic for these two is that we need our own definition if the - * OS *either* has no definition of *sprintf, or if it does have one - * that doesn't work properly according to the autoconf test. - */ -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int snprintf(char *str,size_t count,const char *fmt,...) -{ - size_t ret; - va_list ap; - - va_start(ap, fmt); - ret = vsnprintf(str, count, fmt, ap); - va_end(ap); - return ret; -} -#endif - -#ifndef HAVE_C99_VSNPRINTF - int printf(const char *fmt, ...) -{ - va_list ap; - int ret; - char *s; - - s = NULL; - va_start(ap, fmt); - ret = vasprintf(&s, fmt, ap); - va_end(ap); - - if (s) { - fwrite(s, 1, strlen(s), stdout); - } - free(s); - - return ret; -} -#endif - -#ifndef HAVE_C99_VSNPRINTF - int fprintf(FILE *stream, const char *fmt, ...) -{ - va_list ap; - int ret; - char *s; - - s = NULL; - va_start(ap, fmt); - ret = vasprintf(&s, fmt, ap); - va_end(ap); - - if (s) { - fwrite(s, 1, strlen(s), stream); - } - free(s); - - return ret; -} -#endif - -#endif - -#ifndef HAVE_VASPRINTF - int vasprintf(char **ptr, const char *format, va_list ap) -{ - int ret; - va_list ap2; - - VA_COPY(ap2, ap); - ret = vsnprintf(NULL, 0, format, ap2); - va_end(ap2); - if (ret < 0) return ret; - - (*ptr) = (char *)malloc(ret+1); - if (!*ptr) return -1; - - VA_COPY(ap2, ap); - ret = vsnprintf(*ptr, ret+1, format, ap2); - va_end(ap2); - - return ret; -} -#endif - - -#ifndef HAVE_ASPRINTF - int asprintf(char **ptr, const char *format, ...) -{ - va_list ap; - int ret; - - *ptr = NULL; - va_start(ap, format); - ret = vasprintf(ptr, format, ap); - va_end(ap); - - return ret; -} -#endif - -#ifdef TEST_SNPRINTF - - int sprintf(char *str,const char *fmt,...); - int printf(const char *fmt,...); - - int main (void) -{ - char buf1[1024]; - char buf2[1024]; - char *buf3; - char *fp_fmt[] = { - "%1.1f", - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - "%.0f", - "%f", - "%-8.8f", - "%-9.9f", - NULL - }; - double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996, - 0.9996, 1.996, 4.136, 5.030201, 0.00205, - /* END LIST */ 0}; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - "%d", - NULL - }; - long int_nums[] = { -1, 134, 91340, 341, 0203, 1234567890, 0}; - char *str_fmt[] = { - "%10.5s", - "%-10.5s", - "%5.10s", - "%-5.10s", - "%10.1s", - "%0.10s", - "%10.0s", - "%1.10s", - "%s", - "%.1s", - "%.10s", - "%10s", - NULL - }; - char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; -#ifdef HAVE_LONG_LONG - char *ll_fmt[] = { - "%llu", - NULL - }; - LLONG ll_nums[] = { 134, 91340, 341, 0203, 1234567890, 128006186140000000LL, 0}; -#endif - int x, y; - int fail = 0; - int num = 0; - int l1, l2; - char *ss_fmt[] = { - "%zd", - "%zu", - NULL - }; - size_t ss_nums[] = {134, 91340, 123456789, 0203, 1234567890, 0}; - - printf ("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] ; x++) { - for (y = 0; fp_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); - l2 = sprintf (buf2, fp_fmt[x], fp_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - fp_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } - - for (x = 0; int_fmt[x] ; x++) { - for (y = 0; int_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); - l2 = sprintf (buf2, int_fmt[x], int_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - int_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } - - for (x = 0; str_fmt[x] ; x++) { - for (y = 0; str_vals[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); - l2 = sprintf (buf2, str_fmt[x], str_vals[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - str_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } - -#ifdef HAVE_LONG_LONG - for (x = 0; ll_fmt[x] ; x++) { - for (y = 0; ll_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), ll_fmt[x], ll_nums[y]); - l2 = sprintf (buf2, ll_fmt[x], ll_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - ll_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } -#endif - -#define BUFSZ 2048 - - buf1[0] = buf2[0] = '\0'; - if ((buf3 = malloc(BUFSZ)) == NULL) { - fail++; - } else { - num++; - memset(buf3, 'a', BUFSZ); - snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3); - buf1[1023] = '\0'; - if (strcmp(buf1, "a") != 0) { - printf("length limit buf1 '%s' expected 'a'\n", buf1); - fail++; - } - } - - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); - l2 = sprintf(buf2, "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); - fail++; - } - - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); - l2 = sprintf(buf2, "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); - fail++; - } - - for (x = 0; ss_fmt[x] ; x++) { - for (y = 0; ss_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), ss_fmt[x], ss_nums[y]); - l2 = sprintf (buf2, ss_fmt[x], ss_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - ss_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } -#if 0 - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%lld", (LLONG)1234567890); - l2 = sprintf(buf2, "%lld", (LLONG)1234567890); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%lld", l1, buf1, l2, buf2); - fail++; - } - - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%Lf", (LDOUBLE)890.1234567890123); - l2 = sprintf(buf2, "%Lf", (LDOUBLE)890.1234567890123); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%Lf", l1, buf1, l2, buf2); - fail++; - } -#endif - printf ("%d tests failed out of %d.\n", fail, num); - - printf("seeing how many digits we support\n"); - { - double v0 = 0.12345678901234567890123456789012345678901; - for (x=0; x<100; x++) { - double p = pow(10, x); - double r = v0*p; - snprintf(buf1, sizeof(buf1), "%1.1f", r); - sprintf(buf2, "%1.1f", r); - if (strcmp(buf1, buf2)) { - printf("we seem to support %d digits\n", x-1); - break; - } - } - } - - return 0; -} -#endif /* TEST_SNPRINTF */ diff --git a/replace/socket.c b/replace/socket.c deleted file mode 100644 index 35e975fce7..0000000000 --- a/replace/socket.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * Dummy replacements for socket functions. - * - * Copyright (C) Michael Adam 2008 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "replace.h" -#include "system/network.h" - -int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) -{ - errno = ENOSYS; - return -1; -} - -struct hostent *rep_gethostbyname(const char *name) -{ - errno = ENOSYS; - return NULL; -} diff --git a/replace/socketpair.c b/replace/socketpair.c deleted file mode 100644 index c775730952..0000000000 --- a/replace/socketpair.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * replacement routines for broken systems - * Copyright (C) Jelmer Vernooij 2006 - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/network.h" - -int rep_socketpair(int d, int type, int protocol, int sv[2]) -{ - if (d != AF_UNIX) { - errno = EAFNOSUPPORT; - return -1; - } - - if (protocol != 0) { - errno = EPROTONOSUPPORT; - return -1; - } - - if (type != SOCK_STREAM) { - errno = EOPNOTSUPP; - return -1; - } - - return pipe(sv); -} diff --git a/replace/strptime.c b/replace/strptime.c deleted file mode 100644 index 0e40f7561a..0000000000 --- a/replace/strptime.c +++ /dev/null @@ -1,990 +0,0 @@ -/* Convert a string representation of time to a time value. - Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 1996. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 3 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - see . */ - -/* XXX This version of the implementation is not really complete. - Some of the fields cannot add information alone. But if seeing - some of them in the same format (such as year, week and weekday) - this is enough information for determining the date. */ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" - -#ifndef __P -# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) -# define __P(args) args -# else -# define __P(args) () -# endif /* GCC. */ -#endif /* Not __P. */ - -#if ! HAVE_LOCALTIME_R && ! defined localtime_r -# ifdef _LIBC -# define localtime_r __localtime_r -# else -/* Approximate localtime_r as best we can in its absence. */ -# define localtime_r my_localtime_r -static struct tm *localtime_r __P ((const time_t *, struct tm *)); -static struct tm * -localtime_r (t, tp) - const time_t *t; - struct tm *tp; -{ - struct tm *l = localtime (t); - if (! l) - return 0; - *tp = *l; - return tp; -} -# endif /* ! _LIBC */ -#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ - - -#define match_char(ch1, ch2) if (ch1 != ch2) return NULL -#if defined __GNUC__ && __GNUC__ >= 2 -# define match_string(cs1, s2) \ - ({ size_t len = strlen (cs1); \ - int result = strncasecmp ((cs1), (s2), len) == 0; \ - if (result) (s2) += len; \ - result; }) -#else -/* Oh come on. Get a reasonable compiler. */ -# define match_string(cs1, s2) \ - (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) -#endif -/* We intentionally do not use isdigit() for testing because this will - lead to problems with the wide character version. */ -#define get_number(from, to, n) \ - do { \ - int __n = n; \ - val = 0; \ - while (*rp == ' ') \ - ++rp; \ - if (*rp < '0' || *rp > '9') \ - return NULL; \ - do { \ - val *= 10; \ - val += *rp++ - '0'; \ - } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ - if (val < from || val > to) \ - return NULL; \ - } while (0) -#ifdef _NL_CURRENT -# define get_alt_number(from, to, n) \ - ({ \ - __label__ do_normal; \ - if (*decided != raw) \ - { \ - const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ - int __n = n; \ - int any = 0; \ - while (*rp == ' ') \ - ++rp; \ - val = 0; \ - do { \ - val *= 10; \ - while (*alts != '\0') \ - { \ - size_t len = strlen (alts); \ - if (strncasecmp (alts, rp, len) == 0) \ - break; \ - alts += len + 1; \ - ++val; \ - } \ - if (*alts == '\0') \ - { \ - if (*decided == not && ! any) \ - goto do_normal; \ - /* If we haven't read anything it's an error. */ \ - if (! any) \ - return NULL; \ - /* Correct the premature multiplication. */ \ - val /= 10; \ - break; \ - } \ - else \ - *decided = loc; \ - } while (--__n > 0 && val * 10 <= to); \ - if (val < from || val > to) \ - return NULL; \ - } \ - else \ - { \ - do_normal: \ - get_number (from, to, n); \ - } \ - 0; \ - }) -#else -# define get_alt_number(from, to, n) \ - /* We don't have the alternate representation. */ \ - get_number(from, to, n) -#endif -#define recursive(new_fmt) \ - (*(new_fmt) != '\0' \ - && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) - - -#ifdef _LIBC -/* This is defined in locale/C-time.c in the GNU libc. */ -extern const struct locale_data _nl_C_LC_TIME; -extern const unsigned short int __mon_yday[2][13]; - -# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) -# define ab_weekday_name \ - (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) -# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) -# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) -# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) -# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) -# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) -# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) -# define HERE_T_FMT_AMPM \ - (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) -# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) - -# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) -#else -static char const weekday_name[][10] = - { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }; -static char const ab_weekday_name[][4] = - { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; -static char const month_name[][10] = - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }; -static char const ab_month_name[][4] = - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; -# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" -# define HERE_D_FMT "%m/%d/%y" -# define HERE_AM_STR "AM" -# define HERE_PM_STR "PM" -# define HERE_T_FMT_AMPM "%I:%M:%S %p" -# define HERE_T_FMT "%H:%M:%S" - -static const unsigned short int __mon_yday[2][13] = - { - /* Normal years. */ - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - /* Leap years. */ - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } - }; -#endif - -/* Status of lookup: do we use the locale data or the raw data? */ -enum locale_status { not, loc, raw }; - - -#ifndef __isleap -/* Nonzero if YEAR is a leap year (every 4 years, - except every 100th isn't, and every 400th is). */ -# define __isleap(year) \ - ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) -#endif - -/* Compute the day of the week. */ -static void -day_of_the_week (struct tm *tm) -{ - /* We know that January 1st 1970 was a Thursday (= 4). Compute the - the difference between this data in the one on TM and so determine - the weekday. */ - int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); - int wday = (-473 - + (365 * (tm->tm_year - 70)) - + (corr_year / 4) - - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) - + (((corr_year / 4) / 25) / 4) - + __mon_yday[0][tm->tm_mon] - + tm->tm_mday - 1); - tm->tm_wday = ((wday % 7) + 7) % 7; -} - -/* Compute the day of the year. */ -static void -day_of_the_year (struct tm *tm) -{ - tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] - + (tm->tm_mday - 1)); -} - -static char * -#ifdef _LIBC -internal_function -#endif -strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, - enum locale_status *decided, int era_cnt)); - -static char * -#ifdef _LIBC -internal_function -#endif -strptime_internal (rp, fmt, tm, decided, era_cnt) - const char *rp; - const char *fmt; - struct tm *tm; - enum locale_status *decided; - int era_cnt; -{ - const char *rp_backup; - int cnt; - size_t val; - int have_I, is_pm; - int century, want_century; - int want_era; - int have_wday, want_xday; - int have_yday; - int have_mon, have_mday; -#ifdef _NL_CURRENT - size_t num_eras; -#endif - struct era_entry *era; - - have_I = is_pm = 0; - century = -1; - want_century = 0; - want_era = 0; - era = NULL; - - have_wday = want_xday = have_yday = have_mon = have_mday = 0; - - while (*fmt != '\0') - { - /* A white space in the format string matches 0 more or white - space in the input string. */ - if (isspace (*fmt)) - { - while (isspace (*rp)) - ++rp; - ++fmt; - continue; - } - - /* Any character but `%' must be matched by the same character - in the iput string. */ - if (*fmt != '%') - { - match_char (*fmt++, *rp++); - continue; - } - - ++fmt; -#ifndef _NL_CURRENT - /* We need this for handling the `E' modifier. */ - start_over: -#endif - - /* Make back up of current processing pointer. */ - rp_backup = rp; - - switch (*fmt++) - { - case '%': - /* Match the `%' character itself. */ - match_char ('%', *rp++); - break; - case 'a': - case 'A': - /* Match day of week. */ - for (cnt = 0; cnt < 7; ++cnt) - { -#ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), - weekday_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), - ab_weekday_name[cnt])) - *decided = loc; - break; - } - } -#endif - if (*decided != loc - && (match_string (weekday_name[cnt], rp) - || match_string (ab_weekday_name[cnt], rp))) - { - *decided = raw; - break; - } - } - if (cnt == 7) - /* Does not match a weekday name. */ - return NULL; - tm->tm_wday = cnt; - have_wday = 1; - break; - case 'b': - case 'B': - case 'h': - /* Match month name. */ - for (cnt = 0; cnt < 12; ++cnt) - { -#ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), - month_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), - ab_month_name[cnt])) - *decided = loc; - break; - } - } -#endif - if (match_string (month_name[cnt], rp) - || match_string (ab_month_name[cnt], rp)) - { - *decided = raw; - break; - } - } - if (cnt == 12) - /* Does not match a month name. */ - return NULL; - tm->tm_mon = cnt; - want_xday = 1; - break; - case 'c': - /* Match locale's date and time format. */ -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } -#endif - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - /* Match century number. */ -#ifdef _NL_CURRENT - match_century: -#endif - get_number (0, 99, 2); - century = val; - want_xday = 1; - break; - case 'd': - case 'e': - /* Match day of month. */ - get_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'F': - if (!recursive ("%Y-%m-%d")) - return NULL; - want_xday = 1; - break; - case 'x': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } -#endif - /* Fall through. */ - case 'D': - /* Match standard day format. */ - if (!recursive (HERE_D_FMT)) - return NULL; - want_xday = 1; - break; - case 'k': - case 'H': - /* Match hour in 24-hour clock. */ - get_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock. */ - get_number (1, 12, 2); - tm->tm_hour = val % 12; - have_I = 1; - break; - case 'j': - /* Match day number of year. */ - get_number (1, 366, 3); - tm->tm_yday = val - 1; - have_yday = 1; - break; - case 'm': - /* Match number of month. */ - get_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minute. */ - get_number (0, 59, 2); - tm->tm_min = val; - break; - case 'n': - case 't': - /* Match any white space. */ - while (isspace (*rp)) - ++rp; - break; - case 'p': - /* Match locale's equivalent of AM/PM. */ -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) - *decided = loc; - is_pm = 1; - break; - } - *decided = raw; - } -#endif - if (!match_string (HERE_AM_STR, rp)) { - if (match_string (HERE_PM_STR, rp)) { - is_pm = 1; - } else { - return NULL; - } - } - break; - case 'r': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), - HERE_T_FMT_AMPM)) - *decided = loc; - break; - } - *decided = raw; - } -#endif - if (!recursive (HERE_T_FMT_AMPM)) - return NULL; - break; - case 'R': - if (!recursive ("%H:%M")) - return NULL; - break; - case 's': - { - /* The number of seconds may be very high so we cannot use - the `get_number' macro. Instead read the number - character for character and construct the result while - doing this. */ - time_t secs = 0; - if (*rp < '0' || *rp > '9') - /* We need at least one digit. */ - return NULL; - - do - { - secs *= 10; - secs += *rp++ - '0'; - } - while (*rp >= '0' && *rp <= '9'); - - if (localtime_r (&secs, tm) == NULL) - /* Error in function. */ - return NULL; - } - break; - case 'S': - get_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'X': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } -#endif - /* Fall through. */ - case 'T': - if (!recursive (HERE_T_FMT)) - return NULL; - break; - case 'u': - get_number (1, 7, 1); - tm->tm_wday = val % 7; - have_wday = 1; - break; - case 'g': - get_number (0, 99, 2); - /* XXX This cannot determine any field in TM. */ - break; - case 'G': - if (*rp < '0' || *rp > '9') - return NULL; - /* XXX Ignore the number since we would need some more - information to compute a real date. */ - do - ++rp; - while (*rp >= '0' && *rp <= '9'); - break; - case 'U': - case 'V': - case 'W': - get_number (0, 53, 2); - /* XXX This cannot determine any field in TM without some - information. */ - break; - case 'w': - /* Match number of weekday. */ - get_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': -#ifdef _NL_CURRENT - match_year_in_century: -#endif - /* Match year within century. */ - get_number (0, 99, 2); - /* The "Year 2000: The Millennium Rollover" paper suggests that - values in the range 69-99 refer to the twentieth century. */ - tm->tm_year = val >= 69 ? val : val + 100; - /* Indicate that we want to use the century, if specified. */ - want_century = 1; - want_xday = 1; - break; - case 'Y': - /* Match year including century number. */ - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'Z': - /* XXX How to handle this? */ - break; - case 'E': -#ifdef _NL_CURRENT - switch (*fmt++) - { - case 'c': - /* Match locale's alternate date and time format. */ - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - if (*decided != raw) - { - if (era_cnt >= 0) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - else - return NULL; - } - else - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - } - else - break; - } - - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - goto match_century; - case 'y': - if (*decided == raw) - goto match_year_in_century; - - get_number(0, 9999, 4); - tm->tm_year = val; - want_era = 1; - want_xday = 1; - break; - case 'Y': - if (*decided != raw) - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (recursive (era->era_format)) - break; - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - *decided = loc; - era_cnt = -1; - break; - } - - *decided = raw; - } - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'x': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_D_FMT)) - return NULL; - break; - case 'X': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_T_FMT)) - return NULL; - break; - default: - return NULL; - } - break; -#else - /* We have no information about the era format. Just use - the normal format. */ - if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' - && *fmt != 'x' && *fmt != 'X') - /* This is an illegal format. */ - return NULL; - - goto start_over; -#endif - case 'O': - switch (*fmt++) - { - case 'd': - case 'e': - /* Match day of month using alternate numeric symbols. */ - get_alt_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'H': - /* Match hour in 24-hour clock using alternate numeric - symbols. */ - get_alt_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock using alternate numeric - symbols. */ - get_alt_number (1, 12, 2); - tm->tm_hour = val - 1; - have_I = 1; - break; - case 'm': - /* Match month using alternate numeric symbols. */ - get_alt_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minutes using alternate numeric symbols. */ - get_alt_number (0, 59, 2); - tm->tm_min = val; - break; - case 'S': - /* Match seconds using alternate numeric symbols. */ - get_alt_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'U': - case 'V': - case 'W': - get_alt_number (0, 53, 2); - /* XXX This cannot determine any field in TM without - further information. */ - break; - case 'w': - /* Match number of weekday using alternate numeric symbols. */ - get_alt_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': - /* Match year within century using alternate numeric symbols. */ - get_alt_number (0, 99, 2); - tm->tm_year = val >= 69 ? val : val + 100; - want_xday = 1; - break; - default: - return NULL; - } - break; - default: - return NULL; - } - } - - if (have_I && is_pm) - tm->tm_hour += 12; - - if (century != -1) - { - if (want_century) - tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; - else - /* Only the century, but not the year. Strange, but so be it. */ - tm->tm_year = (century - 19) * 100; - } - -#ifdef _NL_CURRENT - if (era_cnt != -1) - { - era = _nl_select_era_entry(era_cnt); - if (want_era) - tm->tm_year = (era->start_date[0] - + ((tm->tm_year - era->offset) - * era->absolute_direction)); - else - /* Era start year assumed. */ - tm->tm_year = era->start_date[0]; - } - else -#endif - if (want_era) - return NULL; - - if (want_xday && !have_wday) - { - if ( !(have_mon && have_mday) && have_yday) - { - /* We don't have tm_mon and/or tm_mday, compute them. */ - int t_mon = 0; - while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) - t_mon++; - if (!have_mon) - tm->tm_mon = t_mon - 1; - if (!have_mday) - tm->tm_mday = - (tm->tm_yday - - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); - } - day_of_the_week (tm); - } - if (want_xday && !have_yday) - day_of_the_year (tm); - - return discard_const_p(char, rp); -} - - -char *rep_strptime(const char *buf, const char *format, struct tm *tm) -{ - enum locale_status decided; - -#ifdef _NL_CURRENT - decided = not; -#else - decided = raw; -#endif - return strptime_internal (buf, format, tm, &decided, -1); -} diff --git a/replace/strptime.m4 b/replace/strptime.m4 deleted file mode 100644 index da22fc5a97..0000000000 --- a/replace/strptime.m4 +++ /dev/null @@ -1,13 +0,0 @@ -AC_CACHE_CHECK([whether strptime is available and works],libreplace_cv_STRPTIME_OK,[ - AC_TRY_RUN([ - #define LIBREPLACE_CONFIGURE_TEST_STRPTIME - #include "$libreplacedir/test/strptime.c" - ], - [libreplace_cv_STRPTIME_OK=yes], - [libreplace_cv_STRPTIME_OK=no], - [libreplace_cv_STRPTIME_OK="assuming not"]) -]) -if test x"$libreplace_cv_STRPTIME_OK" != x"yes"; then - AC_DEFINE(REPLACE_STRPTIME,1,[Whether strptime should be replaced]) - LIBREPLACEOBJ="${LIBREPLACEOBJ} strptime.o" -fi diff --git a/replace/system/README b/replace/system/README deleted file mode 100644 index 69a2b80b56..0000000000 --- a/replace/system/README +++ /dev/null @@ -1,4 +0,0 @@ -This directory contains wrappers around logical groups of system -include files. The idea is to avoid #ifdef blocks in the main code, -and instead put all the necessary conditional includes in subsystem -specific header files in this directory. diff --git a/replace/system/aio.h b/replace/system/aio.h deleted file mode 100644 index 784d77fa28..0000000000 --- a/replace/system/aio.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _system_aio_h -#define _system_aio_h -/* - Unix SMB/CIFS implementation. - - AIO system include wrappers - - Copyright (C) Andrew Tridgell 2006 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifdef HAVE_LIBAIO_H -#include -#endif - -#endif diff --git a/replace/system/capability.h b/replace/system/capability.h deleted file mode 100644 index a7b78f0275..0000000000 --- a/replace/system/capability.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _system_capability_h -#define _system_capability_h -/* - Unix SMB/CIFS implementation. - - capability system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifdef HAVE_SYS_CAPABILITY_H - -#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) -#define _I386_STATFS_H -#define _PPC_STATFS_H -#define BROKEN_REDHAT_7_STATFS_WORKAROUND -#endif - -#if defined(BROKEN_RHEL5_SYS_CAP_HEADER) && !defined(_LINUX_TYPES_H) -#define BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND -#endif - -#include - -#ifdef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND -#undef _LINUX_TYPES_H -#undef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND -#endif - -#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND -#undef _PPC_STATFS_H -#undef _I386_STATFS_H -#undef BROKEN_REDHAT_7_STATFS_WORKAROUND -#endif - -#endif - -#endif diff --git a/replace/system/config.m4 b/replace/system/config.m4 deleted file mode 100644 index 5c9b53d5c5..0000000000 --- a/replace/system/config.m4 +++ /dev/null @@ -1,130 +0,0 @@ -# filesys -AC_HEADER_DIRENT -AC_CHECK_HEADERS(fcntl.h sys/fcntl.h sys/resource.h sys/ioctl.h sys/mode.h sys/filio.h sys/fs/s5param.h sys/filsys.h) -AC_CHECK_HEADERS(sys/acl.h acl/libacl.h) - -# select -AC_CHECK_HEADERS(sys/select.h) - -# time -AC_CHECK_HEADERS(sys/time.h utime.h) -AC_HEADER_TIME -AC_CHECK_FUNCS(utime utimes) - -# wait -AC_HEADER_SYS_WAIT - -# capability -AC_CHECK_HEADERS(sys/capability.h) - -case "$host_os" in -*linux*) -AC_CACHE_CHECK([for broken RedHat 7.2 system header files],libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS,[ -AC_TRY_COMPILE([ - #ifdef HAVE_SYS_VFS_H - #include - #endif - #ifdef HAVE_SYS_CAPABILITY_H - #include - #endif - ],[ - int i; - ], - libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no, - libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=yes -)]) -if test x"$libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" = x"yes"; then - AC_DEFINE(BROKEN_REDHAT_7_SYSTEM_HEADERS,1,[Broken RedHat 7.2 system header files]) -fi - -AC_CACHE_CHECK([for broken RHEL5 sys/capability.h],libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER,[ -AC_TRY_COMPILE([ - #ifdef HAVE_SYS_CAPABILITY_H - #include - #endif - #include - ],[ - __s8 i; - ], - libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER=no, - libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER=yes -)]) -if test x"$libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER" = x"yes"; then - AC_DEFINE(BROKEN_RHEL5_SYS_CAP_HEADER,1,[Broken RHEL5 sys/capability.h]) -fi -;; -esac - -# passwd -AC_CHECK_HEADERS(grp.h sys/id.h compat.h shadow.h sys/priv.h pwd.h sys/security.h) -AC_CHECK_FUNCS(getpwnam_r getpwuid_r getpwent_r) -AC_HAVE_DECL(getpwent_r, [ - #include - #include - ]) -AC_VERIFY_C_PROTOTYPE([struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)], - [ - #ifndef HAVE_GETPWENT_R_DECL - #error missing getpwent_r prototype - #endif - return NULL; - ],[ - AC_DEFINE(SOLARIS_GETPWENT_R, 1, [getpwent_r solaris function prototype]) - ],[],[ - #include - #include - ]) -AC_VERIFY_C_PROTOTYPE([struct passwd *getpwent_r(struct passwd *src, char *buf, size_t buflen)], - [ - #ifndef HAVE_GETPWENT_R_DECL - #error missing getpwent_r prototype - #endif - return NULL; - ],[ - AC_DEFINE(SOLARIS_GETPWENT_R, 1, [getpwent_r irix (similar to solaris) function prototype]) - ],[],[ - #include - #include - ]) -AC_CHECK_FUNCS(getgrnam_r getgrgid_r getgrent_r) -AC_HAVE_DECL(getgrent_r, [ - #include - #include - ]) -AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, int buflen)], - [ - #ifndef HAVE_GETGRENT_R_DECL - #error missing getgrent_r prototype - #endif - return NULL; - ],[ - AC_DEFINE(SOLARIS_GETGRENT_R, 1, [getgrent_r solaris function prototype]) - ],[],[ - #include - #include - ]) - -AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, size_t buflen)], - [ - #ifndef HAVE_GETGRENT_R_DECL - #error missing getgrent_r prototype - #endif - return NULL; - ],[ - AC_DEFINE(SOLARIS_GETGRENT_R, 1, [getgrent_r irix (similar to solaris) function prototype]) - ],[],[ - #include - #include - ]) - -# locale -AC_CHECK_HEADERS(ctype.h locale.h) - -# glob -AC_CHECK_HEADERS(fnmatch.h) - -# shmem -AC_CHECK_HEADERS(sys/ipc.h sys/mman.h sys/shm.h ) - -# terminal -AC_CHECK_HEADERS(termios.h termio.h sys/termio.h ) diff --git a/replace/system/dir.h b/replace/system/dir.h deleted file mode 100644 index dec2d54649..0000000000 --- a/replace/system/dir.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _system_dir_h -#define _system_dir_h -/* - Unix SMB/CIFS implementation. - - directory system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#if HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -#ifndef HAVE_MKDIR_MODE -#define mkdir(dir, mode) mkdir(dir) -#endif - -/* Test whether a file name is the "." or ".." directory entries. - * These really should be inline functions. - */ -#ifndef ISDOT -#define ISDOT(path) ( \ - *((const char *)(path)) == '.' && \ - *(((const char *)(path)) + 1) == '\0' \ - ) -#endif - -#ifndef ISDOTDOT -#define ISDOTDOT(path) ( \ - *((const char *)(path)) == '.' && \ - *(((const char *)(path)) + 1) == '.' && \ - *(((const char *)(path)) + 2) == '\0' \ - ) -#endif - -#endif diff --git a/replace/system/filesys.h b/replace/system/filesys.h deleted file mode 100644 index 4bf1f64865..0000000000 --- a/replace/system/filesys.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef _system_filesys_h -#define _system_filesys_h -/* - Unix SMB/CIFS implementation. - - filesystem system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#include -#include - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_MOUNT_H -#include -#endif - -#ifdef HAVE_MNTENT_H -#include -#endif - -#ifdef HAVE_SYS_VFS_H -#include -#endif - -#ifdef HAVE_SYS_ACL_H -#include -#endif - -#ifdef HAVE_ACL_LIBACL_H -#include -#endif - -#ifdef HAVE_SYS_FS_S5PARAM_H -#include -#endif - -#if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) -#include -#endif - -#ifdef HAVE_SYS_STATFS_H -# include -#endif - -#ifdef HAVE_DUSTAT_H -#include -#endif - -#ifdef HAVE_SYS_STATVFS_H -#include -#endif - -#ifdef HAVE_SYS_FILIO_H -#include -#endif - -#include - -#ifdef HAVE_FCNTL_H -#include -#else -#ifdef HAVE_SYS_FCNTL_H -#include -#endif -#endif - -#ifdef HAVE_SYS_MODE_H -/* apparently AIX needs this for S_ISLNK */ -#ifndef S_ISLNK -#include -#endif -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -/* - * Veritas File System. Often in addition to native. - * Quotas different. - */ -#if defined(HAVE_SYS_FS_VX_QUOTA_H) -#define VXFS_QUOTA -#endif - -#if HAVE_SYS_ATTRIBUTES_H -#include -#endif - -/* mutually exclusive (SuSE 8.2) */ -#if HAVE_ATTR_XATTR_H -#include -#elif HAVE_SYS_XATTR_H -#include -#endif - - -#ifdef HAVE_SYS_RESOURCE_H -#include -#endif - -/* Some POSIX definitions for those without */ - -#ifndef S_IFDIR -#define S_IFDIR 0x4000 -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) ((mode & 0xF000) == S_IFDIR) -#endif -#ifndef S_IRWXU -#define S_IRWXU 00700 /* read, write, execute: owner */ -#endif -#ifndef S_IRUSR -#define S_IRUSR 00400 /* read permission: owner */ -#endif -#ifndef S_IWUSR -#define S_IWUSR 00200 /* write permission: owner */ -#endif -#ifndef S_IXUSR -#define S_IXUSR 00100 /* execute permission: owner */ -#endif -#ifndef S_IRWXG -#define S_IRWXG 00070 /* read, write, execute: group */ -#endif -#ifndef S_IRGRP -#define S_IRGRP 00040 /* read permission: group */ -#endif -#ifndef S_IWGRP -#define S_IWGRP 00020 /* write permission: group */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 00010 /* execute permission: group */ -#endif -#ifndef S_IRWXO -#define S_IRWXO 00007 /* read, write, execute: other */ -#endif -#ifndef S_IROTH -#define S_IROTH 00004 /* read permission: other */ -#endif -#ifndef S_IWOTH -#define S_IWOTH 00002 /* write permission: other */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 00001 /* execute permission: other */ -#endif - -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -#endif - -#ifndef MAXPATHLEN -#define MAXPATHLEN 256 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -#endif diff --git a/replace/system/glob.h b/replace/system/glob.h deleted file mode 100644 index 3e23db6828..0000000000 --- a/replace/system/glob.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _system_glob_h -#define _system_glob_h -/* - Unix SMB/CIFS implementation. - - glob system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_GLOB_H -#include -#endif - -#ifdef HAVE_FNMATCH_H -#include -#endif - -#endif diff --git a/replace/system/iconv.h b/replace/system/iconv.h deleted file mode 100644 index 3c8a71f2f7..0000000000 --- a/replace/system/iconv.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _system_iconv_h -#define _system_iconv_h -/* - Unix SMB/CIFS implementation. - - iconv memory system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#if !defined(HAVE_ICONV) && defined(HAVE_ICONV_H) -#define HAVE_ICONV -#endif - -#if !defined(HAVE_GICONV) && defined(HAVE_GICONV_H) -#define HAVE_GICONV -#endif - -#if !defined(HAVE_BICONV) && defined(HAVE_BICONV_H) -#define HAVE_BICONV -#endif - -#ifdef HAVE_NATIVE_ICONV -#if defined(HAVE_ICONV) -#include -#elif defined(HAVE_GICONV) -#include -#elif defined(HAVE_BICONV) -#include -#endif -#endif /* HAVE_NATIVE_ICONV */ - -/* needed for some systems without iconv. Doesn't really matter - what error code we use */ -#ifndef EILSEQ -#define EILSEQ EIO -#endif - -#endif diff --git a/replace/system/kerberos.h b/replace/system/kerberos.h deleted file mode 100644 index 2981024bee..0000000000 --- a/replace/system/kerberos.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef _system_kerberos_h -#define _system_kerberos_h - -/* - Unix SMB/CIFS implementation. - - kerberos system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_KRB5 -/* Whether the krb5_address struct has a addrtype property */ -/* #undef HAVE_ADDRTYPE_IN_KRB5_ADDRESS */ -/* Whether the krb5_address struct has a addr_type property */ -#define HAVE_ADDR_TYPE_IN_KRB5_ADDRESS 1 -/* Define to 1 if you have the `gsskrb5_extract_authz_data_from_sec_context' */ -#define HAVE_GSSKRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT 1 -/* Define to 1 if you have the `gsskrb5_get_initiator_subkey' function. */ -#define HAVE_GSSKRB5_GET_INITIATOR_SUBKEY 1 -/* Define to 1 if you have the `gsskrb5_register_acceptor_identity' function. */ -#define HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY 1 -/* Define to 1 if you have the `gss_krb5_ccache_name' function. */ -#define HAVE_GSS_KRB5_CCACHE_NAME 1 -/* Define to 1 if you have the `krb5_addlog_func' function. */ -#define HAVE_KRB5_ADDLOG_FUNC 1 -/* Define to 1 if you have the `krb5_auth_con_setkey' function. */ -#define HAVE_KRB5_AUTH_CON_SETKEY 1 -/* Define to 1 if you have the `krb5_auth_con_setuseruserkey' function. */ -/* #undef HAVE_KRB5_AUTH_CON_SETUSERUSERKEY */ -/* Define to 1 if you have the `krb5_c_enctype_compare' function. */ -#define HAVE_KRB5_C_ENCTYPE_COMPARE 1 -/* Define to 1 if you have the `krb5_c_verify_checksum' function. */ -#define HAVE_KRB5_C_VERIFY_CHECKSUM 1 -/* Whether the type krb5_encrypt_block exists */ -/* #undef HAVE_KRB5_ENCRYPT_BLOCK */ -/* Define to 1 if you have the `krb5_encrypt_data' function. */ -/* #undef HAVE_KRB5_ENCRYPT_DATA */ -/* Define to 1 if you have the `krb5_enctypes_compatible_keys' function. */ -#define HAVE_KRB5_ENCTYPES_COMPATIBLE_KEYS 1 -/* Define to 1 if you have the `krb5_free_data_contents' function. */ -#define HAVE_KRB5_FREE_DATA_CONTENTS 1 -/* Define to 1 if you have the `krb5_free_error_string' function. */ -#define HAVE_KRB5_FREE_ERROR_STRING 1 -/* Define to 1 if you have the `krb5_free_keytab_entry_contents' function. */ -/* #undef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS */ -/* Define to 1 if you have the `krb5_free_ktypes' function. */ -/* #undef HAVE_KRB5_FREE_KTYPES */ -/* Define to 1 if you have the `krb5_free_unparsed_name' function. */ -/* #undef HAVE_KRB5_FREE_UNPARSED_NAME */ -/* Define to 1 if you have the `krb5_get_default_in_tkt_etypes' function. */ -#define HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES 1 -/* Define to 1 if you have the `krb5_get_error_string' function. */ -#define HAVE_KRB5_GET_ERROR_STRING 1 -/* Define to 1 if you have the `krb5_get_permitted_enctypes' function. */ -/* #undef HAVE_KRB5_GET_PERMITTED_ENCTYPES */ -/* Define to 1 if you have the `krb5_get_pw_salt' function. */ -#define HAVE_KRB5_GET_PW_SALT 1 -/* Define to 1 if you have the header file. */ -#define HAVE_KRB5_H 1 -/* Define to 1 if you have the `krb5_initlog' function. */ -#define HAVE_KRB5_INITLOG 1 -/* Define to 1 if you have the `krb5_kdc_default_config' function. */ -#define HAVE_KRB5_KDC_DEFAULT_CONFIG 1 -/* Whether the krb5_creds struct has a keyblock property */ -/* #undef HAVE_KRB5_KEYBLOCK_IN_CREDS */ -/* Whether the krb5_keyblock struct has a keyvalue property */ -#define HAVE_KRB5_KEYBLOCK_KEYVALUE 1 -/* Whether krb5_keytab_entry has key member */ -/* #undef HAVE_KRB5_KEYTAB_ENTRY_KEY */ -/* Whether krb5_keytab_entry has keyblock member */ -#define HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK 1 -/* Define to 1 if you have the `krb5_krbhst_get_addrinfo' function. */ -#define HAVE_KRB5_KRBHST_GET_ADDRINFO 1 -/* Define to 1 if you have the `krb5_kt_compare' function. */ -#define HAVE_KRB5_KT_COMPARE 1 -/* Define to 1 if you have the `krb5_kt_free_entry' function. */ -#define HAVE_KRB5_KT_FREE_ENTRY 1 -/* Whether the type krb5_log_facility exists */ -#define HAVE_KRB5_LOG_FACILITY 1 -/* Define to 1 if you have the `krb5_mk_req_extended' function. */ -#define HAVE_KRB5_MK_REQ_EXTENDED 1 -/* Define to 1 if you have the `krb5_principal2salt' function. */ -/* #undef HAVE_KRB5_PRINCIPAL2SALT */ -/* Define to 1 if you have the `krb5_principal_get_comp_string' function. */ -#define HAVE_KRB5_PRINCIPAL_GET_COMP_STRING 1 -/* Whether krb5_princ_component is available */ -/* #undef HAVE_KRB5_PRINC_COMPONENT */ -/* Whether the krb5_creds struct has a session property */ -#define HAVE_KRB5_SESSION_IN_CREDS 1 -/* Define to 1 if you have the `krb5_set_default_in_tkt_etypes' function. */ -#define HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES 1 -/* Define to 1 if you have the `krb5_set_default_tgs_ktypes' function. */ -/* #undef HAVE_KRB5_SET_DEFAULT_TGS_KTYPES */ -/* Define to 1 if you have the `krb5_set_real_time' function. */ -#define HAVE_KRB5_SET_REAL_TIME 1 -/* Define to 1 if you have the `krb5_set_warn_dest' function. */ -#define HAVE_KRB5_SET_WARN_DEST 1 -/* Define to 1 if you have the `krb5_string_to_key' function. */ -#define HAVE_KRB5_STRING_TO_KEY 1 -/* Define to 1 if you have the `krb5_string_to_key_salt' function. */ -#define HAVE_KRB5_STRING_TO_KEY_SALT 1 -/* Define to 1 if you have the `krb5_ticket_get_authorization_data_type' */ -#define HAVE_KRB5_TICKET_GET_AUTHORIZATION_DATA_TYPE 1 -/* Whether the krb5_ticket struct has a enc_part2 property */ -/* #undef HAVE_KRB5_TKT_ENC_PART2 */ -/* Define to 1 if you have the `krb5_use_enctype' function. */ -/* #undef HAVE_KRB5_USE_ENCTYPE */ -/* Define to 1 if you have the `krb5_verify_checksum' function. */ -#define HAVE_KRB5_VERIFY_CHECKSUM 1 -/* Whether krb5_princ_realm returns krb5_realm or krb5_data */ -#define KRB5_PRINC_REALM_RETURNS_REALM 1 - -#include -#include - -#endif - -#endif diff --git a/replace/system/locale.h b/replace/system/locale.h deleted file mode 100644 index e73a9bb274..0000000000 --- a/replace/system/locale.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _system_locale_h -#define _system_locale_h - -/* - Unix SMB/CIFS implementation. - - locale include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_CTYPE_H -#include -#endif - -#ifdef HAVE_LOCALE_H -#include -#endif - -#endif diff --git a/replace/system/network.h b/replace/system/network.h deleted file mode 100644 index 473d79b5f2..0000000000 --- a/replace/system/network.h +++ /dev/null @@ -1,332 +0,0 @@ -#ifndef _system_network_h -#define _system_network_h -/* - Unix SMB/CIFS implementation. - - networking system include wrappers - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Jelmer Vernooij 2007 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifndef LIBREPLACE_NETWORK_CHECKS -#error "AC_LIBREPLACE_NETWORK_CHECKS missing in configure" -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -#ifdef HAVE_UNIXSOCKET -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef HAVE_NETDB_H -#include -#endif - -#ifdef HAVE_NETINET_TCP_H -#include -#endif - -/* - * The next three defines are needed to access the IPTOS_* options - * on some systems. - */ - -#ifdef HAVE_NETINET_IN_SYSTM_H -#include -#endif - -#ifdef HAVE_NETINET_IN_IP_H -#include -#endif - -#ifdef HAVE_NETINET_IP_H -#include -#endif - -#ifdef HAVE_NET_IF_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_STROPTS_H -#include -#endif - -#ifndef HAVE_SOCKLEN_T -#define HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - -#if !defined (HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) -/* define is in "replace.h" */ -char *rep_inet_ntoa(struct in_addr ip); -#endif - -#ifndef HAVE_INET_PTON -/* define is in "replace.h" */ -int rep_inet_pton(int af, const char *src, void *dst); -#endif - -#ifndef HAVE_INET_NTOP -/* define is in "replace.h" */ -const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); -#endif - -#ifndef HAVE_INET_ATON -/* define is in "replace.h" */ -int rep_inet_aton(const char *src, struct in_addr *dst); -#endif - -#ifndef HAVE_CONNECT -/* define is in "replace.h" */ -int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -#endif - -#ifndef HAVE_GETHOSTBYNAME -/* define is in "replace.h" */ -struct hostent *rep_gethostbyname(const char *name); -#endif - -#ifdef HAVE_IFADDRS_H -#include -#endif - -#ifndef HAVE_STRUCT_IFADDRS -struct ifaddrs { - struct ifaddrs *ifa_next; /* Pointer to next struct */ - char *ifa_name; /* Interface name */ - unsigned int ifa_flags; /* Interface flags */ - struct sockaddr *ifa_addr; /* Interface address */ - struct sockaddr *ifa_netmask; /* Interface netmask */ -#undef ifa_dstaddr - struct sockaddr *ifa_dstaddr; /* P2P interface destination */ - void *ifa_data; /* Address specific data */ -}; -#endif - -#ifndef HAVE_GETIFADDRS -int rep_getifaddrs(struct ifaddrs **); -#endif - -#ifndef HAVE_FREEIFADDRS -void rep_freeifaddrs(struct ifaddrs *); -#endif - -#ifndef HAVE_SOCKETPAIR -/* define is in "replace.h" */ -int rep_socketpair(int d, int type, int protocol, int sv[2]); -#endif - -/* - * Some systems have getaddrinfo but not the - * defines needed to use it. - */ - -/* Various macros that ought to be in , but might not be */ - -#ifndef EAI_FAIL -#define EAI_BADFLAGS (-1) -#define EAI_NONAME (-2) -#define EAI_AGAIN (-3) -#define EAI_FAIL (-4) -#define EAI_FAMILY (-6) -#define EAI_SOCKTYPE (-7) -#define EAI_SERVICE (-8) -#define EAI_MEMORY (-10) -#define EAI_SYSTEM (-11) -#endif /* !EAI_FAIL */ - -#ifndef AI_PASSIVE -#define AI_PASSIVE 0x0001 -#endif - -#ifndef AI_CANONNAME -#define AI_CANONNAME 0x0002 -#endif - -#ifndef AI_NUMERICHOST -/* - * some platforms don't support AI_NUMERICHOST; define as zero if using - * the system version of getaddrinfo... - */ -#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) -#define AI_NUMERICHOST 0 -#else -#define AI_NUMERICHOST 0x0004 -#endif -#endif - -#ifndef AI_ADDRCONFIG -/* - * logic copied from AI_NUMERICHOST - */ -#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) -#define AI_ADDRCONFIG 0 -#else -#define AI_ADDRCONFIG 0x0020 -#endif -#endif - -#ifndef AI_NUMERICSERV -/* - * logic copied from AI_NUMERICHOST - */ -#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) -#define AI_NUMERICSERV 0 -#else -#define AI_NUMERICSERV 0x0400 -#endif -#endif - -#ifndef NI_NUMERICHOST -#define NI_NUMERICHOST 1 -#endif - -#ifndef NI_NUMERICSERV -#define NI_NUMERICSERV 2 -#endif - -#ifndef NI_NOFQDN -#define NI_NOFQDN 4 -#endif - -#ifndef NI_NAMEREQD -#define NI_NAMEREQD 8 -#endif - -#ifndef NI_DGRAM -#define NI_DGRAM 16 -#endif - - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif - -#ifndef NI_MAXSERV -#define NI_MAXSERV 32 -#endif - -/* - * glibc on linux doesn't seem to have MSG_WAITALL - * defined. I think the kernel has it though.. - */ -#ifndef MSG_WAITALL -#define MSG_WAITALL 0 -#endif - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001 -#endif - -#ifndef INADDR_NONE -#define INADDR_NONE 0xffffffff -#endif - -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT EINVAL -#endif - -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 46 -#endif - -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 256 -#endif - -#ifndef HAVE_SA_FAMILY_T -#define HAVE_SA_FAMILY_T -typedef unsigned short int sa_family_t; -#endif - -#ifndef HAVE_STRUCT_SOCKADDR_STORAGE -#define HAVE_STRUCT_SOCKADDR_STORAGE -#ifdef HAVE_STRUCT_SOCKADDR_IN6 -#define sockaddr_storage sockaddr_in6 -#define ss_family sin6_family -#define HAVE_SS_FAMILY 1 -#else -#define sockaddr_storage sockaddr_in -#define ss_family sin_family -#define HAVE_SS_FAMILY 1 -#endif -#endif - -#ifndef HAVE_SS_FAMILY -#ifdef HAVE___SS_FAMILY -#define ss_family __ss_family -#define HAVE_SS_FAMILY 1 -#endif -#endif - -#ifndef HAVE_STRUCT_ADDRINFO -#define HAVE_STRUCT_ADDRINFO -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - socklen_t ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct addrinfo *ai_next; -}; -#endif /* HAVE_STRUCT_ADDRINFO */ - -#if !defined(HAVE_GETADDRINFO) -#include "getaddrinfo.h" -#endif - -/* Needed for some systems that don't define it (Solaris). */ -#ifndef ifr_netmask -#define ifr_netmask ifr_addr -#endif - -#ifdef SOCKET_WRAPPER -#ifndef SOCKET_WRAPPER_NOT_REPLACE -#define SOCKET_WRAPPER_REPLACE -#endif -#include "../socket_wrapper/socket_wrapper.h" -#endif - -#endif diff --git a/replace/system/passwd.h b/replace/system/passwd.h deleted file mode 100644 index 9d7de34bce..0000000000 --- a/replace/system/passwd.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef _system_passwd_h -#define _system_passwd_h - -/* - Unix SMB/CIFS implementation. - - passwd system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -/* this needs to be included before nss_wrapper.h on some systems */ -#include - -#ifdef HAVE_PWD_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_SYS_PRIV_H -#include -#endif -#ifdef HAVE_SYS_ID_H -#include -#endif - -#ifdef HAVE_CRYPT_H -#include -#endif - -#ifdef HAVE_SHADOW_H -#include -#endif - -#ifdef HAVE_SYS_SECURITY_H -#include -#include -#define PASSWORD_LENGTH 16 -#endif /* HAVE_SYS_SECURITY_H */ - -#ifdef HAVE_GETPWANAM -#include -#include -#include -#endif - -#ifdef HAVE_COMPAT_H -#include -#endif - -#ifdef REPLACE_GETPASS -#if defined(REPLACE_GETPASS_BY_GETPASSPHRASE) -#define getpass(prompt) getpassphrase(prompt) -#else -#define getpass(prompt) rep_getpass(prompt) -char *rep_getpass(const char *prompt); -#endif -#endif - -#ifndef NGROUPS_MAX -#define NGROUPS_MAX 32 /* Guess... */ -#endif - -/* what is the longest significant password available on your system? - Knowing this speeds up password searches a lot */ -#ifndef PASSWORD_LENGTH -#define PASSWORD_LENGTH 8 -#endif - -#if defined(HAVE_PUTPRPWNAM) && defined(AUTH_CLEARTEXT_SEG_CHARS) -#define OSF1_ENH_SEC 1 -#endif - -#ifndef ALLOW_CHANGE_PASSWORD -#if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID)) -#define ALLOW_CHANGE_PASSWORD 1 -#endif -#endif - -#if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID) -#define ULTRIX_AUTH 1 -#endif - -#ifdef NSS_WRAPPER -#ifndef NSS_WRAPPER_NOT_REPLACE -#define NSS_WRAPPER_REPLACE -#endif -#include "../nss_wrapper/nss_wrapper.h" -#endif - -#endif diff --git a/replace/system/readline.h b/replace/system/readline.h deleted file mode 100644 index ba34dc6a61..0000000000 --- a/replace/system/readline.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _system_readline_h -#define _system_readline_h -/* - Unix SMB/CIFS implementation. - - Readline wrappers - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_LIBREADLINE -# ifdef HAVE_READLINE_READLINE_H -# include -# ifdef HAVE_READLINE_HISTORY_H -# include -# endif -# else -# ifdef HAVE_READLINE_H -# include -# ifdef HAVE_HISTORY_H -# include -# endif -# else -# undef HAVE_LIBREADLINE -# endif -# endif -#endif - -#ifdef HAVE_NEW_LIBREADLINE -# define RL_COMPLETION_CAST (rl_completion_func_t *) -#else -/* This type is missing from libreadline<4.0 (approximately) */ -# define RL_COMPLETION_CAST -#endif /* HAVE_NEW_LIBREADLINE */ - -#endif diff --git a/replace/system/select.h b/replace/system/select.h deleted file mode 100644 index da18de0cfc..0000000000 --- a/replace/system/select.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _system_select_h -#define _system_select_h -/* - Unix SMB/CIFS implementation. - - select system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#ifdef HAVE_SYS_EPOLL_H -#include -#endif - -#ifndef SELECT_CAST -#define SELECT_CAST -#endif - -#endif diff --git a/replace/system/shmem.h b/replace/system/shmem.h deleted file mode 100644 index 64fe39b6cb..0000000000 --- a/replace/system/shmem.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _system_shmem_h -#define _system_shmem_h -/* - Unix SMB/CIFS implementation. - - shared memory system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#if defined(HAVE_SYS_IPC_H) -#include -#endif /* HAVE_SYS_IPC_H */ - -#if defined(HAVE_SYS_SHM_H) -#include -#endif /* HAVE_SYS_SHM_H */ - -#ifdef HAVE_SYS_MMAN_H -#include -#endif - -/* NetBSD doesn't have these */ -#ifndef SHM_R -#define SHM_R 0400 -#endif - -#ifndef SHM_W -#define SHM_W 0200 -#endif - - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -#ifndef MAP_FAILED -#define MAP_FAILED ((void *)-1) -#endif - -#endif diff --git a/replace/system/syslog.h b/replace/system/syslog.h deleted file mode 100644 index 104be1df84..0000000000 --- a/replace/system/syslog.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _system_syslog_h -#define _system_syslog_h -/* - Unix SMB/CIFS implementation. - - syslog system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_SYSLOG_H -#include -#else -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#endif - -/* For sys_adminlog(). */ -#ifndef LOG_EMERG -#define LOG_EMERG 0 /* system is unusable */ -#endif - -#ifndef LOG_ALERT -#define LOG_ALERT 1 /* action must be taken immediately */ -#endif - -#ifndef LOG_CRIT -#define LOG_CRIT 2 /* critical conditions */ -#endif - -#ifndef LOG_ERR -#define LOG_ERR 3 /* error conditions */ -#endif - -#ifndef LOG_WARNING -#define LOG_WARNING 4 /* warning conditions */ -#endif - -#ifndef LOG_NOTICE -#define LOG_NOTICE 5 /* normal but significant condition */ -#endif - -#ifndef LOG_INFO -#define LOG_INFO 6 /* informational */ -#endif - -#ifndef LOG_DEBUG -#define LOG_DEBUG 7 /* debug-level messages */ -#endif - -#endif diff --git a/replace/system/terminal.h b/replace/system/terminal.h deleted file mode 100644 index 9ad601ace0..0000000000 --- a/replace/system/terminal.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _system_terminal_h -#define _system_terminal_h -/* - Unix SMB/CIFS implementation. - - terminal system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef SUNOS4 -/* on SUNOS4 termios.h conflicts with sys/ioctl.h */ -#undef HAVE_TERMIOS_H -#endif - - -#if defined(HAVE_TERMIOS_H) -/* POSIX terminal handling. */ -#include -#elif defined(HAVE_TERMIO_H) -/* Older SYSV terminal handling - don't use if we can avoid it. */ -#include -#elif defined(HAVE_SYS_TERMIO_H) -/* Older SYSV terminal handling - don't use if we can avoid it. */ -#include -#endif - -#endif diff --git a/replace/system/time.h b/replace/system/time.h deleted file mode 100644 index 4abf295d1a..0000000000 --- a/replace/system/time.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _system_time_h -#define _system_time_h -/* - Unix SMB/CIFS implementation. - - time system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - -#ifdef HAVE_UTIME_H -#include -#else -struct utimbuf { - time_t actime; /* access time */ - time_t modtime; /* modification time */ -}; -#endif - -#ifndef HAVE_MKTIME -/* define is in "replace.h" */ -time_t rep_mktime(struct tm *t); -#endif - -#ifndef HAVE_TIMEGM -/* define is in "replace.h" */ -time_t rep_timegm(struct tm *tm); -#endif - -#ifndef HAVE_UTIME -/* define is in "replace.h" */ -int rep_utime(const char *filename, const struct utimbuf *buf); -#endif - -#ifndef HAVE_UTIMES -/* define is in "replace.h" */ -int rep_utimes(const char *filename, const struct timeval tv[2]); -#endif - -#endif diff --git a/replace/system/wait.h b/replace/system/wait.h deleted file mode 100644 index 5784b1ae92..0000000000 --- a/replace/system/wait.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _system_wait_h -#define _system_wait_h -/* - Unix SMB/CIFS implementation. - - waitpid system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_SYS_WAIT_H -#include -#endif - -#include - -#ifndef SIGCLD -#define SIGCLD SIGCHLD -#endif - -#ifndef SIGNAL_CAST -#define SIGNAL_CAST (RETSIGTYPE (*)(int)) -#endif - -#ifdef HAVE_SETJMP_H -#include -#endif - -#ifndef SA_RESETHAND -#define SA_RESETHAND SA_ONESHOT -#endif - -#if !defined(HAVE_SIG_ATOMIC_T_TYPE) -typedef int sig_atomic_t; -#endif - -#endif diff --git a/replace/test/getifaddrs.c b/replace/test/getifaddrs.c deleted file mode 100644 index 8b00ac2f40..0000000000 --- a/replace/test/getifaddrs.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * libreplace getifaddrs test - * - * Copyright (C) Michael Adam 2008 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef AUTOCONF_TEST -#include "replace.h" -#include "system/network.h" -#endif - -#ifdef HAVE_INET_NTOP -#define rep_inet_ntop inet_ntop -#endif - -static const char *format_sockaddr(struct sockaddr *addr, - char *addrstring, - socklen_t addrlen) -{ - const char *result = NULL; - - if (addr->sa_family == AF_INET) { - result = rep_inet_ntop(AF_INET, - &((struct sockaddr_in *)addr)->sin_addr, - addrstring, - addrlen); -#ifdef HAVE_STRUCT_SOCKADDR_IN6 - } else if (addr->sa_family == AF_INET6) { - result = rep_inet_ntop(AF_INET6, - &((struct sockaddr_in6 *)addr)->sin6_addr, - addrstring, - addrlen); -#endif - } - return result; -} - -int getifaddrs_test(void) -{ - struct ifaddrs *ifs = NULL; - struct ifaddrs *ifs_head = NULL; - int ret; - - ret = getifaddrs(&ifs); - ifs_head = ifs; - if (ret != 0) { - fprintf(stderr, "getifaddrs() failed: %s\n", strerror(errno)); - return 1; - } - - while (ifs) { - printf("%-10s ", ifs->ifa_name); - if (ifs->ifa_addr != NULL) { - char addrstring[INET6_ADDRSTRLEN]; - const char *result; - - result = format_sockaddr(ifs->ifa_addr, - addrstring, - sizeof(addrstring)); - if (result != NULL) { - printf("IP=%s ", addrstring); - } - - if (ifs->ifa_netmask != NULL) { - result = format_sockaddr(ifs->ifa_netmask, - addrstring, - sizeof(addrstring)); - if (result != NULL) { - printf("NETMASK=%s", addrstring); - } - } else { - printf("AF=%d ", ifs->ifa_addr->sa_family); - } - } else { - printf(""); - } - - printf("\n"); - ifs = ifs->ifa_next; - } - - freeifaddrs(ifs_head); - - return 0; -} diff --git a/replace/test/os2_delete.c b/replace/test/os2_delete.c deleted file mode 100644 index b45c135355..0000000000 --- a/replace/test/os2_delete.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - test readdir/unlink pattern that OS/2 uses - tridge@samba.org July 2005 -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUM_FILES 700 -#define READDIR_SIZE 100 -#define DELETE_SIZE 4 - -#define TESTDIR "test.dir" - -static int test_readdir_os2_delete_ret; - -#define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1, 1) - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -static void cleanup(void) -{ - /* I'm a lazy bastard */ - system("rm -rf " TESTDIR); - mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); -} - -static void create_files(void) -{ - int i; - for (i=0;id_name); - } - - if (i == 0) { - return 0; - } - - /* delete the first few */ - for (j=0; jd_name, ".") == 0 || FAILED("match ."); - de = readdir(d); - strcmp(de->d_name, "..") == 0 || FAILED("match .."); - - while (1) { - int n = os2_delete(d); - if (n == 0) break; - total_deleted += n; - } - closedir(d); - - fprintf(stderr, "Deleted %d files of %d\n", total_deleted, NUM_FILES); - - rmdir(TESTDIR) == 0 || FAILED("rmdir"); - - system("rm -rf " TESTDIR); - - return test_readdir_os2_delete_ret; -} diff --git a/replace/test/shared_mmap.c b/replace/test/shared_mmap.c deleted file mode 100644 index 50dad8d696..0000000000 --- a/replace/test/shared_mmap.c +++ /dev/null @@ -1,68 +0,0 @@ -/* this tests whether we can use a shared writeable mmap on a file - - as needed for the mmap variant of FAST_SHARE_MODES */ - -#if defined(HAVE_UNISTD_H) -#include -#endif -#include -#include -#include -#include - -#define DATA "conftest.mmap" - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -main() -{ - int *buf; - int i; - int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); - int count=7; - - if (fd == -1) exit(1); - - for (i=0;i<10000;i++) { - write(fd,&i,sizeof(i)); - } - - close(fd); - - if (fork() == 0) { - fd = open(DATA,O_RDWR); - if (fd == -1) exit(1); - - buf = (int *)mmap(NULL, 10000*sizeof(int), - (PROT_READ | PROT_WRITE), - MAP_FILE | MAP_SHARED, - fd, 0); - - while (count-- && buf[9124] != 55732) sleep(1); - - if (count <= 0) exit(1); - - buf[1763] = 7268; - exit(0); - } - - fd = open(DATA,O_RDWR); - if (fd == -1) exit(1); - - buf = (int *)mmap(NULL, 10000*sizeof(int), - (PROT_READ | PROT_WRITE), - MAP_FILE | MAP_SHARED, - fd, 0); - - if (buf == (int *)-1) exit(1); - - buf[9124] = 55732; - - while (count-- && buf[1763] != 7268) sleep(1); - - unlink(DATA); - - if (count > 0) exit(0); - exit(1); -} diff --git a/replace/test/strptime.c b/replace/test/strptime.c deleted file mode 100644 index fade3ecc57..0000000000 --- a/replace/test/strptime.c +++ /dev/null @@ -1,172 +0,0 @@ - -#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME - -#include -#include -#include - -#define true 1 -#define false 0 - -#ifndef __STRING -#define __STRING(x) #x -#endif - -/* make printf a no-op */ -#define printf if(0) printf - -#else /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ - -#include "replace.h" -#include "system/time.h" - -#endif /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ - -int libreplace_test_strptime(void) -{ - const char *s = "20070414101546Z"; - char *ret; - struct tm t, t2; - - memset(&t, 0, sizeof(t)); - memset(&t2, 0, sizeof(t2)); - - printf("test: strptime\n"); - - ret = strptime(s, "%Y%m%d%H%M%S", &t); - if ( ret == NULL ) { - printf("failure: strptime [\n" - "returned NULL\n" - "]\n"); - return false; - } - - if ( *ret != 'Z' ) { - printf("failure: strptime [\n" - "ret doesn't point to 'Z'\n" - "]\n"); - return false; - } - - ret = strptime(s, "%Y%m%d%H%M%SZ", &t2); - if ( ret == NULL ) { - printf("failure: strptime [\n" - "returned NULL with Z\n" - "]\n"); - return false; - } - - if ( *ret != '\0' ) { - printf("failure: strptime [\n" - "ret doesn't point to '\\0'\n" - "]\n"); - return false; - } - -#define CMP_TM_ELEMENT(t1,t2,elem) \ - if (t1.elem != t2.elem) { \ - printf("failure: strptime [\n" \ - "result differs if the format string has a 'Z' at the end\n" \ - "element: %s %d != %d\n" \ - "]\n", \ - __STRING(elen), t1.elem, t2.elem); \ - return false; \ - } - - CMP_TM_ELEMENT(t,t2,tm_sec); - CMP_TM_ELEMENT(t,t2,tm_min); - CMP_TM_ELEMENT(t,t2,tm_hour); - CMP_TM_ELEMENT(t,t2,tm_mday); - CMP_TM_ELEMENT(t,t2,tm_mon); - CMP_TM_ELEMENT(t,t2,tm_year); - CMP_TM_ELEMENT(t,t2,tm_wday); - CMP_TM_ELEMENT(t,t2,tm_yday); - CMP_TM_ELEMENT(t,t2,tm_isdst); - - if (t.tm_sec != 46) { - printf("failure: strptime [\n" - "tm_sec: expected: 46, got: %d\n" - "]\n", - t.tm_sec); - return false; - } - - if (t.tm_min != 15) { - printf("failure: strptime [\n" - "tm_min: expected: 15, got: %d\n" - "]\n", - t.tm_min); - return false; - } - - if (t.tm_hour != 10) { - printf("failure: strptime [\n" - "tm_hour: expected: 10, got: %d\n" - "]\n", - t.tm_hour); - return false; - } - - if (t.tm_mday != 14) { - printf("failure: strptime [\n" - "tm_mday: expected: 14, got: %d\n" - "]\n", - t.tm_mday); - return false; - } - - if (t.tm_mon != 3) { - printf("failure: strptime [\n" - "tm_mon: expected: 3, got: %d\n" - "]\n", - t.tm_mon); - return false; - } - - if (t.tm_year != 107) { - printf("failure: strptime [\n" - "tm_year: expected: 107, got: %d\n" - "]\n", - t.tm_year); - return false; - } - - if (t.tm_wday != 6) { /* saturday */ - printf("failure: strptime [\n" - "tm_wday: expected: 6, got: %d\n" - "]\n", - t.tm_wday); - return false; - } - - if (t.tm_yday != 103) { - printf("failure: strptime [\n" - "tm_yday: expected: 103, got: %d\n" - "]\n", - t.tm_yday); - return false; - } - - /* we don't test this as it depends on the host configuration - if (t.tm_isdst != 0) { - printf("failure: strptime [\n" - "tm_isdst: expected: 0, got: %d\n" - "]\n", - t.tm_isdst); - return false; - }*/ - - printf("success: strptime\n"); - - return true; -} - -#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME -int main (void) -{ - int ret; - ret = libreplace_test_strptime(); - if (ret == false) return 1; - return 0; -} -#endif diff --git a/replace/test/testsuite.c b/replace/test/testsuite.c deleted file mode 100644 index 1e8290906e..0000000000 --- a/replace/test/testsuite.c +++ /dev/null @@ -1,1080 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - libreplace tests - - Copyright (C) Jelmer Vernooij 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" - -/* - we include all the system/ include files here so that libreplace tests - them in the build farm -*/ -#include "system/capability.h" -#include "system/dir.h" -#include "system/filesys.h" -#include "system/glob.h" -#include "system/iconv.h" -#include "system/locale.h" -#include "system/network.h" -#include "system/passwd.h" -#include "system/readline.h" -#include "system/select.h" -#include "system/shmem.h" -#include "system/syslog.h" -#include "system/terminal.h" -#include "system/time.h" -#include "system/wait.h" -#include "system/aio.h" - -#define TESTFILE "testfile.dat" - -/* - test ftruncate() function - */ -static int test_ftruncate(void) -{ - struct stat st; - int fd; - const int size = 1234; - printf("test: ftruncate\n"); - unlink(TESTFILE); - fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); - if (fd == -1) { - printf("failure: ftruncate [\n" - "creating '%s' failed - %s\n]\n", TESTFILE, strerror(errno)); - return false; - } - if (ftruncate(fd, size) != 0) { - printf("failure: ftruncate [\n%s\n]\n", strerror(errno)); - return false; - } - if (fstat(fd, &st) != 0) { - printf("failure: ftruncate [\nfstat failed - %s\n]\n", strerror(errno)); - return false; - } - if (st.st_size != size) { - printf("failure: ftruncate [\ngave wrong size %d - expected %d\n]\n", - (int)st.st_size, size); - return false; - } - unlink(TESTFILE); - printf("success: ftruncate\n"); - return true; -} - -/* - test strlcpy() function. - see http://www.gratisoft.us/todd/papers/strlcpy.html - */ -static int test_strlcpy(void) -{ - char buf[4]; - const struct { - const char *src; - size_t result; - } tests[] = { - { "abc", 3 }, - { "abcdef", 6 }, - { "abcd", 4 }, - { "", 0 }, - { NULL, 0 } - }; - int i; - printf("test: strlcpy\n"); - for (i=0;tests[i].src;i++) { - if (strlcpy(buf, tests[i].src, sizeof(buf)) != tests[i].result) { - printf("failure: strlcpy [\ntest %d failed\n]\n", i); - return false; - } - } - printf("success: strlcpy\n"); - return true; -} - -static int test_strlcat(void) -{ - char tmp[10]; - printf("test: strlcat\n"); - strlcpy(tmp, "", sizeof(tmp)); - if (strlcat(tmp, "bla", 3) != 3) { - printf("failure: strlcat [\ninvalid return code\n]\n"); - return false; - } - if (strcmp(tmp, "bl") != 0) { - printf("failure: strlcat [\nexpected \"bl\", got \"%s\"\n]\n", - tmp); - return false; - } - - strlcpy(tmp, "da", sizeof(tmp)); - if (strlcat(tmp, "me", 4) != 4) { - printf("failure: strlcat [\nexpected \"dam\", got \"%s\"\n]\n", - tmp); - return false; - } - - printf("success: strlcat\n"); - return true; -} - -static int test_mktime(void) -{ - /* FIXME */ - return true; -} - -static int test_initgroups(void) -{ - /* FIXME */ - return true; -} - -static int test_memmove(void) -{ - /* FIXME */ - return true; -} - -static int test_strdup(void) -{ - char *x; - printf("test: strdup\n"); - x = strdup("bla"); - if (strcmp("bla", x) != 0) { - printf("failure: strdup [\nfailed: expected \"bla\", got \"%s\"\n]\n", - x); - return false; - } - free(x); - printf("success: strdup\n"); - return true; -} - -static int test_setlinebuf(void) -{ - printf("test: setlinebuf\n"); - setlinebuf(stdout); - printf("success: setlinebuf\n"); - return true; -} - -static int test_vsyslog(void) -{ - /* FIXME */ - return true; -} - -static int test_timegm(void) -{ - /* FIXME */ - return true; -} - -static int test_setenv(void) -{ -#define TEST_SETENV(key, value, overwrite, result) do { \ - int _ret; \ - char *_v; \ - _ret = setenv(key, value, overwrite); \ - if (_ret != 0) { \ - printf("failure: setenv [\n" \ - "setenv(%s, %s, %d) failed\n" \ - "]\n", \ - key, value, overwrite); \ - return false; \ - } \ - _v=getenv(key); \ - if (!_v) { \ - printf("failure: setenv [\n" \ - "getenv(%s) returned NULL\n" \ - "]\n", \ - key); \ - return false; \ - } \ - if (strcmp(result, _v) != 0) { \ - printf("failure: setenv [\n" \ - "getenv(%s): '%s' != '%s'\n" \ - "]\n", \ - key, result, _v); \ - return false; \ - } \ -} while(0) - -#define TEST_UNSETENV(key) do { \ - char *_v; \ - unsetenv(key); \ - _v=getenv(key); \ - if (_v) { \ - printf("failure: setenv [\n" \ - "getenv(%s): NULL != '%s'\n" \ - "]\n", \ - SETENVTEST_KEY, _v); \ - return false; \ - } \ -} while (0) - -#define SETENVTEST_KEY "SETENVTESTKEY" -#define SETENVTEST_VAL "SETENVTESTVAL" - - printf("test: setenv\n"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"1", 0, SETENVTEST_VAL"1"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"2", 0, SETENVTEST_VAL"1"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"3", 1, SETENVTEST_VAL"3"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"4", 1, SETENVTEST_VAL"4"); - TEST_UNSETENV(SETENVTEST_KEY); - TEST_UNSETENV(SETENVTEST_KEY); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"5", 0, SETENVTEST_VAL"5"); - TEST_UNSETENV(SETENVTEST_KEY); - TEST_UNSETENV(SETENVTEST_KEY); - printf("success: setenv\n"); - return true; -} - -static int test_strndup(void) -{ - char *x; - printf("test: strndup\n"); - x = strndup("bla", 0); - if (strcmp(x, "") != 0) { - printf("failure: strndup [\ninvalid\n]\n"); - return false; - } - free(x); - x = strndup("bla", 2); - if (strcmp(x, "bl") != 0) { - printf("failure: strndup [\ninvalid\n]\n"); - return false; - } - free(x); - x = strndup("bla", 10); - if (strcmp(x, "bla") != 0) { - printf("failure: strndup [\ninvalid\n]\n"); - return false; - } - free(x); - printf("success: strndup\n"); - return true; -} - -static int test_strnlen(void) -{ - printf("test: strnlen\n"); - if (strnlen("bla", 2) != 2) { - printf("failure: strnlen [\nunexpected length\n]\n"); - return false; - } - - if (strnlen("some text\n", 0) != 0) { - printf("failure: strnlen [\nunexpected length\n]\n"); - return false; - } - - if (strnlen("some text", 20) != 9) { - printf("failure: strnlen [\nunexpected length\n]\n"); - return false; - } - - printf("success: strnlen\n"); - return true; -} - -static int test_waitpid(void) -{ - /* FIXME */ - return true; -} - -static int test_seteuid(void) -{ - /* FIXME */ - return true; -} - -static int test_setegid(void) -{ - /* FIXME */ - return true; -} - -static int test_asprintf(void) -{ - char *x; - printf("test: asprintf\n"); - if (asprintf(&x, "%d", 9) != 1) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - if (strcmp(x, "9") != 0) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - if (asprintf(&x, "dat%s", "a") != 4) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - if (strcmp(x, "data") != 0) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - printf("success: asprintf\n"); - return true; -} - -static int test_snprintf(void) -{ - char tmp[10]; - printf("test: snprintf\n"); - if (snprintf(tmp, 3, "foo%d", 9) != 4) { - printf("failure: snprintf [\nsnprintf return code failed\n]\n"); - return false; - } - - if (strcmp(tmp, "fo") != 0) { - printf("failure: snprintf [\nsnprintf failed\n]\n"); - return false; - } - - printf("success: snprintf\n"); - return true; -} - -static int test_vasprintf(void) -{ - /* FIXME */ - return true; -} - -static int test_vsnprintf(void) -{ - /* FIXME */ - return true; -} - -static int test_opendir(void) -{ - /* FIXME */ - return true; -} - -extern int test_readdir_os2_delete(void); - -static int test_readdir(void) -{ - printf("test: readdir\n"); - if (test_readdir_os2_delete() != 0) { - return false; - } - printf("success: readdir\n"); - return true; -} - -static int test_telldir(void) -{ - /* FIXME */ - return true; -} - -static int test_seekdir(void) -{ - /* FIXME */ - return true; -} - -static int test_dlopen(void) -{ - /* FIXME: test dlopen, dlsym, dlclose, dlerror */ - return true; -} - - -static int test_chroot(void) -{ - /* FIXME: chroot() */ - return true; -} - -static int test_bzero(void) -{ - /* FIXME: bzero */ - return true; -} - -static int test_strerror(void) -{ - /* FIXME */ - return true; -} - -static int test_errno(void) -{ - printf("test: errno\n"); - errno = 3; - if (errno != 3) { - printf("failure: errno [\nerrno failed\n]\n"); - return false; - } - - printf("success: errno\n"); - return true; -} - -static int test_mkdtemp(void) -{ - /* FIXME */ - return true; -} - -static int test_mkstemp(void) -{ - /* FIXME */ - return true; -} - -static int test_pread(void) -{ - /* FIXME */ - return true; -} - -static int test_pwrite(void) -{ - /* FIXME */ - return true; -} - -static int test_getpass(void) -{ - /* FIXME */ - return true; -} - -static int test_inet_ntoa(void) -{ - /* FIXME */ - return true; -} - -#define TEST_STRTO_X(type,fmt,func,str,base,res,diff,rrnoo) do {\ - type _v; \ - char _s[64]; \ - char *_p = NULL;\ - char *_ep = NULL; \ - strlcpy(_s, str, sizeof(_s));\ - if (diff >= 0) { \ - _ep = &_s[diff]; \ - } \ - errno = 0; \ - _v = func(_s, &_p, base); \ - if (errno != rrnoo) { \ - printf("failure: %s [\n" \ - "\t%s\n" \ - "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ - "\terrno: %d != %d\n" \ - "]\n", \ - __STRING(func), __location__, __STRING(func), \ - str, diff, base, res, _v, rrnoo, errno); \ - return false; \ - } else if (_v != res) { \ - printf("failure: %s [\n" \ - "\t%s\n" \ - "\t%s(\"%s\",%d,%d): " fmt " != " fmt "\n" \ - "]\n", \ - __STRING(func), __location__, __STRING(func), \ - str, diff, base, res, _v); \ - return false; \ - } else if (_p != _ep) { \ - printf("failure: %s [\n" \ - "\t%s\n" \ - "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ - "\tptr: %p - %p = %d != %d\n" \ - "]\n", \ - __STRING(func), __location__, __STRING(func), \ - str, diff, base, res, _v, _ep, _p, (int)(diff - (_ep - _p)), diff); \ - return false; \ - } \ -} while (0) - -static int test_strtoll(void) -{ - printf("test: strtoll\n"); - -#define TEST_STRTOLL(str,base,res,diff,errnoo) TEST_STRTO_X(long long int, "%lld", strtoll,str,base,res,diff,errnoo) - - TEST_STRTOLL("15", 10, 15LL, 2, 0); - TEST_STRTOLL(" 15", 10, 15LL, 4, 0); - TEST_STRTOLL("15", 0, 15LL, 2, 0); - TEST_STRTOLL(" 15 ", 0, 15LL, 3, 0); - TEST_STRTOLL("+15", 10, 15LL, 3, 0); - TEST_STRTOLL(" +15", 10, 15LL, 5, 0); - TEST_STRTOLL("+15", 0, 15LL, 3, 0); - TEST_STRTOLL(" +15 ", 0, 15LL, 4, 0); - TEST_STRTOLL("-15", 10, -15LL, 3, 0); - TEST_STRTOLL(" -15", 10, -15LL, 5, 0); - TEST_STRTOLL("-15", 0, -15LL, 3, 0); - TEST_STRTOLL(" -15 ", 0, -15LL, 4, 0); - TEST_STRTOLL("015", 10, 15LL, 3, 0); - TEST_STRTOLL(" 015", 10, 15LL, 5, 0); - TEST_STRTOLL("015", 0, 13LL, 3, 0); - TEST_STRTOLL(" 015", 0, 13LL, 5, 0); - TEST_STRTOLL("0x15", 10, 0LL, 1, 0); - TEST_STRTOLL(" 0x15", 10, 0LL, 3, 0); - TEST_STRTOLL("0x15", 0, 21LL, 4, 0); - TEST_STRTOLL(" 0x15", 0, 21LL, 6, 0); - - TEST_STRTOLL("10", 16, 16LL, 2, 0); - TEST_STRTOLL(" 10 ", 16, 16LL, 4, 0); - TEST_STRTOLL("0x10", 16, 16LL, 4, 0); - TEST_STRTOLL("0x10", 0, 16LL, 4, 0); - TEST_STRTOLL(" 0x10 ", 0, 16LL, 5, 0); - TEST_STRTOLL("+10", 16, 16LL, 3, 0); - TEST_STRTOLL(" +10 ", 16, 16LL, 5, 0); - TEST_STRTOLL("+0x10", 16, 16LL, 5, 0); - TEST_STRTOLL("+0x10", 0, 16LL, 5, 0); - TEST_STRTOLL(" +0x10 ", 0, 16LL, 6, 0); - TEST_STRTOLL("-10", 16, -16LL, 3, 0); - TEST_STRTOLL(" -10 ", 16, -16LL, 5, 0); - TEST_STRTOLL("-0x10", 16, -16LL, 5, 0); - TEST_STRTOLL("-0x10", 0, -16LL, 5, 0); - TEST_STRTOLL(" -0x10 ", 0, -16LL, 6, 0); - TEST_STRTOLL("010", 16, 16LL, 3, 0); - TEST_STRTOLL(" 010 ", 16, 16LL, 5, 0); - TEST_STRTOLL("-010", 16, -16LL, 4, 0); - - TEST_STRTOLL("11", 8, 9LL, 2, 0); - TEST_STRTOLL("011", 8, 9LL, 3, 0); - TEST_STRTOLL("011", 0, 9LL, 3, 0); - TEST_STRTOLL("-11", 8, -9LL, 3, 0); - TEST_STRTOLL("-011", 8, -9LL, 4, 0); - TEST_STRTOLL("-011", 0, -9LL, 4, 0); - - TEST_STRTOLL("011", 8, 9LL, 3, 0); - TEST_STRTOLL("011", 0, 9LL, 3, 0); - TEST_STRTOLL("-11", 8, -9LL, 3, 0); - TEST_STRTOLL("-011", 8, -9LL, 4, 0); - TEST_STRTOLL("-011", 0, -9LL, 4, 0); - - TEST_STRTOLL("Text", 0, 0LL, 0, 0); - - TEST_STRTOLL("9223372036854775807", 10, 9223372036854775807LL, 19, 0); - TEST_STRTOLL("9223372036854775807", 0, 9223372036854775807LL, 19, 0); - TEST_STRTOLL("9223372036854775808", 0, 9223372036854775807LL, 19, ERANGE); - TEST_STRTOLL("9223372036854775808", 10, 9223372036854775807LL, 19, ERANGE); - TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LL, 18, 0); - TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 18, 0); - TEST_STRTOLL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 16, 0); - TEST_STRTOLL("0x8000000000000000", 0, 9223372036854775807LL, 18, ERANGE); - TEST_STRTOLL("0x8000000000000000", 16, 9223372036854775807LL, 18, ERANGE); - TEST_STRTOLL("80000000000000000", 16, 9223372036854775807LL, 17, ERANGE); - TEST_STRTOLL("0777777777777777777777", 0, 9223372036854775807LL, 22, 0); - TEST_STRTOLL("0777777777777777777777", 8, 9223372036854775807LL, 22, 0); - TEST_STRTOLL("777777777777777777777", 8, 9223372036854775807LL, 21, 0); - TEST_STRTOLL("01000000000000000000000", 0, 9223372036854775807LL, 23, ERANGE); - TEST_STRTOLL("01000000000000000000000", 8, 9223372036854775807LL, 23, ERANGE); - TEST_STRTOLL("1000000000000000000000", 8, 9223372036854775807LL, 22, ERANGE); - - TEST_STRTOLL("-9223372036854775808", 10, -9223372036854775807LL -1, 20, 0); - TEST_STRTOLL("-9223372036854775808", 0, -9223372036854775807LL -1, 20, 0); - TEST_STRTOLL("-9223372036854775809", 0, -9223372036854775807LL -1, 20, ERANGE); - TEST_STRTOLL("-9223372036854775809", 10, -9223372036854775807LL -1, 20, ERANGE); - TEST_STRTOLL("-0x8000000000000000", 0, -9223372036854775807LL -1, 19, 0); - TEST_STRTOLL("-0x8000000000000000", 16, -9223372036854775807LL -1, 19, 0); - TEST_STRTOLL("-8000000000000000", 16, -9223372036854775807LL -1, 17, 0); - TEST_STRTOLL("-0x8000000000000001", 0, -9223372036854775807LL -1, 19, ERANGE); - TEST_STRTOLL("-0x8000000000000001", 16, -9223372036854775807LL -1, 19, ERANGE); - TEST_STRTOLL("-80000000000000001", 16, -9223372036854775807LL -1, 18, ERANGE); - TEST_STRTOLL("-01000000000000000000000",0, -9223372036854775807LL -1, 24, 0); - TEST_STRTOLL("-01000000000000000000000",8, -9223372036854775807LL -1, 24, 0); - TEST_STRTOLL("-1000000000000000000000", 8, -9223372036854775807LL -1, 23, 0); - TEST_STRTOLL("-01000000000000000000001",0, -9223372036854775807LL -1, 24, ERANGE); - TEST_STRTOLL("-01000000000000000000001",8, -9223372036854775807LL -1, 24, ERANGE); - TEST_STRTOLL("-1000000000000000000001", 8, -9223372036854775807LL -1, 23, ERANGE); - - printf("success: strtoll\n"); - return true; -} - -static int test_strtoull(void) -{ - printf("test: strtoull\n"); - -#define TEST_STRTOULL(str,base,res,diff,errnoo) TEST_STRTO_X(long long unsigned int,"%llu",strtoull,str,base,res,diff,errnoo) - - TEST_STRTOULL("15", 10, 15LLU, 2, 0); - TEST_STRTOULL(" 15", 10, 15LLU, 4, 0); - TEST_STRTOULL("15", 0, 15LLU, 2, 0); - TEST_STRTOULL(" 15 ", 0, 15LLU, 3, 0); - TEST_STRTOULL("+15", 10, 15LLU, 3, 0); - TEST_STRTOULL(" +15", 10, 15LLU, 5, 0); - TEST_STRTOULL("+15", 0, 15LLU, 3, 0); - TEST_STRTOULL(" +15 ", 0, 15LLU, 4, 0); - TEST_STRTOULL("-15", 10, 18446744073709551601LLU, 3, 0); - TEST_STRTOULL(" -15", 10, 18446744073709551601LLU, 5, 0); - TEST_STRTOULL("-15", 0, 18446744073709551601LLU, 3, 0); - TEST_STRTOULL(" -15 ", 0, 18446744073709551601LLU, 4, 0); - TEST_STRTOULL("015", 10, 15LLU, 3, 0); - TEST_STRTOULL(" 015", 10, 15LLU, 5, 0); - TEST_STRTOULL("015", 0, 13LLU, 3, 0); - TEST_STRTOULL(" 015", 0, 13LLU, 5, 0); - TEST_STRTOULL("0x15", 10, 0LLU, 1, 0); - TEST_STRTOULL(" 0x15", 10, 0LLU, 3, 0); - TEST_STRTOULL("0x15", 0, 21LLU, 4, 0); - TEST_STRTOULL(" 0x15", 0, 21LLU, 6, 0); - - TEST_STRTOULL("10", 16, 16LLU, 2, 0); - TEST_STRTOULL(" 10 ", 16, 16LLU, 4, 0); - TEST_STRTOULL("0x10", 16, 16LLU, 4, 0); - TEST_STRTOULL("0x10", 0, 16LLU, 4, 0); - TEST_STRTOULL(" 0x10 ", 0, 16LLU, 5, 0); - TEST_STRTOULL("+10", 16, 16LLU, 3, 0); - TEST_STRTOULL(" +10 ", 16, 16LLU, 5, 0); - TEST_STRTOULL("+0x10", 16, 16LLU, 5, 0); - TEST_STRTOULL("+0x10", 0, 16LLU, 5, 0); - TEST_STRTOULL(" +0x10 ", 0, 16LLU, 6, 0); - TEST_STRTOULL("-10", 16, -16LLU, 3, 0); - TEST_STRTOULL(" -10 ", 16, -16LLU, 5, 0); - TEST_STRTOULL("-0x10", 16, -16LLU, 5, 0); - TEST_STRTOULL("-0x10", 0, -16LLU, 5, 0); - TEST_STRTOULL(" -0x10 ", 0, -16LLU, 6, 0); - TEST_STRTOULL("010", 16, 16LLU, 3, 0); - TEST_STRTOULL(" 010 ", 16, 16LLU, 5, 0); - TEST_STRTOULL("-010", 16, -16LLU, 4, 0); - - TEST_STRTOULL("11", 8, 9LLU, 2, 0); - TEST_STRTOULL("011", 8, 9LLU, 3, 0); - TEST_STRTOULL("011", 0, 9LLU, 3, 0); - TEST_STRTOULL("-11", 8, -9LLU, 3, 0); - TEST_STRTOULL("-011", 8, -9LLU, 4, 0); - TEST_STRTOULL("-011", 0, -9LLU, 4, 0); - - TEST_STRTOULL("011", 8, 9LLU, 3, 0); - TEST_STRTOULL("011", 0, 9LLU, 3, 0); - TEST_STRTOULL("-11", 8, -9LLU, 3, 0); - TEST_STRTOULL("-011", 8, -9LLU, 4, 0); - TEST_STRTOULL("-011", 0, -9LLU, 4, 0); - - TEST_STRTOULL("Text", 0, 0LLU, 0, 0); - - TEST_STRTOULL("9223372036854775807", 10, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("9223372036854775807", 0, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("9223372036854775808", 0, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("9223372036854775808", 10, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LLU, 18, 0); - TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 18, 0); - TEST_STRTOULL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 16, 0); - TEST_STRTOULL("0x8000000000000000", 0, 9223372036854775808LLU, 18, 0); - TEST_STRTOULL("0x8000000000000000", 16, 9223372036854775808LLU, 18, 0); - TEST_STRTOULL("8000000000000000", 16, 9223372036854775808LLU, 16, 0); - TEST_STRTOULL("0777777777777777777777", 0, 9223372036854775807LLU, 22, 0); - TEST_STRTOULL("0777777777777777777777", 8, 9223372036854775807LLU, 22, 0); - TEST_STRTOULL("777777777777777777777", 8, 9223372036854775807LLU, 21, 0); - TEST_STRTOULL("01000000000000000000000",0, 9223372036854775808LLU, 23, 0); - TEST_STRTOULL("01000000000000000000000",8, 9223372036854775808LLU, 23, 0); - TEST_STRTOULL("1000000000000000000000", 8, 9223372036854775808LLU, 22, 0); - - TEST_STRTOULL("-9223372036854775808", 10, 9223372036854775808LLU, 20, 0); - TEST_STRTOULL("-9223372036854775808", 0, 9223372036854775808LLU, 20, 0); - TEST_STRTOULL("-9223372036854775809", 0, 9223372036854775807LLU, 20, 0); - TEST_STRTOULL("-9223372036854775809", 10, 9223372036854775807LLU, 20, 0); - TEST_STRTOULL("-0x8000000000000000", 0, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("-0x8000000000000000", 16, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("-8000000000000000", 16, 9223372036854775808LLU, 17, 0); - TEST_STRTOULL("-0x8000000000000001", 0, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("-0x8000000000000001", 16, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("-8000000000000001", 16, 9223372036854775807LLU, 17, 0); - TEST_STRTOULL("-01000000000000000000000",0, 9223372036854775808LLU, 24, 0); - TEST_STRTOULL("-01000000000000000000000",8, 9223372036854775808LLU, 24, 0); - TEST_STRTOULL("-1000000000000000000000",8, 9223372036854775808LLU, 23, 0); - TEST_STRTOULL("-01000000000000000000001",0, 9223372036854775807LLU, 24, 0); - TEST_STRTOULL("-01000000000000000000001",8, 9223372036854775807LLU, 24, 0); - TEST_STRTOULL("-1000000000000000000001",8, 9223372036854775807LLU, 23, 0); - - TEST_STRTOULL("18446744073709551615", 0, 18446744073709551615LLU, 20, 0); - TEST_STRTOULL("18446744073709551615", 10, 18446744073709551615LLU, 20, 0); - TEST_STRTOULL("18446744073709551616", 0, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("18446744073709551616", 10, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 0, 18446744073709551615LLU, 18, 0); - TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 18, 0); - TEST_STRTOULL("FFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 16, 0); - TEST_STRTOULL("0x10000000000000000", 0, 18446744073709551615LLU, 19, ERANGE); - TEST_STRTOULL("0x10000000000000000", 16, 18446744073709551615LLU, 19, ERANGE); - TEST_STRTOULL("10000000000000000", 16, 18446744073709551615LLU, 17, ERANGE); - TEST_STRTOULL("01777777777777777777777",0, 18446744073709551615LLU, 23, 0); - TEST_STRTOULL("01777777777777777777777",8, 18446744073709551615LLU, 23, 0); - TEST_STRTOULL("1777777777777777777777", 8, 18446744073709551615LLU, 22, 0); - TEST_STRTOULL("02000000000000000000000",0, 18446744073709551615LLU, 23, ERANGE); - TEST_STRTOULL("02000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); - TEST_STRTOULL("2000000000000000000000", 8, 18446744073709551615LLU, 22, ERANGE); - - TEST_STRTOULL("-18446744073709551615", 0, 1LLU, 21, 0); - TEST_STRTOULL("-18446744073709551615", 10, 1LLU, 21, 0); - TEST_STRTOULL("-18446744073709551616", 0, 18446744073709551615LLU, 21, ERANGE); - TEST_STRTOULL("-18446744073709551616", 10, 18446744073709551615LLU, 21, ERANGE); - TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 0, 1LLU, 19, 0); - TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 16, 1LLU, 19, 0); - TEST_STRTOULL("-FFFFFFFFFFFFFFFF", 16, 1LLU, 17, 0); - TEST_STRTOULL("-0x10000000000000000", 0, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("-0x10000000000000000", 16, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("-10000000000000000", 16, 18446744073709551615LLU, 18, ERANGE); - TEST_STRTOULL("-01777777777777777777777",0, 1LLU, 24, 0); - TEST_STRTOULL("-01777777777777777777777",8, 1LLU, 24, 0); - TEST_STRTOULL("-1777777777777777777777",8, 1LLU, 23, 0); - TEST_STRTOULL("-02000000000000000000000",0, 18446744073709551615LLU, 24, ERANGE); - TEST_STRTOULL("-02000000000000000000000",8, 18446744073709551615LLU, 24, ERANGE); - TEST_STRTOULL("-2000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); - - printf("success: strtoull\n"); - return true; -} - -/* -FIXME: -Types: -bool -socklen_t -uint_t -uint{8,16,32,64}_t -int{8,16,32,64}_t -intptr_t - -Constants: -PATH_NAME_MAX -UINT{16,32,64}_MAX -INT32_MAX -*/ - -static int test_va_copy(void) -{ - /* FIXME */ - return true; -} - -static int test_FUNCTION(void) -{ - printf("test: FUNCTION\n"); - if (strcmp(__FUNCTION__, "test_FUNCTION") != 0) { - printf("failure: FAILURE [\nFAILURE invalid\n]\n"); - return false; - } - printf("success: FUNCTION\n"); - return true; -} - -static int test_MIN(void) -{ - printf("test: MIN\n"); - if (MIN(20, 1) != 1) { - printf("failure: MIN [\nMIN invalid\n]\n"); - return false; - } - if (MIN(1, 20) != 1) { - printf("failure: MIN [\nMIN invalid\n]\n"); - return false; - } - printf("success: MIN\n"); - return true; -} - -static int test_MAX(void) -{ - printf("test: MAX\n"); - if (MAX(20, 1) != 20) { - printf("failure: MAX [\nMAX invalid\n]\n"); - return false; - } - if (MAX(1, 20) != 20) { - printf("failure: MAX [\nMAX invalid\n]\n"); - return false; - } - printf("success: MAX\n"); - return true; -} - -static int test_socketpair(void) -{ - int sock[2]; - char buf[20]; - - printf("test: socketpair\n"); - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock) == -1) { - printf("failure: socketpair [\n" - "socketpair() failed\n" - "]\n"); - return false; - } - - if (write(sock[1], "automatisch", 12) == -1) { - printf("failure: socketpair [\n" - "write() failed: %s\n" - "]\n", strerror(errno)); - return false; - } - - if (read(sock[0], buf, 12) == -1) { - printf("failure: socketpair [\n" - "read() failed: %s\n" - "]\n", strerror(errno)); - return false; - } - - if (strcmp(buf, "automatisch") != 0) { - printf("failure: socketpair [\n" - "expected: automatisch, got: %s\n" - "]\n", buf); - return false; - } - - printf("success: socketpair\n"); - - return true; -} - -extern int libreplace_test_strptime(void); - -static int test_strptime(void) -{ - return libreplace_test_strptime(); -} - -extern int getifaddrs_test(void); - -static int test_getifaddrs(void) -{ - - printf("test: getifaddrs\n"); - - if (getifaddrs_test() != 0) { - printf("failure: getifaddrs\n"); - return false; - } - - printf("success: getifaddrs\n"); - return true; -} - -static int test_utime(void) -{ - struct utimbuf u; - struct stat st1, st2, st3; - int fd; - - printf("test: utime\n"); - unlink(TESTFILE); - - fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); - if (fd == -1) { - printf("failure: utime [\n" - "creating '%s' failed - %s\n]\n", - TESTFILE, strerror(errno)); - return false; - } - - if (fstat(fd, &st1) != 0) { - printf("failure: utime [\n" - "fstat (1) failed - %s\n]\n", - strerror(errno)); - return false; - } - - u.actime = st1.st_atime + 300; - u.modtime = st1.st_mtime - 300; - if (utime(TESTFILE, &u) != 0) { - printf("failure: utime [\n" - "utime(&u) failed - %s\n]\n", - strerror(errno)); - return false; - } - - if (fstat(fd, &st2) != 0) { - printf("failure: utime [\n" - "fstat (2) failed - %s\n]\n", - strerror(errno)); - return false; - } - - if (utime(TESTFILE, NULL) != 0) { - printf("failure: utime [\n" - "utime(NULL) failed - %s\n]\n", - strerror(errno)); - return false; - } - - if (fstat(fd, &st3) != 0) { - printf("failure: utime [\n" - "fstat (3) failed - %s\n]\n", - strerror(errno)); - return false; - } - -#define CMP_VAL(a,c,b) do { \ - if (a c b) { \ - printf("failure: utime [\n" \ - "%s: %s(%d) %s %s(%d)\n]\n", \ - __location__, \ - #a, (int)a, #c, #b, (int)b); \ - return false; \ - } \ -} while(0) -#define EQUAL_VAL(a,b) CMP_VAL(a,!=,b) -#define GREATER_VAL(a,b) CMP_VAL(a,<=,b) -#define LESSER_VAL(a,b) CMP_VAL(a,>=,b) - - EQUAL_VAL(st2.st_atime, st1.st_atime + 300); - EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); - LESSER_VAL(st3.st_atime, st2.st_atime); - GREATER_VAL(st3.st_mtime, st2.st_mtime); - -#undef CMP_VAL -#undef EQUAL_VAL -#undef GREATER_VAL -#undef LESSER_VAL - - unlink(TESTFILE); - printf("success: utime\n"); - return true; -} - -static int test_utimes(void) -{ - struct timeval tv[2]; - struct stat st1, st2; - int fd; - - printf("test: utimes\n"); - unlink(TESTFILE); - - fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); - if (fd == -1) { - printf("failure: utimes [\n" - "creating '%s' failed - %s\n]\n", - TESTFILE, strerror(errno)); - return false; - } - - if (fstat(fd, &st1) != 0) { - printf("failure: utimes [\n" - "fstat (1) failed - %s\n]\n", - strerror(errno)); - return false; - } - - ZERO_STRUCT(tv); - tv[0].tv_sec = st1.st_atime + 300; - tv[1].tv_sec = st1.st_mtime - 300; - if (utimes(TESTFILE, tv) != 0) { - printf("failure: utimes [\n" - "utimes(tv) failed - %s\n]\n", - strerror(errno)); - return false; - } - - if (fstat(fd, &st2) != 0) { - printf("failure: utimes [\n" - "fstat (2) failed - %s\n]\n", - strerror(errno)); - return false; - } - -#define EQUAL_VAL(a,b) do { \ - if (a != b) { \ - printf("failure: utimes [\n" \ - "%s: %s(%d) != %s(%d)\n]\n", \ - __location__, \ - #a, (int)a, #b, (int)b); \ - return false; \ - } \ -} while(0) - - EQUAL_VAL(st2.st_atime, st1.st_atime + 300); - EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); - -#undef EQUAL_VAL - - unlink(TESTFILE); - printf("success: utimes\n"); - return true; -} - -struct torture_context; -bool torture_local_replace(struct torture_context *ctx) -{ - bool ret = true; - ret &= test_ftruncate(); - ret &= test_strlcpy(); - ret &= test_strlcat(); - ret &= test_mktime(); - ret &= test_initgroups(); - ret &= test_memmove(); - ret &= test_strdup(); - ret &= test_setlinebuf(); - ret &= test_vsyslog(); - ret &= test_timegm(); - ret &= test_setenv(); - ret &= test_strndup(); - ret &= test_strnlen(); - ret &= test_waitpid(); - ret &= test_seteuid(); - ret &= test_setegid(); - ret &= test_asprintf(); - ret &= test_snprintf(); - ret &= test_vasprintf(); - ret &= test_vsnprintf(); - ret &= test_opendir(); - ret &= test_readdir(); - ret &= test_telldir(); - ret &= test_seekdir(); - ret &= test_dlopen(); - ret &= test_chroot(); - ret &= test_bzero(); - ret &= test_strerror(); - ret &= test_errno(); - ret &= test_mkdtemp(); - ret &= test_mkstemp(); - ret &= test_pread(); - ret &= test_pwrite(); - ret &= test_getpass(); - ret &= test_inet_ntoa(); - ret &= test_strtoll(); - ret &= test_strtoull(); - ret &= test_va_copy(); - ret &= test_FUNCTION(); - ret &= test_MIN(); - ret &= test_MAX(); - ret &= test_socketpair(); - ret &= test_strptime(); - ret &= test_getifaddrs(); - ret &= test_utime(); - ret &= test_utimes(); - - return ret; -} - -#if _SAMBA_BUILD_<4 -int main(void) -{ - bool ret = torture_local_replace(NULL); - if (ret) - return 0; - return -1; -} -#endif diff --git a/replace/timegm.c b/replace/timegm.c deleted file mode 100644 index 395c684e11..0000000000 --- a/replace/timegm.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1997 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - */ - -/* - adapted for Samba4 by Andrew Tridgell -*/ - -#include "replace.h" -#include "system/time.h" - -static int is_leap(unsigned y) -{ - y += 1900; - return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); -} - -time_t rep_timegm(struct tm *tm) -{ - static const unsigned ndays[2][12] ={ - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; - time_t res = 0; - unsigned i; - - if (tm->tm_mon > 12 || - tm->tm_mon < 0 || - tm->tm_mday > 31 || - tm->tm_min > 60 || - tm->tm_sec > 60 || - tm->tm_hour > 24) { - /* invalid tm structure */ - return 0; - } - - for (i = 70; i < tm->tm_year; ++i) - res += is_leap(i) ? 366 : 365; - - for (i = 0; i < tm->tm_mon; ++i) - res += ndays[is_leap(tm->tm_year)][i]; - res += tm->tm_mday - 1; - res *= 24; - res += tm->tm_hour; - res *= 60; - res += tm->tm_min; - res *= 60; - res += tm->tm_sec; - return res; -} diff --git a/replace/timegm.m4 b/replace/timegm.m4 deleted file mode 100644 index 59f3ae0521..0000000000 --- a/replace/timegm.m4 +++ /dev/null @@ -1 +0,0 @@ -AC_CHECK_FUNCS(timegm,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} timegm.o"]) diff --git a/replace/win32.m4 b/replace/win32.m4 deleted file mode 100644 index eb364e2cb9..0000000000 --- a/replace/win32.m4 +++ /dev/null @@ -1,20 +0,0 @@ -AC_CHECK_HEADERS(direct.h windows.h winsock2.h ws2tcpip.h) - -####################################### -# Check for mkdir mode -AC_CACHE_CHECK( [whether mkdir supports mode], libreplace_cv_mkdir_has_mode, - AC_TRY_COMPILE([ - #include - #ifdef HAVE_DIRECT_H - #include - #endif],[ - mkdir("foo",0777); - return 0; - ], - libreplace_cv_mkdir_has_mode="yes", - libreplace_cv_mkdir_has_mode="no") ) - -if test "$libreplace_cv_mkdir_has_mode" = "yes" -then - AC_DEFINE(HAVE_MKDIR_MODE, 1, [Define if target mkdir supports mode option]) -fi diff --git a/replace/win32_replace.h b/replace/win32_replace.h deleted file mode 100644 index 9901e72f6e..0000000000 --- a/replace/win32_replace.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef _WIN32_REPLACE_H -#define _WIN32_REPLACE_H - -#ifdef HAVE_WINSOCK2_H -#include -#endif - -#ifdef HAVE_WS2TCPIP_H -#include -#endif - -#ifdef HAVE_WINDOWS_H -#include -#endif - -/* Map BSD Socket errorcodes to the WSA errorcodes (if possible) */ - -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define ECONNREFUSED WSAECONNREFUSED -#define EINPROGRESS WSAEINPROGRESS -#define EMSGSIZE WSAEMSGSIZE -#define ENOBUFS WSAENOBUFS -#define ENOTSOCK WSAENOTSOCK -#define ENETUNREACH WSAENETUNREACH -#define ENOPROTOOPT WSAENOPROTOOPT -#define ENOTCONN WSAENOTCONN -#define ENOTSUP 134 - -/* We undefine the following constants due to conflicts with the w32api headers - * and the Windows Platform SDK/DDK. - */ - -#undef interface - -#undef ERROR_INVALID_PARAMETER -#undef ERROR_INSUFFICIENT_BUFFER -#undef ERROR_INVALID_DATATYPE - -#undef FILE_GENERIC_READ -#undef FILE_GENERIC_WRITE -#undef FILE_GENERIC_EXECUTE -#undef FILE_ATTRIBUTE_READONLY -#undef FILE_ATTRIBUTE_HIDDEN -#undef FILE_ATTRIBUTE_SYSTEM -#undef FILE_ATTRIBUTE_DIRECTORY -#undef FILE_ATTRIBUTE_ARCHIVE -#undef FILE_ATTRIBUTE_DEVICE -#undef FILE_ATTRIBUTE_NORMAL -#undef FILE_ATTRIBUTE_TEMPORARY -#undef FILE_ATTRIBUTE_REPARSE_POINT -#undef FILE_ATTRIBUTE_COMPRESSED -#undef FILE_ATTRIBUTE_OFFLINE -#undef FILE_ATTRIBUTE_ENCRYPTED -#undef FILE_FLAG_WRITE_THROUGH -#undef FILE_FLAG_NO_BUFFERING -#undef FILE_FLAG_RANDOM_ACCESS -#undef FILE_FLAG_SEQUENTIAL_SCAN -#undef FILE_FLAG_DELETE_ON_CLOSE -#undef FILE_FLAG_BACKUP_SEMANTICS -#undef FILE_FLAG_POSIX_SEMANTICS -#undef FILE_TYPE_DISK -#undef FILE_TYPE_UNKNOWN -#undef FILE_CASE_SENSITIVE_SEARCH -#undef FILE_CASE_PRESERVED_NAMES -#undef FILE_UNICODE_ON_DISK -#undef FILE_PERSISTENT_ACLS -#undef FILE_FILE_COMPRESSION -#undef FILE_VOLUME_QUOTAS -#undef FILE_VOLUME_IS_COMPRESSED -#undef FILE_NOTIFY_CHANGE_FILE_NAME -#undef FILE_NOTIFY_CHANGE_DIR_NAME -#undef FILE_NOTIFY_CHANGE_ATTRIBUTES -#undef FILE_NOTIFY_CHANGE_SIZE -#undef FILE_NOTIFY_CHANGE_LAST_WRITE -#undef FILE_NOTIFY_CHANGE_LAST_ACCESS -#undef FILE_NOTIFY_CHANGE_CREATION -#undef FILE_NOTIFY_CHANGE_EA -#undef FILE_NOTIFY_CHANGE_SECURITY -#undef FILE_NOTIFY_CHANGE_STREAM_NAME -#undef FILE_NOTIFY_CHANGE_STREAM_SIZE -#undef FILE_NOTIFY_CHANGE_STREAM_WRITE -#undef FILE_NOTIFY_CHANGE_NAME - -#undef PRINTER_ATTRIBUTE_QUEUED -#undef PRINTER_ATTRIBUTE_DIRECT -#undef PRINTER_ATTRIBUTE_DEFAULT -#undef PRINTER_ATTRIBUTE_SHARED -#undef PRINTER_ATTRIBUTE_NETWORK -#undef PRINTER_ATTRIBUTE_HIDDEN -#undef PRINTER_ATTRIBUTE_LOCAL -#undef PRINTER_ATTRIBUTE_ENABLE_DEVQ -#undef PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS -#undef PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST -#undef PRINTER_ATTRIBUTE_WORK_OFFLINE -#undef PRINTER_ATTRIBUTE_ENABLE_BIDI -#undef PRINTER_ATTRIBUTE_RAW_ONLY -#undef PRINTER_ATTRIBUTE_PUBLISHED -#undef PRINTER_ENUM_DEFAULT -#undef PRINTER_ENUM_LOCAL -#undef PRINTER_ENUM_CONNECTIONS -#undef PRINTER_ENUM_FAVORITE -#undef PRINTER_ENUM_NAME -#undef PRINTER_ENUM_REMOTE -#undef PRINTER_ENUM_SHARED -#undef PRINTER_ENUM_NETWORK -#undef PRINTER_ENUM_EXPAND -#undef PRINTER_ENUM_CONTAINER -#undef PRINTER_ENUM_ICON1 -#undef PRINTER_ENUM_ICON2 -#undef PRINTER_ENUM_ICON3 -#undef PRINTER_ENUM_ICON4 -#undef PRINTER_ENUM_ICON5 -#undef PRINTER_ENUM_ICON6 -#undef PRINTER_ENUM_ICON7 -#undef PRINTER_ENUM_ICON8 -#undef PRINTER_STATUS_PAUSED -#undef PRINTER_STATUS_ERROR -#undef PRINTER_STATUS_PENDING_DELETION -#undef PRINTER_STATUS_PAPER_JAM -#undef PRINTER_STATUS_PAPER_OUT -#undef PRINTER_STATUS_MANUAL_FEED -#undef PRINTER_STATUS_PAPER_PROBLEM -#undef PRINTER_STATUS_OFFLINE -#undef PRINTER_STATUS_IO_ACTIVE -#undef PRINTER_STATUS_BUSY -#undef PRINTER_STATUS_PRINTING -#undef PRINTER_STATUS_OUTPUT_BIN_FULL -#undef PRINTER_STATUS_NOT_AVAILABLE -#undef PRINTER_STATUS_WAITING -#undef PRINTER_STATUS_PROCESSING -#undef PRINTER_STATUS_INITIALIZING -#undef PRINTER_STATUS_WARMING_UP -#undef PRINTER_STATUS_TONER_LOW -#undef PRINTER_STATUS_NO_TONER -#undef PRINTER_STATUS_PAGE_PUNT -#undef PRINTER_STATUS_USER_INTERVENTION -#undef PRINTER_STATUS_OUT_OF_MEMORY -#undef PRINTER_STATUS_DOOR_OPEN -#undef PRINTER_STATUS_SERVER_UNKNOWN -#undef PRINTER_STATUS_POWER_SAVE - -#undef DWORD -#undef HKEY_CLASSES_ROOT -#undef HKEY_CURRENT_USER -#undef HKEY_LOCAL_MACHINE -#undef HKEY_USERS -#undef HKEY_PERFORMANCE_DATA -#undef HKEY_CURRENT_CONFIG -#undef HKEY_DYN_DATA -#undef REG_DWORD -#undef REG_QWORD - -#undef SERVICE_STATE_ALL - -#undef SE_GROUP_MANDATORY -#undef SE_GROUP_ENABLED_BY_DEFAULT -#undef SE_GROUP_ENABLED - -#endif /* _WIN32_REPLACE_H */ diff --git a/socket_wrapper/config.m4 b/socket_wrapper/config.m4 deleted file mode 100644 index 23f033e664..0000000000 --- a/socket_wrapper/config.m4 +++ /dev/null @@ -1,22 +0,0 @@ -AC_ARG_ENABLE(socket-wrapper, -[ --enable-socket-wrapper Turn on socket wrapper library (default=no)]) - -DEFAULT_TEST_OPTIONS= -HAVE_SOCKET_WRAPPER=no - -if eval "test x$developer = xyes"; then - enable_socket_wrapper=yes -fi - -if eval "test x$enable_socket_wrapper = xyes"; then - AC_DEFINE(SOCKET_WRAPPER,1,[Use socket wrapper library]) - DEFAULT_TEST_OPTIONS=--socket-wrapper - HAVE_SOCKET_WRAPPER=yes - - # this is only used for samba3 - SOCKET_WRAPPER_OBJS="../socket_wrapper/socket_wrapper.o" -fi - -AC_SUBST(DEFAULT_TEST_OPTIONS) -AC_SUBST(HAVE_SOCKET_WRAPPER) -AC_SUBST(SOCKET_WRAPPER_OBJS) diff --git a/socket_wrapper/config.mk b/socket_wrapper/config.mk deleted file mode 100644 index 60cfb3209a..0000000000 --- a/socket_wrapper/config.mk +++ /dev/null @@ -1,8 +0,0 @@ -############################## -# Start SUBSYSTEM SOCKET_WRAPPER -[SUBSYSTEM::SOCKET_WRAPPER] -PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK -# End SUBSYSTEM SOCKET_WRAPPER -############################## - -SOCKET_WRAPPER_OBJ_FILES = $(socketwrappersrcdir)/socket_wrapper.o diff --git a/socket_wrapper/socket_wrapper.c b/socket_wrapper/socket_wrapper.c deleted file mode 100644 index e8d27adc37..0000000000 --- a/socket_wrapper/socket_wrapper.c +++ /dev/null @@ -1,1841 +0,0 @@ -/* - * Copyright (C) Jelmer Vernooij 2005,2008 - * Copyright (C) Stefan Metzmacher 2006 - * - * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. - * - */ - -/* - Socket wrapper library. Passes all socket communication over - unix domain sockets if the environment variable SOCKET_WRAPPER_DIR - is set. -*/ - -#ifdef _SAMBA_BUILD_ - -#define SOCKET_WRAPPER_NOT_REPLACE -#include "../replace/replace.h" -#include "system/network.h" -#include "system/filesys.h" -#include "system/time.h" - -#else /* _SAMBA_BUILD_ */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif - -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif - -#define SWRAP_DLIST_ADD(list,item) do { \ - if (!(list)) { \ - (item)->prev = NULL; \ - (item)->next = NULL; \ - (list) = (item); \ - } else { \ - (item)->prev = NULL; \ - (item)->next = (list); \ - (list)->prev = (item); \ - (list) = (item); \ - } \ -} while (0) - -#define SWRAP_DLIST_REMOVE(list,item) do { \ - if ((list) == (item)) { \ - (list) = (item)->next; \ - if (list) { \ - (list)->prev = NULL; \ - } \ - } else { \ - if ((item)->prev) { \ - (item)->prev->next = (item)->next; \ - } \ - if ((item)->next) { \ - (item)->next->prev = (item)->prev; \ - } \ - } \ - (item)->prev = NULL; \ - (item)->next = NULL; \ -} while (0) - -/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support - * for now */ -#define REWRITE_CALLS - -#ifdef REWRITE_CALLS -#define real_accept accept -#define real_connect connect -#define real_bind bind -#define real_listen listen -#define real_getpeername getpeername -#define real_getsockname getsockname -#define real_getsockopt getsockopt -#define real_setsockopt setsockopt -#define real_recvfrom recvfrom -#define real_sendto sendto -#define real_ioctl ioctl -#define real_recv recv -#define real_send send -#define real_socket socket -#define real_close close -#endif - -#ifdef HAVE_GETTIMEOFDAY_TZ -#define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL) -#else -#define swrapGetTimeOfDay(tval) gettimeofday(tval) -#endif - -/* we need to use a very terse format here as IRIX 6.4 silently - truncates names to 16 chars, so if we use a longer name then we - can't tell which port a packet came from with recvfrom() - - with this format we have 8 chars left for the directory name -*/ -#define SOCKET_FORMAT "%c%02X%04X" -#define SOCKET_TYPE_CHAR_TCP 'T' -#define SOCKET_TYPE_CHAR_UDP 'U' -#define SOCKET_TYPE_CHAR_TCP_V6 'X' -#define SOCKET_TYPE_CHAR_UDP_V6 'Y' - -#define MAX_WRAPPED_INTERFACES 16 - -#define SW_IPV6_ADDRESS 1 - -static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) -{ - struct sockaddr *ret = (struct sockaddr *)malloc(len); - memcpy(ret, data, len); - return ret; -} - -static void set_port(int family, int prt, struct sockaddr *addr) -{ - switch (family) { - case AF_INET: - ((struct sockaddr_in *)addr)->sin_port = htons(prt); - break; -#ifdef HAVE_IPV6 - case AF_INET6: - ((struct sockaddr_in6 *)addr)->sin6_port = htons(prt); - break; -#endif - } -} - -static size_t socket_length(int family) -{ - switch (family) { - case AF_INET: - return sizeof(struct sockaddr_in); -#ifdef HAVE_IPV6 - case AF_INET6: - return sizeof(struct sockaddr_in6); -#endif - } - return 0; -} - - - -struct socket_info -{ - int fd; - - int family; - int type; - int protocol; - int bound; - int bcast; - int is_server; - - char *path; - char *tmp_path; - - struct sockaddr *myname; - socklen_t myname_len; - - struct sockaddr *peername; - socklen_t peername_len; - - struct { - unsigned long pck_snd; - unsigned long pck_rcv; - } io; - - struct socket_info *prev, *next; -}; - -static struct socket_info *sockets; - -const char *socket_wrapper_dir(void) -{ - const char *s = getenv("SOCKET_WRAPPER_DIR"); - if (s == NULL) { - return NULL; - } - if (strncmp(s, "./", 2) == 0) { - s += 2; - } - return s; -} - -unsigned int socket_wrapper_default_iface(void) -{ - const char *s = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); - if (s) { - unsigned int iface; - if (sscanf(s, "%u", &iface) == 1) { - if (iface >= 1 && iface <= MAX_WRAPPED_INTERFACES) { - return iface; - } - } - } - - return 1;/* 127.0.0.1 */ -} - -static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len) -{ - unsigned int iface; - unsigned int prt; - const char *p; - char type; - - p = strrchr(un->sun_path, '/'); - if (p) p++; else p = un->sun_path; - - if (sscanf(p, SOCKET_FORMAT, &type, &iface, &prt) != 3) { - errno = EINVAL; - return -1; - } - - if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { - errno = EINVAL; - return -1; - } - - if (prt > 0xFFFF) { - errno = EINVAL; - return -1; - } - - switch(type) { - case SOCKET_TYPE_CHAR_TCP: - case SOCKET_TYPE_CHAR_UDP: { - struct sockaddr_in *in2 = (struct sockaddr_in *)in; - - if ((*len) < sizeof(*in2)) { - errno = EINVAL; - return -1; - } - - memset(in2, 0, sizeof(*in2)); - in2->sin_family = AF_INET; - in2->sin_addr.s_addr = htonl((127<<24) | iface); - in2->sin_port = htons(prt); - - *len = sizeof(*in2); - break; - } -#ifdef HAVE_IPV6 - case SOCKET_TYPE_CHAR_TCP_V6: - case SOCKET_TYPE_CHAR_UDP_V6: { - struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in; - - if ((*len) < sizeof(*in2)) { - errno = EINVAL; - return -1; - } - - memset(in2, 0, sizeof(*in2)); - in2->sin6_family = AF_INET6; - in2->sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS; - in2->sin6_port = htons(prt); - - *len = sizeof(*in2); - break; - } -#endif - default: - errno = EINVAL; - return -1; - } - - return 0; -} - -static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un, - int *bcast) -{ - char type = '\0'; - unsigned int prt; - unsigned int iface; - int is_bcast = 0; - - if (bcast) *bcast = 0; - - switch (si->family) { - case AF_INET: { - const struct sockaddr_in *in = - (const struct sockaddr_in *)inaddr; - unsigned int addr = ntohl(in->sin_addr.s_addr); - char u_type = '\0'; - char b_type = '\0'; - char a_type = '\0'; - - switch (si->type) { - case SOCK_STREAM: - u_type = SOCKET_TYPE_CHAR_TCP; - break; - case SOCK_DGRAM: - u_type = SOCKET_TYPE_CHAR_UDP; - a_type = SOCKET_TYPE_CHAR_UDP; - b_type = SOCKET_TYPE_CHAR_UDP; - break; - } - - prt = ntohs(in->sin_port); - if (a_type && addr == 0xFFFFFFFF) { - /* 255.255.255.255 only udp */ - is_bcast = 2; - type = a_type; - iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { - /* 127.255.255.255 only udp */ - is_bcast = 1; - type = b_type; - iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { - /* 127.0.0.X */ - is_bcast = 0; - type = u_type; - iface = (addr & 0x000000FF); - } else { - errno = ENETUNREACH; - return -1; - } - if (bcast) *bcast = is_bcast; - break; - } -#ifdef HAVE_IPV6 - case AF_INET6: { - const struct sockaddr_in6 *in = - (const struct sockaddr_in6 *)inaddr; - - switch (si->type) { - case SOCK_STREAM: - type = SOCKET_TYPE_CHAR_TCP_V6; - break; - case SOCK_DGRAM: - type = SOCKET_TYPE_CHAR_UDP_V6; - break; - } - - /* XXX no multicast/broadcast */ - - prt = ntohs(in->sin6_port); - iface = SW_IPV6_ADDRESS; - - break; - } -#endif - default: - errno = ENETUNREACH; - return -1; - } - - if (prt == 0) { - errno = EINVAL; - return -1; - } - - if (is_bcast) { - snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", - socket_wrapper_dir()); - /* the caller need to do more processing */ - return 0; - } - - snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); - - return 0; -} - -static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un, - int *bcast) -{ - char type = '\0'; - unsigned int prt; - unsigned int iface; - struct stat st; - int is_bcast = 0; - - if (bcast) *bcast = 0; - - switch (si->family) { - case AF_INET: { - const struct sockaddr_in *in = - (const struct sockaddr_in *)inaddr; - unsigned int addr = ntohl(in->sin_addr.s_addr); - char u_type = '\0'; - char d_type = '\0'; - char b_type = '\0'; - char a_type = '\0'; - - prt = ntohs(in->sin_port); - - switch (si->type) { - case SOCK_STREAM: - u_type = SOCKET_TYPE_CHAR_TCP; - d_type = SOCKET_TYPE_CHAR_TCP; - break; - case SOCK_DGRAM: - u_type = SOCKET_TYPE_CHAR_UDP; - d_type = SOCKET_TYPE_CHAR_UDP; - a_type = SOCKET_TYPE_CHAR_UDP; - b_type = SOCKET_TYPE_CHAR_UDP; - break; - } - - if (addr == 0) { - /* 0.0.0.0 */ - is_bcast = 0; - type = d_type; - iface = socket_wrapper_default_iface(); - } else if (a_type && addr == 0xFFFFFFFF) { - /* 255.255.255.255 only udp */ - is_bcast = 2; - type = a_type; - iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { - /* 127.255.255.255 only udp */ - is_bcast = 1; - type = b_type; - iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { - /* 127.0.0.X */ - is_bcast = 0; - type = u_type; - iface = (addr & 0x000000FF); - } else { - errno = EADDRNOTAVAIL; - return -1; - } - break; - } -#ifdef HAVE_IPV6 - case AF_INET6: { - const struct sockaddr_in6 *in = - (const struct sockaddr_in6 *)inaddr; - - switch (si->type) { - case SOCK_STREAM: - type = SOCKET_TYPE_CHAR_TCP_V6; - break; - case SOCK_DGRAM: - type = SOCKET_TYPE_CHAR_UDP_V6; - break; - } - - /* XXX no multicast/broadcast */ - - prt = ntohs(in->sin6_port); - iface = SW_IPV6_ADDRESS; - - break; - } -#endif - default: - errno = ENETUNREACH; - return -1; - } - - - if (bcast) *bcast = is_bcast; - - if (prt == 0) { - /* handle auto-allocation of ephemeral ports */ - for (prt = 5001; prt < 10000; prt++) { - snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); - if (stat(un->sun_path, &st) == 0) continue; - - set_port(si->family, prt, si->myname); - break; - } - if (prt == 10000) { - errno = ENFILE; - return -1; - } - } - - snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); - return 0; -} - -static struct socket_info *find_socket_info(int fd) -{ - struct socket_info *i; - for (i = sockets; i; i = i->next) { - if (i->fd == fd) - return i; - } - - return NULL; -} - -static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, - struct sockaddr_un *out_addr, int alloc_sock, int *bcast) -{ - if (!out_addr) - return 0; - - out_addr->sun_family = AF_UNIX; - - switch (in_addr->sa_family) { - case AF_INET: -#ifdef HAVE_IPV6 - case AF_INET6: -#endif - switch (si->type) { - case SOCK_STREAM: - case SOCK_DGRAM: - break; - default: - errno = ESOCKTNOSUPPORT; - return -1; - } - if (alloc_sock) { - return convert_in_un_alloc(si, in_addr, out_addr, bcast); - } else { - return convert_in_un_remote(si, in_addr, out_addr, bcast); - } - default: - break; - } - - errno = EAFNOSUPPORT; - return -1; -} - -static int sockaddr_convert_from_un(const struct socket_info *si, - const struct sockaddr_un *in_addr, - socklen_t un_addrlen, - int family, - struct sockaddr *out_addr, - socklen_t *out_addrlen) -{ - if (out_addr == NULL || out_addrlen == NULL) - return 0; - - if (un_addrlen == 0) { - *out_addrlen = 0; - return 0; - } - - switch (family) { - case AF_INET: -#ifdef HAVE_IPV6 - case AF_INET6: -#endif - switch (si->type) { - case SOCK_STREAM: - case SOCK_DGRAM: - break; - default: - errno = ESOCKTNOSUPPORT; - return -1; - } - return convert_un_in(in_addr, out_addr, out_addrlen); - default: - break; - } - - errno = EAFNOSUPPORT; - return -1; -} - -enum swrap_packet_type { - SWRAP_CONNECT_SEND, - SWRAP_CONNECT_UNREACH, - SWRAP_CONNECT_RECV, - SWRAP_CONNECT_ACK, - SWRAP_ACCEPT_SEND, - SWRAP_ACCEPT_RECV, - SWRAP_ACCEPT_ACK, - SWRAP_RECVFROM, - SWRAP_SENDTO, - SWRAP_SENDTO_UNREACH, - SWRAP_PENDING_RST, - SWRAP_RECV, - SWRAP_RECV_RST, - SWRAP_SEND, - SWRAP_SEND_RST, - SWRAP_CLOSE_SEND, - SWRAP_CLOSE_RECV, - SWRAP_CLOSE_ACK -}; - -struct swrap_file_hdr { - uint32_t magic; - uint16_t version_major; - uint16_t version_minor; - int32_t timezone; - uint32_t sigfigs; - uint32_t frame_max_len; -#define SWRAP_FRAME_LENGTH_MAX 0xFFFF - uint32_t link_type; -}; -#define SWRAP_FILE_HDR_SIZE 24 - -struct swrap_packet { - struct { - uint32_t seconds; - uint32_t micro_seconds; - uint32_t recorded_length; - uint32_t full_length; - } frame; -#define SWRAP_PACKET__FRAME_SIZE 16 - - struct { - struct { - uint8_t ver_hdrlen; - uint8_t tos; - uint16_t packet_length; - uint16_t identification; - uint8_t flags; - uint8_t fragment; - uint8_t ttl; - uint8_t protocol; - uint16_t hdr_checksum; - uint32_t src_addr; - uint32_t dest_addr; - } hdr; -#define SWRAP_PACKET__IP_HDR_SIZE 20 - - union { - struct { - uint16_t source_port; - uint16_t dest_port; - uint32_t seq_num; - uint32_t ack_num; - uint8_t hdr_length; - uint8_t control; - uint16_t window; - uint16_t checksum; - uint16_t urg; - } tcp; -#define SWRAP_PACKET__IP_P_TCP_SIZE 20 - struct { - uint16_t source_port; - uint16_t dest_port; - uint16_t length; - uint16_t checksum; - } udp; -#define SWRAP_PACKET__IP_P_UDP_SIZE 8 - struct { - uint8_t type; - uint8_t code; - uint16_t checksum; - uint32_t unused; - } icmp; -#define SWRAP_PACKET__IP_P_ICMP_SIZE 8 - } p; - } ip; -}; -#define SWRAP_PACKET_SIZE 56 - -static const char *socket_wrapper_pcap_file(void) -{ - static int initialized = 0; - static const char *s = NULL; - static const struct swrap_file_hdr h = { 0, }; - static const struct swrap_packet p = { { 0, }, { { 0, }, { { 0, } } } }; - - if (initialized == 1) { - return s; - } - initialized = 1; - - /* - * TODO: don't use the structs use plain buffer offsets - * and PUSH_U8(), PUSH_U16() and PUSH_U32() - * - * for now make sure we disable PCAP support - * if the struct has alignment! - */ - if (sizeof(h) != SWRAP_FILE_HDR_SIZE) { - return NULL; - } - if (sizeof(p) != SWRAP_PACKET_SIZE) { - return NULL; - } - if (sizeof(p.frame) != SWRAP_PACKET__FRAME_SIZE) { - return NULL; - } - if (sizeof(p.ip.hdr) != SWRAP_PACKET__IP_HDR_SIZE) { - return NULL; - } - if (sizeof(p.ip.p.tcp) != SWRAP_PACKET__IP_P_TCP_SIZE) { - return NULL; - } - if (sizeof(p.ip.p.udp) != SWRAP_PACKET__IP_P_UDP_SIZE) { - return NULL; - } - if (sizeof(p.ip.p.icmp) != SWRAP_PACKET__IP_P_ICMP_SIZE) { - return NULL; - } - - s = getenv("SOCKET_WRAPPER_PCAP_FILE"); - if (s == NULL) { - return NULL; - } - if (strncmp(s, "./", 2) == 0) { - s += 2; - } - return s; -} - -static struct swrap_packet *swrap_packet_init(struct timeval *tval, - const struct sockaddr_in *src_addr, - const struct sockaddr_in *dest_addr, - int socket_type, - const unsigned char *payload, - size_t payload_len, - unsigned long tcp_seq, - unsigned long tcp_ack, - unsigned char tcp_ctl, - int unreachable, - size_t *_packet_len) -{ - struct swrap_packet *ret; - struct swrap_packet *packet; - size_t packet_len; - size_t alloc_len; - size_t nonwire_len = sizeof(packet->frame); - size_t wire_hdr_len = 0; - size_t wire_len = 0; - size_t icmp_hdr_len = 0; - size_t icmp_truncate_len = 0; - unsigned char protocol = 0, icmp_protocol = 0; - unsigned short src_port = src_addr->sin_port; - unsigned short dest_port = dest_addr->sin_port; - - switch (socket_type) { - case SOCK_STREAM: - protocol = 0x06; /* TCP */ - wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.tcp); - wire_len = wire_hdr_len + payload_len; - break; - - case SOCK_DGRAM: - protocol = 0x11; /* UDP */ - wire_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.udp); - wire_len = wire_hdr_len + payload_len; - break; - - default: - return NULL; - } - - if (unreachable) { - icmp_protocol = protocol; - protocol = 0x01; /* ICMP */ - if (wire_len > 64 ) { - icmp_truncate_len = wire_len - 64; - } - icmp_hdr_len = sizeof(packet->ip.hdr) + sizeof(packet->ip.p.icmp); - wire_hdr_len += icmp_hdr_len; - wire_len += icmp_hdr_len; - } - - packet_len = nonwire_len + wire_len; - alloc_len = packet_len; - if (alloc_len < sizeof(struct swrap_packet)) { - alloc_len = sizeof(struct swrap_packet); - } - ret = (struct swrap_packet *)malloc(alloc_len); - if (!ret) return NULL; - - packet = ret; - - packet->frame.seconds = tval->tv_sec; - packet->frame.micro_seconds = tval->tv_usec; - packet->frame.recorded_length = wire_len - icmp_truncate_len; - packet->frame.full_length = wire_len - icmp_truncate_len; - - packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ - packet->ip.hdr.tos = 0x00; - packet->ip.hdr.packet_length = htons(wire_len - icmp_truncate_len); - packet->ip.hdr.identification = htons(0xFFFF); - packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ - packet->ip.hdr.fragment = htons(0x0000); - packet->ip.hdr.ttl = 0xFF; - packet->ip.hdr.protocol = protocol; - packet->ip.hdr.hdr_checksum = htons(0x0000); - packet->ip.hdr.src_addr = src_addr->sin_addr.s_addr; - packet->ip.hdr.dest_addr = dest_addr->sin_addr.s_addr; - - if (unreachable) { - packet->ip.p.icmp.type = 0x03; /* destination unreachable */ - packet->ip.p.icmp.code = 0x01; /* host unreachable */ - packet->ip.p.icmp.checksum = htons(0x0000); - packet->ip.p.icmp.unused = htonl(0x00000000); - - /* set the ip header in the ICMP payload */ - packet = (struct swrap_packet *)(((unsigned char *)ret) + icmp_hdr_len); - packet->ip.hdr.ver_hdrlen = 0x45; /* version 4 and 5 * 32 bit words */ - packet->ip.hdr.tos = 0x00; - packet->ip.hdr.packet_length = htons(wire_len - icmp_hdr_len); - packet->ip.hdr.identification = htons(0xFFFF); - packet->ip.hdr.flags = 0x40; /* BIT 1 set - means don't fraqment */ - packet->ip.hdr.fragment = htons(0x0000); - packet->ip.hdr.ttl = 0xFF; - packet->ip.hdr.protocol = icmp_protocol; - packet->ip.hdr.hdr_checksum = htons(0x0000); - packet->ip.hdr.src_addr = dest_addr->sin_addr.s_addr; - packet->ip.hdr.dest_addr = src_addr->sin_addr.s_addr; - - src_port = dest_addr->sin_port; - dest_port = src_addr->sin_port; - } - - switch (socket_type) { - case SOCK_STREAM: - packet->ip.p.tcp.source_port = src_port; - packet->ip.p.tcp.dest_port = dest_port; - packet->ip.p.tcp.seq_num = htonl(tcp_seq); - packet->ip.p.tcp.ack_num = htonl(tcp_ack); - packet->ip.p.tcp.hdr_length = 0x50; /* 5 * 32 bit words */ - packet->ip.p.tcp.control = tcp_ctl; - packet->ip.p.tcp.window = htons(0x7FFF); - packet->ip.p.tcp.checksum = htons(0x0000); - packet->ip.p.tcp.urg = htons(0x0000); - - break; - - case SOCK_DGRAM: - packet->ip.p.udp.source_port = src_addr->sin_port; - packet->ip.p.udp.dest_port = dest_addr->sin_port; - packet->ip.p.udp.length = htons(8 + payload_len); - packet->ip.p.udp.checksum = htons(0x0000); - - break; - } - - if (payload && payload_len > 0) { - unsigned char *p = (unsigned char *)ret; - p += nonwire_len; - p += wire_hdr_len; - memcpy(p, payload, payload_len); - } - - *_packet_len = packet_len - icmp_truncate_len; - return ret; -} - -static int swrap_get_pcap_fd(const char *fname) -{ - static int fd = -1; - - if (fd != -1) return fd; - - fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0644); - if (fd != -1) { - struct swrap_file_hdr file_hdr; - file_hdr.magic = 0xA1B2C3D4; - file_hdr.version_major = 0x0002; - file_hdr.version_minor = 0x0004; - file_hdr.timezone = 0x00000000; - file_hdr.sigfigs = 0x00000000; - file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX; - file_hdr.link_type = 0x0065; /* 101 RAW IP */ - - write(fd, &file_hdr, sizeof(file_hdr)); - return fd; - } - - fd = open(fname, O_WRONLY|O_APPEND, 0644); - - return fd; -} - -static struct swrap_packet *swrap_marshall_packet(struct socket_info *si, - const struct sockaddr *addr, - enum swrap_packet_type type, - const void *buf, size_t len, - size_t *packet_len) -{ - const struct sockaddr_in *src_addr; - const struct sockaddr_in *dest_addr; - unsigned long tcp_seq = 0; - unsigned long tcp_ack = 0; - unsigned char tcp_ctl = 0; - int unreachable = 0; - - struct timeval tv; - - switch (si->family) { - case AF_INET: - break; - default: - return NULL; - } - - switch (type) { - case SWRAP_CONNECT_SEND: - if (si->type != SOCK_STREAM) return NULL; - - src_addr = (const struct sockaddr_in *)si->myname; - dest_addr = (const struct sockaddr_in *)addr; - - tcp_seq = si->io.pck_snd; - tcp_ack = si->io.pck_rcv; - tcp_ctl = 0x02; /* SYN */ - - si->io.pck_snd += 1; - - break; - - case SWRAP_CONNECT_RECV: - if (si->type != SOCK_STREAM) return NULL; - - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)addr; - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x12; /** SYN,ACK */ - - si->io.pck_rcv += 1; - - break; - - case SWRAP_CONNECT_UNREACH: - if (si->type != SOCK_STREAM) return NULL; - - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)addr; - - /* Unreachable: resend the data of SWRAP_CONNECT_SEND */ - tcp_seq = si->io.pck_snd - 1; - tcp_ack = si->io.pck_rcv; - tcp_ctl = 0x02; /* SYN */ - unreachable = 1; - - break; - - case SWRAP_CONNECT_ACK: - if (si->type != SOCK_STREAM) return NULL; - - src_addr = (const struct sockaddr_in *)si->myname; - dest_addr = (const struct sockaddr_in *)addr; - - tcp_seq = si->io.pck_snd; - tcp_ack = si->io.pck_rcv; - tcp_ctl = 0x10; /* ACK */ - - break; - - case SWRAP_ACCEPT_SEND: - if (si->type != SOCK_STREAM) return NULL; - - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)addr; - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x02; /* SYN */ - - si->io.pck_rcv += 1; - - break; - - case SWRAP_ACCEPT_RECV: - if (si->type != SOCK_STREAM) return NULL; - - src_addr = (const struct sockaddr_in *)si->myname; - dest_addr = (const struct sockaddr_in *)addr; - - tcp_seq = si->io.pck_snd; - tcp_ack = si->io.pck_rcv; - tcp_ctl = 0x12; /* SYN,ACK */ - - si->io.pck_snd += 1; - - break; - - case SWRAP_ACCEPT_ACK: - if (si->type != SOCK_STREAM) return NULL; - - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)addr; - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x10; /* ACK */ - - break; - - case SWRAP_SEND: - src_addr = (const struct sockaddr_in *)si->myname; - dest_addr = (const struct sockaddr_in *)si->peername; - - tcp_seq = si->io.pck_snd; - tcp_ack = si->io.pck_rcv; - tcp_ctl = 0x18; /* PSH,ACK */ - - si->io.pck_snd += len; - - break; - - case SWRAP_SEND_RST: - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)si->peername; - - if (si->type == SOCK_DGRAM) { - return swrap_marshall_packet(si, si->peername, - SWRAP_SENDTO_UNREACH, - buf, len, packet_len); - } - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x14; /** RST,ACK */ - - break; - - case SWRAP_PENDING_RST: - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)si->peername; - - if (si->type == SOCK_DGRAM) { - return NULL; - } - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x14; /* RST,ACK */ - - break; - - case SWRAP_RECV: - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)si->peername; - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x18; /* PSH,ACK */ - - si->io.pck_rcv += len; - - break; - - case SWRAP_RECV_RST: - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)si->peername; - - if (si->type == SOCK_DGRAM) { - return NULL; - } - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x14; /* RST,ACK */ - - break; - - case SWRAP_SENDTO: - src_addr = (const struct sockaddr_in *)si->myname; - dest_addr = (const struct sockaddr_in *)addr; - - si->io.pck_snd += len; - - break; - - case SWRAP_SENDTO_UNREACH: - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)addr; - - unreachable = 1; - - break; - - case SWRAP_RECVFROM: - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)addr; - - si->io.pck_rcv += len; - - break; - - case SWRAP_CLOSE_SEND: - if (si->type != SOCK_STREAM) return NULL; - - src_addr = (const struct sockaddr_in *)si->myname; - dest_addr = (const struct sockaddr_in *)si->peername; - - tcp_seq = si->io.pck_snd; - tcp_ack = si->io.pck_rcv; - tcp_ctl = 0x11; /* FIN, ACK */ - - si->io.pck_snd += 1; - - break; - - case SWRAP_CLOSE_RECV: - if (si->type != SOCK_STREAM) return NULL; - - dest_addr = (const struct sockaddr_in *)si->myname; - src_addr = (const struct sockaddr_in *)si->peername; - - tcp_seq = si->io.pck_rcv; - tcp_ack = si->io.pck_snd; - tcp_ctl = 0x11; /* FIN,ACK */ - - si->io.pck_rcv += 1; - - break; - - case SWRAP_CLOSE_ACK: - if (si->type != SOCK_STREAM) return NULL; - - src_addr = (const struct sockaddr_in *)si->myname; - dest_addr = (const struct sockaddr_in *)si->peername; - - tcp_seq = si->io.pck_snd; - tcp_ack = si->io.pck_rcv; - tcp_ctl = 0x10; /* ACK */ - - break; - default: - return NULL; - } - - swrapGetTimeOfDay(&tv); - - return swrap_packet_init(&tv, src_addr, dest_addr, si->type, - (const unsigned char *)buf, len, - tcp_seq, tcp_ack, tcp_ctl, unreachable, - packet_len); -} - -static void swrap_dump_packet(struct socket_info *si, - const struct sockaddr *addr, - enum swrap_packet_type type, - const void *buf, size_t len) -{ - const char *file_name; - struct swrap_packet *packet; - size_t packet_len = 0; - int fd; - - file_name = socket_wrapper_pcap_file(); - if (!file_name) { - return; - } - - packet = swrap_marshall_packet(si, addr, type, buf, len, &packet_len); - if (!packet) { - return; - } - - fd = swrap_get_pcap_fd(file_name); - if (fd != -1) { - write(fd, packet, packet_len); - } - - free(packet); -} - -_PUBLIC_ int swrap_socket(int family, int type, int protocol) -{ - struct socket_info *si; - int fd; - - if (!socket_wrapper_dir()) { - return real_socket(family, type, protocol); - } - - switch (family) { - case AF_INET: -#ifdef HAVE_IPV6 - case AF_INET6: -#endif - break; - case AF_UNIX: - return real_socket(family, type, protocol); - default: - errno = EAFNOSUPPORT; - return -1; - } - - switch (type) { - case SOCK_STREAM: - break; - case SOCK_DGRAM: - break; - default: - errno = EPROTONOSUPPORT; - return -1; - } - - switch (protocol) { - case 0: - break; - case 6: - if (type == SOCK_STREAM) { - break; - } - /*fall through*/ - case 17: - if (type == SOCK_DGRAM) { - break; - } - /*fall through*/ - default: - errno = EPROTONOSUPPORT; - return -1; - } - - fd = real_socket(AF_UNIX, type, 0); - - if (fd == -1) return -1; - - si = (struct socket_info *)calloc(1, sizeof(struct socket_info)); - - si->family = family; - si->type = type; - si->protocol = protocol; - si->fd = fd; - - SWRAP_DLIST_ADD(sockets, si); - - return si->fd; -} - -_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - struct socket_info *parent_si, *child_si; - int fd; - struct sockaddr_un un_addr; - socklen_t un_addrlen = sizeof(un_addr); - struct sockaddr_un un_my_addr; - socklen_t un_my_addrlen = sizeof(un_my_addr); - struct sockaddr *my_addr; - socklen_t my_addrlen, len; - int ret; - - parent_si = find_socket_info(s); - if (!parent_si) { - return real_accept(s, addr, addrlen); - } - - /* - * assume out sockaddr have the same size as the in parent - * socket family - */ - my_addrlen = socket_length(parent_si->family); - if (my_addrlen <= 0) { - errno = EINVAL; - return -1; - } - - my_addr = (struct sockaddr *)malloc(my_addrlen); - if (my_addr == NULL) { - return -1; - } - - memset(&un_addr, 0, sizeof(un_addr)); - memset(&un_my_addr, 0, sizeof(un_my_addr)); - - ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); - if (ret == -1) { - free(my_addr); - return ret; - } - - fd = ret; - - len = my_addrlen; - ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen, - parent_si->family, my_addr, &len); - if (ret == -1) { - free(my_addr); - close(fd); - return ret; - } - - child_si = (struct socket_info *)malloc(sizeof(struct socket_info)); - memset(child_si, 0, sizeof(*child_si)); - - child_si->fd = fd; - child_si->family = parent_si->family; - child_si->type = parent_si->type; - child_si->protocol = parent_si->protocol; - child_si->bound = 1; - child_si->is_server = 1; - - child_si->peername_len = len; - child_si->peername = sockaddr_dup(my_addr, len); - - if (addr != NULL && addrlen != NULL) { - *addrlen = len; - if (*addrlen >= len) - memcpy(addr, my_addr, len); - *addrlen = 0; - } - - ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen); - if (ret == -1) { - free(child_si); - close(fd); - return ret; - } - - len = my_addrlen; - ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen, - child_si->family, my_addr, &len); - if (ret == -1) { - free(child_si); - free(my_addr); - close(fd); - return ret; - } - - child_si->myname_len = len; - child_si->myname = sockaddr_dup(my_addr, len); - free(my_addr); - - SWRAP_DLIST_ADD(sockets, child_si); - - swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0); - swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0); - swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0); - - return fd; -} - -static int autobind_start_init; -static int autobind_start; - -/* using sendto() or connect() on an unbound socket would give the - recipient no way to reply, as unlike UDP and TCP, a unix domain - socket can't auto-assign emphemeral port numbers, so we need to - assign it here */ -static int swrap_auto_bind(struct socket_info *si) -{ - struct sockaddr_un un_addr; - int i; - char type; - int ret; - int port; - struct stat st; - - if (autobind_start_init != 1) { - autobind_start_init = 1; - autobind_start = getpid(); - autobind_start %= 50000; - autobind_start += 10000; - } - - un_addr.sun_family = AF_UNIX; - - switch (si->family) { - case AF_INET: { - struct sockaddr_in in; - - switch (si->type) { - case SOCK_STREAM: - type = SOCKET_TYPE_CHAR_TCP; - break; - case SOCK_DGRAM: - type = SOCKET_TYPE_CHAR_UDP; - break; - default: - errno = ESOCKTNOSUPPORT; - return -1; - } - - memset(&in, 0, sizeof(in)); - in.sin_family = AF_INET; - in.sin_addr.s_addr = htonl(127<<24 | - socket_wrapper_default_iface()); - - si->myname_len = sizeof(in); - si->myname = sockaddr_dup(&in, si->myname_len); - break; - } -#ifdef HAVE_IPV6 - case AF_INET6: { - struct sockaddr_in6 in6; - - switch (si->type) { - case SOCK_STREAM: - type = SOCKET_TYPE_CHAR_TCP_V6; - break; - case SOCK_DGRAM: - type = SOCKET_TYPE_CHAR_UDP_V6; - break; - default: - errno = ESOCKTNOSUPPORT; - return -1; - } - - memset(&in6, 0, sizeof(in6)); - in6.sin6_family = AF_INET6; - in6.sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS; - si->myname_len = sizeof(in6); - si->myname = sockaddr_dup(&in6, si->myname_len); - break; - } -#endif - default: - errno = ESOCKTNOSUPPORT; - return -1; - } - - if (autobind_start > 60000) { - autobind_start = 10000; - } - - for (i=0;i<1000;i++) { - port = autobind_start + i; - snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), - "%s/"SOCKET_FORMAT, socket_wrapper_dir(), - type, socket_wrapper_default_iface(), port); - if (stat(un_addr.sun_path, &st) == 0) continue; - - ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)); - if (ret == -1) return ret; - - si->tmp_path = strdup(un_addr.sun_path); - si->bound = 1; - autobind_start = port + 1; - break; - } - if (i == 1000) { - errno = ENFILE; - return -1; - } - - set_port(si->family, port, si->myname); - - return 0; -} - - -_PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen) -{ - int ret; - struct sockaddr_un un_addr; - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_connect(s, serv_addr, addrlen); - } - - if (si->bound == 0) { - ret = swrap_auto_bind(si); - if (ret == -1) return -1; - } - - if (si->family != serv_addr->sa_family) { - errno = EINVAL; - return -1; - } - - ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); - if (ret == -1) return -1; - - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); - - ret = real_connect(s, (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); - - /* to give better errors */ - if (ret == -1 && errno == ENOENT) { - errno = EHOSTUNREACH; - } - - if (ret == 0) { - si->peername_len = addrlen; - si->peername = sockaddr_dup(serv_addr, addrlen); - - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_RECV, NULL, 0); - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_ACK, NULL, 0); - } else { - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_UNREACH, NULL, 0); - } - - return ret; -} - -_PUBLIC_ int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) -{ - int ret; - struct sockaddr_un un_addr; - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_bind(s, myaddr, addrlen); - } - - si->myname_len = addrlen; - si->myname = sockaddr_dup(myaddr, addrlen); - - ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast); - if (ret == -1) return -1; - - unlink(un_addr.sun_path); - - ret = real_bind(s, (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); - - if (ret == 0) { - si->bound = 1; - } - - return ret; -} - -_PUBLIC_ int swrap_listen(int s, int backlog) -{ - int ret; - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_listen(s, backlog); - } - - ret = real_listen(s, backlog); - - return ret; -} - -_PUBLIC_ int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen) -{ - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_getpeername(s, name, addrlen); - } - - if (!si->peername) - { - errno = ENOTCONN; - return -1; - } - - memcpy(name, si->peername, si->peername_len); - *addrlen = si->peername_len; - - return 0; -} - -_PUBLIC_ int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen) -{ - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_getsockname(s, name, addrlen); - } - - memcpy(name, si->myname, si->myname_len); - *addrlen = si->myname_len; - - return 0; -} - -_PUBLIC_ int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_getsockopt(s, level, optname, optval, optlen); - } - - if (level == SOL_SOCKET) { - return real_getsockopt(s, level, optname, optval, optlen); - } - - errno = ENOPROTOOPT; - return -1; -} - -_PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_setsockopt(s, level, optname, optval, optlen); - } - - if (level == SOL_SOCKET) { - return real_setsockopt(s, level, optname, optval, optlen); - } - - switch (si->family) { - case AF_INET: - return 0; - default: - errno = ENOPROTOOPT; - return -1; - } -} - -_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) -{ - struct sockaddr_un un_addr; - socklen_t un_addrlen = sizeof(un_addr); - int ret; - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_recvfrom(s, buf, len, flags, from, fromlen); - } - - len = MIN(len, 1500); - - /* irix 6.4 forgets to null terminate the sun_path string :-( */ - memset(&un_addr, 0, sizeof(un_addr)); - ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); - if (ret == -1) - return ret; - - if (sockaddr_convert_from_un(si, &un_addr, un_addrlen, - si->family, from, fromlen) == -1) { - return -1; - } - - swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret); - - return ret; -} - - -_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) -{ - struct sockaddr_un un_addr; - int ret; - struct socket_info *si = find_socket_info(s); - int bcast = 0; - - if (!si) { - return real_sendto(s, buf, len, flags, to, tolen); - } - - len = MIN(len, 1500); - - switch (si->type) { - case SOCK_STREAM: - ret = real_send(s, buf, len, flags); - break; - case SOCK_DGRAM: - if (si->bound == 0) { - ret = swrap_auto_bind(si); - if (ret == -1) return -1; - } - - ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast); - if (ret == -1) return -1; - - if (bcast) { - struct stat st; - unsigned int iface; - unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port); - char type; - - type = SOCKET_TYPE_CHAR_UDP; - - for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { - snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); - if (stat(un_addr.sun_path, &st) != 0) continue; - - /* ignore the any errors in broadcast sends */ - real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); - } - - swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); - - return len; - } - - ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); - break; - default: - ret = -1; - errno = EHOSTUNREACH; - break; - } - - /* to give better errors */ - if (ret == -1 && errno == ENOENT) { - errno = EHOSTUNREACH; - } - - if (ret == -1) { - swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len); - swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len); - } else { - swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret); - } - - return ret; -} - -_PUBLIC_ int swrap_ioctl(int s, int r, void *p) -{ - int ret; - struct socket_info *si = find_socket_info(s); - int value; - - if (!si) { - return real_ioctl(s, r, p); - } - - ret = real_ioctl(s, r, p); - - switch (r) { - case FIONREAD: - value = *((int *)p); - if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { - swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); - } else if (value == 0) { /* END OF FILE */ - swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0); - } - break; - } - - return ret; -} - -_PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) -{ - int ret; - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_recv(s, buf, len, flags); - } - - len = MIN(len, 1500); - - ret = real_recv(s, buf, len, flags); - if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { - swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); - } else if (ret == 0) { /* END OF FILE */ - swrap_dump_packet(si, NULL, SWRAP_RECV_RST, NULL, 0); - } else { - swrap_dump_packet(si, NULL, SWRAP_RECV, buf, ret); - } - - return ret; -} - - -_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) -{ - int ret; - struct socket_info *si = find_socket_info(s); - - if (!si) { - return real_send(s, buf, len, flags); - } - - len = MIN(len, 1500); - - ret = real_send(s, buf, len, flags); - - if (ret == -1) { - swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len); - swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0); - } else { - swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret); - } - - return ret; -} - -_PUBLIC_ int swrap_close(int fd) -{ - struct socket_info *si = find_socket_info(fd); - int ret; - - if (!si) { - return real_close(fd); - } - - SWRAP_DLIST_REMOVE(sockets, si); - - if (si->myname && si->peername) { - swrap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0); - } - - ret = real_close(fd); - - if (si->myname && si->peername) { - swrap_dump_packet(si, NULL, SWRAP_CLOSE_RECV, NULL, 0); - swrap_dump_packet(si, NULL, SWRAP_CLOSE_ACK, NULL, 0); - } - - if (si->path) free(si->path); - if (si->myname) free(si->myname); - if (si->peername) free(si->peername); - if (si->tmp_path) { - unlink(si->tmp_path); - free(si->tmp_path); - } - free(si); - - return ret; -} diff --git a/socket_wrapper/socket_wrapper.h b/socket_wrapper/socket_wrapper.h deleted file mode 100644 index cc8b937608..0000000000 --- a/socket_wrapper/socket_wrapper.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) Jelmer Vernooij 2005 - * Copyright (C) Stefan Metzmacher 2006 - * - * 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. Neither the name of the author 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 AUTHOR 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 AUTHOR 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. - * - */ - -#ifndef __SOCKET_WRAPPER_H__ -#define __SOCKET_WRAPPER_H__ - -const char *socket_wrapper_dir(void); -unsigned int socket_wrapper_default_iface(void); -int swrap_socket(int family, int type, int protocol); -int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); -int swrap_bind(int s, const struct sockaddr *myaddr, socklen_t addrlen); -int swrap_listen(int s, int backlog); -int swrap_getpeername(int s, struct sockaddr *name, socklen_t *addrlen); -int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen); -int swrap_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); -int swrap_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); -ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); -ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); -int swrap_ioctl(int s, int req, void *ptr); -ssize_t swrap_recv(int s, void *buf, size_t len, int flags); -ssize_t swrap_send(int s, const void *buf, size_t len, int flags); -int swrap_close(int); - -#ifdef SOCKET_WRAPPER_REPLACE - -#ifdef accept -#undef accept -#endif -#define accept(s,addr,addrlen) swrap_accept(s,addr,addrlen) - -#ifdef connect -#undef connect -#endif -#define connect(s,serv_addr,addrlen) swrap_connect(s,serv_addr,addrlen) - -#ifdef bind -#undef bind -#endif -#define bind(s,myaddr,addrlen) swrap_bind(s,myaddr,addrlen) - -#ifdef listen -#undef listen -#endif -#define listen(s,blog) swrap_listen(s,blog) - -#ifdef getpeername -#undef getpeername -#endif -#define getpeername(s,name,addrlen) swrap_getpeername(s,name,addrlen) - -#ifdef getsockname -#undef getsockname -#endif -#define getsockname(s,name,addrlen) swrap_getsockname(s,name,addrlen) - -#ifdef getsockopt -#undef getsockopt -#endif -#define getsockopt(s,level,optname,optval,optlen) swrap_getsockopt(s,level,optname,optval,optlen) - -#ifdef setsockopt -#undef setsockopt -#endif -#define setsockopt(s,level,optname,optval,optlen) swrap_setsockopt(s,level,optname,optval,optlen) - -#ifdef recvfrom -#undef recvfrom -#endif -#define recvfrom(s,buf,len,flags,from,fromlen) swrap_recvfrom(s,buf,len,flags,from,fromlen) - -#ifdef sendto -#undef sendto -#endif -#define sendto(s,buf,len,flags,to,tolen) swrap_sendto(s,buf,len,flags,to,tolen) - -#ifdef ioctl -#undef ioctl -#endif -#define ioctl(s,req,ptr) swrap_ioctl(s,req,ptr) - -#ifdef recv -#undef recv -#endif -#define recv(s,buf,len,flags) swrap_recv(s,buf,len,flags) - -#ifdef send -#undef send -#endif -#define send(s,buf,len,flags) swrap_send(s,buf,len,flags) - -#ifdef socket -#undef socket -#endif -#define socket(domain,type,protocol) swrap_socket(domain,type,protocol) - -#ifdef close -#undef close -#endif -#define close(s) swrap_close(s) -#endif - - -#endif /* __SOCKET_WRAPPER_H__ */ diff --git a/socket_wrapper/testsuite.c b/socket_wrapper/testsuite.c deleted file mode 100644 index e6e08e3be6..0000000000 --- a/socket_wrapper/testsuite.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - local testing of the socket wrapper - - Copyright (C) Jelmer Vernooij 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "system/network.h" -#include "../socket_wrapper/socket_wrapper.h" -#include "torture/torture.h" - -static char *old_dir = NULL; -static char *old_iface = NULL; - -static void backup_env(void) -{ - old_dir = getenv("SOCKET_WRAPPER_DIR"); - old_iface = getenv("SOCKET_WRAPPER_DEFAULT_IFACE"); -} - -static void restore_env(void) -{ - if (old_dir == NULL) - unsetenv("SOCKET_WRAPPER_DIR"); - else - setenv("SOCKET_WRAPPER_DIR", old_dir, 1); - if (old_iface == NULL) - unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE"); - else - setenv("SOCKET_WRAPPER_DEFAULT_IFACE", old_iface, 1); -} - -static bool test_socket_wrapper_dir(struct torture_context *tctx) -{ - backup_env(); - - setenv("SOCKET_WRAPPER_DIR", "foo", 1); - torture_assert_str_equal(tctx, socket_wrapper_dir(), "foo", "setting failed"); - setenv("SOCKET_WRAPPER_DIR", "./foo", 1); - torture_assert_str_equal(tctx, socket_wrapper_dir(), "foo", "setting failed"); - unsetenv("SOCKET_WRAPPER_DIR"); - torture_assert_str_equal(tctx, socket_wrapper_dir(), NULL, "resetting failed"); - - restore_env(); - - return true; -} - -static bool test_swrap_socket(struct torture_context *tctx) -{ - backup_env(); - setenv("SOCKET_WRAPPER_DIR", "foo", 1); - - torture_assert_int_equal(tctx, swrap_socket(1337, 1337, 0), -1, "unknown address family fails"); - torture_assert_int_equal(tctx, errno, EAFNOSUPPORT, "correct errno set"); - torture_assert_int_equal(tctx, swrap_socket(AF_INET, 1337, 0), -1, "unknown type fails"); - torture_assert_int_equal(tctx, errno, EPROTONOSUPPORT, "correct errno set"); - torture_assert_int_equal(tctx, swrap_socket(AF_INET, SOCK_DGRAM, 10), -1, "unknown protocol fails"); - torture_assert_int_equal(tctx, errno, EPROTONOSUPPORT, "correct errno set"); - - restore_env(); - - return true; -} - -unsigned int socket_wrapper_default_iface(void); -static bool test_socket_wrapper_default_iface(struct torture_context *tctx) -{ - backup_env(); - unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE"); - torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset"); - setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "2", 1); - torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 2, "unset"); - setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "bla", 1); - torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset"); - restore_env(); - return true; -} - -struct torture_suite *torture_local_socket_wrapper(TALLOC_CTX *mem_ctx) -{ - struct torture_suite *suite = torture_suite_create(mem_ctx, - "SOCKET-WRAPPER"); - - torture_suite_add_simple_test(suite, "socket_wrapper_dir", test_socket_wrapper_dir); - torture_suite_add_simple_test(suite, "socket", test_swrap_socket); - torture_suite_add_simple_test(suite, "socket_wrapper_default_iface", test_socket_wrapper_default_iface); - - return suite; -} diff --git a/source3/Makefile.in b/source3/Makefile.in index d4a4914825..032efd53a3 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -249,7 +249,7 @@ LIBNDR_DRSUAPI_OBJ = librpc/ndr/ndr_drsuapi.o \ librpc/gen_ndr/ndr_drsuapi.o \ librpc/gen_ndr/ndr_drsblobs.o -COMPRESSION_OBJ = ../compression/mszip.o +COMPRESSION_OBJ = ../lib/compression/mszip.o DRSUAPI_OBJ = $(LIBNDR_DRSUAPI_OBJ) \ $(COMPRESSION_OBJ) diff --git a/source3/autogen.sh b/source3/autogen.sh index e27e817d61..deed774b39 100755 --- a/source3/autogen.sh +++ b/source3/autogen.sh @@ -53,7 +53,7 @@ echo "$0: running script/mkversion.sh" rm -rf autom4te*.cache rm -f configure include/config.h* -IPATHS="-Im4 -I../replace -I../source4" +IPATHS="-Im4 -I../lib/replace -I../source4" echo "$0: running $AUTOHEADER $IPATHS" $AUTOHEADER $IPATHS || exit 1 diff --git a/source3/configure.in b/source3/configure.in index fd0ea4361a..294092e721 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -23,7 +23,7 @@ m4_include(m4/check_path.m4) AC_LIBREPLACE_CC_CHECKS -m4_include(../talloc/libtalloc.m4) +m4_include(../lib/talloc/libtalloc.m4) LIBTALLOC_OBJ0="" for obj in ${TALLOC_OBJ}; do @@ -33,7 +33,7 @@ AC_SUBST(LIBTALLOC_OBJ0) # TODO: These should come from m4_include(lib/tdb/libtdb.m4) # but currently this fails: things have to get merged from s4. -tdbdir="../tdb" +tdbdir="../lib/tdb" AC_SUBST(tdbdir) TDB_CFLAGS="-I${srcdir-.}/$tdbdir/include" AC_SUBST(TDB_CFLAGS) @@ -48,13 +48,13 @@ done AC_SUBST(LIBTDB_OBJ0) SAMBA_CPPFLAGS="-Iinclude -I${srcdir-.}/include -I. -I${srcdir-.}" -SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../replace" +SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../lib/replace" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TALLOC_CFLAGS}" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TDB_CFLAGS}" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/libaddns" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/librpc" -SAMBA_CONFIGURE_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../popt" +SAMBA_CONFIGURE_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../lib/popt" ## cleanup the $(srcdir) in the Makefile if we are outside of the tree if test "x${srcdir-.}" != "x."; then @@ -131,8 +131,8 @@ else CFLAGS="-O" fi -m4_include(../socket_wrapper/config.m4) -m4_include(../nss_wrapper/config.m4) +m4_include(../lib/socket_wrapper/config.m4) +m4_include(../lib/nss_wrapper/config.m4) m4_include(m4/swat.m4) @@ -5872,7 +5872,7 @@ if test x"$INCLUDED_POPT" = x"yes"; then AC_MSG_RESULT(yes) BUILD_POPT='$(POPT_OBJ)' POPTLIBS='$(POPT_OBJ)' - FLAGS1="-I\$(srcdir)/../popt" + FLAGS1="-I\$(srcdir)/../lib/popt" else AC_MSG_RESULT(no) BUILD_POPT="" diff --git a/source3/m4/aclocal.m4 b/source3/m4/aclocal.m4 index beeabbba78..aae729c825 100644 --- a/source3/m4/aclocal.m4 +++ b/source3/m4/aclocal.m4 @@ -886,4 +886,4 @@ int main(void) ]) ]) -m4_include(../replace/libreplace.m4) +m4_include(../lib/replace/libreplace.m4) diff --git a/source3/samba4.m4 b/source3/samba4.m4 index 19d3cc141b..8ac9372ff3 100644 --- a/source3/samba4.m4 +++ b/source3/samba4.m4 @@ -31,19 +31,19 @@ AC_CONFIG_FILES(../source4/librpc/dcerpc_atsvc.pc) SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, [], [ - SMB_INCLUDE_MK(../talloc/config.mk) + SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.0, [], [ - m4_include(../tdb/libtdb.m4) - SMB_INCLUDE_MK(../tdb/config.mk) + m4_include(../lib/tdb/libtdb.m4) + SMB_INCLUDE_MK(../lib/tdb/config.mk) ] ) -SMB_INCLUDE_MK(../tdb/python.mk) +SMB_INCLUDE_MK(../lib/tdb/python.mk) SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1, [ diff --git a/source4/Makefile b/source4/Makefile index 04f0ae9457..91390d833f 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -62,7 +62,7 @@ libsrcdir := lib libsocketsrcdir := lib/socket libcharsetsrcdir := lib/charset ldb_sambasrcdir := lib/ldb-samba -tdbsrcdir := ../tdb +tdbsrcdir := ../lib/tdb ldbsrcdir := lib/ldb libtlssrcdir := lib/tls libregistrysrcdir := lib/registry @@ -70,9 +70,9 @@ smbreadlinesrcdir := lib/smbreadline libmessagingsrcdir := lib/messaging libeventssrcdir := lib/events libcmdlinesrcdir := lib/cmdline -poptsrcdir := ../popt -socketwrappersrcdir := ../socket_wrapper -nsswrappersrcdir := ../nss_wrapper +poptsrcdir := ../lib/popt +socketwrappersrcdir := ../lib/socket_wrapper +nsswrappersrcdir := ../lib/nss_wrapper appwebsrcdir := lib/appweb libstreamsrcdir := lib/stream libutilsrcdir := lib/util @@ -81,7 +81,7 @@ libdbwrapsrcdir := lib/dbwrap libcryptosrcdir := lib/crypto libtorturesrcdir := lib/torture smb_serversrcdir := smb_server -libcompressionsrcdir := ../compression +libcompressionsrcdir := ../lib/compression libgencachesrcdir := lib paramsrcdir := param rpc_serversrcdir := rpc_server @@ -103,7 +103,7 @@ pyscriptsrcdir := $(srcdir)/scripting/python kdcsrcdir := kdc ntp_signdsrcdir := ntp_signd wmisrcdir := lib/wmi -tallocsrcdir := ../talloc +tallocsrcdir := ../lib/talloc include data.mk diff --git a/source4/aclocal.m4 b/source4/aclocal.m4 index 0e75fa51f5..240a994f9d 100644 --- a/source4/aclocal.m4 +++ b/source4/aclocal.m4 @@ -53,7 +53,7 @@ AC_DEFUN(LIB_REMOVE_USR_LIB,[ $1=[$]ac_new_flags ]) -m4_include(../replace/libreplace.m4) +m4_include(../lib/replace/libreplace.m4) m4_include(build/m4/ax_cflags_gcc_option.m4) m4_include(build/m4/ax_cflags_irix_option.m4) m4_include(build/m4/public.m4) diff --git a/source4/autogen.sh b/source4/autogen.sh index 89f5abeb96..a56c5a2238 100755 --- a/source4/autogen.sh +++ b/source4/autogen.sh @@ -53,7 +53,7 @@ echo "$0: running script/mkversion.sh" rm -rf autom4te*.cache rm -f configure include/config_tmp.h* -IPATHS="-I. -I../replace" +IPATHS="-I. -I../lib/replace" echo "$0: running $AUTOHEADER $IPATHS" $AUTOHEADER $IPATHS || exit 1 diff --git a/source4/configure.ac b/source4/configure.ac index 357121a43b..099da400e7 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -11,7 +11,7 @@ AC_DEFINE(CONFIG_H_IS_FROM_SAMBA,1,[Marker for samba's config.h]) # Configuration rules. m4_include(build/m4/env.m4) -m4_include(../replace/samba.m4) +m4_include(../lib/replace/samba.m4) m4_include(lib/smbreadline/readline.m4) m4_include(heimdal_build/config.m4) m4_include(lib/util/fault.m4) @@ -21,7 +21,7 @@ m4_include(lib/util/fsusage.m4) m4_include(lib/util/xattr.m4) m4_include(lib/util/capability.m4) m4_include(lib/util/time.m4) -m4_include(../popt/samba.m4) +m4_include(../lib/popt/samba.m4) m4_include(lib/charset/config.m4) m4_include(lib/socket/config.m4) m4_include(lib/zlib.m4) @@ -41,20 +41,20 @@ AC_CONFIG_FILES(librpc/dcerpc_atsvc.pc) SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, [], [ - m4_include(../talloc/libtalloc.m4) - SMB_INCLUDE_MK(../talloc/config.mk) + m4_include(../lib/talloc/libtalloc.m4) + SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.0, [], [ - m4_include(../tdb/libtdb.m4) - SMB_INCLUDE_MK(../tdb/config.mk) + m4_include(../lib/tdb/libtdb.m4) + SMB_INCLUDE_MK(../lib/tdb/config.mk) ] ) -SMB_INCLUDE_MK(../tdb/python.mk) +SMB_INCLUDE_MK(../lib/tdb/python.mk) SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1, [ @@ -99,8 +99,8 @@ m4_include(auth/gensec/config.m4) m4_include(smbd/process_model.m4) m4_include(ntvfs/posix/config.m4) m4_include(ntvfs/unixuid/config.m4) -m4_include(../socket_wrapper/config.m4) -m4_include(../nss_wrapper/config.m4) +m4_include(../lib/socket_wrapper/config.m4) +m4_include(../lib/nss_wrapper/config.m4) m4_include(auth/config.m4) m4_include(kdc/config.m4) m4_include(ntvfs/sysdep/config.m4) @@ -159,7 +159,7 @@ then builddir_headers="-I\$(builddir)/include -I\$(builddir) -I\$(builddir)/lib "; fi -CPPFLAGS="$builddir_headers-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -I\$(srcdir)/../replace -I\$(srcdir)/../talloc -D_SAMBA_BUILD_=4 -DHAVE_CONFIG_H $CPPFLAGS" +CPPFLAGS="$builddir_headers-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -I\$(srcdir)/../lib/replace -I\$(srcdir)/../lib/talloc -D_SAMBA_BUILD_=4 -DHAVE_CONFIG_H $CPPFLAGS" SMB_WRITE_PERLVARS(build/smb_build/config.pm) diff --git a/source4/librpc/ndr/ndr_compression.c b/source4/librpc/ndr/ndr_compression.c index 92c5b049df..05a80e20b2 100644 --- a/source4/librpc/ndr/ndr_compression.c +++ b/source4/librpc/ndr/ndr_compression.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "lib/compression/lzxpress.h" +#include "../lib/compression/lzxpress.h" #include "librpc/ndr/libndr.h" #include "librpc/ndr/ndr_compression.h" #include diff --git a/source4/main.mk b/source4/main.mk index 5ab9f95c05..ddeb4baf2e 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -16,8 +16,8 @@ mkinclude lib/registry/config.mk mkinclude lib/messaging/config.mk mkinclude lib/events/config.mk mkinclude lib/cmdline/config.mk -mkinclude ../socket_wrapper/config.mk -mkinclude ../nss_wrapper/config.mk +mkinclude ../lib/socket_wrapper/config.mk +mkinclude ../lib/nss_wrapper/config.mk mkinclude lib/appweb/config.mk mkinclude lib/stream/config.mk mkinclude lib/util/config.mk diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk index 54cbdae837..4cd9f6c865 100644 --- a/source4/torture/local/config.mk +++ b/source4/torture/local/config.mk @@ -20,23 +20,23 @@ PRIVATE_DEPENDENCIES = \ TORTURE_LOCAL_OBJ_FILES = \ $(torturesrcdir)/../lib/charset/tests/iconv.o \ - $(torturesrcdir)/../../talloc/testsuite.o \ - $(torturesrcdir)/../../replace/test/getifaddrs.o \ - $(torturesrcdir)/../../replace/test/os2_delete.o \ - $(torturesrcdir)/../../replace/test/strptime.o \ - $(torturesrcdir)/../../replace/test/testsuite.o \ + $(torturesrcdir)/../../lib/talloc/testsuite.o \ + $(torturesrcdir)/../../lib/replace/test/getifaddrs.o \ + $(torturesrcdir)/../../lib/replace/test/os2_delete.o \ + $(torturesrcdir)/../../lib/replace/test/strptime.o \ + $(torturesrcdir)/../../lib/replace/test/testsuite.o \ $(torturesrcdir)/../lib/messaging/tests/messaging.o \ $(torturesrcdir)/../lib/messaging/tests/irpc.o \ $(torturesrcdir)/../librpc/tests/binding_string.o \ $(torturesrcdir)/../lib/util/tests/idtree.o \ $(torturesrcdir)/../lib/socket/testsuite.o \ - $(torturesrcdir)/../../socket_wrapper/testsuite.o \ + $(torturesrcdir)/../../lib/socket_wrapper/testsuite.o \ $(torturesrcdir)/../libcli/resolve/testsuite.o \ $(torturesrcdir)/../lib/util/tests/strlist.o \ $(torturesrcdir)/../lib/util/tests/str.o \ $(torturesrcdir)/../lib/util/tests/file.o \ $(torturesrcdir)/../lib/util/tests/genrand.o \ - $(torturesrcdir)/../../compression/testsuite.o \ + $(torturesrcdir)/../../lib/compression/testsuite.o \ $(torturesrcdir)/../lib/charset/tests/charset.o \ $(torturesrcdir)/../libcli/security/tests/sddl.o \ $(torturesrcdir)/../lib/tdr/testsuite.o \ diff --git a/talloc/Makefile.in b/talloc/Makefile.in deleted file mode 100644 index 07b8fd4ff0..0000000000 --- a/talloc/Makefile.in +++ /dev/null @@ -1,43 +0,0 @@ -#!gmake -# -prefix = @prefix@ -datarootdir = @datarootdir@ -exec_prefix = @exec_prefix@ -includedir = @includedir@ -libdir = @libdir@ -mandir = @mandir@ -VPATH = @srcdir@:@libreplacedir@ -srcdir = @srcdir@ -builddir = @builddir@ -XSLTPROC = @XSLTPROC@ -INSTALLCMD = @INSTALL@ -CC = @CC@ -CFLAGS = @CFLAGS@ -DHAVE_CONFIG_H= -I. -I@srcdir@ -EXTRA_TARGETS = @DOC_TARGET@ -PICFLAG = @PICFLAG@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -SHLIBEXT = @SHLIBEXT@ -SHLD = @SHLD@ -SHLD_FLAGS = @SHLD_FLAGS@ -tallocdir = @tallocdir@ - -LIBOBJ = $(TALLOC_OBJ) @LIBREPLACEOBJ@ - -all:: showflags $(EXTRA_TARGETS) - -include $(tallocdir)/rules.mk -include $(tallocdir)/talloc.mk - -$(TALLOC_SOLIB): $(LIBOBJ) - $(SHLD) $(SHLD_FLAGS) -o $@ $(LIBOBJ) @SONAMEFLAG@$(TALLOC_SONAME) - -check: test - -installcheck:: test install - -distclean:: clean - rm -f Makefile - rm -f config.log config.status config.h config.cache - -realdistclean:: distclean - rm -f configure config.h.in diff --git a/talloc/NEWS b/talloc/NEWS deleted file mode 100644 index e5b3aa0731..0000000000 --- a/talloc/NEWS +++ /dev/null @@ -1,13 +0,0 @@ -1.0.1 26 May 2007 - - BUGS - - * Set name of correctly when using talloc_append_string() (metze) - - LICENSE - - * Change license of files in lib/replace to LGPL (was GPL). (jelmer) - -1.0.0 30 April 2007 - - Initial release. diff --git a/talloc/aclocal.m4 b/talloc/aclocal.m4 deleted file mode 100644 index 5605e476ba..0000000000 --- a/talloc/aclocal.m4 +++ /dev/null @@ -1 +0,0 @@ -m4_include(libreplace.m4) diff --git a/talloc/autogen.sh b/talloc/autogen.sh deleted file mode 100755 index bf84eeee19..0000000000 --- a/talloc/autogen.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f configure config.h.in - -IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace" -autoconf $IPATHS || exit 1 -autoheader $IPATHS || exit 1 - -rm -rf autom4te.cache - -echo "Now run ./configure and then make." -exit 0 - diff --git a/talloc/config.guess b/talloc/config.guess deleted file mode 100755 index 354dbe175a..0000000000 --- a/talloc/config.guess +++ /dev/null @@ -1,1464 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-08-03' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/talloc/config.mk b/talloc/config.mk deleted file mode 100644 index 5cdf3a1a8e..0000000000 --- a/talloc/config.mk +++ /dev/null @@ -1,7 +0,0 @@ -[LIBRARY::LIBTALLOC] -OUTPUT_TYPE = MERGED_OBJ -CFLAGS = -I$(tallocsrcdir) - -LIBTALLOC_OBJ_FILES = $(tallocsrcdir)/talloc.o - -MANPAGES += $(tallocdir)/talloc.3 diff --git a/talloc/config.sub b/talloc/config.sub deleted file mode 100755 index 23cd6fd75c..0000000000 --- a/talloc/config.sub +++ /dev/null @@ -1,1577 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-07-08' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ms1 \ - | msp430 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | ms1-* \ - | msp430-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - m32c-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/talloc/configure.ac b/talloc/configure.ac deleted file mode 100644 index 4719aa04b5..0000000000 --- a/talloc/configure.ac +++ /dev/null @@ -1,24 +0,0 @@ -AC_PREREQ(2.50) -AC_INIT(talloc, 1.2.0) -AC_CONFIG_SRCDIR([talloc.c]) -AC_SUBST(datarootdir) -AC_CONFIG_HEADER(config.h) - -AC_LIBREPLACE_ALL_CHECKS - -m4_include(libtalloc.m4) - -AC_PATH_PROG(XSLTPROC,xsltproc) -DOC_TARGET="" -if test -n "$XSLTPROC"; then - DOC_TARGET=doc -fi -AC_SUBST(DOC_TARGET) - -AC_LD_PICFLAG -AC_LD_SHLIBEXT -AC_LD_SONAMEFLAG -AC_LIBREPLACE_SHLD -AC_LIBREPLACE_SHLD_FLAGS - -AC_OUTPUT(Makefile talloc.pc) diff --git a/talloc/install-sh b/talloc/install-sh deleted file mode 100755 index 58719246f0..0000000000 --- a/talloc/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -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=: - 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 diff --git a/talloc/libtalloc.m4 b/talloc/libtalloc.m4 deleted file mode 100644 index fd2b4b22cd..0000000000 --- a/talloc/libtalloc.m4 +++ /dev/null @@ -1,33 +0,0 @@ -dnl find the talloc sources. This is meant to work both for -dnl talloc standalone builds, and builds of packages using talloc -tallocdir="" -tallocpaths=". lib/talloc talloc ../talloc" -for d in $tallocpaths; do - if test -f "$srcdir/$d/talloc.c"; then - tallocdir="$d" - AC_SUBST(tallocdir) - break; - fi -done -if test x"$tallocdir" = "x"; then - AC_MSG_ERROR([cannot find talloc source in $tallocpaths]) -fi -TALLOC_OBJ="talloc.o" -AC_SUBST(TALLOC_OBJ) - -TALLOC_CFLAGS="-I$srcdir/$tallocdir" -AC_SUBST(TALLOC_CFLAGS) - -TALLOC_LIBS="" -AC_SUBST(TALLOC_LIBS) - -AC_CHECK_SIZEOF(size_t,cross) -AC_CHECK_SIZEOF(void *,cross) - -if test $ac_cv_sizeof_size_t -lt $ac_cv_sizeof_void_p; then - AC_WARN([size_t cannot represent the amount of used memory of a process]) - AC_WARN([please report this to ]) - AC_WARN([sizeof(size_t) = $ac_cv_sizeof_size_t]) - AC_WARN([sizeof(void *) = $ac_cv_sizeof_void_p]) - AC_ERROR([sizeof(size_t) < sizeof(void *)]) -fi diff --git a/talloc/rules.mk b/talloc/rules.mk deleted file mode 100644 index 6cee126529..0000000000 --- a/talloc/rules.mk +++ /dev/null @@ -1,18 +0,0 @@ -.SUFFIXES: .c .o .3 .3.xml .xml .html - -showflags:: - @echo 'talloc will be compiled with flags:' - @echo ' CFLAGS = $(CFLAGS)' - @echo ' LIBS = $(LIBS)' - -.c.o: - $(CC) $(PICFLAG) -o $@ -c $< $(CFLAGS) - -.3.xml.3: - -test -z "$(XSLTPROC)" || $(XSLTPROC) --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< - -.xml.html: - -test -z "$(XSLTPROC)" || $(XSLTPROC) --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< - -distclean:: - rm -f *~ */*~ diff --git a/talloc/talloc.3.xml b/talloc/talloc.3.xml deleted file mode 100644 index 67de15bfc8..0000000000 --- a/talloc/talloc.3.xml +++ /dev/null @@ -1,738 +0,0 @@ - - - - - talloc - 3 - - - talloc -hierarchical reference counted memory pool system with destructors - - -#include <talloc/talloc.h> - - DESCRIPTION - - If you are used to talloc from Samba3 then please read this - carefully, as talloc has changed a lot. - - - The new talloc is a hierarchical, reference counted memory pool - system with destructors. Quite a mouthful really, but not too bad - once you get used to it. - - - Perhaps the biggest change from Samba3 is that there is no - distinction between a "talloc context" and a "talloc pointer". Any - pointer returned from talloc() is itself a valid talloc context. - This means you can do this: - - - struct foo *X = talloc(mem_ctx, struct foo); - X->name = talloc_strdup(X, "foo"); - - - and the pointer X->name - would be a "child" of the talloc context X which is itself a child of - mem_ctx. So if you do - talloc_free(mem_ctx) then - it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if - you do talloc_free(X->name) then just - the name element of X is - destroyed. - - - If you think about this, then what this effectively gives you is an - n-ary tree, where you can free any part of the tree with - talloc_free(). - - - If you find this confusing, then I suggest you run the testsuite program to watch talloc - in action. You may also like to add your own tests to testsuite.c to clarify how some - particular situation is handled. - - - TALLOC API - - The following is a complete guide to the talloc API. Read it all at - least twice. - - (type *)talloc(const void *ctx, type); - - The talloc() macro is the core of the talloc library. It takes a - memory ctx and a type, and returns a pointer to a new - area of memory of the given type. - - - The returned pointer is itself a talloc context, so you can use - it as the ctx argument to more - calls to talloc() if you wish. - - - The returned pointer is a "child" of the supplied context. This - means that if you talloc_free() the ctx then the new child disappears as - well. Alternatively you can free just the child. - - - The ctx argument to talloc() - can be NULL, in which case a new top level context is created. - - - void *talloc_size(const void *ctx, size_t size); - - The function talloc_size() should be used when you don't have a - convenient type to pass to talloc(). Unlike talloc(), it is not - type safe (as it returns a void *), so you are on your own for - type checking. - - - (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); - - The talloc_ptrtype() macro should be used when you have a pointer and - want to allocate memory to point at with this pointer. When compiling - with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() - and talloc_get_name() will return the current location in the source file. - and not the type. - - - int talloc_free(void *ptr); - - The talloc_free() function frees a piece of talloc memory, and - all its children. You can call talloc_free() on any pointer - returned by talloc(). - - - The return value of talloc_free() indicates success or failure, - with 0 returned for success and -1 for failure. The only - possible failure condition is if ptr had a destructor attached to it and - the destructor returned -1. See talloc_set_destructor() - for details on destructors. - - - If this pointer has an additional parent when talloc_free() is - called then the memory is not actually released, but instead the - most recently established parent is destroyed. See talloc_reference() - for details on establishing additional parents. - - - For more control on which parent is removed, see talloc_unlink(). - - - talloc_free() operates recursively on its children. - - - void *talloc_reference(const void *ctx, const void *ptr); - - The talloc_reference() function makes ctx an additional parent of ptr. - - - The return value of talloc_reference() is always the original - pointer ptr, unless talloc ran - out of memory in creating the reference in which case it will - return NULL (each additional reference consumes around 48 bytes - of memory on intel x86 platforms). - - - If ptr is NULL, then the - function is a no-op, and simply returns NULL. - - - After creating a reference you can free it in one of the - following ways: - - - - - - you can talloc_free() any parent of the original pointer. - That will reduce the number of parents of this pointer by 1, - and will cause this pointer to be freed if it runs out of - parents. - - - - - you can talloc_free() the pointer itself. That will destroy - the most recently established parent to the pointer and leave - the pointer as a child of its current parent. - - - - - - For more control on which parent to remove, see talloc_unlink(). - - - int talloc_unlink(const void *ctx, const void *ptr); - - The talloc_unlink() function removes a specific parent from - ptr. The ctx passed must either be a context used - in talloc_reference() with this pointer, or must be a direct - parent of ptr. - - - Note that if the parent has already been removed using - talloc_free() then this function will fail and will return -1. - Likewise, if ptr is NULL, then - the function will make no modifications and return -1. - - - Usually you can just use talloc_free() instead of - talloc_unlink(), but sometimes it is useful to have the - additional control on which parent is removed. - - - void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - - The function talloc_set_destructor() sets the destructor for the pointer ptr. A destructor is a function that is called - when the memory used by a pointer is about to be released. The - destructor receives ptr as an - argument, and should return 0 for success and -1 for failure. - - - The destructor can do anything - it wants to, including freeing other pieces of memory. A common - use for destructors is to clean up operating system resources - (such as open file descriptors) contained in the structure the - destructor is placed on. - - - You can only place one destructor on a pointer. If you need more - than one destructor then you can create a zero-length child of - the pointer and place an additional destructor on that. - - - To remove a destructor call talloc_set_destructor() with NULL for - the destructor. - - - If your destructor attempts to talloc_free() the pointer that it - is the destructor for then talloc_free() will return -1 and the - free will be ignored. This would be a pointless operation - anyway, as the destructor is only called when the memory is just - about to go away. - - - int talloc_increase_ref_count(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_increase_ref_count(ptr) function is exactly equivalent to: - - talloc_reference(NULL, ptr); - - You can use either syntax, depending on which you think is - clearer in your code. - - - It returns 0 on success and -1 on failure. - - - size_t talloc_reference_count(const void *<emphasis role="italic">ptr</emphasis>); - - Return the number of references to the pointer. - - - void talloc_set_name(const void *ptr, const char *fmt, ...); - - Each talloc pointer has a "name". The name is used principally - for debugging purposes, although it is also possible to set and - get the name on a pointer in as a way of "marking" pointers in - your code. - - - The main use for names on pointer is for "talloc reports". See - talloc_report_depth_cb(), - talloc_report_depth_file(), - talloc_report() - talloc_report() - and talloc_report_full() - for details. Also see talloc_enable_leak_report() - and talloc_enable_leak_report_full(). - - - The talloc_set_name() function allocates memory as a child of the - pointer. It is logically equivalent to: - - talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - - Note that multiple calls to talloc_set_name() will allocate more - memory without releasing the name. All of the memory is released - when the ptr is freed using talloc_free(). - - - void talloc_set_name_const(const void *<emphasis role="italic">ptr</emphasis>, const char *<emphasis role="italic">name</emphasis>); - - The function talloc_set_name_const() is just like - talloc_set_name(), but it takes a string constant, and is much - faster. It is extensively used by the "auto naming" macros, such - as talloc_p(). - - - This function does not allocate any memory. It just copies the - supplied pointer into the internal representation of the talloc - ptr. This means you must not pass a name pointer to memory that will - disappear before ptr is freed - with talloc_free(). - - - void *talloc_named(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); - - The talloc_named() function creates a named talloc pointer. It - is equivalent to: - - ptr = talloc_size(ctx, size); -talloc_set_name(ptr, fmt, ....); - - void *talloc_named_const(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">name</emphasis>); - - This is equivalent to: - - ptr = talloc_size(ctx, size); -talloc_set_name_const(ptr, name); - - const char *talloc_get_name(const void *<emphasis role="italic">ptr</emphasis>); - - This returns the current name for the given talloc pointer, - ptr. See talloc_set_name() - for details. - - - void *talloc_init(const char *<emphasis role="italic">fmt</emphasis>, ...); - - This function creates a zero length named talloc context as a top - level context. It is equivalent to: - - talloc_named(NULL, 0, fmt, ...); - - void *talloc_new(void *<emphasis role="italic">ctx</emphasis>); - - This is a utility macro that creates a new memory context hanging - off an exiting context, automatically naming it "talloc_new: - __location__" where __location__ is the source line it is called - from. It is particularly useful for creating a new temporary - working context. - - - (<emphasis role="italic">type</emphasis> *)talloc_realloc(const void *<emphasis role="italic">ctx</emphasis>, void *<emphasis role="italic">ptr</emphasis>, <emphasis role="italic">type</emphasis>, <emphasis role="italic">count</emphasis>); - - The talloc_realloc() macro changes the size of a talloc pointer. - It has the following equivalences: - - talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); -talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); - - The ctx argument is only used - if ptr is not NULL, otherwise - it is ignored. - - - talloc_realloc() returns the new pointer, or NULL on failure. - The call will fail either due to a lack of memory, or because the - pointer has more than one parent (see talloc_reference()). - - - void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); - - the talloc_realloc_size() function is useful when the type is not - known so the type-safe talloc_realloc() cannot be used. - - - TYPE *talloc_steal(const void *<emphasis role="italic">new_ctx</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); - - The talloc_steal() function changes the parent context of a - talloc pointer. It is typically used when the context that the - pointer is currently a child of is going to be freed and you wish - to keep the memory for a longer time. - - - The talloc_steal() function returns the pointer that you pass it. - It does not have any failure modes. - - - NOTE: It is possible to produce loops in the parent/child - relationship if you are not careful with talloc_steal(). No - guarantees are provided as to your sanity or the safety of your - data if you do this. - - - TYPE *talloc_move(const void *<emphasis role="italic">new_ctx</emphasis>, TYPE **<emphasis role="italic">ptr</emphasis>); - - The talloc_move() function is a wrapper around - talloc_steal() which zeros the source pointer after the - move. This avoids a potential source of bugs where a - programmer leaves a pointer in two structures, and uses the - pointer from the old structure after it has been moved to a - new one. - - - size_t talloc_total_size(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_total_size() function returns the total size in bytes - used by this pointer and all child pointers. Mostly useful for - debugging. - - - Passing NULL is allowed, but it will only give a meaningful - result if talloc_enable_leak_report() or - talloc_enable_leak_report_full() has been called. - - - size_t talloc_total_blocks(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_total_blocks() function returns the total memory block - count used by this pointer and all child pointers. Mostly useful - for debugging. - - - Passing NULL is allowed, but it will only give a meaningful - result if talloc_enable_leak_report() or - talloc_enable_leak_report_full() has been called. - - - void talloc_report(const void *ptr, FILE *f); - - The talloc_report() function prints a summary report of all - memory used by ptr. One line - of report is printed for each immediate child of ptr, showing the - total memory and number of blocks used by that child. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - void talloc_report_full(const void *<emphasis role="italic">ptr</emphasis>, FILE *<emphasis role="italic">f</emphasis>); - - This provides a more detailed report than talloc_report(). It - will recursively print the entire tree of memory referenced by - the pointer. References in the tree are shown by giving the name - of the pointer that is referenced. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - - - void talloc_report_depth_cb - const void *ptr - int depth - int max_depth - void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv) - void *priv - - - This provides a more flexible reports than talloc_report(). It - will recursively call the callback for the entire tree of memory - referenced by the pointer. References in the tree are passed with - is_ref = 1 and the pointer that is referenced. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - The recursion is stopped when depth >= max_depth. - max_depth = -1 means only stop at leaf nodes. - - - - - void talloc_report_depth_file - const void *ptr - int depth - int max_depth - FILE *f - - - This provides a more flexible reports than talloc_report(). It - will let you specify the depth and max_depth. - - - void talloc_enable_leak_report(void); - - This enables calling of talloc_report(NULL, stderr) when the - program exits. In Samba4 this is enabled by using the - --leak-report command line option. - - - For it to be useful, this function must be called before any - other talloc function as it establishes a "null context" that - acts as the top of the tree. If you don't call this function - first then passing NULL to talloc_report() or - talloc_report_full() won't give you the full tree printout. - - - Here is a typical talloc report: - - talloc report on 'null_context' (total 267 bytes in 15 blocks) -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -iconv(UTF8,CP850) contains 42 bytes in 2 blocks -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -iconv(CP850,UTF8) contains 42 bytes in 2 blocks -iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks -iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks - - - void talloc_enable_leak_report_full(void); - - This enables calling of talloc_report_full(NULL, stderr) when the - program exits. In Samba4 this is enabled by using the - --leak-report-full command line option. - - - For it to be useful, this function must be called before any - other talloc function as it establishes a "null context" that - acts as the top of the tree. If you don't call this function - first then passing NULL to talloc_report() or - talloc_report_full() won't give you the full tree printout. - - - Here is a typical full report: - - full talloc report on 'root' (total 18 bytes in 8 blocks) -p1 contains 18 bytes in 7 blocks (ref 0) - r1 contains 13 bytes in 2 blocks (ref 0) - reference to: p2 - p2 contains 1 bytes in 1 blocks (ref 1) - x3 contains 1 bytes in 1 blocks (ref 0) - x2 contains 1 bytes in 1 blocks (ref 0) - x1 contains 1 bytes in 1 blocks (ref 0) - - - (<emphasis role="italic">type</emphasis> *)talloc_zero(const void *<emphasis role="italic">ctx</emphasis>, <emphasis role="italic">type</emphasis>); - - The talloc_zero() macro is equivalent to: - - ptr = talloc(ctx, type); -if (ptr) memset(ptr, 0, sizeof(type)); - - void *talloc_zero_size(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>) - - The talloc_zero_size() function is useful when you don't have a - known type. - - - void *talloc_memdup(const void *<emphasis role="italic">ctx</emphasis>, const void *<emphasis role="italic">p</emphasis>, size_t size); - - The talloc_memdup() function is equivalent to: - - ptr = talloc_size(ctx, size); -if (ptr) memcpy(ptr, p, size); - - char *talloc_strdup(const void *<emphasis role="italic">ctx</emphasis>, const char *<emphasis role="italic">p</emphasis>); - - The talloc_strdup() function is equivalent to: - - ptr = talloc_size(ctx, strlen(p)+1); -if (ptr) memcpy(ptr, p, strlen(p)+1); - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_strndup(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">p</emphasis>, size_t <emphasis role="italic">n</emphasis>); - - The talloc_strndup() function is the talloc equivalent of the C - library function strndup(3). - - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_append_string(const void *<emphasis role="italic">t</emphasis>, char *<emphasis role="italic">orig</emphasis>, const char *<emphasis role="italic">append</emphasis>); - - The talloc_append_string() function appends the given formatted - string to the given string. - - - This function sets the name of the new pointer to the new - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>); - - The talloc_vasprintf() function is the talloc equivalent of the C - library function vasprintf(3). - - - This function sets the name of the new pointer to the new - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); - - The talloc_asprintf() function is the talloc equivalent of the C - library function asprintf(3). - - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_asprintf_append(char *s, const char *fmt, ...); - - The talloc_asprintf_append() function appends the given formatted - string to the given string. - - - This function sets the name of the new pointer to the new - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - (type *)talloc_array(const void *ctx, type, uint_t count); - - The talloc_array() macro is equivalent to: - - (type *)talloc_size(ctx, sizeof(type) * count); - - except that it provides integer overflow protection for the - multiply, returning NULL if the multiply overflows. - - - void *talloc_array_size(const void *ctx, size_t size, uint_t count); - - The talloc_array_size() function is useful when the type is not - known. It operates in the same way as talloc_array(), but takes a - size instead of a type. - - - (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count); - - The talloc_ptrtype() macro should be used when you have a pointer to an array - and want to allocate memory of an array to point at with this pointer. When compiling - with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() - and talloc_get_name() will return the current location in the source file. - and not the type. - - - void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size) - - This is a non-macro version of talloc_realloc(), which is useful - as libraries sometimes want a realloc function pointer. A - realloc(3) implementation encapsulates the functionality of - malloc(3), free(3) and realloc(3) in one call, which is why it is - useful to be able to pass around a single function pointer. - - - void *talloc_autofree_context(void); - - This is a handy utility function that returns a talloc context - which will be automatically freed on program exit. This can be - used to reduce the noise in memory leak reports. - - - void *talloc_check_name(const void *ptr, const char *name); - - This function checks if a pointer has the specified name. If it does then the pointer is - returned. It it doesn't then NULL is returned. - - - (type *)talloc_get_type(const void *ptr, type); - - This macro allows you to do type checking on talloc pointers. It - is particularly useful for void* private pointers. It is - equivalent to this: - - (type *)talloc_check_name(ptr, #type) - - talloc_set_type(const void *ptr, type); - - This macro allows you to force the name of a pointer to be a - particular type. This can be - used in conjunction with talloc_get_type() to do type checking on - void* pointers. - - - It is equivalent to this: - - talloc_set_name_const(ptr, #type) - - - PERFORMANCE - - All the additional features of talloc(3) over malloc(3) do come at a - price. We have a simple performance test in Samba4 that measures - talloc() versus malloc() performance, and it seems that talloc() is - about 10% slower than malloc() on my x86 Debian Linux box. For - Samba, the great reduction in code complexity that we get by using - talloc makes this worthwhile, especially as the total overhead of - talloc/malloc in Samba is already quite small. - - - SEE ALSO - - malloc(3), strndup(3), vasprintf(3), asprintf(3), - - - - COPYRIGHT/LICENSE - - Copyright (C) Andrew Tridgell 2004 - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or (at - your option) any later version. - - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - - You should have received a copy of the GNU General Public License - along with this program; if not, see http://www.gnu.org/licenses/. - - - diff --git a/talloc/talloc.c b/talloc/talloc.c deleted file mode 100644 index 1f7e52439f..0000000000 --- a/talloc/talloc.c +++ /dev/null @@ -1,1732 +0,0 @@ -/* - Samba Unix SMB/CIFS implementation. - - Samba trivial allocation library - new interface - - NOTE: Please read talloc_guide.txt for full documentation - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - inspired by http://swapped.cc/halloc/ -*/ - -#ifdef _SAMBA_BUILD_ -#include "version.h" -#if (SAMBA_VERSION_MAJOR<4) -#include "includes.h" -/* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file - * we trust ourselves... */ -#ifdef malloc -#undef malloc -#endif -#ifdef realloc -#undef realloc -#endif -#define _TALLOC_SAMBA3 -#endif /* (SAMBA_VERSION_MAJOR<4) */ -#endif /* _SAMBA_BUILD_ */ - -#ifndef _TALLOC_SAMBA3 -#include "replace.h" -#include "talloc.h" -#endif /* not _TALLOC_SAMBA3 */ - -/* use this to force every realloc to change the pointer, to stress test - code that might not cope */ -#define ALWAYS_REALLOC 0 - - -#define MAX_TALLOC_SIZE 0x10000000 -#define TALLOC_MAGIC 0xe814ec70 -#define TALLOC_FLAG_FREE 0x01 -#define TALLOC_FLAG_LOOP 0x02 -#define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ -#define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ -#define TALLOC_MAGIC_REFERENCE ((const char *)1) - -/* by default we abort when given a bad pointer (such as when talloc_free() is called - on a pointer that came from malloc() */ -#ifndef TALLOC_ABORT -#define TALLOC_ABORT(reason) abort() -#endif - -#ifndef discard_const_p -#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) -# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) -#else -# define discard_const_p(type, ptr) ((type *)(ptr)) -#endif -#endif - -/* these macros gain us a few percent of speed on gcc */ -#if (__GNUC__ >= 3) -/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 - as its first argument */ -#ifndef likely -#define likely(x) __builtin_expect(!!(x), 1) -#endif -#ifndef unlikely -#define unlikely(x) __builtin_expect(!!(x), 0) -#endif -#else -#ifndef likely -#define likely(x) (x) -#endif -#ifndef unlikely -#define unlikely(x) (x) -#endif -#endif - -/* this null_context is only used if talloc_enable_leak_report() or - talloc_enable_leak_report_full() is called, otherwise it remains - NULL -*/ -static void *null_context; -static void *autofree_context; - -struct talloc_reference_handle { - struct talloc_reference_handle *next, *prev; - void *ptr; -}; - -typedef int (*talloc_destructor_t)(void *); - -struct talloc_chunk { - struct talloc_chunk *next, *prev; - struct talloc_chunk *parent, *child; - struct talloc_reference_handle *refs; - talloc_destructor_t destructor; - const char *name; - size_t size; - unsigned flags; - - /* - * "pool" has dual use: - * - * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" - * marks the end of the currently allocated area. - * - * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" - * is a pointer to the struct talloc_chunk of the pool that it was - * allocated from. This way children can quickly find the pool to chew - * from. - */ - void *pool; -}; - -/* 16 byte alignment seems to keep everyone happy */ -#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15) -#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) - -static void talloc_abort_double_free(void) -{ - TALLOC_ABORT("Bad talloc magic value - double free"); -} - -static void talloc_abort_unknown_value(void) -{ - TALLOC_ABORT("Bad talloc magic value - unknown value"); -} - -/* panic if we get a bad magic value */ -static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) -{ - const char *pp = (const char *)ptr; - struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); - if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { - if (tc->flags & TALLOC_FLAG_FREE) { - talloc_abort_double_free(); - } else { - talloc_abort_unknown_value(); - } - } - return tc; -} - -/* hook into the front of the list */ -#define _TLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - (list)->prev = (p); \ - (p)->next = (list); \ - (p)->prev = NULL; \ - (list) = (p); \ - }\ -} while (0) - -/* remove an element from a list - element doesn't have to be in list. */ -#define _TLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - (list) = (p)->next; \ - if (list) (list)->prev = NULL; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ -} while (0) - - -/* - return the parent chunk of a pointer -*/ -static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return NULL; - } - - tc = talloc_chunk_from_ptr(ptr); - while (tc->prev) tc=tc->prev; - - return tc->parent; -} - -void *talloc_parent(const void *ptr) -{ - struct talloc_chunk *tc = talloc_parent_chunk(ptr); - return tc? TC_PTR_FROM_CHUNK(tc) : NULL; -} - -/* - find parents name -*/ -const char *talloc_parent_name(const void *ptr) -{ - struct talloc_chunk *tc = talloc_parent_chunk(ptr); - return tc? tc->name : NULL; -} - -/* - A pool carries an in-pool object count count in the first 16 bytes. - bytes. This is done to support talloc_steal() to a parent outside of the - pool. The count includes the pool itself, so a talloc_free() on a pool will - only destroy the pool if the count has dropped to zero. A talloc_free() of a - pool member will reduce the count, and eventually also call free(3) on the - pool memory. - - The object count is not put into "struct talloc_chunk" because it is only - relevant for talloc pools and the alignment to 16 bytes would increase the - memory footprint of each talloc chunk by those 16 bytes. -*/ - -#define TALLOC_POOL_HDR_SIZE 16 - -static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc) -{ - return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk)); -} - -/* - Allocate from a pool -*/ - -static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, - size_t size) -{ - struct talloc_chunk *pool_ctx = NULL; - size_t space_left; - struct talloc_chunk *result; - size_t chunk_size; - - if (parent == NULL) { - return NULL; - } - - if (parent->flags & TALLOC_FLAG_POOL) { - pool_ctx = parent; - } - else if (parent->flags & TALLOC_FLAG_POOLMEM) { - pool_ctx = (struct talloc_chunk *)parent->pool; - } - - if (pool_ctx == NULL) { - return NULL; - } - - space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size) - - ((char *)pool_ctx->pool); - - /* - * Align size to 16 bytes - */ - chunk_size = ((size + 15) & ~15); - - if (space_left < chunk_size) { - return NULL; - } - - result = (struct talloc_chunk *)pool_ctx->pool; - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) - VALGRIND_MAKE_MEM_UNDEFINED(result, size); -#endif - - pool_ctx->pool = (void *)((char *)result + chunk_size); - - result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; - result->pool = pool_ctx; - - *talloc_pool_objectcount(pool_ctx) += 1; - - return result; -} - -/* - Allocate a bit of memory as a child of an existing pointer -*/ -static inline void *__talloc(const void *context, size_t size) -{ - struct talloc_chunk *tc = NULL; - - if (unlikely(context == NULL)) { - context = null_context; - } - - if (unlikely(size >= MAX_TALLOC_SIZE)) { - return NULL; - } - - if (context != NULL) { - tc = talloc_alloc_pool(talloc_chunk_from_ptr(context), - TC_HDR_SIZE+size); - } - - if (tc == NULL) { - tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); - if (unlikely(tc == NULL)) return NULL; - tc->flags = TALLOC_MAGIC; - tc->pool = NULL; - } - - tc->size = size; - tc->destructor = NULL; - tc->child = NULL; - tc->name = NULL; - tc->refs = NULL; - - if (likely(context)) { - struct talloc_chunk *parent = talloc_chunk_from_ptr(context); - - if (parent->child) { - parent->child->parent = NULL; - tc->next = parent->child; - tc->next->prev = tc; - } else { - tc->next = NULL; - } - tc->parent = parent; - tc->prev = NULL; - parent->child = tc; - } else { - tc->next = tc->prev = tc->parent = NULL; - } - - return TC_PTR_FROM_CHUNK(tc); -} - -/* - * Create a talloc pool - */ - -void *talloc_pool(const void *context, size_t size) -{ - void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE); - struct talloc_chunk *tc; - - if (unlikely(result == NULL)) { - return NULL; - } - - tc = talloc_chunk_from_ptr(result); - - tc->flags |= TALLOC_FLAG_POOL; - tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE; - - *talloc_pool_objectcount(tc) = 1; - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) - VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size); -#endif - - return result; -} - -/* - setup a destructor to be called on free of a pointer - the destructor should return 0 on success, or -1 on failure. - if the destructor fails then the free is failed, and the memory can - be continued to be used -*/ -void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->destructor = destructor; -} - -/* - increase the reference count on a piece of memory. -*/ -int talloc_increase_ref_count(const void *ptr) -{ - if (unlikely(!talloc_reference(null_context, ptr))) { - return -1; - } - return 0; -} - -/* - helper for talloc_reference() - - this is referenced by a function pointer and should not be inline -*/ -static int talloc_reference_destructor(struct talloc_reference_handle *handle) -{ - struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr); - _TLIST_REMOVE(ptr_tc->refs, handle); - return 0; -} - -/* - more efficient way to add a name to a pointer - the name must point to a - true string constant -*/ -static inline void _talloc_set_name_const(const void *ptr, const char *name) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->name = name; -} - -/* - internal talloc_named_const() -*/ -static inline void *_talloc_named_const(const void *context, size_t size, const char *name) -{ - void *ptr; - - ptr = __talloc(context, size); - if (unlikely(ptr == NULL)) { - return NULL; - } - - _talloc_set_name_const(ptr, name); - - return ptr; -} - -/* - make a secondary reference to a pointer, hanging off the given context. - the pointer remains valid until both the original caller and this given - context are freed. - - the major use for this is when two different structures need to reference the - same underlying data, and you want to be able to free the two instances separately, - and in either order -*/ -void *_talloc_reference(const void *context, const void *ptr) -{ - struct talloc_chunk *tc; - struct talloc_reference_handle *handle; - if (unlikely(ptr == NULL)) return NULL; - - tc = talloc_chunk_from_ptr(ptr); - handle = (struct talloc_reference_handle *)_talloc_named_const(context, - sizeof(struct talloc_reference_handle), - TALLOC_MAGIC_REFERENCE); - if (unlikely(handle == NULL)) return NULL; - - /* note that we hang the destructor off the handle, not the - main context as that allows the caller to still setup their - own destructor on the context if they want to */ - talloc_set_destructor(handle, talloc_reference_destructor); - handle->ptr = discard_const_p(void, ptr); - _TLIST_ADD(tc->refs, handle); - return handle->ptr; -} - - -/* - internal talloc_free call -*/ -static inline int _talloc_free(void *ptr) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return -1; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (unlikely(tc->refs)) { - int is_child; - /* check this is a reference from a child or grantchild - * back to it's parent or grantparent - * - * in that case we need to remove the reference and - * call another instance of talloc_free() on the current - * pointer. - */ - is_child = talloc_is_parent(tc->refs, ptr); - _talloc_free(tc->refs); - if (is_child) { - return _talloc_free(ptr); - } - return -1; - } - - if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) { - /* we have a free loop - stop looping */ - return 0; - } - - if (unlikely(tc->destructor)) { - talloc_destructor_t d = tc->destructor; - if (d == (talloc_destructor_t)-1) { - return -1; - } - tc->destructor = (talloc_destructor_t)-1; - if (d(ptr) == -1) { - tc->destructor = d; - return -1; - } - tc->destructor = NULL; - } - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - while (tc->child) { - /* we need to work out who will own an abandoned child - if it cannot be freed. In priority order, the first - choice is owner of any remaining reference to this - pointer, the second choice is our parent, and the - final choice is the null context. */ - void *child = TC_PTR_FROM_CHUNK(tc->child); - const void *new_parent = null_context; - if (unlikely(tc->child->refs)) { - struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - if (unlikely(_talloc_free(child) == -1)) { - if (new_parent == null_context) { - struct talloc_chunk *p = talloc_parent_chunk(ptr); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - talloc_steal(new_parent, child); - } - } - - tc->flags |= TALLOC_FLAG_FREE; - - if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) { - struct talloc_chunk *pool; - unsigned int *pool_object_count; - - pool = (tc->flags & TALLOC_FLAG_POOL) - ? tc : (struct talloc_chunk *)tc->pool; - - pool_object_count = talloc_pool_objectcount(pool); - - if (*pool_object_count == 0) { - TALLOC_ABORT("Pool object count zero!"); - } - - *pool_object_count -= 1; - - if (*pool_object_count == 0) { - free(pool); - } - } - else { - free(tc); - } - return 0; -} - -/* - move a lump of memory from one talloc context to another return the - ptr on success, or NULL if it could not be transferred. - passing NULL as ptr will always return NULL with no side effects. -*/ -void *_talloc_steal(const void *new_ctx, const void *ptr) -{ - struct talloc_chunk *tc, *new_tc; - - if (unlikely(!ptr)) { - return NULL; - } - - if (unlikely(new_ctx == NULL)) { - new_ctx = null_context; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (unlikely(new_ctx == NULL)) { - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->parent = tc->next = tc->prev = NULL; - return discard_const_p(void, ptr); - } - - new_tc = talloc_chunk_from_ptr(new_ctx); - - if (unlikely(tc == new_tc || tc->parent == new_tc)) { - return discard_const_p(void, ptr); - } - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->parent = new_tc; - if (new_tc->child) new_tc->child->parent = NULL; - _TLIST_ADD(new_tc->child, tc); - - return discard_const_p(void, ptr); -} - - - -/* - remove a secondary reference to a pointer. This undo's what - talloc_reference() has done. The context and pointer arguments - must match those given to a talloc_reference() -*/ -static inline int talloc_unreference(const void *context, const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - - if (unlikely(context == NULL)) { - context = null_context; - } - - for (h=tc->refs;h;h=h->next) { - struct talloc_chunk *p = talloc_parent_chunk(h); - if (p == NULL) { - if (context == NULL) break; - } else if (TC_PTR_FROM_CHUNK(p) == context) { - break; - } - } - if (h == NULL) { - return -1; - } - - return _talloc_free(h); -} - -/* - remove a specific parent context from a pointer. This is a more - controlled varient of talloc_free() -*/ -int talloc_unlink(const void *context, void *ptr) -{ - struct talloc_chunk *tc_p, *new_p; - void *new_parent; - - if (ptr == NULL) { - return -1; - } - - if (context == NULL) { - context = null_context; - } - - if (talloc_unreference(context, ptr) == 0) { - return 0; - } - - if (context == NULL) { - if (talloc_parent_chunk(ptr) != NULL) { - return -1; - } - } else { - if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) { - return -1; - } - } - - tc_p = talloc_chunk_from_ptr(ptr); - - if (tc_p->refs == NULL) { - return _talloc_free(ptr); - } - - new_p = talloc_parent_chunk(tc_p->refs); - if (new_p) { - new_parent = TC_PTR_FROM_CHUNK(new_p); - } else { - new_parent = NULL; - } - - if (talloc_unreference(new_parent, ptr) != 0) { - return -1; - } - - talloc_steal(new_parent, ptr); - - return 0; -} - -/* - add a name to an existing pointer - va_list version -*/ -static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); - -static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->name = talloc_vasprintf(ptr, fmt, ap); - if (likely(tc->name)) { - _talloc_set_name_const(tc->name, ".name"); - } - return tc->name; -} - -/* - add a name to an existing pointer -*/ -const char *talloc_set_name(const void *ptr, const char *fmt, ...) -{ - const char *name; - va_list ap; - va_start(ap, fmt); - name = talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - return name; -} - - -/* - create a named talloc pointer. Any talloc pointer can be named, and - talloc_named() operates just like talloc() except that it allows you - to name the pointer. -*/ -void *talloc_named(const void *context, size_t size, const char *fmt, ...) -{ - va_list ap; - void *ptr; - const char *name; - - ptr = __talloc(context, size); - if (unlikely(ptr == NULL)) return NULL; - - va_start(ap, fmt); - name = talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - - if (unlikely(name == NULL)) { - _talloc_free(ptr); - return NULL; - } - - return ptr; -} - -/* - return the name of a talloc ptr, or "UNNAMED" -*/ -const char *talloc_get_name(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { - return ".reference"; - } - if (likely(tc->name)) { - return tc->name; - } - return "UNNAMED"; -} - - -/* - check if a pointer has the given name. If it does, return the pointer, - otherwise return NULL -*/ -void *talloc_check_name(const void *ptr, const char *name) -{ - const char *pname; - if (unlikely(ptr == NULL)) return NULL; - pname = talloc_get_name(ptr); - if (likely(pname == name || strcmp(pname, name) == 0)) { - return discard_const_p(void, ptr); - } - return NULL; -} - - -/* - this is for compatibility with older versions of talloc -*/ -void *talloc_init(const char *fmt, ...) -{ - va_list ap; - void *ptr; - const char *name; - - /* - * samba3 expects talloc_report_depth_cb(NULL, ...) - * reports all talloc'ed memory, so we need to enable - * null_tracking - */ - talloc_enable_null_tracking(); - - ptr = __talloc(NULL, 0); - if (unlikely(ptr == NULL)) return NULL; - - va_start(ap, fmt); - name = talloc_set_name_v(ptr, fmt, ap); - va_end(ap); - - if (unlikely(name == NULL)) { - _talloc_free(ptr); - return NULL; - } - - return ptr; -} - -/* - this is a replacement for the Samba3 talloc_destroy_pool functionality. It - should probably not be used in new code. It's in here to keep the talloc - code consistent across Samba 3 and 4. -*/ -void talloc_free_children(void *ptr) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return; - } - - tc = talloc_chunk_from_ptr(ptr); - - while (tc->child) { - /* we need to work out who will own an abandoned child - if it cannot be freed. In priority order, the first - choice is owner of any remaining reference to this - pointer, the second choice is our parent, and the - final choice is the null context. */ - void *child = TC_PTR_FROM_CHUNK(tc->child); - const void *new_parent = null_context; - if (unlikely(tc->child->refs)) { - struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - if (unlikely(_talloc_free(child) == -1)) { - if (new_parent == null_context) { - struct talloc_chunk *p = talloc_parent_chunk(ptr); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - talloc_steal(new_parent, child); - } - } - - if ((tc->flags & TALLOC_FLAG_POOL) - && (*talloc_pool_objectcount(tc) == 1)) { - tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE); -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) - VALGRIND_MAKE_MEM_NOACCESS( - tc->pool, tc->size - TALLOC_POOL_HDR_SIZE); -#endif - } -} - -/* - Allocate a bit of memory as a child of an existing pointer -*/ -void *_talloc(const void *context, size_t size) -{ - return __talloc(context, size); -} - -/* - externally callable talloc_set_name_const() -*/ -void talloc_set_name_const(const void *ptr, const char *name) -{ - _talloc_set_name_const(ptr, name); -} - -/* - create a named talloc pointer. Any talloc pointer can be named, and - talloc_named() operates just like talloc() except that it allows you - to name the pointer. -*/ -void *talloc_named_const(const void *context, size_t size, const char *name) -{ - return _talloc_named_const(context, size, name); -} - -/* - free a talloc pointer. This also frees all child pointers of this - pointer recursively - - return 0 if the memory is actually freed, otherwise -1. The memory - will not be freed if the ref_count is > 1 or the destructor (if - any) returns non-zero -*/ -int talloc_free(void *ptr) -{ - return _talloc_free(ptr); -} - - - -/* - A talloc version of realloc. The context argument is only used if - ptr is NULL -*/ -void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) -{ - struct talloc_chunk *tc; - void *new_ptr; - bool malloced = false; - - /* size zero is equivalent to free() */ - if (unlikely(size == 0)) { - _talloc_free(ptr); - return NULL; - } - - if (unlikely(size >= MAX_TALLOC_SIZE)) { - return NULL; - } - - /* realloc(NULL) is equivalent to malloc() */ - if (ptr == NULL) { - return _talloc_named_const(context, size, name); - } - - tc = talloc_chunk_from_ptr(ptr); - - /* don't allow realloc on referenced pointers */ - if (unlikely(tc->refs)) { - return NULL; - } - - /* don't shrink if we have less than 1k to gain */ - if ((size < tc->size) && ((tc->size - size) < 1024)) { - tc->size = size; - return ptr; - } - - /* by resetting magic we catch users of the old memory */ - tc->flags |= TALLOC_FLAG_FREE; - -#if ALWAYS_REALLOC - new_ptr = malloc(size + TC_HDR_SIZE); - if (new_ptr) { - memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE); - free(tc); - } -#else - if (tc->flags & TALLOC_FLAG_POOLMEM) { - - new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); - *talloc_pool_objectcount((struct talloc_chunk *) - (tc->pool)) -= 1; - - if (new_ptr == NULL) { - new_ptr = malloc(TC_HDR_SIZE+size); - malloced = true; - } - - if (new_ptr) { - memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); - } - } - else { - new_ptr = realloc(tc, size + TC_HDR_SIZE); - } -#endif - if (unlikely(!new_ptr)) { - tc->flags &= ~TALLOC_FLAG_FREE; - return NULL; - } - - tc = (struct talloc_chunk *)new_ptr; - tc->flags &= ~TALLOC_FLAG_FREE; - if (malloced) { - tc->flags &= ~TALLOC_FLAG_POOLMEM; - } - if (tc->parent) { - tc->parent->child = tc; - } - if (tc->child) { - tc->child->parent = tc; - } - - if (tc->prev) { - tc->prev->next = tc; - } - if (tc->next) { - tc->next->prev = tc; - } - - tc->size = size; - _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name); - - return TC_PTR_FROM_CHUNK(tc); -} - -/* - a wrapper around talloc_steal() for situations where you are moving a pointer - between two structures, and want the old pointer to be set to NULL -*/ -void *_talloc_move(const void *new_ctx, const void *_pptr) -{ - const void **pptr = discard_const_p(const void *,_pptr); - void *ret = _talloc_steal(new_ctx, *pptr); - (*pptr) = NULL; - return ret; -} - -/* - return the total size of a talloc pool (subtree) -*/ -size_t talloc_total_size(const void *ptr) -{ - size_t total = 0; - struct talloc_chunk *c, *tc; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - total = tc->size; - for (c=tc->child;c;c=c->next) { - total += talloc_total_size(TC_PTR_FROM_CHUNK(c)); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; -} - -/* - return the total number of blocks in a talloc pool (subtree) -*/ -size_t talloc_total_blocks(const void *ptr) -{ - size_t total = 0; - struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - total++; - for (c=tc->child;c;c=c->next) { - total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c)); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; -} - -/* - return the number of external references to a pointer -*/ -size_t talloc_reference_count(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - size_t ret = 0; - - for (h=tc->refs;h;h=h->next) { - ret++; - } - return ret; -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *private_data), - void *private_data) -{ - struct talloc_chunk *c, *tc; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) return; - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return; - } - - callback(ptr, depth, max_depth, 0, private_data); - - if (max_depth >= 0 && depth >= max_depth) { - return; - } - - tc->flags |= TALLOC_FLAG_LOOP; - for (c=tc->child;c;c=c->next) { - if (c->name == TALLOC_MAGIC_REFERENCE) { - struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c); - callback(h->ptr, depth + 1, max_depth, 1, private_data); - } else { - talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data); - } - } - tc->flags &= ~TALLOC_FLAG_LOOP; -} - -static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) -{ - const char *name = talloc_get_name(ptr); - FILE *f = (FILE *)_f; - - if (is_ref) { - fprintf(f, "%*sreference to: %s\n", depth*4, "", name); - return; - } - - if (depth == 0) { - fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", - (max_depth < 0 ? "full " :""), name, - (unsigned long)talloc_total_size(ptr), - (unsigned long)talloc_total_blocks(ptr)); - return; - } - - fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", - depth*4, "", - name, - (unsigned long)talloc_total_size(ptr), - (unsigned long)talloc_total_blocks(ptr), - (int)talloc_reference_count(ptr), ptr); - -#if 0 - fprintf(f, "content: "); - if (talloc_total_size(ptr)) { - int tot = talloc_total_size(ptr); - int i; - - for (i = 0; i < tot; i++) { - if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { - fprintf(f, "%c", ((char *)ptr)[i]); - } else { - fprintf(f, "~%02x", ((char *)ptr)[i]); - } - } - } - fprintf(f, "\n"); -#endif -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f) -{ - talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); - fflush(f); -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -void talloc_report_full(const void *ptr, FILE *f) -{ - talloc_report_depth_file(ptr, 0, -1, f); -} - -/* - report on memory usage by all children of a pointer -*/ -void talloc_report(const void *ptr, FILE *f) -{ - talloc_report_depth_file(ptr, 0, 1, f); -} - -/* - report on any memory hanging off the null context -*/ -static void talloc_report_null(void) -{ - if (talloc_total_size(null_context) != 0) { - talloc_report(null_context, stderr); - } -} - -/* - report on any memory hanging off the null context -*/ -static void talloc_report_null_full(void) -{ - if (talloc_total_size(null_context) != 0) { - talloc_report_full(null_context, stderr); - } -} - -/* - enable tracking of the NULL context -*/ -void talloc_enable_null_tracking(void) -{ - if (null_context == NULL) { - null_context = _talloc_named_const(NULL, 0, "null_context"); - } -} - -/* - disable tracking of the NULL context -*/ -void talloc_disable_null_tracking(void) -{ - _talloc_free(null_context); - null_context = NULL; -} - -/* - enable leak reporting on exit -*/ -void talloc_enable_leak_report(void) -{ - talloc_enable_null_tracking(); - atexit(talloc_report_null); -} - -/* - enable full leak reporting on exit -*/ -void talloc_enable_leak_report_full(void) -{ - talloc_enable_null_tracking(); - atexit(talloc_report_null_full); -} - -/* - talloc and zero memory. -*/ -void *_talloc_zero(const void *ctx, size_t size, const char *name) -{ - void *p = _talloc_named_const(ctx, size, name); - - if (p) { - memset(p, '\0', size); - } - - return p; -} - -/* - memdup with a talloc. -*/ -void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) -{ - void *newp = _talloc_named_const(t, size, name); - - if (likely(newp)) { - memcpy(newp, p, size); - } - - return newp; -} - -static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) -{ - char *ret; - - ret = (char *)__talloc(t, len + 1); - if (unlikely(!ret)) return NULL; - - memcpy(ret, p, len); - ret[len] = 0; - - _talloc_set_name_const(ret, ret); - return ret; -} - -/* - strdup with a talloc -*/ -char *talloc_strdup(const void *t, const char *p) -{ - if (unlikely(!p)) return NULL; - return __talloc_strlendup(t, p, strlen(p)); -} - -/* - strndup with a talloc -*/ -char *talloc_strndup(const void *t, const char *p, size_t n) -{ - if (unlikely(!p)) return NULL; - return __talloc_strlendup(t, p, strnlen(p, n)); -} - -static inline char *__talloc_strlendup_append(char *s, size_t slen, - const char *a, size_t alen) -{ - char *ret; - - ret = talloc_realloc(NULL, s, char, slen + alen + 1); - if (unlikely(!ret)) return NULL; - - /* append the string and the trailing \0 */ - memcpy(&ret[slen], a, alen); - ret[slen+alen] = 0; - - _talloc_set_name_const(ret, ret); - return ret; -} - -/* - * Appends at the end of the string. - */ -char *talloc_strdup_append(char *s, const char *a) -{ - if (unlikely(!s)) { - return talloc_strdup(NULL, a); - } - - if (unlikely(!a)) { - return s; - } - - return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); -} - -/* - * Appends at the end of the talloc'ed buffer, - * not the end of the string. - */ -char *talloc_strdup_append_buffer(char *s, const char *a) -{ - size_t slen; - - if (unlikely(!s)) { - return talloc_strdup(NULL, a); - } - - if (unlikely(!a)) { - return s; - } - - slen = talloc_get_size(s); - if (likely(slen > 0)) { - slen--; - } - - return __talloc_strlendup_append(s, slen, a, strlen(a)); -} - -/* - * Appends at the end of the string. - */ -char *talloc_strndup_append(char *s, const char *a, size_t n) -{ - if (unlikely(!s)) { - return talloc_strdup(NULL, a); - } - - if (unlikely(!a)) { - return s; - } - - return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); -} - -/* - * Appends at the end of the talloc'ed buffer, - * not the end of the string. - */ -char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) -{ - size_t slen; - - if (unlikely(!s)) { - return talloc_strdup(NULL, a); - } - - if (unlikely(!a)) { - return s; - } - - slen = talloc_get_size(s); - if (likely(slen > 0)) { - slen--; - } - - return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); -} - -#ifndef HAVE_VA_COPY -#ifdef HAVE___VA_COPY -#define va_copy(dest, src) __va_copy(dest, src) -#else -#define va_copy(dest, src) (dest) = (src) -#endif -#endif - -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) -{ - int len; - char *ret; - va_list ap2; - char c; - - /* this call looks strange, but it makes it work on older solaris boxes */ - va_copy(ap2, ap); - len = vsnprintf(&c, 1, fmt, ap2); - va_end(ap2); - if (unlikely(len < 0)) { - return NULL; - } - - ret = (char *)__talloc(t, len+1); - if (unlikely(!ret)) return NULL; - - va_copy(ap2, ap); - vsnprintf(ret, len+1, fmt, ap2); - va_end(ap2); - - _talloc_set_name_const(ret, ret); - return ret; -} - - -/* - Perform string formatting, and return a pointer to newly allocated - memory holding the result, inside a memory pool. - */ -char *talloc_asprintf(const void *t, const char *fmt, ...) -{ - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = talloc_vasprintf(t, fmt, ap); - va_end(ap); - return ret; -} - -static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, - const char *fmt, va_list ap) - PRINTF_ATTRIBUTE(3,0); - -static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, - const char *fmt, va_list ap) -{ - ssize_t alen; - va_list ap2; - char c; - - va_copy(ap2, ap); - alen = vsnprintf(&c, 1, fmt, ap2); - va_end(ap2); - - if (alen <= 0) { - /* Either the vsnprintf failed or the format resulted in - * no characters being formatted. In the former case, we - * ought to return NULL, in the latter we ought to return - * the original string. Most current callers of this - * function expect it to never return NULL. - */ - return s; - } - - s = talloc_realloc(NULL, s, char, slen + alen + 1); - if (!s) return NULL; - - va_copy(ap2, ap); - vsnprintf(s + slen, alen + 1, fmt, ap2); - va_end(ap2); - - _talloc_set_name_const(s, s); - return s; -} - -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Good for gradually - * accumulating output into a string buffer. Appends at the end - * of the string. - **/ -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) -{ - if (unlikely(!s)) { - return talloc_vasprintf(NULL, fmt, ap); - } - - return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); -} - -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Always appends at the - * end of the talloc'ed buffer, not the end of the string. - **/ -char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) -{ - size_t slen; - - if (unlikely(!s)) { - return talloc_vasprintf(NULL, fmt, ap); - } - - slen = talloc_get_size(s); - if (likely(slen > 0)) { - slen--; - } - - return __talloc_vaslenprintf_append(s, slen, fmt, ap); -} - -/* - Realloc @p s to append the formatted result of @p fmt and return @p - s, which may have moved. Good for gradually accumulating output - into a string buffer. - */ -char *talloc_asprintf_append(char *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - s = talloc_vasprintf_append(s, fmt, ap); - va_end(ap); - return s; -} - -/* - Realloc @p s to append the formatted result of @p fmt and return @p - s, which may have moved. Good for gradually accumulating output - into a buffer. - */ -char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - s = talloc_vasprintf_append_buffer(s, fmt, ap); - va_end(ap); - return s; -} - -/* - alloc an array, checking for integer overflow in the array size -*/ -void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_named_const(ctx, el_size * count, name); -} - -/* - alloc an zero array, checking for integer overflow in the array size -*/ -void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_zero(ctx, el_size * count, name); -} - -/* - realloc an array, checking for integer overflow in the array size -*/ -void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_realloc(ctx, ptr, el_size * count, name); -} - -/* - a function version of talloc_realloc(), so it can be passed as a function pointer - to libraries that want a realloc function (a realloc function encapsulates - all the basic capabilities of an allocation library, which is why this is useful) -*/ -void *talloc_realloc_fn(const void *context, void *ptr, size_t size) -{ - return _talloc_realloc(context, ptr, size, NULL); -} - - -static int talloc_autofree_destructor(void *ptr) -{ - autofree_context = NULL; - return 0; -} - -static void talloc_autofree(void) -{ - _talloc_free(autofree_context); -} - -/* - return a context which will be auto-freed on exit - this is useful for reducing the noise in leak reports -*/ -void *talloc_autofree_context(void) -{ - if (autofree_context == NULL) { - autofree_context = _talloc_named_const(NULL, 0, "autofree_context"); - talloc_set_destructor(autofree_context, talloc_autofree_destructor); - atexit(talloc_autofree); - } - return autofree_context; -} - -size_t talloc_get_size(const void *context) -{ - struct talloc_chunk *tc; - - if (context == NULL) - return 0; - - tc = talloc_chunk_from_ptr(context); - - return tc->size; -} - -/* - find a parent of this context that has the given name, if any -*/ -void *talloc_find_parent_byname(const void *context, const char *name) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return NULL; - } - - tc = talloc_chunk_from_ptr(context); - while (tc) { - if (tc->name && strcmp(tc->name, name) == 0) { - return TC_PTR_FROM_CHUNK(tc); - } - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - return NULL; -} - -/* - show the parentage of a context -*/ -void talloc_show_parents(const void *context, FILE *file) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - fprintf(file, "talloc no parents for NULL\n"); - return; - } - - tc = talloc_chunk_from_ptr(context); - fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context)); - while (tc) { - fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc))); - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - fflush(file); -} - -/* - return 1 if ptr is a parent of context -*/ -int talloc_is_parent(const void *context, const void *ptr) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(context); - while (tc) { - if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - return 0; -} diff --git a/talloc/talloc.h b/talloc/talloc.h deleted file mode 100644 index 5431971655..0000000000 --- a/talloc/talloc.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef _TALLOC_H_ -#define _TALLOC_H_ -/* - Unix SMB/CIFS implementation. - Samba temporary memory allocation functions - - Copyright (C) Andrew Tridgell 2004-2005 - Copyright (C) Stefan Metzmacher 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include -#include -#include - -/* this is only needed for compatibility with the old talloc */ -typedef void TALLOC_CTX; - -/* - this uses a little trick to allow __LINE__ to be stringified -*/ -#ifndef __location__ -#define __TALLOC_STRING_LINE1__(s) #s -#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s) -#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__) -#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__ -#endif - -#ifndef TALLOC_DEPRECATED -#define TALLOC_DEPRECATED 0 -#endif - -#ifndef PRINTF_ATTRIBUTE -#if (__GNUC__ >= 3) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -/* try to make talloc_set_destructor() and talloc_steal() type safe, - if we have a recent gcc */ -#if (__GNUC__ >= 3) -#define _TALLOC_TYPEOF(ptr) __typeof__(ptr) -#define talloc_set_destructor(ptr, function) \ - do { \ - int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \ - _talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \ - } while(0) -/* this extremely strange macro is to avoid some braindamaged warning - stupidity in gcc 4.1.x */ -#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; }) -#else -#define talloc_set_destructor(ptr, function) \ - _talloc_set_destructor((ptr), (int (*)(void *))(function)) -#define _TALLOC_TYPEOF(ptr) void * -#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)) -#endif - -#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr)) -#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr)) - -/* useful macros for creating type checked pointers */ -#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) -#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) -#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) - -#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) - -#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) -#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) - -#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) -#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) -#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) -#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) - -#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) -#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) - -#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) - -#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) -#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) - -#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) - -#if TALLOC_DEPRECATED -#define talloc_zero_p(ctx, type) talloc_zero(ctx, type) -#define talloc_p(ctx, type) talloc(ctx, type) -#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) -#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) -#define talloc_destroy(ctx) talloc_free(ctx) -#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) -#endif - -/* The following definitions come from talloc.c */ -void *_talloc(const void *context, size_t size); -void *talloc_pool(const void *context, size_t size); -void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); -int talloc_increase_ref_count(const void *ptr); -size_t talloc_reference_count(const void *ptr); -void *_talloc_reference(const void *context, const void *ptr); -int talloc_unlink(const void *context, void *ptr); -const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -void talloc_set_name_const(const void *ptr, const char *name); -void *talloc_named(const void *context, size_t size, - const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); -void *talloc_named_const(const void *context, size_t size, const char *name); -const char *talloc_get_name(const void *ptr); -void *talloc_check_name(const void *ptr, const char *name); -void *talloc_parent(const void *ptr); -const char *talloc_parent_name(const void *ptr); -void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); -int talloc_free(void *ptr); -void talloc_free_children(void *ptr); -void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); -void *_talloc_steal(const void *new_ctx, const void *ptr); -void *_talloc_move(const void *new_ctx, const void *pptr); -size_t talloc_total_size(const void *ptr); -size_t talloc_total_blocks(const void *ptr); -void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *private_data), - void *private_data); -void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); -void talloc_report_full(const void *ptr, FILE *f); -void talloc_report(const void *ptr, FILE *f); -void talloc_enable_null_tracking(void); -void talloc_disable_null_tracking(void); -void talloc_enable_leak_report(void); -void talloc_enable_leak_report_full(void); -void *_talloc_zero(const void *ctx, size_t size, const char *name); -void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); -void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); -void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); -void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); -void *talloc_realloc_fn(const void *context, void *ptr, size_t size); -void *talloc_autofree_context(void); -size_t talloc_get_size(const void *ctx); -void *talloc_find_parent_byname(const void *ctx, const char *name); -void talloc_show_parents(const void *context, FILE *file); -int talloc_is_parent(const void *context, const void *ptr); - -char *talloc_strdup(const void *t, const char *p); -char *talloc_strdup_append(char *s, const char *a); -char *talloc_strdup_append_buffer(char *s, const char *a); - -char *talloc_strndup(const void *t, const char *p, size_t n); -char *talloc_strndup_append(char *s, const char *a, size_t n); -char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); - -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); - -char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -#endif diff --git a/talloc/talloc.i b/talloc/talloc.i deleted file mode 100644 index a9afb97ed7..0000000000 --- a/talloc/talloc.i +++ /dev/null @@ -1,31 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) Jelmer Vernooij 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* Don't expose talloc contexts in Python code. Python does reference - counting for us, so just create a new top-level talloc context. - */ -%typemap(in, numinputs=0, noblock=1) TALLOC_CTX * { - $1 = NULL; -} - -%define %talloctype(TYPE) -%nodefaultctor TYPE; -%extend TYPE { - ~TYPE() { talloc_free($self); } -} -%enddef diff --git a/talloc/talloc.mk b/talloc/talloc.mk deleted file mode 100644 index e1fe88c84b..0000000000 --- a/talloc/talloc.mk +++ /dev/null @@ -1,37 +0,0 @@ -TALLOC_OBJ = $(tallocdir)/talloc.o - -TALLOC_SOLIB = libtalloc.$(SHLIBEXT).$(PACKAGE_VERSION) -TALLOC_SONAME = libtalloc.$(SHLIBEXT).1 - -all:: libtalloc.a $(TALLOC_SOLIB) testsuite - -testsuite:: $(LIBOBJ) testsuite.o - $(CC) $(CFLAGS) -o testsuite testsuite.o $(LIBOBJ) $(LIBS) - -libtalloc.a: $(LIBOBJ) - ar -rv $@ $(LIBOBJ) - @-ranlib $@ - -install:: all - ${INSTALLCMD} -d $(DESTDIR)$(libdir) - ${INSTALLCMD} -d $(DESTDIR)$(libdir)/pkgconfig - ${INSTALLCMD} -m 755 libtalloc.a $(DESTDIR)$(libdir) - ${INSTALLCMD} -m 755 $(TALLOC_SOLIB) $(DESTDIR)$(libdir) - ${INSTALLCMD} -d $(DESTDIR)${includedir} - ${INSTALLCMD} -m 644 $(srcdir)/talloc.h $(DESTDIR)$(includedir) - ${INSTALLCMD} -m 644 talloc.pc $(DESTDIR)$(libdir)/pkgconfig - if [ -f talloc.3 ];then ${INSTALLCMD} -d $(DESTDIR)$(mandir)/man3; fi - if [ -f talloc.3 ];then ${INSTALLCMD} -m 644 talloc.3 $(DESTDIR)$(mandir)/man3; fi - which swig >/dev/null 2>&1 && ${INSTALLCMD} -d $(DESTDIR)`swig -swiglib` || true - which swig >/dev/null 2>&1 && ${INSTALLCMD} -m 644 talloc.i $(DESTDIR)`swig -swiglib` || true - -doc:: talloc.3 talloc.3.html - -clean:: - rm -f *~ $(LIBOBJ) $(TALLOC_SOLIB) libtalloc.a testsuite testsuite.o *.gc?? talloc.3 talloc.3.html - -test:: testsuite - ./testsuite - -gcov:: - gcov talloc.c diff --git a/talloc/talloc.pc.in b/talloc/talloc.pc.in deleted file mode 100644 index 459cce70b1..0000000000 --- a/talloc/talloc.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: talloc -Description: A hierarchical pool based memory system with destructors -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -ltalloc -Cflags: -I${includedir} -URL: http://talloc.samba.org/ diff --git a/talloc/talloc_guide.txt b/talloc/talloc_guide.txt deleted file mode 100644 index 18663b370d..0000000000 --- a/talloc/talloc_guide.txt +++ /dev/null @@ -1,685 +0,0 @@ -Using talloc in Samba4 ----------------------- - -Andrew Tridgell -September 2004 - -The most current version of this document is available at - http://samba.org/ftp/unpacked/samba4/source/lib/talloc/talloc_guide.txt - -If you are used to the "old" talloc from Samba3 before 3.0.20 then please read -this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the -Samba4 talloc has been ported back to Samba3, so this guide applies to both. - -The new talloc is a hierarchical, reference counted memory pool system -with destructors. Quite a mouthful really, but not too bad once you -get used to it. - -Perhaps the biggest change from Samba3 is that there is no distinction -between a "talloc context" and a "talloc pointer". Any pointer -returned from talloc() is itself a valid talloc context. This means -you can do this: - - struct foo *X = talloc(mem_ctx, struct foo); - X->name = talloc_strdup(X, "foo"); - -and the pointer X->name would be a "child" of the talloc context "X" -which is itself a child of mem_ctx. So if you do talloc_free(mem_ctx) -then it is all destroyed, whereas if you do talloc_free(X) then just X -and X->name are destroyed, and if you do talloc_free(X->name) then -just the name element of X is destroyed. - -If you think about this, then what this effectively gives you is an -n-ary tree, where you can free any part of the tree with -talloc_free(). - -If you find this confusing, then I suggest you run the testsuite to -watch talloc in action. You may also like to add your own tests to -testsuite.c to clarify how some particular situation is handled. - - -Performance ------------ - -All the additional features of talloc() over malloc() do come at a -price. We have a simple performance test in Samba4 that measures -talloc() versus malloc() performance, and it seems that talloc() is -about 4% slower than malloc() on my x86 Debian Linux box. For Samba, -the great reduction in code complexity that we get by using talloc -makes this worthwhile, especially as the total overhead of -talloc/malloc in Samba is already quite small. - - -talloc API ----------- - -The following is a complete guide to the talloc API. Read it all at -least twice. - -Multi-threading ---------------- - -talloc itself does not deal with threads. It is thread-safe (assuming -the underlying "malloc" is), as long as each thread uses different -memory contexts. -If two threads uses the same context then they need to synchronize in -order to be safe. In particular: -- when using talloc_enable_leak_report(), giving directly NULL as a -parent context implicitly refers to a hidden "null context" global -variable, so this should not be used in a multi-threaded environment -without proper synchronization ; -- the context returned by talloc_autofree_context() is also global so -shouldn't be used by several threads simultaneously without -synchronization. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc(const void *context, type); - -The talloc() macro is the core of the talloc library. It takes a -memory context and a type, and returns a pointer to a new area of -memory of the given type. - -The returned pointer is itself a talloc context, so you can use it as -the context argument to more calls to talloc if you wish. - -The returned pointer is a "child" of the supplied context. This means -that if you talloc_free() the context then the new child disappears as -well. Alternatively you can free just the child. - -The context argument to talloc() can be NULL, in which case a new top -level context is created. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_size(const void *context, size_t size); - -The function talloc_size() should be used when you don't have a -convenient type to pass to talloc(). Unlike talloc(), it is not type -safe (as it returns a void *), so you are on your own for type checking. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); - -The talloc_ptrtype() macro should be used when you have a pointer and -want to allocate memory to point at with this pointer. When compiling -with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() -and talloc_get_name() will return the current location in the source file. -and not the type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_free(void *ptr); - -The talloc_free() function frees a piece of talloc memory, and all its -children. You can call talloc_free() on any pointer returned by -talloc(). - -The return value of talloc_free() indicates success or failure, with 0 -returned for success and -1 for failure. The only possible failure -condition is if the pointer had a destructor attached to it and the -destructor returned -1. See talloc_set_destructor() for details on -destructors. - -If this pointer has an additional parent when talloc_free() is called -then the memory is not actually released, but instead the most -recently established parent is destroyed. See talloc_reference() for -details on establishing additional parents. - -For more control on which parent is removed, see talloc_unlink() - -talloc_free() operates recursively on its children. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_free_children(void *ptr); - -The talloc_free_children() walks along the list of all children of a -talloc context and talloc_free()s only the children, not the context -itself. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_reference(const void *context, const void *ptr); - -The talloc_reference() function makes "context" an additional parent -of "ptr". - -The return value of talloc_reference() is always the original pointer -"ptr", unless talloc ran out of memory in creating the reference in -which case it will return NULL (each additional reference consumes -around 48 bytes of memory on intel x86 platforms). - -If "ptr" is NULL, then the function is a no-op, and simply returns NULL. - -After creating a reference you can free it in one of the following -ways: - - - you can talloc_free() any parent of the original pointer. That - will reduce the number of parents of this pointer by 1, and will - cause this pointer to be freed if it runs out of parents. - - - you can talloc_free() the pointer itself. That will destroy the - most recently established parent to the pointer and leave the - pointer as a child of its current parent. - -For more control on which parent to remove, see talloc_unlink() - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_unlink(const void *context, const void *ptr); - -The talloc_unlink() function removes a specific parent from ptr. The -context passed must either be a context used in talloc_reference() -with this pointer, or must be a direct parent of ptr. - -Note that if the parent has already been removed using talloc_free() -then this function will fail and will return -1. Likewise, if "ptr" -is NULL, then the function will make no modifications and return -1. - -Usually you can just use talloc_free() instead of talloc_unlink(), but -sometimes it is useful to have the additional control on which parent -is removed. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - -The function talloc_set_destructor() sets the "destructor" for the -pointer "ptr". A destructor is a function that is called when the -memory used by a pointer is about to be released. The destructor -receives the pointer as an argument, and should return 0 for success -and -1 for failure. - -The destructor can do anything it wants to, including freeing other -pieces of memory. A common use for destructors is to clean up -operating system resources (such as open file descriptors) contained -in the structure the destructor is placed on. - -You can only place one destructor on a pointer. If you need more than -one destructor then you can create a zero-length child of the pointer -and place an additional destructor on that. - -To remove a destructor call talloc_set_destructor() with NULL for the -destructor. - -If your destructor attempts to talloc_free() the pointer that it is -the destructor for then talloc_free() will return -1 and the free will -be ignored. This would be a pointless operation anyway, as the -destructor is only called when the memory is just about to go away. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_increase_ref_count(const void *ptr); - -The talloc_increase_ref_count(ptr) function is exactly equivalent to: - - talloc_reference(NULL, ptr); - -You can use either syntax, depending on which you think is clearer in -your code. - -It returns 0 on success and -1 on failure. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_reference_count(const void *ptr); - -Return the number of references to the pointer. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name(const void *ptr, const char *fmt, ...); - -Each talloc pointer has a "name". The name is used principally for -debugging purposes, although it is also possible to set and get the -name on a pointer in as a way of "marking" pointers in your code. - -The main use for names on pointer is for "talloc reports". See -talloc_report() and talloc_report_full() for details. Also see -talloc_enable_leak_report() and talloc_enable_leak_report_full(). - -The talloc_set_name() function allocates memory as a child of the -pointer. It is logically equivalent to: - talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - -Note that multiple calls to talloc_set_name() will allocate more -memory without releasing the name. All of the memory is released when -the ptr is freed using talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name_const(const void *ptr, const char *name); - -The function talloc_set_name_const() is just like talloc_set_name(), -but it takes a string constant, and is much faster. It is extensively -used by the "auto naming" macros, such as talloc_p(). - -This function does not allocate any memory. It just copies the -supplied pointer into the internal representation of the talloc -ptr. This means you must not pass a name pointer to memory that will -disappear before the ptr is freed with talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named(const void *context, size_t size, const char *fmt, ...); - -The talloc_named() function creates a named talloc pointer. It is -equivalent to: - - ptr = talloc_size(context, size); - talloc_set_name(ptr, fmt, ....); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named_const(const void *context, size_t size, const char *name); - -This is equivalent to: - - ptr = talloc_size(context, size); - talloc_set_name_const(ptr, name); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const char *talloc_get_name(const void *ptr); - -This returns the current name for the given talloc pointer. See -talloc_set_name() for details. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_init(const char *fmt, ...); - -This function creates a zero length named talloc context as a top -level context. It is equivalent to: - - talloc_named(NULL, 0, fmt, ...); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_new(void *ctx); - -This is a utility macro that creates a new memory context hanging -off an exiting context, automatically naming it "talloc_new: __location__" -where __location__ is the source line it is called from. It is -particularly useful for creating a new temporary working context. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_realloc(const void *context, void *ptr, type, count); - -The talloc_realloc() macro changes the size of a talloc -pointer. The "count" argument is the number of elements of type "type" -that you want the resulting pointer to hold. - -talloc_realloc() has the following equivalences: - - talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); - talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); - talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); - -The "context" argument is only used if "ptr" is NULL, otherwise it is -ignored. - -talloc_realloc() returns the new pointer, or NULL on failure. The call -will fail either due to a lack of memory, or because the pointer has -more than one parent (see talloc_reference()). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_realloc_size(const void *context, void *ptr, size_t size); - -the talloc_realloc_size() function is useful when the type is not -known so the typesafe talloc_realloc() cannot be used. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_steal(const void *new_ctx, const void *ptr); - -The talloc_steal() function changes the parent context of a talloc -pointer. It is typically used when the context that the pointer is -currently a child of is going to be freed and you wish to keep the -memory for a longer time. - -The talloc_steal() function returns the pointer that you pass it. It -does not have any failure modes. - -NOTE: It is possible to produce loops in the parent/child relationship -if you are not careful with talloc_steal(). No guarantees are provided -as to your sanity or the safety of your data if you do this. - -talloc_steal (new_ctx, NULL) will return NULL with no sideeffects. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_total_size(const void *ptr); - -The talloc_total_size() function returns the total size in bytes used -by this pointer and all child pointers. Mostly useful for debugging. - -Passing NULL is allowed, but it will only give a meaningful result if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_total_blocks(const void *ptr); - -The talloc_total_blocks() function returns the total memory block -count used by this pointer and all child pointers. Mostly useful for -debugging. - -Passing NULL is allowed, but it will only give a meaningful result if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *priv), - void *priv); - -This provides a more flexible reports than talloc_report(). It -will recursively call the callback for the entire tree of memory -referenced by the pointer. References in the tree are passed with -is_ref = 1 and the pointer that is referenced. - -You can pass NULL for the pointer, in which case a report is -printed for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() -has been called. - -The recursion is stopped when depth >= max_depth. -max_depth = -1 means only stop at leaf nodes. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); - -This provides a more flexible reports than talloc_report(). It -will let you specify the depth and max_depth. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report(const void *ptr, FILE *f); - -The talloc_report() function prints a summary report of all memory -used by ptr. One line of report is printed for each immediate child of -ptr, showing the total memory and number of blocks used by that child. - -You can pass NULL for the pointer, in which case a report is printed -for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_full(const void *ptr, FILE *f); - -This provides a more detailed report than talloc_report(). It will -recursively print the ensire tree of memory referenced by the -pointer. References in the tree are shown by giving the name of the -pointer that is referenced. - -You can pass NULL for the pointer, in which case a report is printed -for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_leak_report(void); - -This enables calling of talloc_report(NULL, stderr) when the program -exits. In Samba4 this is enabled by using the --leak-report command -line option. - -For it to be useful, this function must be called before any other -talloc function as it establishes a "null context" that acts as the -top of the tree. If you don't call this function first then passing -NULL to talloc_report() or talloc_report_full() won't give you the -full tree printout. - -Here is a typical talloc report: - -talloc report on 'null_context' (total 267 bytes in 15 blocks) - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(UTF8,CP850) contains 42 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(CP850,UTF8) contains 42 bytes in 2 blocks - iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks - iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_leak_report_full(void); - -This enables calling of talloc_report_full(NULL, stderr) when the -program exits. In Samba4 this is enabled by using the ---leak-report-full command line option. - -For it to be useful, this function must be called before any other -talloc function as it establishes a "null context" that acts as the -top of the tree. If you don't call this function first then passing -NULL to talloc_report() or talloc_report_full() won't give you the -full tree printout. - -Here is a typical full report: - -full talloc report on 'root' (total 18 bytes in 8 blocks) - p1 contains 18 bytes in 7 blocks (ref 0) - r1 contains 13 bytes in 2 blocks (ref 0) - reference to: p2 - p2 contains 1 bytes in 1 blocks (ref 1) - x3 contains 1 bytes in 1 blocks (ref 0) - x2 contains 1 bytes in 1 blocks (ref 0) - x1 contains 1 bytes in 1 blocks (ref 0) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_null_tracking(void); - -This enables tracking of the NULL memory context without enabling leak -reporting on exit. Useful for when you want to do your own leak -reporting call via talloc_report_null_full(); - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_disable_null_tracking(void); - -This disables tracking of the NULL memory context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_zero(const void *ctx, type); - -The talloc_zero() macro is equivalent to: - - ptr = talloc(ctx, type); - if (ptr) memset(ptr, 0, sizeof(type)); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_zero_size(const void *ctx, size_t size) - -The talloc_zero_size() function is useful when you don't have a known type - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_memdup(const void *ctx, const void *p, size_t size); - -The talloc_memdup() function is equivalent to: - - ptr = talloc_size(ctx, size); - if (ptr) memcpy(ptr, p, size); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_strdup(const void *ctx, const char *p); - -The talloc_strdup() function is equivalent to: - - ptr = talloc_size(ctx, strlen(p)+1); - if (ptr) memcpy(ptr, p, strlen(p)+1); - -This functions sets the name of the new pointer to the passed -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_strndup(const void *t, const char *p, size_t n); - -The talloc_strndup() function is the talloc equivalent of the C -library function strndup() - -This functions sets the name of the new pointer to the passed -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_append_string(const void *t, char *orig, const char *append); - -The talloc_append_string() function appends the given formatted -string to the given string. - -This function sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); - -The talloc_vasprintf() function is the talloc equivalent of the C -library function vasprintf() - -This functions sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf(const void *t, const char *fmt, ...); - -The talloc_asprintf() function is the talloc equivalent of the C -library function asprintf() - -This functions sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf_append(char *s, const char *fmt, ...); - -The talloc_asprintf_append() function appends the given formatted -string to the given string. -Use this varient when the string in the current talloc buffer may -have been truncated in length. - -This functions sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); - -The talloc_asprintf_append() function appends the given formatted -string to the end of the currently allocated talloc buffer. -Use this varient when the string in the current talloc buffer has -not been changed. - -This functions sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -((type *)talloc_array(const void *ctx, type, uint_t count); - -The talloc_array() macro is equivalent to: - - (type *)talloc_size(ctx, sizeof(type) * count); - -except that it provides integer overflow protection for the multiply, -returning NULL if the multiply overflows. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_array_size(const void *ctx, size_t size, uint_t count); - -The talloc_array_size() function is useful when the type is not -known. It operates in the same way as talloc_array(), but takes a size -instead of a type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, uint_t count); - -The talloc_ptrtype() macro should be used when you have a pointer to an array -and want to allocate memory of an array to point at with this pointer. When compiling -with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() -and talloc_get_name() will return the current location in the source file. -and not the type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size); - -This is a non-macro version of talloc_realloc(), which is useful -as libraries sometimes want a ralloc function pointer. A realloc() -implementation encapsulates the functionality of malloc(), free() and -realloc() in one call, which is why it is useful to be able to pass -around a single function pointer. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_autofree_context(void); - -This is a handy utility function that returns a talloc context -which will be automatically freed on program exit. This can be used -to reduce the noise in memory leak reports. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_check_name(const void *ptr, const char *name); - -This function checks if a pointer has the specified name. If it does -then the pointer is returned. It it doesn't then NULL is returned. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_get_type(const void *ptr, type); - -This macro allows you to do type checking on talloc pointers. It is -particularly useful for void* private pointers. It is equivalent to -this: - - (type *)talloc_check_name(ptr, #type) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -talloc_set_type(const void *ptr, type); - -This macro allows you to force the name of a pointer to be a -particular type. This can be used in conjunction with -talloc_get_type() to do type checking on void* pointers. - -It is equivalent to this: - talloc_set_name_const(ptr, #type) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -talloc_get_size(const void *ctx); - -This function lets you know the amount of memory alloced so far by -this context. It does NOT account for subcontext memory. -This can be used to calculate the size of an array. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_find_parent_byname(const void *ctx, const char *name); - -Find a parent memory context of the current context that has the given -name. This can be very useful in complex programs where it may be -difficult to pass all information down to the level you need, but you -know the structure you want is a parent of another context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_find_parent_bytype(ctx, type); - -Like talloc_find_parent_byname() but takes a type, making it typesafe. - diff --git a/talloc/testsuite.c b/talloc/testsuite.c deleted file mode 100644 index 3f06eee566..0000000000 --- a/talloc/testsuite.c +++ /dev/null @@ -1,1152 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - local testing of talloc routines. - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/time.h" -#include "talloc.h" - -static struct timeval timeval_current(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv; -} - -static double timeval_elapsed(struct timeval *tv) -{ - struct timeval tv2 = timeval_current(); - return (tv2.tv_sec - tv->tv_sec) + - (tv2.tv_usec - tv->tv_usec)*1.0e-6; -} - -#define torture_assert(test, expr, str) if (!(expr)) { \ - printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \ - test, __location__, #expr, str); \ - return false; \ -} - -#define torture_assert_str_equal(test, arg1, arg2, desc) \ - if (arg1 == NULL && arg2 == NULL) { \ - } else if (strcmp(arg1, arg2)) { \ - printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \ - test, __location__, arg1, arg2, desc); \ - return false; \ - } - -#if _SAMBA_BUILD_==3 -#ifdef malloc -#undef malloc -#endif -#ifdef strdup -#undef strdup -#endif -#endif - -#define CHECK_SIZE(test, ptr, tsize) do { \ - if (talloc_total_size(ptr) != (tsize)) { \ - printf("failed: %s [\nwrong '%s' tree size: got %u expected %u\n]\n", \ - test, #ptr, \ - (unsigned)talloc_total_size(ptr), \ - (unsigned)tsize); \ - talloc_report_full(ptr, stdout); \ - return false; \ - } \ -} while (0) - -#define CHECK_BLOCKS(test, ptr, tblocks) do { \ - if (talloc_total_blocks(ptr) != (tblocks)) { \ - printf("failed: %s [\nwrong '%s' tree blocks: got %u expected %u\n]\n", \ - test, #ptr, \ - (unsigned)talloc_total_blocks(ptr), \ - (unsigned)tblocks); \ - talloc_report_full(ptr, stdout); \ - return false; \ - } \ -} while (0) - -#define CHECK_PARENT(test, ptr, parent) do { \ - if (talloc_parent(ptr) != (parent)) { \ - printf("failed: %s [\n'%s' has wrong parent: got %p expected %p\n]\n", \ - test, #ptr, \ - talloc_parent(ptr), \ - (parent)); \ - talloc_report_full(ptr, stdout); \ - talloc_report_full(parent, stdout); \ - talloc_report_full(NULL, stdout); \ - return false; \ - } \ -} while (0) - - -/* - test references -*/ -static bool test_ref1(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref1\n# SINGLE REFERENCE FREE\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - p2 = talloc_named_const(p1, 1, "p2"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 2, "x2"); - talloc_named_const(p1, 3, "x3"); - - r1 = talloc_named_const(root, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref1", p1, 5); - CHECK_BLOCKS("ref1", p2, 1); - CHECK_BLOCKS("ref1", r1, 2); - - fprintf(stderr, "Freeing p2\n"); - talloc_free(p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref1", p1, 5); - CHECK_BLOCKS("ref1", p2, 1); - CHECK_BLOCKS("ref1", r1, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref1", r1, 1); - - fprintf(stderr, "Freeing r1\n"); - talloc_free(r1); - talloc_report_full(NULL, stderr); - - fprintf(stderr, "Testing NULL\n"); - if (talloc_reference(root, NULL)) { - return false; - } - - CHECK_BLOCKS("ref1", root, 1); - - CHECK_SIZE("ref1", root, 0); - - talloc_free(root); - printf("success: ref1\n"); - return true; -} - -/* - test references -*/ -static bool test_ref2(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref2\n# DOUBLE REFERENCE FREE\n"); - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 1, "x2"); - talloc_named_const(p1, 1, "x3"); - p2 = talloc_named_const(p1, 1, "p2"); - - r1 = talloc_named_const(root, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", p1, 5); - CHECK_BLOCKS("ref2", p2, 1); - CHECK_BLOCKS("ref2", r1, 2); - - fprintf(stderr, "Freeing ref\n"); - talloc_free(ref); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", p1, 5); - CHECK_BLOCKS("ref2", p2, 1); - CHECK_BLOCKS("ref2", r1, 1); - - fprintf(stderr, "Freeing p2\n"); - talloc_free(p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", p1, 4); - CHECK_BLOCKS("ref2", r1, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", r1, 1); - - fprintf(stderr, "Freeing r1\n"); - talloc_free(r1); - talloc_report_full(root, stderr); - - CHECK_SIZE("ref2", root, 0); - - talloc_free(root); - printf("success: ref2\n"); - return true; -} - -/* - test references -*/ -static bool test_ref3(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref3\n# PARENT REFERENCE FREE\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - p2 = talloc_named_const(root, 1, "p2"); - r1 = talloc_named_const(p1, 1, "r1"); - ref = talloc_reference(p2, r1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref3", p1, 2); - CHECK_BLOCKS("ref3", p2, 2); - CHECK_BLOCKS("ref3", r1, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref3", p2, 2); - CHECK_BLOCKS("ref3", r1, 1); - - fprintf(stderr, "Freeing p2\n"); - talloc_free(p2); - talloc_report_full(root, stderr); - - CHECK_SIZE("ref3", root, 0); - - talloc_free(root); - - printf("success: ref3\n"); - return true; -} - -/* - test references -*/ -static bool test_ref4(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref4\n# REFERRER REFERENCE FREE\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 1, "x2"); - talloc_named_const(p1, 1, "x3"); - p2 = talloc_named_const(p1, 1, "p2"); - - r1 = talloc_named_const(root, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref4", p1, 5); - CHECK_BLOCKS("ref4", p2, 1); - CHECK_BLOCKS("ref4", r1, 2); - - fprintf(stderr, "Freeing r1\n"); - talloc_free(r1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref4", p1, 5); - CHECK_BLOCKS("ref4", p2, 1); - - fprintf(stderr, "Freeing p2\n"); - talloc_free(p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref4", p1, 4); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_SIZE("ref4", root, 0); - - talloc_free(root); - - printf("success: ref4\n"); - return true; -} - - -/* - test references -*/ -static bool test_unlink1(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: unlink\n# UNLINK\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 1, "x2"); - talloc_named_const(p1, 1, "x3"); - p2 = talloc_named_const(p1, 1, "p2"); - - r1 = talloc_named_const(p1, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("unlink", p1, 7); - CHECK_BLOCKS("unlink", p2, 1); - CHECK_BLOCKS("unlink", r1, 2); - - fprintf(stderr, "Unreferencing r1\n"); - talloc_unlink(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("unlink", p1, 6); - CHECK_BLOCKS("unlink", p2, 1); - CHECK_BLOCKS("unlink", r1, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_SIZE("unlink", root, 0); - - talloc_free(root); - - printf("success: unlink\n"); - return true; -} - -static int fail_destructor(void *ptr) -{ - return -1; -} - -/* - miscellaneous tests to try to get a higher test coverage percentage -*/ -static bool test_misc(void) -{ - void *root, *p1; - char *p2; - double *d; - const char *name; - - printf("test: misc\n# MISCELLANEOUS\n"); - - root = talloc_new(NULL); - - p1 = talloc_size(root, 0x7fffffff); - torture_assert("misc", !p1, "failed: large talloc allowed\n"); - - p1 = talloc_strdup(root, "foo"); - talloc_increase_ref_count(p1); - talloc_increase_ref_count(p1); - talloc_increase_ref_count(p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - talloc_free(p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - talloc_unlink(NULL, p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - p2 = talloc_strdup(p1, "foo"); - torture_assert("misc", talloc_unlink(root, p2) == -1, - "failed: talloc_unlink() of non-reference context should return -1\n"); - torture_assert("misc", talloc_unlink(p1, p2) == 0, - "failed: talloc_unlink() of parent should succeed\n"); - talloc_free(p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - - name = talloc_set_name(p1, "my name is %s", "foo"); - torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", - "failed: wrong name after talloc_set_name(my name is foo)"); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - - talloc_set_name_const(p1, NULL); - torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", - "failed: wrong name after talloc_set_name(NULL)"); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - - torture_assert("misc", talloc_free(NULL) == -1, - "talloc_free(NULL) should give -1\n"); - - talloc_set_destructor(p1, fail_destructor); - torture_assert("misc", talloc_free(p1) == -1, - "Failed destructor should cause talloc_free to fail\n"); - talloc_set_destructor(p1, NULL); - - talloc_report(root, stderr); - - - p2 = (char *)talloc_zero_size(p1, 20); - torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); - talloc_free(p2); - - torture_assert("misc", talloc_strdup(root, NULL) == NULL, - "failed: strdup on NULL should give NULL\n"); - - p2 = talloc_strndup(p1, "foo", 2); - torture_assert("misc", strcmp("fo", p2) == 0, - "strndup doesn't work\n"); - p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); - torture_assert("misc", strcmp("food", p2) == 0, - "talloc_asprintf_append_buffer doesn't work\n"); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 3); - - p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); - torture_assert("misc", strcmp("hello world", p2) == 0, - "talloc_asprintf_append_buffer doesn't work\n"); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 3); - talloc_free(p2); - - d = talloc_array(p1, double, 0x20000000); - torture_assert("misc", !d, "failed: integer overflow not detected\n"); - - d = talloc_realloc(p1, d, double, 0x20000000); - torture_assert("misc", !d, "failed: integer overflow not detected\n"); - - talloc_free(p1); - CHECK_BLOCKS("misc", root, 1); - - p1 = talloc_named(root, 100, "%d bytes", 100); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - talloc_unlink(root, p1); - - p1 = talloc_init("%d bytes", 200); - p2 = talloc_asprintf(p1, "my test '%s'", "string"); - torture_assert_str_equal("misc", p2, "my test 'string'", - "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); - CHECK_BLOCKS("misc", p1, 3); - CHECK_SIZE("misc", p2, 17); - CHECK_BLOCKS("misc", root, 1); - talloc_unlink(NULL, p1); - - p1 = talloc_named_const(root, 10, "p1"); - p2 = (char *)talloc_named_const(root, 20, "p2"); - (void)talloc_reference(p1, p2); - talloc_report_full(root, stderr); - talloc_unlink(root, p2); - talloc_report_full(root, stderr); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - talloc_unlink(p1, p2); - talloc_unlink(root, p1); - - p1 = talloc_named_const(root, 10, "p1"); - p2 = (char *)talloc_named_const(root, 20, "p2"); - (void)talloc_reference(NULL, p2); - talloc_report_full(root, stderr); - talloc_unlink(root, p2); - talloc_report_full(root, stderr); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - talloc_unlink(NULL, p2); - talloc_unlink(root, p1); - - /* Test that talloc_unlink is a no-op */ - - torture_assert("misc", talloc_unlink(root, NULL) == -1, - "failed: talloc_unlink(root, NULL) == -1\n"); - - talloc_report(root, stderr); - talloc_report(NULL, stderr); - - CHECK_SIZE("misc", root, 0); - - talloc_free(root); - - CHECK_SIZE("misc", NULL, 0); - - talloc_enable_leak_report(); - talloc_enable_leak_report_full(); - - printf("success: misc\n"); - - return true; -} - - -/* - test realloc -*/ -static bool test_realloc(void) -{ - void *root, *p1, *p2; - - printf("test: realloc\n# REALLOC\n"); - - root = talloc_new(NULL); - - p1 = talloc_size(root, 10); - CHECK_SIZE("realloc", p1, 10); - - p1 = talloc_realloc_size(NULL, p1, 20); - CHECK_SIZE("realloc", p1, 20); - - talloc_new(p1); - - p2 = talloc_realloc_size(p1, NULL, 30); - - talloc_new(p1); - - p2 = talloc_realloc_size(p1, p2, 40); - - CHECK_SIZE("realloc", p2, 40); - CHECK_SIZE("realloc", root, 60); - CHECK_BLOCKS("realloc", p1, 4); - - p1 = talloc_realloc_size(NULL, p1, 20); - CHECK_SIZE("realloc", p1, 60); - - talloc_increase_ref_count(p2); - torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL, - "failed: talloc_realloc() on a referenced pointer should fail\n"); - CHECK_BLOCKS("realloc", p1, 4); - - talloc_realloc_size(NULL, p2, 0); - talloc_realloc_size(NULL, p2, 0); - CHECK_BLOCKS("realloc", p1, 3); - - torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL, - "failed: oversize talloc should fail\n"); - - talloc_realloc_size(NULL, p1, 0); - - CHECK_BLOCKS("realloc", root, 1); - CHECK_SIZE("realloc", root, 0); - - talloc_free(root); - - printf("success: realloc\n"); - - return true; -} - -/* - test realloc with a child -*/ -static bool test_realloc_child(void) -{ - void *root; - struct el2 { - const char *name; - } *el2; - struct el1 { - int count; - struct el2 **list, **list2, **list3; - } *el1; - - printf("test: REALLOC WITH CHILD\n"); - - root = talloc_new(NULL); - - el1 = talloc(root, struct el1); - el1->list = talloc(el1, struct el2 *); - el1->list[0] = talloc(el1->list, struct el2); - el1->list[0]->name = talloc_strdup(el1->list[0], "testing"); - - el1->list2 = talloc(el1, struct el2 *); - el1->list2[0] = talloc(el1->list2, struct el2); - el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2"); - - el1->list3 = talloc(el1, struct el2 *); - el1->list3[0] = talloc(el1->list3, struct el2); - el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2"); - - el2 = talloc(el1->list, struct el2); - el2 = talloc(el1->list2, struct el2); - el2 = talloc(el1->list3, struct el2); - - el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); - el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200); - el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300); - - talloc_free(root); - - printf("success: REALLOC WITH CHILD\n"); - return true; -} - -/* - test type checking -*/ -static bool test_type(void) -{ - void *root; - struct el1 { - int count; - }; - struct el2 { - int count; - }; - struct el1 *el1; - - printf("test: type\n# talloc type checking\n"); - - root = talloc_new(NULL); - - el1 = talloc(root, struct el1); - - el1->count = 1; - - torture_assert("type", talloc_get_type(el1, struct el1) == el1, - "type check failed on el1\n"); - torture_assert("type", talloc_get_type(el1, struct el2) == NULL, - "type check failed on el1 with el2\n"); - talloc_set_type(el1, struct el2); - torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1, - "type set failed on el1 with el2\n"); - - talloc_free(root); - - printf("success: type\n"); - return true; -} - -/* - test steal -*/ -static bool test_steal(void) -{ - void *root, *p1, *p2; - - printf("test: steal\n# STEAL\n"); - - root = talloc_new(NULL); - - p1 = talloc_array(root, char, 10); - CHECK_SIZE("steal", p1, 10); - - p2 = talloc_realloc(root, NULL, char, 20); - CHECK_SIZE("steal", p1, 10); - CHECK_SIZE("steal", root, 30); - - torture_assert("steal", talloc_steal(p1, NULL) == NULL, - "failed: stealing NULL should give NULL\n"); - - torture_assert("steal", talloc_steal(p1, p1) == p1, - "failed: stealing to ourselves is a nop\n"); - CHECK_BLOCKS("steal", root, 3); - CHECK_SIZE("steal", root, 30); - - talloc_steal(NULL, p1); - talloc_steal(NULL, p2); - CHECK_BLOCKS("steal", root, 1); - CHECK_SIZE("steal", root, 0); - - talloc_free(p1); - talloc_steal(root, p2); - CHECK_BLOCKS("steal", root, 2); - CHECK_SIZE("steal", root, 20); - - talloc_free(p2); - - CHECK_BLOCKS("steal", root, 1); - CHECK_SIZE("steal", root, 0); - - talloc_free(root); - - p1 = talloc_size(NULL, 3); - talloc_report_full(NULL, stderr); - CHECK_SIZE("steal", NULL, 3); - talloc_free(p1); - - printf("success: steal\n"); - return true; -} - -/* - test move -*/ -static bool test_move(void) -{ - void *root; - struct t_move { - char *p; - int *x; - } *t1, *t2; - - printf("test: move\n# MOVE\n"); - - root = talloc_new(NULL); - - t1 = talloc(root, struct t_move); - t2 = talloc(root, struct t_move); - t1->p = talloc_strdup(t1, "foo"); - t1->x = talloc(t1, int); - *t1->x = 42; - - t2->p = talloc_move(t2, &t1->p); - t2->x = talloc_move(t2, &t1->x); - torture_assert("move", t1->p == NULL && t1->x == NULL && - strcmp(t2->p, "foo") == 0 && *t2->x == 42, - "talloc move failed"); - - talloc_free(root); - - printf("success: move\n"); - - return true; -} - -/* - test talloc_realloc_fn -*/ -static bool test_realloc_fn(void) -{ - void *root, *p1; - - printf("test: realloc_fn\n# talloc_realloc_fn\n"); - - root = talloc_new(NULL); - - p1 = talloc_realloc_fn(root, NULL, 10); - CHECK_BLOCKS("realloc_fn", root, 2); - CHECK_SIZE("realloc_fn", root, 10); - p1 = talloc_realloc_fn(root, p1, 20); - CHECK_BLOCKS("realloc_fn", root, 2); - CHECK_SIZE("realloc_fn", root, 20); - p1 = talloc_realloc_fn(root, p1, 0); - CHECK_BLOCKS("realloc_fn", root, 1); - CHECK_SIZE("realloc_fn", root, 0); - - talloc_free(root); - - printf("success: realloc_fn\n"); - return true; -} - - -static bool test_unref_reparent(void) -{ - void *root, *p1, *p2, *c1; - - printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "orig parent"); - p2 = talloc_named_const(root, 1, "parent by reference"); - - c1 = talloc_named_const(p1, 1, "child"); - talloc_reference(p2, c1); - - CHECK_PARENT("unref_reparent", c1, p1); - - talloc_free(p1); - - CHECK_PARENT("unref_reparent", c1, p2); - - talloc_unlink(p2, c1); - - CHECK_SIZE("unref_reparent", root, 1); - - talloc_free(p2); - talloc_free(root); - - printf("success: unref_reparent\n"); - return true; -} - -/* - measure the speed of talloc versus malloc -*/ -static bool test_speed(void) -{ - void *ctx = talloc_new(NULL); - unsigned count; - const int loop = 1000; - int i; - struct timeval tv; - - printf("test: speed\n# TALLOC VS MALLOC SPEED\n"); - - tv = timeval_current(); - count = 0; - do { - void *p1, *p2, *p3; - for (i=0;ireq2 = talloc_strdup(req1, "req2"); - talloc_set_destructor(req1->req2, test_loop_destructor); - req1->req3 = talloc_strdup(req1, "req3"); - (void)talloc_reference(req1->req3, req1); - talloc_report_full(top, stderr); - talloc_free(parent); - talloc_report_full(top, stderr); - talloc_report_full(NULL, stderr); - talloc_free(top); - - torture_assert("loop", loop_destructor_count == 1, - "FAILED TO FIRE LOOP DESTRUCTOR\n"); - loop_destructor_count = 0; - - printf("success: loop\n"); - return true; -} - -static int fail_destructor_str(char *ptr) -{ - return -1; -} - -static bool test_free_parent_deny_child(void) -{ - void *top = talloc_new(NULL); - char *level1; - char *level2; - char *level3; - - printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n"); - - level1 = talloc_strdup(top, "level1"); - level2 = talloc_strdup(level1, "level2"); - level3 = talloc_strdup(level2, "level3"); - - talloc_set_destructor(level3, fail_destructor_str); - talloc_free(level1); - talloc_set_destructor(level3, NULL); - - CHECK_PARENT("free_parent_deny_child", level3, top); - - talloc_free(top); - - printf("success: free_parent_deny_child\n"); - return true; -} - -static bool test_talloc_ptrtype(void) -{ - void *top = talloc_new(NULL); - struct struct1 { - int foo; - int bar; - } *s1, *s2, **s3, ***s4; - const char *location1; - const char *location2; - const char *location3; - const char *location4; - - printf("test: ptrtype\n# TALLOC PTRTYPE\n"); - - s1 = talloc_ptrtype(top, s1);location1 = __location__; - - if (talloc_get_size(s1) != sizeof(struct struct1)) { - printf("failure: ptrtype [\n" - "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n" - "]\n", (unsigned long)talloc_get_size(s1), - (unsigned long)sizeof(struct struct1)); - return false; - } - - if (strcmp(location1, talloc_get_name(s1)) != 0) { - printf("failure: ptrtype [\n" - "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", - talloc_get_name(s1), location1); - return false; - } - - s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__; - - if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() allocated the wrong size " - "%lu (should be %lu)\n]\n", - (unsigned long)talloc_get_size(s2), - (unsigned long)(sizeof(struct struct1)*10)); - return false; - } - - if (strcmp(location2, talloc_get_name(s2)) != 0) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", - talloc_get_name(s2), location2); - return false; - } - - s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__; - - if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() allocated the wrong size " - "%lu (should be %lu)\n]\n", - (unsigned long)talloc_get_size(s3), - (unsigned long)(sizeof(struct struct1 *)*10)); - return false; - } - - torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3), - "talloc_array_ptrtype() sets the wrong name"); - - s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; - - if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() allocated the wrong size " - "%lu (should be %lu)\n]\n", - (unsigned long)talloc_get_size(s4), - (unsigned long)(sizeof(struct struct1 **)*10)); - return false; - } - - torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4), - "talloc_array_ptrtype() sets the wrong name"); - - talloc_free(top); - - printf("success: ptrtype\n"); - return true; -} - -static int _test_talloc_free_in_destructor(void **ptr) -{ - talloc_free(*ptr); - return 0; -} - -static bool test_talloc_free_in_destructor(void) -{ - void *level0; - void *level1; - void *level2; - void *level3; - void *level4; - void **level5; - - printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n"); - - level0 = talloc_new(NULL); - level1 = talloc_new(level0); - level2 = talloc_new(level1); - level3 = talloc_new(level2); - level4 = talloc_new(level3); - level5 = talloc(level4, void *); - - *level5 = level3; - (void)talloc_reference(level0, level3); - (void)talloc_reference(level3, level3); - (void)talloc_reference(level5, level3); - - talloc_set_destructor(level5, _test_talloc_free_in_destructor); - - talloc_free(level1); - - talloc_free(level0); - - printf("success: free_in_destructor\n"); - return true; -} - -static bool test_autofree(void) -{ -#if _SAMBA_BUILD_ < 4 - /* autofree test would kill smbtorture */ - void *p; - printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n"); - - p = talloc_autofree_context(); - talloc_free(p); - - p = talloc_autofree_context(); - talloc_free(p); - - printf("success: autofree\n"); -#endif - return true; -} - -static bool test_pool(void) -{ - void *pool; - void *p1, *p2, *p3, *p4; - - pool = talloc_pool(NULL, 1024); - - p1 = talloc_size(pool, 80); - p2 = talloc_size(pool, 20); - p3 = talloc_size(p1, 50); - p4 = talloc_size(p3, 1000); - - talloc_free(pool); - - return true; -} - -struct torture_context; -bool torture_local_talloc(struct torture_context *tctx) -{ - bool ret = true; - - setlinebuf(stdout); - - talloc_disable_null_tracking(); - talloc_enable_null_tracking(); - - ret &= test_ref1(); - ret &= test_ref2(); - ret &= test_ref3(); - ret &= test_ref4(); - ret &= test_unlink1(); - ret &= test_misc(); - ret &= test_realloc(); - ret &= test_realloc_child(); - ret &= test_steal(); - ret &= test_move(); - ret &= test_unref_reparent(); - ret &= test_realloc_fn(); - ret &= test_type(); - ret &= test_lifeless(); - ret &= test_loop(); - ret &= test_free_parent_deny_child(); - ret &= test_talloc_ptrtype(); - ret &= test_talloc_free_in_destructor(); - ret &= test_pool(); - - if (ret) { - ret &= test_speed(); - } - ret &= test_autofree(); - - return ret; -} - -#if _SAMBA_BUILD_ < 4 -int main(void) -{ - bool ret = torture_local_talloc(NULL); - if (!ret) - return -1; - return 0; -} -#endif diff --git a/talloc/web/index.html b/talloc/web/index.html deleted file mode 100644 index 5deab93665..0000000000 --- a/talloc/web/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - -talloc - - - -

talloc

- -talloc is a hierarchical pool based memory allocator with -destructors. It is the core memory allocator used in Samba4, and has -made a huge difference in many aspects of Samba4 development.

- -To get started with talloc, I would recommend you read the talloc guide. - -

Discussion and bug reports

- -talloc does not currently have its own mailing list or bug tracking -system. For now, please use the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -

Download

- -You can download the latest release either via rsync or git.
-
-To fetch via git see the following guide:
-Using Git for Samba Development
-Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/talloc directory.
-
-To fetch via rsync use this command: - -
-  rsync -Pavz samba.org::ftp/unpacked/talloc .
-
- -
- -Andrew Tridgell
-talloc AT tridgell.net -
- - - diff --git a/tdb/Makefile.in b/tdb/Makefile.in deleted file mode 100644 index 090bb6e2dc..0000000000 --- a/tdb/Makefile.in +++ /dev/null @@ -1,59 +0,0 @@ -#!gmake -# -# Makefile for tdb directory -# - -CC = @CC@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -includedir = @includedir@ -libdir = @libdir@ -VPATH = @srcdir@:@libreplacedir@ -srcdir = @srcdir@ -builddir = @builddir@ -CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -CFLAGS = $(CPPFLAGS) @CFLAGS@ -LDFLAGS = @LDFLAGS@ -EXEEXT = @EXEEXT@ -SHLD = @SHLD@ -SHLD_FLAGS = @SHLD_FLAGS@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PICFLAG = @PICFLAG@ -SHLIBEXT = @SHLIBEXT@ -SWIG = swig -PYTHON = @PYTHON@ -PYTHON_CONFIG = @PYTHON_CONFIG@ -PYTHON_BUILD_TARGET = @PYTHON_BUILD_TARGET@ -PYTHON_INSTALL_TARGET = @PYTHON_INSTALL_TARGET@ -PYTHON_CHECK_TARGET = @PYTHON_CHECK_TARGET@ -LIB_PATH_VAR = @LIB_PATH_VAR@ -tdbdir = @tdbdir@ - -TDB_OBJ = @TDB_OBJ@ @LIBREPLACEOBJ@ - -default: all - -include $(tdbdir)/tdb.mk -include $(tdbdir)/rules.mk - -all:: showflags dirs $(PROGS) $(TDB_SOLIB) libtdb.a $(PYTHON_BUILD_TARGET) - -install:: all -$(TDB_SOLIB): $(TDB_OBJ) - $(SHLD) $(SHLD_FLAGS) -o $@ $(TDB_OBJ) @SONAMEFLAG@$(TDB_SONAME) - -check: test - -test:: $(PYTHON_CHECK_TARGET) -installcheck:: test install - -clean:: - rm -f *.o *.a */*.o - -distclean:: clean - rm -f config.log config.status include/config.h config.cache - rm -f Makefile - -realdistclean:: distclean - rm -f configure include/config.h.in diff --git a/tdb/aclocal.m4 b/tdb/aclocal.m4 deleted file mode 100644 index 5605e476ba..0000000000 --- a/tdb/aclocal.m4 +++ /dev/null @@ -1 +0,0 @@ -m4_include(libreplace.m4) diff --git a/tdb/autogen.sh b/tdb/autogen.sh deleted file mode 100755 index 88ac4cfcf7..0000000000 --- a/tdb/autogen.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f configure config.h.in - -IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace" -autoconf $IPATHS || exit 1 -autoheader $IPATHS || exit 1 - -rm -rf autom4te.cache - -swig -O -Wall -python -keyword tdb.i # Ignore errors for now - -echo "Now run ./configure and then make." -exit 0 - diff --git a/tdb/common/dump.c b/tdb/common/dump.c deleted file mode 100644 index d1c902ddfd..0000000000 --- a/tdb/common/dump.c +++ /dev/null @@ -1,137 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash, - tdb_off_t offset) -{ - struct list_struct rec; - tdb_off_t tailer_ofs, tailer; - - if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, - sizeof(rec), DOCONV()) == -1) { - printf("ERROR: failed to read record at %u\n", offset); - return 0; - } - - printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%d " - "key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", - hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, - rec.full_hash, rec.magic); - - tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t); - - if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) { - printf("ERROR: failed to read tailer at %u\n", tailer_ofs); - return rec.next; - } - - if (tailer != rec.rec_len + sizeof(rec)) { - printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", - (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec))); - } - return rec.next; -} - -static int tdb_dump_chain(struct tdb_context *tdb, int i) -{ - tdb_off_t rec_ptr, top; - - top = TDB_HASH_TOP(i); - - if (tdb_lock(tdb, i, F_WRLCK) != 0) - return -1; - - if (tdb_ofs_read(tdb, top, &rec_ptr) == -1) - return tdb_unlock(tdb, i, F_WRLCK); - - if (rec_ptr) - printf("hash=%d\n", i); - - while (rec_ptr) { - rec_ptr = tdb_dump_record(tdb, i, rec_ptr); - } - - return tdb_unlock(tdb, i, F_WRLCK); -} - -void tdb_dump_all(struct tdb_context *tdb) -{ - int i; - for (i=0;iheader.hash_size;i++) { - tdb_dump_chain(tdb, i); - } - printf("freelist:\n"); - tdb_dump_chain(tdb, -1); -} - -int tdb_printfreelist(struct tdb_context *tdb) -{ - int ret; - long total_free = 0; - tdb_off_t offset, rec_ptr; - struct list_struct rec; - - if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) - return ret; - - offset = FREELIST_TOP; - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - } - - printf("freelist top=[0x%08x]\n", rec_ptr ); - while (rec_ptr) { - if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, - sizeof(rec), DOCONV()) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - if (rec.magic != TDB_FREE_MAGIC) { - printf("bad magic 0x%08x in free list\n", rec.magic); - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n", - rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); - total_free += rec.rec_len; - - /* move to the next record */ - rec_ptr = rec.next; - } - printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, - (int)total_free); - - return tdb_unlock(tdb, -1, F_WRLCK); -} - diff --git a/tdb/common/error.c b/tdb/common/error.c deleted file mode 100644 index 195ab23815..0000000000 --- a/tdb/common/error.c +++ /dev/null @@ -1,57 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -enum TDB_ERROR tdb_error(struct tdb_context *tdb) -{ - return tdb->ecode; -} - -static struct tdb_errname { - enum TDB_ERROR ecode; const char *estring; -} emap[] = { {TDB_SUCCESS, "Success"}, - {TDB_ERR_CORRUPT, "Corrupt database"}, - {TDB_ERR_IO, "IO Error"}, - {TDB_ERR_LOCK, "Locking error"}, - {TDB_ERR_OOM, "Out of memory"}, - {TDB_ERR_EXISTS, "Record exists"}, - {TDB_ERR_NOLOCK, "Lock exists on other keys"}, - {TDB_ERR_EINVAL, "Invalid parameter"}, - {TDB_ERR_NOEXIST, "Record does not exist"}, - {TDB_ERR_RDONLY, "write not permitted"} }; - -/* Error string for the last tdb error */ -const char *tdb_errorstr(struct tdb_context *tdb) -{ - uint32_t i; - for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) - if (tdb->ecode == emap[i].ecode) - return emap[i].estring; - return "Invalid error code"; -} - diff --git a/tdb/common/freelist.c b/tdb/common/freelist.c deleted file mode 100644 index 2f2a4c379b..0000000000 --- a/tdb/common/freelist.c +++ /dev/null @@ -1,382 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* 'right' merges can involve O(n^2) cost when combined with a - traverse, so they are disabled until we find a way to do them in - O(1) time -*/ -#define USE_RIGHT_MERGES 0 - -/* read a freelist record and check for simple errors */ -int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct *rec) -{ - if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - - if (rec->magic == TDB_MAGIC) { - /* this happens when a app is showdown while deleting a record - we should - not completely fail when this happens */ - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", - rec->magic, off)); - rec->magic = TDB_FREE_MAGIC; - if (tdb->methods->tdb_write(tdb, off, rec, sizeof(*rec)) == -1) - return -1; - } - - if (rec->magic != TDB_FREE_MAGIC) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%d\n", - rec->magic, off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) - return -1; - return 0; -} - - -#if USE_RIGHT_MERGES -/* Remove an element from the freelist. Must have alloc lock. */ -static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next) -{ - tdb_off_t last_ptr, i; - - /* read in the freelist top */ - last_ptr = FREELIST_TOP; - while (tdb_ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { - if (i == off) { - /* We've found it! */ - return tdb_ofs_write(tdb, last_ptr, &next); - } - /* Follow chain (next offset is at start of record) */ - last_ptr = i; - } - TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); -} -#endif - - -/* update a record tailer (must hold allocation lock) */ -static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, - const struct list_struct *rec) -{ - tdb_off_t totalsize; - - /* Offset of tailer from record header */ - totalsize = sizeof(*rec) + rec->rec_len; - return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t), - &totalsize); -} - -/* Add an element into the freelist. Merge adjacent records if - neccessary. */ -int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) -{ - /* Allocation and tailer lock */ - if (tdb_lock(tdb, -1, F_WRLCK) != 0) - return -1; - - /* set an initial tailer, so if we fail we don't leave a bogus record */ - if (update_tailer(tdb, offset, rec) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n")); - goto fail; - } - -#if USE_RIGHT_MERGES - /* Look right first (I'm an Australian, dammit) */ - if (offset + sizeof(*rec) + rec->rec_len + sizeof(*rec) <= tdb->map_size) { - tdb_off_t right = offset + sizeof(*rec) + rec->rec_len; - struct list_struct r; - - if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right read failed at %u\n", right)); - goto left; - } - - /* If it's free, expand to include it. */ - if (r.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, right, r.next) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right free failed at %u\n", right)); - goto left; - } - rec->rec_len += sizeof(r) + r.rec_len; - if (update_tailer(tdb, offset, rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } - } - } -left: -#endif - - /* Look left */ - if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->header.hash_size)) { - tdb_off_t left = offset - sizeof(tdb_off_t); - struct list_struct l; - tdb_off_t leftsize; - - /* Read in tailer and jump back to header */ - if (tdb_ofs_read(tdb, left, &leftsize) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left)); - goto update; - } - - /* it could be uninitialised data */ - if (leftsize == 0 || leftsize == TDB_PAD_U32) { - goto update; - } - - left = offset - leftsize; - - if (leftsize > offset || - left < TDB_DATA_START(tdb->header.hash_size)) { - goto update; - } - - /* Now read in the left record */ - if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); - goto update; - } - - /* If it's free, expand to include it. */ - if (l.magic == TDB_FREE_MAGIC) { - /* we now merge the new record into the left record, rather than the other - way around. This makes the operation O(1) instead of O(n). This change - prevents traverse from being O(n^2) after a lot of deletes */ - l.rec_len += sizeof(*rec) + rec->rec_len; - if (tdb_rec_write(tdb, left, &l) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_left failed at %u\n", left)); - goto fail; - } - if (update_tailer(tdb, left, &l) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - } - } - -update: - - /* Now, prepend to free list */ - rec->magic = TDB_FREE_MAGIC; - - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || - tdb_rec_write(tdb, offset, rec) == -1 || - tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%d\n", offset)); - goto fail; - } - - /* And we're done. */ - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - - - -/* - the core of tdb_allocate - called when we have decided which - free list entry to use - - Note that we try to allocate by grabbing data from the end of an existing record, - not the beginning. This is so the left merge in a free is more likely to be - able to free up the record without fragmentation - */ -static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, - tdb_len_t length, tdb_off_t rec_ptr, - struct list_struct *rec, tdb_off_t last_ptr) -{ -#define MIN_REC_SIZE (sizeof(struct list_struct) + sizeof(tdb_off_t) + 8) - - if (rec->rec_len < length + MIN_REC_SIZE) { - /* we have to grab the whole record */ - - /* unlink it from the previous record */ - if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { - return 0; - } - - /* mark it not free */ - rec->magic = TDB_MAGIC; - if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - return rec_ptr; - } - - /* we're going to just shorten the existing record */ - rec->rec_len -= (length + sizeof(*rec)); - if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - /* and setup the new record */ - rec_ptr += sizeof(*rec) + rec->rec_len; - - memset(rec, '\0', sizeof(*rec)); - rec->rec_len = length; - rec->magic = TDB_MAGIC; - - if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - return rec_ptr; -} - -/* allocate some space from the free list. The offset returned points - to a unconnected list_struct within the database with room for at - least length bytes of total data - - 0 is returned if the space could not be allocated - */ -tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec) -{ - tdb_off_t rec_ptr, last_ptr, newrec_ptr; - struct { - tdb_off_t rec_ptr, last_ptr; - tdb_len_t rec_len; - } bestfit; - float multiplier = 1.0; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) - return 0; - - /* Extra bytes required for tailer */ - length += sizeof(tdb_off_t); - length = TDB_ALIGN(length, TDB_ALIGNMENT); - - again: - last_ptr = FREELIST_TOP; - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) - goto fail; - - bestfit.rec_ptr = 0; - bestfit.last_ptr = 0; - bestfit.rec_len = 0; - - /* - this is a best fit allocation strategy. Originally we used - a first fit strategy, but it suffered from massive fragmentation - issues when faced with a slowly increasing record size. - */ - while (rec_ptr) { - if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { - goto fail; - } - - if (rec->rec_len >= length) { - if (bestfit.rec_ptr == 0 || - rec->rec_len < bestfit.rec_len) { - bestfit.rec_len = rec->rec_len; - bestfit.rec_ptr = rec_ptr; - bestfit.last_ptr = last_ptr; - } - } - - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec->next; - - /* if we've found a record that is big enough, then - stop searching if its also not too big. The - definition of 'too big' changes as we scan - through */ - if (bestfit.rec_len > 0 && - bestfit.rec_len < length * multiplier) { - break; - } - - /* this multiplier means we only extremely rarely - search more than 50 or so records. At 50 records we - accept records up to 11 times larger than what we - want */ - multiplier *= 1.05; - } - - if (bestfit.rec_ptr != 0) { - if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { - goto fail; - } - - newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, - rec, bestfit.last_ptr); - tdb_unlock(tdb, -1, F_WRLCK); - return newrec_ptr; - } - - /* we didn't find enough space. See if we can expand the - database and if we can then try again */ - if (tdb_expand(tdb, length + sizeof(*rec)) == 0) - goto again; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return 0; -} - - - -/* - return the size of the freelist - used to decide if we should repack -*/ -int tdb_freelist_size(struct tdb_context *tdb) -{ - tdb_off_t ptr; - int count=0; - - if (tdb_lock(tdb, -1, F_RDLCK) == -1) { - return -1; - } - - ptr = FREELIST_TOP; - while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { - count++; - } - - tdb_unlock(tdb, -1, F_RDLCK); - return count; -} diff --git a/tdb/common/freelistcheck.c b/tdb/common/freelistcheck.c deleted file mode 100644 index efc050df9c..0000000000 --- a/tdb/common/freelistcheck.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Jeremy Allison 2006 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* Check the freelist is good and contains no loops. - Very memory intensive - only do this as a consistency - checker. Heh heh - uses an in memory tdb as the storage - for the "seen" record list. For some reason this strikes - me as extremely clever as I don't have to write another tree - data structure implementation :-). - */ - -static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) -{ - TDB_DATA key, data; - - memset(&data, '\0', sizeof(data)); - key.dptr = (unsigned char *)&rec_ptr; - key.dsize = sizeof(rec_ptr); - return tdb_store(mem_tdb, key, data, TDB_INSERT); -} - -int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) -{ - struct tdb_context *mem_tdb = NULL; - struct list_struct rec; - tdb_off_t rec_ptr, last_ptr; - int ret = -1; - - *pnum_entries = 0; - - mem_tdb = tdb_open("flval", tdb->header.hash_size, - TDB_INTERNAL, O_RDWR, 0600); - if (!mem_tdb) { - return -1; - } - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - tdb_close(mem_tdb); - return 0; - } - - last_ptr = FREELIST_TOP; - - /* Store the FREELIST_TOP record. */ - if (seen_insert(mem_tdb, last_ptr) == -1) { - ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - goto fail; - } - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) { - goto fail; - } - - while (rec_ptr) { - - /* If we can't store this record (we've seen it - before) then the free list has a loop and must - be corrupt. */ - - if (seen_insert(mem_tdb, rec_ptr)) { - ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - goto fail; - } - - if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec.next; - *pnum_entries += 1; - } - - ret = 0; - - fail: - - tdb_close(mem_tdb); - tdb_unlock(tdb, -1, F_WRLCK); - return ret; -} diff --git a/tdb/common/io.c b/tdb/common/io.c deleted file mode 100644 index 661f761489..0000000000 --- a/tdb/common/io.c +++ /dev/null @@ -1,473 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - - -#include "tdb_private.h" - -/* check for an out of bounds access - if it is out of bounds then - see if the database has been expanded by someone else and expand - if necessary - note that "len" is the minimum length needed for the db -*/ -static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, int probe) -{ - struct stat st; - if (len <= tdb->map_size) - return 0; - if (tdb->flags & TDB_INTERNAL) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond internal malloc size %d\n", - (int)len, (int)tdb->map_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - if (fstat(tdb->fd, &st) == -1) { - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - if (st.st_size < (size_t)len) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond eof at %d\n", - (int)len, (int)st.st_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - /* Unmap, update size, remap */ - if (tdb_munmap(tdb) == -1) - return TDB_ERRCODE(TDB_ERR_IO, -1); - tdb->map_size = st.st_size; - tdb_mmap(tdb); - return 0; -} - -/* write a lump of data at a specified offset */ -static int tdb_write(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - if (len == 0) { - return 0; - } - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->map_ptr) { - memcpy(off + (char *)tdb->map_ptr, buf, len); - } else { - ssize_t written = pwrite(tdb->fd, buf, len, off); - if ((written != (ssize_t)len) && (written != -1)) { - /* try once more */ - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only " - "%d of %d bytes at %d, trying once more\n", - (int)written, len, off)); - errno = ENOSPC; - written = pwrite(tdb->fd, (const void *)((const char *)buf+written), - len-written, - off+written); - } - if (written == -1) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d " - "len=%d (%s)\n", off, len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } else if (written != (ssize_t)len) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to " - "write %d bytes at %d in two attempts\n", - len, off)); - errno = ENOSPC; - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - } - return 0; -} - -/* Endian conversion: we only ever deal with 4 byte quantities */ -void *tdb_convert(void *buf, uint32_t size) -{ - uint32_t i, *p = (uint32_t *)buf; - for (i = 0; i < size / 4; i++) - p[i] = TDB_BYTEREV(p[i]); - return buf; -} - - -/* read a lump of data at a specified offset, maybe convert */ -static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, - tdb_len_t len, int cv) -{ - if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) { - return -1; - } - - if (tdb->map_ptr) { - memcpy(buf, off + (char *)tdb->map_ptr, len); - } else { - ssize_t ret = pread(tdb->fd, buf, len, off); - if (ret != (ssize_t)len) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %d " - "len=%d ret=%d (%s) map_size=%d\n", - (int)off, (int)len, (int)ret, strerror(errno), - (int)tdb->map_size)); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - } - if (cv) { - tdb_convert(buf, len); - } - return 0; -} - - - -/* - do an unlocked scan of the hash table heads to find the next non-zero head. The value - will then be confirmed with the lock held -*/ -static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - if (tdb->map_ptr) { - for (;h < tdb->header.hash_size;h++) { - if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { - break; - } - } - } else { - uint32_t off=0; - for (;h < tdb->header.hash_size;h++) { - if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { - break; - } - } - } - (*chain) = h; -} - - -int tdb_munmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#ifdef HAVE_MMAP - if (tdb->map_ptr) { - int ret; - - ret = munmap(tdb->map_ptr, tdb->map_size); - if (ret != 0) - return ret; - } -#endif - tdb->map_ptr = NULL; - return 0; -} - -void tdb_mmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return; - -#ifdef HAVE_MMAP - if (!(tdb->flags & TDB_NOMMAP)) { - tdb->map_ptr = mmap(NULL, tdb->map_size, - PROT_READ|(tdb->read_only? 0:PROT_WRITE), - MAP_SHARED|MAP_FILE, tdb->fd, 0); - - /* - * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! - */ - - if (tdb->map_ptr == MAP_FAILED) { - tdb->map_ptr = NULL; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", - tdb->map_size, strerror(errno))); - } - } else { - tdb->map_ptr = NULL; - } -#else - tdb->map_ptr = NULL; -#endif -} - -/* expand a file. we prefer to use ftruncate, as that is what posix - says to use for mmap expansion */ -static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) -{ - char buf[8192]; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (ftruncate(tdb->fd, size+addition) == -1) { - char b = 0; - ssize_t written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); - if (written == 0) { - /* try once more, potentially revealing errno */ - written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); - } - if (written == 0) { - /* again - give up, guessing errno */ - errno = ENOSPC; - } - if (written != 1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", - size+addition, strerror(errno))); - return -1; - } - } - - /* now fill the file with something. This ensures that the - file isn't sparse, which would be very bad if we ran out of - disk. This must be done with write, not via mmap */ - memset(buf, TDB_PAD_BYTE, sizeof(buf)); - while (addition) { - size_t n = addition>sizeof(buf)?sizeof(buf):addition; - ssize_t written = pwrite(tdb->fd, buf, n, size); - if (written == 0) { - /* prevent infinite loops: try _once_ more */ - written = pwrite(tdb->fd, buf, n, size); - } - if (written == 0) { - /* give up, trying to provide a useful errno */ - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " - "returned 0 twice: giving up!\n")); - errno = ENOSPC; - return -1; - } else if (written == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of " - "%d bytes failed (%s)\n", (int)n, - strerror(errno))); - return -1; - } else if (written != n) { - TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote " - "only %d of %d bytes - retrying\n", (int)written, - (int)n)); - } - addition -= written; - size += written; - } - return 0; -} - - -/* expand the database at least size bytes by expanding the underlying - file and doing the mmap again if necessary */ -int tdb_expand(struct tdb_context *tdb, tdb_off_t size) -{ - struct list_struct rec; - tdb_off_t offset, new_size; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); - return -1; - } - - /* must know about any previous expansions by another process */ - tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - - /* always make room for at least 100 more records, and at - least 25% more space. Round the database up to a multiple - of the page size */ - new_size = MAX(tdb->map_size + size*100, tdb->map_size * 1.25); - size = TDB_ALIGN(new_size, tdb->page_size) - tdb->map_size; - - if (!(tdb->flags & TDB_INTERNAL)) - tdb_munmap(tdb); - - /* - * We must ensure the file is unmapped before doing this - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* expand the file itself */ - if (!(tdb->flags & TDB_INTERNAL)) { - if (tdb->methods->tdb_expand_file(tdb, tdb->map_size, size) != 0) - goto fail; - } - - tdb->map_size += size; - - if (tdb->flags & TDB_INTERNAL) { - char *new_map_ptr = (char *)realloc(tdb->map_ptr, - tdb->map_size); - if (!new_map_ptr) { - tdb->map_size -= size; - goto fail; - } - tdb->map_ptr = new_map_ptr; - } else { - /* - * We must ensure the file is remapped before adding the space - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* We're ok if the mmap fails as we'll fallback to read/write */ - tdb_mmap(tdb); - } - - /* form a new freelist record */ - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = size - sizeof(rec); - - /* link it into the free list */ - offset = tdb->map_size - size; - if (tdb_free(tdb, offset, &rec) == -1) - goto fail; - - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - -/* read/write a tdb_off_t */ -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); -} - -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - tdb_off_t off = *d; - return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); -} - - -/* read a lump of data, allocating the space for it */ -unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len) -{ - unsigned char *buf; - - /* some systems don't like zero length malloc */ - if (len == 0) { - len = 1; - } - - if (!(buf = (unsigned char *)malloc(len))) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%d (%s)\n", - len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_OOM, buf); - } - if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) { - SAFE_FREE(buf); - return NULL; - } - return buf; -} - -/* Give a piece of tdb data to a parser */ - -int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb_off_t offset, tdb_len_t len, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data) -{ - TDB_DATA data; - int result; - - data.dsize = len; - - if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { - /* - * Optimize by avoiding the malloc/memcpy/free, point the - * parser directly at the mmap area. - */ - if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) { - return -1; - } - data.dptr = offset + (unsigned char *)tdb->map_ptr; - return parser(key, data, private_data); - } - - if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) { - return -1; - } - - result = parser(key, data, private_data); - free(data.dptr); - return result; -} - -/* read/write a record */ -int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) -{ - if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - if (TDB_BAD_MAGIC(rec)) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - return tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0); -} - -int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) -{ - struct list_struct r = *rec; - return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); -} - -static const struct tdb_methods io_methods = { - tdb_read, - tdb_write, - tdb_next_hash_chain, - tdb_oob, - tdb_expand_file, - tdb_brlock -}; - -/* - initialise the default methods table -*/ -void tdb_io_init(struct tdb_context *tdb) -{ - tdb->methods = &io_methods; -} diff --git a/tdb/common/lock.c b/tdb/common/lock.c deleted file mode 100644 index f156c0fa7b..0000000000 --- a/tdb/common/lock.c +++ /dev/null @@ -1,553 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -#define TDB_MARK_LOCK 0x80000000 - -void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) -{ - tdb->interrupt_sig_ptr = ptr; -} - -/* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. - - On error, errno is also set so that errors are passed back properly - through tdb_open(). - - note that a len of zero means lock to end of file -*/ -int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, - int rw_type, int lck_type, int probe, size_t len) -{ - struct flock fl; - int ret; - - if (tdb->flags & TDB_NOLOCK) { - return 0; - } - - if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - fl.l_type = rw_type; - fl.l_whence = SEEK_SET; - fl.l_start = offset; - fl.l_len = len; - fl.l_pid = 0; - - do { - ret = fcntl(tdb->fd,lck_type,&fl); - - /* Check for a sigalarm break. */ - if (ret == -1 && errno == EINTR && - tdb->interrupt_sig_ptr && - *tdb->interrupt_sig_ptr) { - break; - } - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - /* Generic lock error. errno set by fcntl. - * EAGAIN is an expected return from non-blocking - * locks. */ - if (!probe && lck_type != F_SETLK) { - /* Ensure error code is set for log fun to examine. */ - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n", - tdb->fd, offset, rw_type, lck_type, (int)len)); - } - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - return 0; -} - - -/* - upgrade a read lock to a write lock. This needs to be handled in a - special way as some OSes (such as solaris) have too conservative - deadlock detection and claim a deadlock when progress can be - made. For those OSes we may loop for a while. -*/ -int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len) -{ - int count = 1000; - while (count--) { - struct timeval tv; - if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) { - return 0; - } - if (errno != EDEADLK) { - break; - } - /* sleep for as short a time as we can - more portable than usleep() */ - tv.tv_sec = 0; - tv.tv_usec = 1; - select(0, NULL, NULL, NULL, &tv); - } - TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock_upgrade failed at offset %d\n", offset)); - return -1; -} - - -/* lock a list in the database. list -1 is the alloc list */ -static int _tdb_lock(struct tdb_context *tdb, int list, int ltype, int op) -{ - struct tdb_lock_type *new_lck; - int i; - bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); - - ltype &= ~TDB_MARK_LOCK; - - /* a global lock allows us to avoid per chain locks */ - if (tdb->global_lock.count && - (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { - return 0; - } - - if (tdb->global_lock.count) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid list %d for ltype=%d\n", - list, ltype)); - return -1; - } - if (tdb->flags & TDB_NOLOCK) - return 0; - - for (i=0; inum_lockrecs; i++) { - if (tdb->lockrecs[i].list == list) { - if (tdb->lockrecs[i].count == 0) { - /* - * Can't happen, see tdb_unlock(). It should - * be an assert. - */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock: " - "lck->count == 0 for list %d", list)); - } - /* - * Just increment the in-memory struct, posix locks - * don't stack. - */ - tdb->lockrecs[i].count++; - return 0; - } - } - - new_lck = (struct tdb_lock_type *)realloc( - tdb->lockrecs, - sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); - if (new_lck == NULL) { - errno = ENOMEM; - return -1; - } - tdb->lockrecs = new_lck; - - /* Since fcntl locks don't nest, we do a lock for the first one, - and simply bump the count for future ones */ - if (!mark_lock && - tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list, ltype, op, - 0, 1)) { - return -1; - } - - tdb->num_locks++; - - tdb->lockrecs[tdb->num_lockrecs].list = list; - tdb->lockrecs[tdb->num_lockrecs].count = 1; - tdb->lockrecs[tdb->num_lockrecs].ltype = ltype; - tdb->num_lockrecs += 1; - - return 0; -} - -/* lock a list in the database. list -1 is the alloc list */ -int tdb_lock(struct tdb_context *tdb, int list, int ltype) -{ - int ret; - ret = _tdb_lock(tdb, list, ltype, F_SETLKW); - if (ret) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " - "ltype=%d (%s)\n", list, ltype, strerror(errno))); - } - return ret; -} - -/* lock a list in the database. list -1 is the alloc list. non-blocking lock */ -int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) -{ - return _tdb_lock(tdb, list, ltype, F_SETLK); -} - - -/* unlock the database: returns void because it's too late for errors. */ - /* changed to return int it may be interesting to know there - has been an error --simo */ -int tdb_unlock(struct tdb_context *tdb, int list, int ltype) -{ - int ret = -1; - int i; - struct tdb_lock_type *lck = NULL; - bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); - - ltype &= ~TDB_MARK_LOCK; - - /* a global lock allows us to avoid per chain locks */ - if (tdb->global_lock.count && - (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { - return 0; - } - - if (tdb->global_lock.count) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->flags & TDB_NOLOCK) - return 0; - - /* Sanity checks */ - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); - return ret; - } - - for (i=0; inum_lockrecs; i++) { - if (tdb->lockrecs[i].list == list) { - lck = &tdb->lockrecs[i]; - break; - } - } - - if ((lck == NULL) || (lck->count == 0)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); - return -1; - } - - if (lck->count > 1) { - lck->count--; - return 0; - } - - /* - * This lock has count==1 left, so we need to unlock it in the - * kernel. We don't bother with decrementing the in-memory array - * element, we're about to overwrite it with the last array element - * anyway. - */ - - if (mark_lock) { - ret = 0; - } else { - ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, - F_SETLKW, 0, 1); - } - tdb->num_locks--; - - /* - * Shrink the array by overwriting the element just unlocked with the - * last array element. - */ - - if (tdb->num_lockrecs > 1) { - *lck = tdb->lockrecs[tdb->num_lockrecs-1]; - } - tdb->num_lockrecs -= 1; - - /* - * We don't bother with realloc when the array shrinks, but if we have - * a completely idle tdb we should get rid of the locked array. - */ - - if (tdb->num_lockrecs == 0) { - SAFE_FREE(tdb->lockrecs); - } - - if (ret) - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); - return ret; -} - -/* - get the transaction lock - */ -int tdb_transaction_lock(struct tdb_context *tdb, int ltype) -{ - if (tdb->have_transaction_lock || tdb->global_lock.count) { - return 0; - } - if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype, - F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - tdb->have_transaction_lock = 1; - return 0; -} - -/* - release the transaction lock - */ -int tdb_transaction_unlock(struct tdb_context *tdb) -{ - int ret; - if (!tdb->have_transaction_lock) { - return 0; - } - ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); - if (ret == 0) { - tdb->have_transaction_lock = 0; - } - return ret; -} - - - - -/* lock/unlock entire database */ -static int _tdb_lockall(struct tdb_context *tdb, int ltype, int op) -{ - bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); - - ltype &= ~TDB_MARK_LOCK; - - /* There are no locks on read-only dbs */ - if (tdb->read_only || tdb->traverse_read) - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - - if (tdb->global_lock.count && tdb->global_lock.ltype == ltype) { - tdb->global_lock.count++; - return 0; - } - - if (tdb->global_lock.count) { - /* a global lock of a different type exists */ - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->num_locks != 0) { - /* can't combine global and chain locks */ - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (!mark_lock && - tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, op, - 0, 4*tdb->header.hash_size)) { - if (op == F_SETLKW) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno))); - } - return -1; - } - - tdb->global_lock.count = 1; - tdb->global_lock.ltype = ltype; - - return 0; -} - - - -/* unlock entire db */ -static int _tdb_unlockall(struct tdb_context *tdb, int ltype) -{ - bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK); - - ltype &= ~TDB_MARK_LOCK; - - /* There are no locks on read-only dbs */ - if (tdb->read_only || tdb->traverse_read) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->global_lock.ltype != ltype || tdb->global_lock.count == 0) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->global_lock.count > 1) { - tdb->global_lock.count--; - return 0; - } - - if (!mark_lock && - tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, - 0, 4*tdb->header.hash_size)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno))); - return -1; - } - - tdb->global_lock.count = 0; - tdb->global_lock.ltype = 0; - - return 0; -} - -/* lock entire database with write lock */ -int tdb_lockall(struct tdb_context *tdb) -{ - return _tdb_lockall(tdb, F_WRLCK, F_SETLKW); -} - -/* lock entire database with write lock - mark only */ -int tdb_lockall_mark(struct tdb_context *tdb) -{ - return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW); -} - -/* unlock entire database with write lock - unmark only */ -int tdb_lockall_unmark(struct tdb_context *tdb) -{ - return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK); -} - -/* lock entire database with write lock - nonblocking varient */ -int tdb_lockall_nonblock(struct tdb_context *tdb) -{ - return _tdb_lockall(tdb, F_WRLCK, F_SETLK); -} - -/* unlock entire database with write lock */ -int tdb_unlockall(struct tdb_context *tdb) -{ - return _tdb_unlockall(tdb, F_WRLCK); -} - -/* lock entire database with read lock */ -int tdb_lockall_read(struct tdb_context *tdb) -{ - return _tdb_lockall(tdb, F_RDLCK, F_SETLKW); -} - -/* lock entire database with read lock - nonblock varient */ -int tdb_lockall_read_nonblock(struct tdb_context *tdb) -{ - return _tdb_lockall(tdb, F_RDLCK, F_SETLK); -} - -/* unlock entire database with read lock */ -int tdb_unlockall_read(struct tdb_context *tdb) -{ - return _tdb_unlockall(tdb, F_RDLCK); -} - -/* lock/unlock one hash chain. This is meant to be used to reduce - contention - it cannot guarantee how many records will be locked */ -int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -/* lock/unlock one hash chain, non-blocking. This is meant to be used - to reduce contention - it cannot guarantee how many records will be - locked */ -int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -/* mark a chain as locked without actually locking it. Warning! use with great caution! */ -int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); -} - -/* unmark a chain as locked without actually locking it. Warning! use with great caution! */ -int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK); -} - -int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); -} - -int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); -} - - - -/* record lock stops delete underneath */ -int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) -{ - if (tdb->global_lock.count) { - return 0; - } - return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0; -} - -/* - Write locks override our own fcntl readlocks, so check it here. - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ -int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off) -{ - struct tdb_traverse_lock *i; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - return -1; - return tdb->methods->tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1, 1); -} - -/* - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ -int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off) -{ - return tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0, 1); -} - -/* fcntl locks don't stack: avoid unlocking someone else's */ -int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) -{ - struct tdb_traverse_lock *i; - uint32_t count = 0; - - if (tdb->global_lock.count) { - return 0; - } - - if (off == 0) - return 0; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - count++; - return (count == 1 ? tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0, 1) : 0); -} diff --git a/tdb/common/open.c b/tdb/common/open.c deleted file mode 100644 index b19e4cea29..0000000000 --- a/tdb/common/open.c +++ /dev/null @@ -1,488 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ -static struct tdb_context *tdbs = NULL; - - -/* This is based on the hash algorithm from gdbm */ -static unsigned int default_tdb_hash(TDB_DATA *key) -{ - uint32_t value; /* Used to compute the hash value. */ - uint32_t i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) - value = (value + (key->dptr[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - - -/* initialise a new database with a specified hash size */ -static int tdb_new_database(struct tdb_context *tdb, int hash_size) -{ - struct tdb_header *newdb; - size_t size; - int ret = -1; - ssize_t written; - - /* We make it up in memory, then write it out if not internal */ - size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t); - if (!(newdb = (struct tdb_header *)calloc(size, 1))) - return TDB_ERRCODE(TDB_ERR_OOM, -1); - - /* Fill in the header */ - newdb->version = TDB_VERSION; - newdb->hash_size = hash_size; - if (tdb->flags & TDB_INTERNAL) { - tdb->map_size = size; - tdb->map_ptr = (char *)newdb; - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Convert the `ondisk' version if asked. */ - CONVERT(*newdb); - return 0; - } - if (lseek(tdb->fd, 0, SEEK_SET) == -1) - goto fail; - - if (ftruncate(tdb->fd, 0) == -1) - goto fail; - - /* This creates an endian-converted header, as if read from disk */ - CONVERT(*newdb); - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Don't endian-convert the magic food! */ - memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - /* we still have "ret == -1" here */ - written = write(tdb->fd, newdb, size); - if (written == size) { - ret = 0; - } else if (written != -1) { - /* call write once again, this usually should return -1 and - * set errno appropriately */ - size -= written; - written = write(tdb->fd, newdb+written, size); - if (written == size) { - ret = 0; - } else if (written >= 0) { - /* a second incomplete write - we give up. - * guessing the errno... */ - errno = ENOSPC; - } - } - - fail: - SAFE_FREE(newdb); - return ret; -} - - - -static int tdb_already_open(dev_t device, - ino_t ino) -{ - struct tdb_context *i; - - for (i = tdbs; i; i = i->next) { - if (i->device == device && i->inode == ino) { - return 1; - } - } - - return 0; -} - -/* open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the - database file. A flags value of O_WRONLY is invalid. The hash size - is advisory, use zero for a default value. - - Return is NULL on error, in which case errno is also set. Don't - try to call tdb_error or tdb_errname, just do strerror(errno). - - @param name may be NULL for internal databases. */ -struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); -} - -/* a default logging function */ -static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ -} - - -struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - const struct tdb_logging_context *log_ctx, - tdb_hash_func hash_fn) -{ - struct tdb_context *tdb; - struct stat st; - int rev = 0, locked = 0; - unsigned char *vp; - uint32_t vertest; - unsigned v; - - if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { - /* Can't log this */ - errno = ENOMEM; - goto fail; - } - tdb_io_init(tdb); - tdb->fd = -1; - tdb->name = NULL; - tdb->map_ptr = NULL; - tdb->flags = tdb_flags; - tdb->open_flags = open_flags; - if (log_ctx) { - tdb->log = *log_ctx; - } else { - tdb->log.log_fn = null_log_fn; - tdb->log.log_private = NULL; - } - tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash; - - /* cache the page size */ - tdb->page_size = getpagesize(); - if (tdb->page_size <= 0) { - tdb->page_size = 0x2000; - } - - tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0; - - if ((open_flags & O_ACCMODE) == O_WRONLY) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", - name)); - errno = EINVAL; - goto fail; - } - - if (hash_size == 0) - hash_size = DEFAULT_HASH_SIZE; - if ((open_flags & O_ACCMODE) == O_RDONLY) { - tdb->read_only = 1; - /* read only databases don't do locking or clear if first */ - tdb->flags |= TDB_NOLOCK; - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - } - - /* internal databases don't mmap or lock, and start off cleared */ - if (tdb->flags & TDB_INTERNAL) { - tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - if (tdb_new_database(tdb, hash_size) != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!")); - goto fail; - } - goto internal; - } - - if ((tdb->fd = open(name, open_flags, mode)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by open(2) */ - } - - /* on exec, don't inherit the fd */ - v = fcntl(tdb->fd, F_GETFD, 0); - fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); - - /* ensure there is only one process initialising at once */ - if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by tdb_brlock */ - } - - /* we need to zero database if we are the only one with it open */ - if ((tdb_flags & TDB_CLEAR_IF_FIRST) && - (!tdb->read_only) && - (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) { - open_flags |= O_CREAT; - if (ftruncate(tdb->fd, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "failed to truncate %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by ftruncate */ - } - } - - errno = 0; - if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) - || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 - || (tdb->header.version != TDB_VERSION - && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { - /* its not a valid database - possibly initialise it */ - if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { - if (errno == 0) { - errno = EIO; /* ie bad format or something */ - } - goto fail; - } - rev = (tdb->flags & TDB_CONVERT); - } - vp = (unsigned char *)&tdb->header.version; - vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | - (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; - tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; - if (!rev) - tdb->flags &= ~TDB_CONVERT; - else { - tdb->flags |= TDB_CONVERT; - tdb_convert(&tdb->header, sizeof(tdb->header)); - } - if (fstat(tdb->fd, &st) == -1) - goto fail; - - if (tdb->header.rwlocks != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n")); - goto fail; - } - - /* Is it already in the open list? If so, fail. */ - if (tdb_already_open(st.st_dev, st.st_ino)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "%s (%d,%d) is already open in this process\n", - name, (int)st.st_dev, (int)st.st_ino)); - errno = EBUSY; - goto fail; - } - - if (!(tdb->name = (char *)strdup(name))) { - errno = ENOMEM; - goto fail; - } - - tdb->map_size = st.st_size; - tdb->device = st.st_dev; - tdb->inode = st.st_ino; - tdb_mmap(tdb); - if (locked) { - if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "failed to take ACTIVE_LOCK on %s: %s\n", - name, strerror(errno))); - goto fail; - } - - } - - /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if - we didn't get the initial exclusive lock as we need to let all other - users know we're using it. */ - - if (tdb_flags & TDB_CLEAR_IF_FIRST) { - /* leave this lock in place to indicate it's in use */ - if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) - goto fail; - } - - /* if needed, run recovery */ - if (tdb_transaction_recover(tdb) == -1) { - goto fail; - } - - internal: - /* Internal (memory-only) databases skip all the code above to - * do with disk files, and resume here by releasing their - * global lock and hooking into the active list. */ - if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1) - goto fail; - tdb->next = tdbs; - tdbs = tdb; - return tdb; - - fail: - { int save_errno = errno; - - if (!tdb) - return NULL; - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - if (close(tdb->fd) != 0) - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); - SAFE_FREE(tdb); - errno = save_errno; - return NULL; - } -} - -/* - * Set the maximum number of dead records per hash chain - */ - -void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) -{ - tdb->max_dead_records = max_dead; -} - -/** - * Close a database. - * - * @returns -1 for error; 0 for success. - **/ -int tdb_close(struct tdb_context *tdb) -{ - struct tdb_context **i; - int ret = 0; - - if (tdb->transaction) { - tdb_transaction_cancel(tdb); - } - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - ret = close(tdb->fd); - SAFE_FREE(tdb->lockrecs); - - /* Remove from contexts list */ - for (i = &tdbs; *i; i = &(*i)->next) { - if (*i == tdb) { - *i = tdb->next; - break; - } - } - - memset(tdb, 0, sizeof(*tdb)); - SAFE_FREE(tdb); - - return ret; -} - -/* register a loging function */ -void tdb_set_logging_function(struct tdb_context *tdb, - const struct tdb_logging_context *log_ctx) -{ - tdb->log = *log_ctx; -} - -void *tdb_get_logging_private(struct tdb_context *tdb) -{ - return tdb->log.log_private; -} - -/* reopen a tdb - this can be used after a fork to ensure that we have an independent - seek pointer from our parent and to re-establish locks */ -int tdb_reopen(struct tdb_context *tdb) -{ - struct stat st; - - if (tdb->flags & TDB_INTERNAL) { - return 0; /* Nothing to do. */ - } - - if (tdb->num_locks != 0 || tdb->global_lock.count) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n")); - goto fail; - } - - if (tdb->transaction != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n")); - goto fail; - } - - if (tdb_munmap(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); - goto fail; - } - if (close(tdb->fd) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n")); - tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); - if (tdb->fd == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno))); - goto fail; - } - if ((tdb->flags & TDB_CLEAR_IF_FIRST) && - (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n")); - goto fail; - } - if (fstat(tdb->fd, &st) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); - goto fail; - } - if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); - goto fail; - } - tdb_mmap(tdb); - - return 0; - -fail: - tdb_close(tdb); - return -1; -} - -/* reopen all tdb's */ -int tdb_reopen_all(int parent_longlived) -{ - struct tdb_context *tdb; - - for (tdb=tdbs; tdb; tdb = tdb->next) { - /* - * If the parent is longlived (ie. a - * parent daemon architecture), we know - * it will keep it's active lock on a - * tdb opened with CLEAR_IF_FIRST. Thus - * for child processes we don't have to - * add an active lock. This is essential - * to improve performance on systems that - * keep POSIX locks as a non-scalable data - * structure in the kernel. - */ - if (parent_longlived) { - /* Ensure no clear-if-first. */ - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - } - - if (tdb_reopen(tdb) != 0) - return -1; - } - - return 0; -} diff --git a/tdb/common/tdb.c b/tdb/common/tdb.c deleted file mode 100644 index c7cec297f6..0000000000 --- a/tdb/common/tdb.c +++ /dev/null @@ -1,802 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -TDB_DATA tdb_null; - -/* - non-blocking increment of the tdb sequence number if the tdb has been opened using - the TDB_SEQNUM flag -*/ -void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) -{ - tdb_off_t seqnum=0; - - if (!(tdb->flags & TDB_SEQNUM)) { - return; - } - - /* we ignore errors from this, as we have no sane way of - dealing with them. - */ - tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); - seqnum++; - tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); -} - -/* - increment the tdb sequence number if the tdb has been opened using - the TDB_SEQNUM flag -*/ -static void tdb_increment_seqnum(struct tdb_context *tdb) -{ - if (!(tdb->flags & TDB_SEQNUM)) { - return; - } - - if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) { - return; - } - - tdb_increment_seqnum_nonblock(tdb); - - tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1); -} - -static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) -{ - return memcmp(data.dptr, key.dptr, data.dsize); -} - -/* Returns 0 on fail. On success, return offset of record, and fills - in rec */ -static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, - struct list_struct *r) -{ - tdb_off_t rec_ptr; - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (tdb_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (!TDB_DEAD(r) && hash==r->full_hash - && key.dsize==r->key_len - && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), - r->key_len, tdb_key_compare, - NULL) == 0) { - return rec_ptr; - } - rec_ptr = r->next; - } - return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); -} - -/* As tdb_find, but if you succeed, keep the lock */ -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, - struct list_struct *rec) -{ - uint32_t rec_ptr; - - if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) - return 0; - if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) - tdb_unlock(tdb, BUCKET(hash), locktype); - return rec_ptr; -} - - -/* update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. -*/ -static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf) -{ - struct list_struct rec; - tdb_off_t rec_ptr; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) - return -1; - - /* must be long enough key, data and tailer */ - if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) { - tdb->ecode = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - if (tdb->methods->tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, - dbuf.dptr, dbuf.dsize) == -1) - return -1; - - if (dbuf.dsize != rec.data_len) { - /* update size */ - rec.data_len = dbuf.dsize; - return tdb_rec_write(tdb, rec_ptr, &rec); - } - - return 0; -} - -/* find an entry in the database given a key */ -/* If an entry doesn't exist tdb_err will be set to - * TDB_ERR_NOEXIST. If a key has no data attached - * then the TDB_DATA will have zero length but - * a non-zero pointer - */ -TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) -{ - tdb_off_t rec_ptr; - struct list_struct rec; - TDB_DATA ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) - return tdb_null; - - ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len); - ret.dsize = rec.data_len; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return ret; -} - -/* - * Find an entry in the database and hand the record's data to a parsing - * function. The parsing function is executed under the chain read lock, so it - * should be fast and should not block on other syscalls. - * - * DONT CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS. - * - * For mmapped tdb's that do not have a transaction open it points the parsing - * function directly at the mmap area, it avoids the malloc/memcpy in this - * case. If a transaction is open or no mmap is available, it has to do - * malloc/read/parse/free. - * - * This is interesting for all readers of potentially large data structures in - * the tdb records, ldb indexes being one example. - */ - -int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data) -{ - tdb_off_t rec_ptr; - struct list_struct rec; - int ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - - if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { - return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); - } - - ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len, parser, private_data); - - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - - return ret; -} - -/* check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm -*/ -static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - struct list_struct rec; - - if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) - return 0; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return 1; -} - -int tdb_exists(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb->hash_fn(&key); - return tdb_exists_hash(tdb, key, hash); -} - -/* actually delete an entry in the database given the offset */ -int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec) -{ - tdb_off_t last_ptr, i; - struct list_struct lastrec; - - if (tdb->read_only || tdb->traverse_read) return -1; - - if (((tdb->traverse_write != 0) && (!TDB_DEAD(rec))) || - tdb_write_lock_record(tdb, rec_ptr) == -1) { - /* Someone traversing here: mark it as dead */ - rec->magic = TDB_DEAD_MAGIC; - return tdb_rec_write(tdb, rec_ptr, rec); - } - if (tdb_write_unlock_record(tdb, rec_ptr) != 0) - return -1; - - /* find previous record in hash chain */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) - return -1; - for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) - if (tdb_rec_read(tdb, i, &lastrec) == -1) - return -1; - - /* unlink it: next ptr is at start of record. */ - if (last_ptr == 0) - last_ptr = TDB_HASH_TOP(rec->full_hash); - if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) - return -1; - - /* recover the space */ - if (tdb_free(tdb, rec_ptr, rec) == -1) - return -1; - return 0; -} - -static int tdb_count_dead(struct tdb_context *tdb, uint32_t hash) -{ - int res = 0; - tdb_off_t rec_ptr; - struct list_struct rec; - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - while (rec_ptr) { - if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) - return 0; - - if (rec.magic == TDB_DEAD_MAGIC) { - res += 1; - } - rec_ptr = rec.next; - } - return res; -} - -/* - * Purge all DEAD records from a hash chain - */ -static int tdb_purge_dead(struct tdb_context *tdb, uint32_t hash) -{ - int res = -1; - struct list_struct rec; - tdb_off_t rec_ptr; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - return -1; - } - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - goto fail; - - while (rec_ptr) { - tdb_off_t next; - - if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - next = rec.next; - - if (rec.magic == TDB_DEAD_MAGIC - && tdb_do_delete(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - rec_ptr = next; - } - res = 0; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return res; -} - -/* delete an entry in the database given a key */ -static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - tdb_off_t rec_ptr; - struct list_struct rec; - int ret; - - if (tdb->max_dead_records != 0) { - - /* - * Allow for some dead records per hash chain, mainly for - * tdb's with a very high create/delete rate like locking.tdb. - */ - - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - if (tdb_count_dead(tdb, hash) >= tdb->max_dead_records) { - /* - * Don't let the per-chain freelist grow too large, - * delete all existing dead records - */ - tdb_purge_dead(tdb, hash); - } - - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return -1; - } - - /* - * Just mark the record as dead. - */ - rec.magic = TDB_DEAD_MAGIC; - ret = tdb_rec_write(tdb, rec_ptr, &rec); - } - else { - if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, - &rec))) - return -1; - - ret = tdb_do_delete(tdb, rec_ptr, &rec); - } - - if (ret == 0) { - tdb_increment_seqnum(tdb); - } - - if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); - return ret; -} - -int tdb_delete(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb->hash_fn(&key); - return tdb_delete_hash(tdb, key, hash); -} - -/* - * See if we have a dead record around with enough space - */ -static tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, - struct list_struct *r, tdb_len_t length) -{ - tdb_off_t rec_ptr; - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (tdb_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (TDB_DEAD(r) && r->rec_len >= length) { - /* - * First fit for simple coding, TODO: change to best - * fit - */ - return rec_ptr; - } - rec_ptr = r->next; - } - return 0; -} - -/* store an element in the database, replacing any existing element - with the same key - - return 0 on success, -1 on failure -*/ -int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) -{ - struct list_struct rec; - uint32_t hash; - tdb_off_t rec_ptr; - char *p = NULL; - int ret = -1; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - /* check for it existing, on insert. */ - if (flag == TDB_INSERT) { - if (tdb_exists_hash(tdb, key, hash)) { - tdb->ecode = TDB_ERR_EXISTS; - goto fail; - } - } else { - /* first try in-place update, on modify or replace. */ - if (tdb_update_hash(tdb, key, hash, dbuf) == 0) { - goto done; - } - if (tdb->ecode == TDB_ERR_NOEXIST && - flag == TDB_MODIFY) { - /* if the record doesn't exist and we are in TDB_MODIFY mode then - we should fail the store */ - goto fail; - } - } - /* reset the error code potentially set by the tdb_update() */ - tdb->ecode = TDB_SUCCESS; - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - if (flag != TDB_INSERT) - tdb_delete_hash(tdb, key, hash); - - /* Copy key+value *before* allocating free space in case malloc - fails and we are left with a dead spot in the tdb. */ - - if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - memcpy(p, key.dptr, key.dsize); - if (dbuf.dsize) - memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); - - if (tdb->max_dead_records != 0) { - /* - * Allow for some dead records per hash chain, look if we can - * find one that can hold the new record. We need enough space - * for key, data and tailer. If we find one, we don't have to - * consult the central freelist. - */ - rec_ptr = tdb_find_dead( - tdb, hash, &rec, - key.dsize + dbuf.dsize + sizeof(tdb_off_t)); - - if (rec_ptr != 0) { - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 - || tdb->methods->tdb_write( - tdb, rec_ptr + sizeof(rec), - p, key.dsize + dbuf.dsize) == -1) { - goto fail; - } - goto done; - } - } - - /* - * We have to allocate some space from the freelist, so this means we - * have to lock it. Use the chance to purge all the DEAD records from - * the hash chain under the freelist lock. - */ - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - goto fail; - } - - if ((tdb->max_dead_records != 0) - && (tdb_purge_dead(tdb, hash) == -1)) { - tdb_unlock(tdb, -1, F_WRLCK); - goto fail; - } - - /* we have to allocate some space */ - rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec); - - tdb_unlock(tdb, -1, F_WRLCK); - - if (rec_ptr == 0) { - goto fail; - } - - /* Read hash top into next ptr */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - /* write out and point the top of the hash chain at it */ - if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 - || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 - || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { - /* Need to tdb_unallocate() here */ - goto fail; - } - - done: - ret = 0; - fail: - if (ret == 0) { - tdb_increment_seqnum(tdb); - } - - SAFE_FREE(p); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; -} - - -/* Append to an entry. Create if not exist. */ -int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) -{ - uint32_t hash; - TDB_DATA dbuf; - int ret = -1; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - dbuf = tdb_fetch(tdb, key); - - if (dbuf.dptr == NULL) { - dbuf.dptr = (unsigned char *)malloc(new_dbuf.dsize); - } else { - unsigned char *new_dptr = (unsigned char *)realloc(dbuf.dptr, - dbuf.dsize + new_dbuf.dsize); - if (new_dptr == NULL) { - free(dbuf.dptr); - } - dbuf.dptr = new_dptr; - } - - if (dbuf.dptr == NULL) { - tdb->ecode = TDB_ERR_OOM; - goto failed; - } - - memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize); - dbuf.dsize += new_dbuf.dsize; - - ret = tdb_store(tdb, key, dbuf, 0); - -failed: - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - SAFE_FREE(dbuf.dptr); - return ret; -} - - -/* - return the name of the current tdb file - useful for external logging functions -*/ -const char *tdb_name(struct tdb_context *tdb) -{ - return tdb->name; -} - -/* - return the underlying file descriptor being used by tdb, or -1 - useful for external routines that want to check the device/inode - of the fd -*/ -int tdb_fd(struct tdb_context *tdb) -{ - return tdb->fd; -} - -/* - return the current logging function - useful for external tdb routines that wish to log tdb errors -*/ -tdb_log_func tdb_log_fn(struct tdb_context *tdb) -{ - return tdb->log.log_fn; -} - - -/* - get the tdb sequence number. Only makes sense if the writers opened - with TDB_SEQNUM set. Note that this sequence number will wrap quite - quickly, so it should only be used for a 'has something changed' - test, not for code that relies on the count of the number of changes - made. If you want a counter then use a tdb record. - - The aim of this sequence number is to allow for a very lightweight - test of a possible tdb change. -*/ -int tdb_get_seqnum(struct tdb_context *tdb) -{ - tdb_off_t seqnum=0; - - tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); - return seqnum; -} - -int tdb_hash_size(struct tdb_context *tdb) -{ - return tdb->header.hash_size; -} - -size_t tdb_map_size(struct tdb_context *tdb) -{ - return tdb->map_size; -} - -int tdb_get_flags(struct tdb_context *tdb) -{ - return tdb->flags; -} - -void tdb_add_flags(struct tdb_context *tdb, unsigned flags) -{ - tdb->flags |= flags; -} - -void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) -{ - tdb->flags &= ~flags; -} - - -/* - enable sequence number handling on an open tdb -*/ -void tdb_enable_seqnum(struct tdb_context *tdb) -{ - tdb->flags |= TDB_SEQNUM; -} - - -/* - add a region of the file to the freelist. Length is the size of the region in bytes, - which includes the free list header that needs to be added - */ -static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) -{ - struct list_struct rec; - if (length <= sizeof(rec)) { - /* the region is not worth adding */ - return 0; - } - if (length + offset > tdb->map_size) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); - return -1; - } - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = length - sizeof(rec); - if (tdb_free(tdb, offset, &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n")); - return -1; - } - return 0; -} - -/* - wipe the entire database, deleting all records. This can be done - very fast by using a global lock. The entire data portion of the - file becomes a single entry in the freelist. - - This code carefully steps around the recovery area, leaving it alone - */ -int tdb_wipe_all(struct tdb_context *tdb) -{ - int i; - tdb_off_t offset = 0; - ssize_t data_len; - tdb_off_t recovery_head; - tdb_len_t recovery_size = 0; - - if (tdb_lockall(tdb) != 0) { - return -1; - } - - /* see if the tdb has a recovery area, and remember its size - if so. We don't want to lose this as otherwise each - tdb_wipe_all() in a transaction will increase the size of - the tdb by the size of the recovery area */ - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n")); - goto failed; - } - - if (recovery_head != 0) { - struct list_struct rec; - if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); - return -1; - } - recovery_size = rec.rec_len + sizeof(rec); - } - - /* wipe the hashes */ - for (i=0;iheader.hash_size;i++) { - if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); - goto failed; - } - } - - /* wipe the freelist */ - if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); - goto failed; - } - - /* add all the rest of the file to the freelist, possibly leaving a gap - for the recovery area */ - if (recovery_size == 0) { - /* the simple case - the whole file can be used as a freelist */ - data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)); - if (tdb_free_region(tdb, TDB_DATA_START(tdb->header.hash_size), data_len) != 0) { - goto failed; - } - } else { - /* we need to add two freelist entries - one on either - side of the recovery area - - Note that we cannot shift the recovery area during - this operation. Only the transaction.c code may - move the recovery area or we risk subtle data - corruption - */ - data_len = (recovery_head - TDB_DATA_START(tdb->header.hash_size)); - if (tdb_free_region(tdb, TDB_DATA_START(tdb->header.hash_size), data_len) != 0) { - goto failed; - } - /* and the 2nd free list entry after the recovery area - if any */ - data_len = tdb->map_size - (recovery_head+recovery_size); - if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { - goto failed; - } - } - - if (tdb_unlockall(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); - goto failed; - } - - return 0; - -failed: - tdb_unlockall(tdb); - return -1; -} diff --git a/tdb/common/tdb_private.h b/tdb/common/tdb_private.h deleted file mode 100644 index ffac89ff0e..0000000000 --- a/tdb/common/tdb_private.h +++ /dev/null @@ -1,213 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - private includes - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "system/shmem.h" -#include "system/select.h" -#include "system/wait.h" -#include "tdb.h" - -#ifndef HAVE_GETPAGESIZE -#define getpagesize() 0x2000 -#endif - -typedef uint32_t tdb_len_t; -typedef uint32_t tdb_off_t; - -#ifndef offsetof -#define offsetof(t,f) ((unsigned int)&((t *)0)->f) -#endif - -#define TDB_MAGIC_FOOD "TDB file\n" -#define TDB_VERSION (0x26011967 + 6) -#define TDB_MAGIC (0x26011999U) -#define TDB_FREE_MAGIC (~TDB_MAGIC) -#define TDB_DEAD_MAGIC (0xFEE1DEAD) -#define TDB_RECOVERY_MAGIC (0xf53bc0e7U) -#define TDB_ALIGNMENT 4 -#define DEFAULT_HASH_SIZE 131 -#define FREELIST_TOP (sizeof(struct tdb_header)) -#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) -#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) -#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) -#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) -#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) -#define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t)) -#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) -#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) -#define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) -#define TDB_PAD_BYTE 0x42 -#define TDB_PAD_U32 0x42424242 - -/* NB assumes there is a local variable called "tdb" that is the - * current context, also takes doubly-parenthesized print-style - * argument. */ -#define TDB_LOG(x) tdb->log.log_fn x - -/* lock offsets */ -#define GLOBAL_LOCK 0 -#define ACTIVE_LOCK 4 -#define TRANSACTION_LOCK 8 - -/* free memory if the pointer is valid and zero the pointer */ -#ifndef SAFE_FREE -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) -#endif - -#define BUCKET(hash) ((hash) % tdb->header.hash_size) - -#define DOCONV() (tdb->flags & TDB_CONVERT) -#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) - - -/* the body of the database is made of one list_struct for the free space - plus a separate data list for each hash value */ -struct list_struct { - tdb_off_t next; /* offset of the next record in the list */ - tdb_len_t rec_len; /* total byte length of record */ - tdb_len_t key_len; /* byte length of key */ - tdb_len_t data_len; /* byte length of data */ - uint32_t full_hash; /* the full 32 bit hash of the key */ - uint32_t magic; /* try to catch errors */ - /* the following union is implied: - union { - char record[rec_len]; - struct { - char key[key_len]; - char data[data_len]; - } - uint32_t totalsize; (tailer) - } - */ -}; - - -/* this is stored at the front of every database */ -struct tdb_header { - char magic_food[32]; /* for /etc/magic */ - uint32_t version; /* version of the code */ - uint32_t hash_size; /* number of hash entries */ - tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ - tdb_off_t recovery_start; /* offset of transaction recovery region */ - tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ - tdb_off_t reserved[29]; -}; - -struct tdb_lock_type { - int list; - uint32_t count; - uint32_t ltype; -}; - -struct tdb_traverse_lock { - struct tdb_traverse_lock *next; - uint32_t off; - uint32_t hash; - int lock_rw; -}; - - -struct tdb_methods { - int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); - int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); - void (*next_hash_chain)(struct tdb_context *, uint32_t *); - int (*tdb_oob)(struct tdb_context *, tdb_off_t , int ); - int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); - int (*tdb_brlock)(struct tdb_context *, tdb_off_t , int, int, int, size_t); -}; - -struct tdb_context { - char *name; /* the name of the database */ - void *map_ptr; /* where it is currently mapped */ - int fd; /* open file descriptor for the database */ - tdb_len_t map_size; /* how much space has been mapped */ - int read_only; /* opened read-only */ - int traverse_read; /* read-only traversal */ - int traverse_write; /* read-write traversal */ - struct tdb_lock_type global_lock; - int num_lockrecs; - struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ - enum TDB_ERROR ecode; /* error code for last tdb error */ - struct tdb_header header; /* a cached copy of the header */ - uint32_t flags; /* the flags passed to tdb_open */ - struct tdb_traverse_lock travlocks; /* current traversal locks */ - struct tdb_context *next; /* all tdbs to avoid multiple opens */ - dev_t device; /* uniquely identifies this tdb */ - ino_t inode; /* uniquely identifies this tdb */ - struct tdb_logging_context log; - unsigned int (*hash_fn)(TDB_DATA *key); - int open_flags; /* flags used in the open - needed by reopen */ - unsigned int num_locks; /* number of chain locks held */ - const struct tdb_methods *methods; - struct tdb_transaction *transaction; - int page_size; - int max_dead_records; - bool have_transaction_lock; - volatile sig_atomic_t *interrupt_sig_ptr; -}; - - -/* - internal prototypes -*/ -int tdb_munmap(struct tdb_context *tdb); -void tdb_mmap(struct tdb_context *tdb); -int tdb_lock(struct tdb_context *tdb, int list, int ltype); -int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); -int tdb_unlock(struct tdb_context *tdb, int list, int ltype); -int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); -int tdb_transaction_lock(struct tdb_context *tdb, int ltype); -int tdb_transaction_unlock(struct tdb_context *tdb); -int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len); -int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -void *tdb_convert(void *buf, uint32_t size); -int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); -tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec); -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); -int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); -int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec); -unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); -int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb_off_t offset, tdb_len_t len, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data); -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, - struct list_struct *rec); -void tdb_io_init(struct tdb_context *tdb); -int tdb_expand(struct tdb_context *tdb, tdb_off_t size); -int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, - struct list_struct *rec); - - diff --git a/tdb/common/transaction.c b/tdb/common/transaction.c deleted file mode 100644 index 7acda640c8..0000000000 --- a/tdb/common/transaction.c +++ /dev/null @@ -1,1119 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* - transaction design: - - - only allow a single transaction at a time per database. This makes - using the transaction API simpler, as otherwise the caller would - have to cope with temporary failures in transactions that conflict - with other current transactions - - - keep the transaction recovery information in the same file as the - database, using a special 'transaction recovery' record pointed at - by the header. This removes the need for extra journal files as - used by some other databases - - - dynamically allocated the transaction recover record, re-using it - for subsequent transactions. If a larger record is needed then - tdb_free() the old record to place it on the normal tdb freelist - before allocating the new record - - - during transactions, keep a linked list of writes all that have - been performed by intercepting all tdb_write() calls. The hooked - transaction versions of tdb_read() and tdb_write() check this - linked list and try to use the elements of the list in preference - to the real database. - - - don't allow any locks to be held when a transaction starts, - otherwise we can end up with deadlock (plus lack of lock nesting - in posix locks would mean the lock is lost) - - - if the caller gains a lock during the transaction but doesn't - release it then fail the commit - - - allow for nested calls to tdb_transaction_start(), re-using the - existing transaction record. If the inner transaction is cancelled - then a subsequent commit will fail - - - keep a mirrored copy of the tdb hash chain heads to allow for the - fast hash heads scan on traverse, updating the mirrored copy in - the transaction version of tdb_write - - - allow callers to mix transaction and non-transaction use of tdb, - although once a transaction is started then an exclusive lock is - gained until the transaction is committed or cancelled - - - the commit stategy involves first saving away all modified data - into a linearised buffer in the transaction recovery area, then - marking the transaction recovery area with a magic value to - indicate a valid recovery record. In total 4 fsync/msync calls are - needed per commit to prevent race conditions. It might be possible - to reduce this to 3 or even 2 with some more work. - - - check for a valid recovery record on open of the tdb, while the - global lock is held. Automatically recover from the transaction - recovery area if needed, then continue with the open as - usual. This allows for smooth crash recovery with no administrator - intervention. - - - if TDB_NOSYNC is passed to flags in tdb_open then transactions are - still available, but no transaction recovery area is used and no - fsync/msync calls are made. - -*/ - - -/* - hold the context of any current transaction -*/ -struct tdb_transaction { - /* we keep a mirrored copy of the tdb hash heads here so - tdb_next_hash_chain() can operate efficiently */ - uint32_t *hash_heads; - - /* the original io methods - used to do IOs to the real db */ - const struct tdb_methods *io_methods; - - /* the list of transaction blocks. When a block is first - written to, it gets created in this list */ - uint8_t **blocks; - uint32_t num_blocks; - uint32_t block_size; /* bytes in each block */ - uint32_t last_block_size; /* number of valid bytes in the last block */ - - /* non-zero when an internal transaction error has - occurred. All write operations will then fail until the - transaction is ended */ - int transaction_error; - - /* when inside a transaction we need to keep track of any - nested tdb_transaction_start() calls, as these are allowed, - but don't create a new transaction */ - int nesting; - - /* old file size before transaction */ - tdb_len_t old_map_size; -}; - - -/* - read while in a transaction. We need to check first if the data is in our list - of transaction elements, then if not do a real read -*/ -static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, - tdb_len_t len, int cv) -{ - uint32_t blk; - - /* break it down into block sized ops */ - while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); - if (transaction_read(tdb, off, buf, len2, cv) != 0) { - return -1; - } - len -= len2; - off += len2; - buf = (void *)(len2 + (char *)buf); - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->transaction->block_size; - - /* see if we have it in the block list */ - if (tdb->transaction->num_blocks <= blk || - tdb->transaction->blocks[blk] == NULL) { - /* nope, do a real read */ - if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { - goto fail; - } - return 0; - } - - /* it is in the block list. Now check for the last block */ - if (blk == tdb->transaction->num_blocks-1) { - if (len > tdb->transaction->last_block_size) { - goto fail; - } - } - - /* now copy it out of this block */ - memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); - if (cv) { - tdb_convert(buf, len); - } - return 0; - -fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%d len=%d\n", off, len)); - tdb->ecode = TDB_ERR_IO; - tdb->transaction->transaction_error = 1; - return -1; -} - - -/* - write while in a transaction -*/ -static int transaction_write(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - uint32_t blk; - - /* if the write is to a hash head, then update the transaction - hash heads */ - if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && - off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) { - uint32_t chain = (off-FREELIST_TOP) / sizeof(tdb_off_t); - memcpy(&tdb->transaction->hash_heads[chain], buf, len); - } - - /* break it up into block sized chunks */ - while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); - if (transaction_write(tdb, off, buf, len2) != 0) { - return -1; - } - len -= len2; - off += len2; - if (buf != NULL) { - buf = (const void *)(len2 + (const char *)buf); - } - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->transaction->block_size; - off = off % tdb->transaction->block_size; - - if (tdb->transaction->num_blocks <= blk) { - uint8_t **new_blocks; - /* expand the blocks array */ - if (tdb->transaction->blocks == NULL) { - new_blocks = (uint8_t **)malloc( - (blk+1)*sizeof(uint8_t *)); - } else { - new_blocks = (uint8_t **)realloc( - tdb->transaction->blocks, - (blk+1)*sizeof(uint8_t *)); - } - if (new_blocks == NULL) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - memset(&new_blocks[tdb->transaction->num_blocks], 0, - (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); - tdb->transaction->blocks = new_blocks; - tdb->transaction->num_blocks = blk+1; - tdb->transaction->last_block_size = 0; - } - - /* allocate and fill a block? */ - if (tdb->transaction->blocks[blk] == NULL) { - tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); - if (tdb->transaction->blocks[blk] == NULL) { - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; - } - if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size; - if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { - len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); - } - if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, - tdb->transaction->blocks[blk], - len2, 0) != 0) { - SAFE_FREE(tdb->transaction->blocks[blk]); - tdb->ecode = TDB_ERR_IO; - goto fail; - } - if (blk == tdb->transaction->num_blocks-1) { - tdb->transaction->last_block_size = len2; - } - } - } - - /* overwrite part of an existing block */ - if (buf == NULL) { - memset(tdb->transaction->blocks[blk] + off, 0, len); - } else { - memcpy(tdb->transaction->blocks[blk] + off, buf, len); - } - if (blk == tdb->transaction->num_blocks-1) { - if (len + off > tdb->transaction->last_block_size) { - tdb->transaction->last_block_size = len + off; - } - } - - return 0; - -fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", - (blk*tdb->transaction->block_size) + off, len)); - tdb->transaction->transaction_error = 1; - return -1; -} - - -/* - write while in a transaction - this varient never expands the transaction blocks, it only - updates existing blocks. This means it cannot change the recovery size -*/ -static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - uint32_t blk; - - /* break it up into block sized chunks */ - while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); - if (transaction_write_existing(tdb, off, buf, len2) != 0) { - return -1; - } - len -= len2; - off += len2; - if (buf != NULL) { - buf = (const void *)(len2 + (const char *)buf); - } - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->transaction->block_size; - off = off % tdb->transaction->block_size; - - if (tdb->transaction->num_blocks <= blk || - tdb->transaction->blocks[blk] == NULL) { - return 0; - } - - if (blk == tdb->transaction->num_blocks-1 && - off + len > tdb->transaction->last_block_size) { - if (off >= tdb->transaction->last_block_size) { - return 0; - } - len = tdb->transaction->last_block_size - off; - } - - /* overwrite part of an existing block */ - memcpy(tdb->transaction->blocks[blk] + off, buf, len); - - return 0; -} - - -/* - accelerated hash chain head search, using the cached hash heads -*/ -static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - for (;h < tdb->header.hash_size;h++) { - /* the +1 takes account of the freelist */ - if (0 != tdb->transaction->hash_heads[h+1]) { - break; - } - } - (*chain) = h; -} - -/* - out of bounds check during a transaction -*/ -static int transaction_oob(struct tdb_context *tdb, tdb_off_t len, int probe) -{ - if (len <= tdb->map_size) { - return 0; - } - return TDB_ERRCODE(TDB_ERR_IO, -1); -} - -/* - transaction version of tdb_expand(). -*/ -static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, - tdb_off_t addition) -{ - /* add a write to the transaction elements, so subsequent - reads see the zero data */ - if (transaction_write(tdb, size, NULL, addition) != 0) { - return -1; - } - - return 0; -} - -/* - brlock during a transaction - ignore them -*/ -static int transaction_brlock(struct tdb_context *tdb, tdb_off_t offset, - int rw_type, int lck_type, int probe, size_t len) -{ - return 0; -} - -static const struct tdb_methods transaction_methods = { - transaction_read, - transaction_write, - transaction_next_hash_chain, - transaction_oob, - transaction_expand_file, - transaction_brlock -}; - - -/* - start a tdb transaction. No token is returned, as only a single - transaction is allowed to be pending per tdb_context -*/ -int tdb_transaction_start(struct tdb_context *tdb) -{ - /* some sanity checks */ - if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n")); - tdb->ecode = TDB_ERR_EINVAL; - return -1; - } - - /* cope with nested tdb_transaction_start() calls */ - if (tdb->transaction != NULL) { - tdb->transaction->nesting++; - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", - tdb->transaction->nesting)); - return 0; - } - - if (tdb->num_locks != 0 || tdb->global_lock.count) { - /* the caller must not have any locks when starting a - transaction as otherwise we'll be screwed by lack - of nested locks in posix */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb->travlocks.next != NULL) { - /* you cannot use transactions inside a traverse (although you can use - traverse inside a transaction) as otherwise you can end up with - deadlock */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - tdb->transaction = (struct tdb_transaction *) - calloc(sizeof(struct tdb_transaction), 1); - if (tdb->transaction == NULL) { - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - /* a page at a time seems like a reasonable compromise between compactness and efficiency */ - tdb->transaction->block_size = tdb->page_size; - - /* get the transaction write lock. This is a blocking lock. As - discussed with Volker, there are a number of ways we could - make this async, which we will probably do in the future */ - if (tdb_transaction_lock(tdb, F_WRLCK) == -1) { - SAFE_FREE(tdb->transaction->blocks); - SAFE_FREE(tdb->transaction); - return -1; - } - - /* get a read lock from the freelist to the end of file. This - is upgraded to a write lock during the commit */ - if (tdb_brlock(tdb, FREELIST_TOP, F_RDLCK, F_SETLKW, 0, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n")); - tdb->ecode = TDB_ERR_LOCK; - goto fail; - } - - /* setup a copy of the hash table heads so the hash scan in - traverse can be fast */ - tdb->transaction->hash_heads = (uint32_t *) - calloc(tdb->header.hash_size+1, sizeof(uint32_t)); - if (tdb->transaction->hash_heads == NULL) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads, - TDB_HASHTABLE_SIZE(tdb), 0) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n")); - tdb->ecode = TDB_ERR_IO; - goto fail; - } - - /* make sure we know about any file expansions already done by - anyone else */ - tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - tdb->transaction->old_map_size = tdb->map_size; - - /* finally hook the io methods, replacing them with - transaction specific methods */ - tdb->transaction->io_methods = tdb->methods; - tdb->methods = &transaction_methods; - - return 0; - -fail: - tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); - tdb_transaction_unlock(tdb); - SAFE_FREE(tdb->transaction->blocks); - SAFE_FREE(tdb->transaction->hash_heads); - SAFE_FREE(tdb->transaction); - return -1; -} - - -/* - cancel the current transaction -*/ -int tdb_transaction_cancel(struct tdb_context *tdb) -{ - int i; - - if (tdb->transaction == NULL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); - return -1; - } - - if (tdb->transaction->nesting != 0) { - tdb->transaction->transaction_error = 1; - tdb->transaction->nesting--; - return 0; - } - - tdb->map_size = tdb->transaction->old_map_size; - - /* free all the transaction blocks */ - for (i=0;itransaction->num_blocks;i++) { - if (tdb->transaction->blocks[i] != NULL) { - free(tdb->transaction->blocks[i]); - } - } - SAFE_FREE(tdb->transaction->blocks); - - /* remove any global lock created during the transaction */ - if (tdb->global_lock.count != 0) { - tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 4*tdb->header.hash_size); - tdb->global_lock.count = 0; - } - - /* remove any locks created during the transaction */ - if (tdb->num_locks != 0) { - for (i=0;inum_lockrecs;i++) { - tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list, - F_UNLCK,F_SETLKW, 0, 1); - } - tdb->num_locks = 0; - tdb->num_lockrecs = 0; - SAFE_FREE(tdb->lockrecs); - } - - /* restore the normal io methods */ - tdb->methods = tdb->transaction->io_methods; - - tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); - tdb_transaction_unlock(tdb); - SAFE_FREE(tdb->transaction->hash_heads); - SAFE_FREE(tdb->transaction); - - return 0; -} - -/* - sync to disk -*/ -static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) -{ - if (fsync(tdb->fd) != 0) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); - return -1; - } -#ifdef HAVE_MMAP - if (tdb->map_ptr) { - tdb_off_t moffset = offset & ~(tdb->page_size-1); - if (msync(moffset + (char *)tdb->map_ptr, - length + (offset - moffset), MS_SYNC) != 0) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", - strerror(errno))); - return -1; - } - } -#endif - return 0; -} - - -/* - work out how much space the linearised recovery data will consume -*/ -static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) -{ - tdb_len_t recovery_size = 0; - int i; - - recovery_size = sizeof(uint32_t); - for (i=0;itransaction->num_blocks;i++) { - if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { - break; - } - if (tdb->transaction->blocks[i] == NULL) { - continue; - } - recovery_size += 2*sizeof(tdb_off_t); - if (i == tdb->transaction->num_blocks-1) { - recovery_size += tdb->transaction->last_block_size; - } else { - recovery_size += tdb->transaction->block_size; - } - } - - return recovery_size; -} - -/* - allocate the recovery area, or use an existing recovery area if it is - large enough -*/ -static int tdb_recovery_allocate(struct tdb_context *tdb, - tdb_len_t *recovery_size, - tdb_off_t *recovery_offset, - tdb_len_t *recovery_max_size) -{ - struct list_struct rec; - const struct tdb_methods *methods = tdb->transaction->io_methods; - tdb_off_t recovery_head; - - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); - return -1; - } - - rec.rec_len = 0; - - if (recovery_head != 0 && - methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery record\n")); - return -1; - } - - *recovery_size = tdb_recovery_size(tdb); - - if (recovery_head != 0 && *recovery_size <= rec.rec_len) { - /* it fits in the existing area */ - *recovery_max_size = rec.rec_len; - *recovery_offset = recovery_head; - return 0; - } - - /* we need to free up the old recovery area, then allocate a - new one at the end of the file. Note that we cannot use - tdb_allocate() to allocate the new one as that might return - us an area that is being currently used (as of the start of - the transaction) */ - if (recovery_head != 0) { - if (tdb_free(tdb, recovery_head, &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to free previous recovery area\n")); - return -1; - } - } - - /* the tdb_free() call might have increased the recovery size */ - *recovery_size = tdb_recovery_size(tdb); - - /* round up to a multiple of page size */ - *recovery_max_size = TDB_ALIGN(sizeof(rec) + *recovery_size, tdb->page_size) - sizeof(rec); - *recovery_offset = tdb->map_size; - recovery_head = *recovery_offset; - - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - (tdb->map_size - tdb->transaction->old_map_size) + - sizeof(rec) + *recovery_max_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); - return -1; - } - - /* remap the file (if using mmap) */ - methods->tdb_oob(tdb, tdb->map_size + 1, 1); - - /* we have to reset the old map size so that we don't try to expand the file - again in the transaction commit, which would destroy the recovery area */ - tdb->transaction->old_map_size = tdb->map_size; - - /* write the recovery header offset and sync - we can sync without a race here - as the magic ptr in the recovery record has not been set */ - CONVERT(recovery_head); - if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, - &recovery_head, sizeof(tdb_off_t)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); - return -1; - } - if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); - return -1; - } - - return 0; -} - - -/* - setup the recovery data that will be used on a crash during commit -*/ -static int transaction_setup_recovery(struct tdb_context *tdb, - tdb_off_t *magic_offset) -{ - tdb_len_t recovery_size; - unsigned char *data, *p; - const struct tdb_methods *methods = tdb->transaction->io_methods; - struct list_struct *rec; - tdb_off_t recovery_offset, recovery_max_size; - tdb_off_t old_map_size = tdb->transaction->old_map_size; - uint32_t magic, tailer; - int i; - - /* - check that the recovery area has enough space - */ - if (tdb_recovery_allocate(tdb, &recovery_size, - &recovery_offset, &recovery_max_size) == -1) { - return -1; - } - - data = (unsigned char *)malloc(recovery_size + sizeof(*rec)); - if (data == NULL) { - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - rec = (struct list_struct *)data; - memset(rec, 0, sizeof(*rec)); - - rec->magic = 0; - rec->data_len = recovery_size; - rec->rec_len = recovery_max_size; - rec->key_len = old_map_size; - CONVERT(rec); - - /* build the recovery data into a single blob to allow us to do a single - large write, which should be more efficient */ - p = data + sizeof(*rec); - for (i=0;itransaction->num_blocks;i++) { - tdb_off_t offset; - tdb_len_t length; - - if (tdb->transaction->blocks[i] == NULL) { - continue; - } - - offset = i * tdb->transaction->block_size; - length = tdb->transaction->block_size; - if (i == tdb->transaction->num_blocks-1) { - length = tdb->transaction->last_block_size; - } - - if (offset >= old_map_size) { - continue; - } - if (offset + length > tdb->transaction->old_map_size) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); - free(data); - tdb->ecode = TDB_ERR_CORRUPT; - return -1; - } - memcpy(p, &offset, 4); - memcpy(p+4, &length, 4); - if (DOCONV()) { - tdb_convert(p, 8); - } - /* the recovery area contains the old data, not the - new data, so we have to call the original tdb_read - method to get it */ - if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - p += 8 + length; - } - - /* and the tailer */ - tailer = sizeof(*rec) + recovery_max_size; - memcpy(p, &tailer, 4); - CONVERT(p); - - /* write the recovery data to the recovery area */ - if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n")); - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* as we don't have ordered writes, we have to sync the recovery - data before we update the magic to indicate that the recovery - data is present */ - if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { - free(data); - return -1; - } - - free(data); - - magic = TDB_RECOVERY_MAGIC; - CONVERT(magic); - - *magic_offset = recovery_offset + offsetof(struct list_struct, magic); - - if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* ensure the recovery magic marker is on disk */ - if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { - return -1; - } - - return 0; -} - -/* - commit the current transaction -*/ -int tdb_transaction_commit(struct tdb_context *tdb) -{ - const struct tdb_methods *methods; - tdb_off_t magic_offset = 0; - uint32_t zero = 0; - int i; - - if (tdb->transaction == NULL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); - return -1; - } - - if (tdb->transaction->transaction_error) { - tdb->ecode = TDB_ERR_IO; - tdb_transaction_cancel(tdb); - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n")); - return -1; - } - - - if (tdb->transaction->nesting != 0) { - tdb->transaction->nesting--; - return 0; - } - - /* check for a null transaction */ - if (tdb->transaction->blocks == NULL) { - tdb_transaction_cancel(tdb); - return 0; - } - - methods = tdb->transaction->io_methods; - - /* if there are any locks pending then the caller has not - nested their locks properly, so fail the transaction */ - if (tdb->num_locks || tdb->global_lock.count) { - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: locks pending on commit\n")); - tdb_transaction_cancel(tdb); - return -1; - } - - /* upgrade the main transaction lock region to a write lock */ - if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to upgrade hash locks\n")); - tdb->ecode = TDB_ERR_LOCK; - tdb_transaction_cancel(tdb); - return -1; - } - - /* get the global lock - this prevents new users attaching to the database - during the commit */ - if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: failed to get global lock\n")); - tdb->ecode = TDB_ERR_LOCK; - tdb_transaction_cancel(tdb); - return -1; - } - - if (!(tdb->flags & TDB_NOSYNC)) { - /* write the recovery data to the end of the file */ - if (transaction_setup_recovery(tdb, &magic_offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to setup recovery data\n")); - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - tdb_transaction_cancel(tdb); - return -1; - } - } - - /* expand the file to the new size if needed */ - if (tdb->map_size != tdb->transaction->old_map_size) { - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - tdb->map_size - - tdb->transaction->old_map_size) == -1) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: expansion failed\n")); - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - tdb_transaction_cancel(tdb); - return -1; - } - tdb->map_size = tdb->transaction->old_map_size; - methods->tdb_oob(tdb, tdb->map_size + 1, 1); - } - - /* perform all the writes */ - for (i=0;itransaction->num_blocks;i++) { - tdb_off_t offset; - tdb_len_t length; - - if (tdb->transaction->blocks[i] == NULL) { - continue; - } - - offset = i * tdb->transaction->block_size; - length = tdb->transaction->block_size; - if (i == tdb->transaction->num_blocks-1) { - length = tdb->transaction->last_block_size; - } - - if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); - - /* we've overwritten part of the data and - possibly expanded the file, so we need to - run the crash recovery code */ - tdb->methods = methods; - tdb_transaction_recover(tdb); - - tdb_transaction_cancel(tdb); - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); - return -1; - } - SAFE_FREE(tdb->transaction->blocks[i]); - } - - SAFE_FREE(tdb->transaction->blocks); - tdb->transaction->num_blocks = 0; - - if (!(tdb->flags & TDB_NOSYNC)) { - /* ensure the new data is on disk */ - if (transaction_sync(tdb, 0, tdb->map_size) == -1) { - return -1; - } - - /* remove the recovery marker */ - if (methods->tdb_write(tdb, magic_offset, &zero, 4) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to remove recovery magic\n")); - return -1; - } - - /* ensure the recovery marker has been removed on disk */ - if (transaction_sync(tdb, magic_offset, 4) == -1) { - return -1; - } - } - - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - - /* - TODO: maybe write to some dummy hdr field, or write to magic - offset without mmap, before the last sync, instead of the - utime() call - */ - - /* on some systems (like Linux 2.6.x) changes via mmap/msync - don't change the mtime of the file, this means the file may - not be backed up (as tdb rounding to block sizes means that - file size changes are quite rare too). The following forces - mtime changes when a transaction completes */ -#ifdef HAVE_UTIME - utime(tdb->name, NULL); -#endif - - /* use a transaction cancel to free memory and remove the - transaction locks */ - tdb_transaction_cancel(tdb); - - return 0; -} - - -/* - recover from an aborted transaction. Must be called with exclusive - database write access already established (including the global - lock to prevent new processes attaching) -*/ -int tdb_transaction_recover(struct tdb_context *tdb) -{ - tdb_off_t recovery_head, recovery_eof; - unsigned char *data, *p; - uint32_t zero = 0; - struct list_struct rec; - - /* find the recovery area */ - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - if (recovery_head == 0) { - /* we have never allocated a recovery record */ - return 0; - } - - /* read the recovery record */ - if (tdb->methods->tdb_read(tdb, recovery_head, &rec, - sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - if (rec.magic != TDB_RECOVERY_MAGIC) { - /* there is no valid recovery data */ - return 0; - } - - if (tdb->read_only) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n")); - tdb->ecode = TDB_ERR_CORRUPT; - return -1; - } - - recovery_eof = rec.key_len; - - data = (unsigned char *)malloc(rec.data_len); - if (data == NULL) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - /* read the full recovery data */ - if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, - rec.data_len, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* recover the file data */ - p = data; - while (p+8 < data + rec.data_len) { - uint32_t ofs, len; - if (DOCONV()) { - tdb_convert(p, 8); - } - memcpy(&ofs, p, 4); - memcpy(&len, p+4, 4); - - if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) { - free(data); - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %d bytes at offset %d\n", len, ofs)); - tdb->ecode = TDB_ERR_IO; - return -1; - } - p += 8 + len; - } - - free(data); - - if (transaction_sync(tdb, 0, tdb->map_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* if the recovery area is after the recovered eof then remove it */ - if (recovery_eof <= recovery_head) { - if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - } - - /* remove the recovery magic */ - if (tdb_ofs_write(tdb, recovery_head + offsetof(struct list_struct, magic), - &zero) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* reduce the file size to the old size */ - tdb_munmap(tdb); - if (ftruncate(tdb->fd, recovery_eof) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to reduce to recovery size\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - tdb->map_size = recovery_eof; - tdb_mmap(tdb); - - if (transaction_sync(tdb, 0, recovery_eof) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %d byte database\n", - recovery_eof)); - - /* all done */ - return 0; -} diff --git a/tdb/common/traverse.c b/tdb/common/traverse.c deleted file mode 100644 index 69c81e6e98..0000000000 --- a/tdb/common/traverse.c +++ /dev/null @@ -1,348 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ -static int tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock, - struct list_struct *rec) -{ - int want_next = (tlock->off != 0); - - /* Lock each chain from the start one. */ - for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { - if (!tlock->off && tlock->hash != 0) { - /* this is an optimisation for the common case where - the hash chain is empty, which is particularly - common for the use of tdb with ldb, where large - hashes are used. In that case we spend most of our - time in tdb_brlock(), locking empty hash chains. - - To avoid this, we do an unlocked pre-check to see - if the hash chain is empty before starting to look - inside it. If it is empty then we can avoid that - hash chain. If it isn't empty then we can't believe - the value we get back, as we read it without a - lock, so instead we get the lock and re-fetch the - value below. - - Notice that not doing this optimisation on the - first hash chain is critical. We must guarantee - that we have done at least one fcntl lock at the - start of a search to guarantee that memory is - coherent on SMP systems. If records are added by - others during the search then thats OK, and we - could possibly miss those with this trick, but we - could miss them anyway without this trick, so the - semantics don't change. - - With a non-indexed ldb search this trick gains us a - factor of around 80 in speed on a linux 2.6.x - system (testing using ldbtest). - */ - tdb->methods->next_hash_chain(tdb, &tlock->hash); - if (tlock->hash == tdb->header.hash_size) { - continue; - } - } - - if (tdb_lock(tdb, tlock->hash, tlock->lock_rw) == -1) - return -1; - - /* No previous record? Start at top of chain. */ - if (!tlock->off) { - if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->hash), - &tlock->off) == -1) - goto fail; - } else { - /* Otherwise unlock the previous record. */ - if (tdb_unlock_record(tdb, tlock->off) != 0) - goto fail; - } - - if (want_next) { - /* We have offset of old record: grab next */ - if (tdb_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - tlock->off = rec->next; - } - - /* Iterate through chain */ - while( tlock->off) { - tdb_off_t current; - if (tdb_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - - /* Detect infinite loops. From "Shlomi Yaakobovich" . */ - if (tlock->off == rec->next) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n")); - goto fail; - } - - if (!TDB_DEAD(rec)) { - /* Woohoo: we found one! */ - if (tdb_lock_record(tdb, tlock->off) != 0) - goto fail; - return tlock->off; - } - - /* Try to clean dead ones from old traverses */ - current = tlock->off; - tlock->off = rec->next; - if (!(tdb->read_only || tdb->traverse_read) && - tdb_do_delete(tdb, current, rec) != 0) - goto fail; - } - tdb_unlock(tdb, tlock->hash, tlock->lock_rw); - want_next = 0; - } - /* We finished iteration without finding anything */ - return TDB_ERRCODE(TDB_SUCCESS, 0); - - fail: - tlock->off = 0; - if (tdb_unlock(tdb, tlock->hash, tlock->lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n")); - return -1; -} - -/* traverse the entire database - calling fn(tdb, key, data) on each element. - return -1 on error or the record count traversed - if fn is NULL then it is not called - a non-zero return value from fn() indicates that the traversal should stop - */ -static int tdb_traverse_internal(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data, - struct tdb_traverse_lock *tl) -{ - TDB_DATA key, dbuf; - struct list_struct rec; - int ret, count = 0; - - /* This was in the initializaton, above, but the IRIX compiler - * did not like it. crh - */ - tl->next = tdb->travlocks.next; - - /* fcntl locks don't stack: beware traverse inside traverse */ - tdb->travlocks.next = tl; - - /* tdb_next_lock places locks on the record returned, and its chain */ - while ((ret = tdb_next_lock(tdb, tl, &rec)) > 0) { - count++; - /* now read the full record */ - key.dptr = tdb_alloc_read(tdb, tl->off + sizeof(rec), - rec.key_len + rec.data_len); - if (!key.dptr) { - ret = -1; - if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) - goto out; - if (tdb_unlock_record(tdb, tl->off) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); - goto out; - } - key.dsize = rec.key_len; - dbuf.dptr = key.dptr + rec.key_len; - dbuf.dsize = rec.data_len; - - /* Drop chain lock, call out */ - if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) { - ret = -1; - SAFE_FREE(key.dptr); - goto out; - } - if (fn && fn(tdb, key, dbuf, private_data)) { - /* They want us to terminate traversal */ - ret = count; - if (tdb_unlock_record(tdb, tl->off) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; - ret = -1; - } - SAFE_FREE(key.dptr); - goto out; - } - SAFE_FREE(key.dptr); - } -out: - tdb->travlocks.next = tl->next; - if (ret < 0) - return -1; - else - return count; -} - - -/* - a write style traverse - temporarily marks the db read only -*/ -int tdb_traverse_read(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data) -{ - struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; - int ret; - bool in_transaction = (tdb->transaction != NULL); - - /* we need to get a read lock on the transaction lock here to - cope with the lock ordering semantics of solaris10 */ - if (!in_transaction) { - if (tdb_transaction_lock(tdb, F_RDLCK)) { - return -1; - } - } - - tdb->traverse_read++; - ret = tdb_traverse_internal(tdb, fn, private_data, &tl); - tdb->traverse_read--; - - if (!in_transaction) { - tdb_transaction_unlock(tdb); - } - - return ret; -} - -/* - a write style traverse - needs to get the transaction lock to - prevent deadlocks - - WARNING: The data buffer given to the callback fn does NOT meet the - alignment restrictions malloc gives you. -*/ -int tdb_traverse(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data) -{ - struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; - int ret; - bool in_transaction = (tdb->transaction != NULL); - - if (tdb->read_only || tdb->traverse_read) { - return tdb_traverse_read(tdb, fn, private_data); - } - - if (!in_transaction) { - if (tdb_transaction_lock(tdb, F_WRLCK)) { - return -1; - } - } - - tdb->traverse_write++; - ret = tdb_traverse_internal(tdb, fn, private_data, &tl); - tdb->traverse_write--; - - if (!in_transaction) { - tdb_transaction_unlock(tdb); - } - - return ret; -} - - -/* find the first entry in the database and return its key */ -TDB_DATA tdb_firstkey(struct tdb_context *tdb) -{ - TDB_DATA key; - struct list_struct rec; - - /* release any old lock */ - if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) - return tdb_null; - tdb->travlocks.off = tdb->travlocks.hash = 0; - tdb->travlocks.lock_rw = F_RDLCK; - - /* Grab first record: locks chain and returned record. */ - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) - return tdb_null; - /* now read the key */ - key.dsize = rec.key_len; - key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); - - /* Unlock the hash chain of the record we just read. */ - if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); - return key; -} - -/* find the next entry in the database, returning its key */ -TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) -{ - uint32_t oldhash; - TDB_DATA key = tdb_null; - struct list_struct rec; - unsigned char *k = NULL; - - /* Is locked key the old key? If so, traverse will be reliable. */ - if (tdb->travlocks.off) { - if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw)) - return tdb_null; - if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 - || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), - rec.key_len)) - || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { - /* No, it wasn't: unlock it and start from scratch */ - if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) { - SAFE_FREE(k); - return tdb_null; - } - if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) { - SAFE_FREE(k); - return tdb_null; - } - tdb->travlocks.off = 0; - } - - SAFE_FREE(k); - } - - if (!tdb->travlocks.off) { - /* No previous element: do normal find, and lock record */ - tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); - if (!tdb->travlocks.off) - return tdb_null; - tdb->travlocks.hash = BUCKET(rec.full_hash); - if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); - return tdb_null; - } - } - oldhash = tdb->travlocks.hash; - - /* Grab next record: locks chain and returned record, - unlocks old record */ - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { - key.dsize = rec.key_len; - key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), - key.dsize); - /* Unlock the chain of this new record */ - if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - } - /* Unlock the chain of old record */ - if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - return key; -} - diff --git a/tdb/config.guess b/tdb/config.guess deleted file mode 100755 index 354dbe175a..0000000000 --- a/tdb/config.guess +++ /dev/null @@ -1,1464 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-08-03' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/tdb/config.mk b/tdb/config.mk deleted file mode 100644 index 90c9ba2863..0000000000 --- a/tdb/config.mk +++ /dev/null @@ -1,57 +0,0 @@ -################################################ -# Start SUBSYSTEM LIBTDB -[LIBRARY::LIBTDB] -OUTPUT_TYPE = STATIC_LIBRARY -CFLAGS = -I$(tdbsrcdir)/include -# -# End SUBSYSTEM ldb -################################################ - -LIBTDB_OBJ_FILES = $(addprefix $(tdbsrcdir)/common/, \ - tdb.o dump.o io.o lock.o \ - open.o traverse.o freelist.o \ - error.o transaction.o) - -################################################ -# Start BINARY tdbtool -[BINARY::tdbtool] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbtool -################################################ - -tdbtool_OBJ_FILES = $(tdbsrcdir)/tools/tdbtool.o - -################################################ -# Start BINARY tdbtorture -[BINARY::tdbtorture] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbtorture -################################################ - -tdbtorture_OBJ_FILES = $(tdbsrcdir)/tools/tdbtorture.o - -################################################ -# Start BINARY tdbdump -[BINARY::tdbdump] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbdump -################################################ - -tdbdump_OBJ_FILES = $(tdbsrcdir)/tools/tdbdump.o - -################################################ -# Start BINARY tdbbackup -[BINARY::tdbbackup] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbbackup -################################################ - -tdbbackup_OBJ_FILES = $(tdbsrcdir)/tools/tdbbackup.o diff --git a/tdb/config.sub b/tdb/config.sub deleted file mode 100755 index 23cd6fd75c..0000000000 --- a/tdb/config.sub +++ /dev/null @@ -1,1577 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-07-08' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ms1 \ - | msp430 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | ms1-* \ - | msp430-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - m32c-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/tdb/configure.ac b/tdb/configure.ac deleted file mode 100644 index eaf70d30b4..0000000000 --- a/tdb/configure.ac +++ /dev/null @@ -1,30 +0,0 @@ -AC_PREREQ(2.50) -AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) -AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) -AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(tdb, 1.1.2) -AC_CONFIG_SRCDIR([common/tdb.c]) -AC_CONFIG_HEADER(include/config.h) -AC_LIBREPLACE_ALL_CHECKS -AC_LD_SONAMEFLAG -AC_LD_PICFLAG -AC_LD_SHLIBEXT -AC_LIBREPLACE_SHLD -AC_LIBREPLACE_SHLD_FLAGS -AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR -m4_include(libtdb.m4) -AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config]) -AC_PATH_PROGS([PYTHON], [python2.6 python2.5 python2.4 python]) - -PYTHON_BUILD_TARGET="build-python" -PYTHON_INSTALL_TARGET="install-python" -PYTHON_CHECK_TARGET="check-python" -AC_SUBST(PYTHON_BUILD_TARGET) -AC_SUBST(PYTHON_INSTALL_TARGET) -AC_SUBST(PYTHON_CHECK_TARGET) -if test -z "$PYTHON_CONFIG"; then - PYTHON_BUILD_TARGET="" - PYTHON_INSTALL_TARGET="" - PYTHON_CHECK_TARGET="" -fi -AC_OUTPUT(Makefile tdb.pc) diff --git a/tdb/docs/README b/tdb/docs/README deleted file mode 100644 index 63fcf5e049..0000000000 --- a/tdb/docs/README +++ /dev/null @@ -1,238 +0,0 @@ -tdb - a trivial database system -tridge@linuxcare.com December 1999 -================================== - -This is a simple database API. It was inspired by the realisation that -in Samba we have several ad-hoc bits of code that essentially -implement small databases for sharing structures between parts of -Samba. As I was about to add another I realised that a generic -database module was called for to replace all the ad-hoc bits. - -I based the interface on gdbm. I couldn't use gdbm as we need to be -able to have multiple writers to the databases at one time. - -Compilation ------------ - -add HAVE_MMAP=1 to use mmap instead of read/write -add NOLOCK=1 to disable locking code - -Testing -------- - -Compile tdbtest.c and link with gdbm for testing. tdbtest will perform -identical operations via tdb and gdbm then make sure the result is the -same - -Also included is tdbtool, which allows simple database manipulation -on the commandline. - -tdbtest and tdbtool are not built as part of Samba, but are included -for completeness. - -Interface ---------- - -The interface is very similar to gdbm except for the following: - -- different open interface. The tdb_open call is more similar to a - traditional open() -- no tdbm_reorganise() function -- no tdbm_sync() function. No operations are cached in the library anyway -- added a tdb_traverse() function for traversing the whole database -- added transactions support - -A general rule for using tdb is that the caller frees any returned -TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA -return value called p. This is the same as gdbm. - -here is a full list of tdb functions with brief descriptions. - - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) - - open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the database - file. A flags value of O_WRONLY is invalid - - The hash size is advisory, use zero for a default value. - - return is NULL on error - - possible tdb_flags are: - TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open - TDB_INTERNAL - don't use a file, instaed store the data in - memory. The filename is ignored in this case. - TDB_NOLOCK - don't do any locking - TDB_NOMMAP - don't use mmap - TDB_NOSYNC - don't synchronise transactions to disk - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn, - tdb_hash_func hash_fn) - -This is like tdb_open(), but allows you to pass an initial logging and -hash function. Be careful when passing a hash function - all users of -the database must use the same hash function or you will get data -corruption. - - ----------------------------------------------------------------------- -char *tdb_error(TDB_CONTEXT *tdb); - - return a error string for the last tdb error - ----------------------------------------------------------------------- -int tdb_close(TDB_CONTEXT *tdb); - - close a database - ----------------------------------------------------------------------- -int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf); - - update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1 - ----------------------------------------------------------------------- -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); - - fetch an entry in the database given a key - if the return value has a null dptr then a error occurred - - caller must free the resulting data - ----------------------------------------------------------------------- -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); - - check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm - ----------------------------------------------------------------------- -int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on each - element. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal - should stop. Traversal callbacks may not start transactions. - - WARNING: The data buffer given to the callback fn does NOT meet the - alignment restrictions malloc gives you. - ----------------------------------------------------------------------- -int tdb_traverse_read(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on - each element, but marking the database read only during the - traversal, so any write operations will fail. This allows tdb to - use read locks, which increases the parallelism possible during the - traversal. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal - should stop. Traversal callbacks may not start transactions. - ----------------------------------------------------------------------- -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); - - find the first entry in the database and return its key - - the caller must free the returned data - ----------------------------------------------------------------------- -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); - - find the next entry in the database, returning its key - - the caller must free the returned data - ----------------------------------------------------------------------- -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); - - delete an entry in the database given a key - ----------------------------------------------------------------------- -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); - - store an element in the database, replacing any existing element - with the same key - - If flag==TDB_INSERT then don't overwrite an existing entry - If flag==TDB_MODIFY then don't create a new entry - - return 0 on success, -1 on failure - ----------------------------------------------------------------------- -int tdb_writelock(TDB_CONTEXT *tdb); - - lock the database. If we already have it locked then don't do anything - ----------------------------------------------------------------------- -int tdb_writeunlock(TDB_CONTEXT *tdb); - unlock the database - ----------------------------------------------------------------------- -int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - lock one hash chain. This is meant to be used to reduce locking - contention - it cannot guarantee how many records will be locked - ----------------------------------------------------------------------- -int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - unlock one hash chain - ----------------------------------------------------------------------- -int tdb_transaction_start(TDB_CONTEXT *tdb) - - start a transaction. All operations after the transaction start can - either be committed with tdb_transaction_commit() or cancelled with - tdb_transaction_cancel(). - - If you call tdb_transaction_start() again on the same tdb context - while a transaction is in progress, then the same transaction - buffer is re-used. The number of tdb_transaction_{commit,cancel} - operations must match the number of successful - tdb_transaction_start() calls. - - Note that transactions are by default disk synchronous, and use a - recover area in the database to automatically recover the database - on the next open if the system crashes during a transaction. You - can disable the synchronous transaction recovery setup using the - TDB_NOSYNC flag, which will greatly speed up operations at the risk - of corrupting your database if the system crashes. - - Operations made within a transaction are not visible to other users - of the database until a successful commit. - ----------------------------------------------------------------------- -int tdb_transaction_cancel(TDB_CONTEXT *tdb) - - cancel a current transaction, discarding all write and lock - operations that have been made since the transaction started. - - ----------------------------------------------------------------------- -int tdb_transaction_commit(TDB_CONTEXT *tdb) - - commit a current transaction, updating the database and releasing - the transaction locks. - diff --git a/tdb/docs/tdb.magic b/tdb/docs/tdb.magic deleted file mode 100644 index f5619e7327..0000000000 --- a/tdb/docs/tdb.magic +++ /dev/null @@ -1,10 +0,0 @@ -# Magic file(1) information about tdb files. -# -# Install this into /etc/magic or the corresponding location for your -# system, or pass as a -m argument to file(1). - -# You may use and redistribute this file without restriction. - -0 string TDB\ file TDB database ->32 lelong =0x2601196D version 6, little-endian ->>36 lelong x hash size %d bytes diff --git a/tdb/include/tdb.h b/tdb/include/tdb.h deleted file mode 100644 index 0008085de5..0000000000 --- a/tdb/include/tdb.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef __TDB_H__ -#define __TDB_H__ - -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2004 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* flags to tdb_store() */ -#define TDB_REPLACE 1 /* Unused */ -#define TDB_INSERT 2 /* Don't overwrite an existing entry */ -#define TDB_MODIFY 3 /* Don't create an existing entry */ - -/* flags for tdb_open() */ -#define TDB_DEFAULT 0 /* just a readability place holder */ -#define TDB_CLEAR_IF_FIRST 1 -#define TDB_INTERNAL 2 /* don't store on disk */ -#define TDB_NOLOCK 4 /* don't do any locking */ -#define TDB_NOMMAP 8 /* don't use mmap */ -#define TDB_CONVERT 16 /* convert endian (internal use) */ -#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ -#define TDB_NOSYNC 64 /* don't use synchronous transactions */ -#define TDB_SEQNUM 128 /* maintain a sequence number */ -#define TDB_VOLATILE 256 /* Activate the per-hashchain freelist, default 5 */ - -#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) - -/* error codes */ -enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, - TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, - TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY}; - -/* debugging uses one of the following levels */ -enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, - TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; - -typedef struct TDB_DATA { - unsigned char *dptr; - size_t dsize; -} TDB_DATA; - -#ifndef PRINTF_ATTRIBUTE -#if (__GNUC__ >= 3) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -/* this is the context structure that is returned from a db open */ -typedef struct tdb_context TDB_CONTEXT; - -typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); -typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4); -typedef unsigned int (*tdb_hash_func)(TDB_DATA *key); - -struct tdb_logging_context { - tdb_log_func log_fn; - void *log_private; -}; - -struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); -struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - const struct tdb_logging_context *log_ctx, - tdb_hash_func hash_fn); -void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); - -int tdb_reopen(struct tdb_context *tdb); -int tdb_reopen_all(int parent_longlived); -void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); -enum TDB_ERROR tdb_error(struct tdb_context *tdb); -const char *tdb_errorstr(struct tdb_context *tdb); -TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); -int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data); -int tdb_delete(struct tdb_context *tdb, TDB_DATA key); -int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); -int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); -int tdb_close(struct tdb_context *tdb); -TDB_DATA tdb_firstkey(struct tdb_context *tdb); -TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); -int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *); -int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *); -int tdb_exists(struct tdb_context *tdb, TDB_DATA key); -int tdb_lockall(struct tdb_context *tdb); -int tdb_lockall_nonblock(struct tdb_context *tdb); -int tdb_unlockall(struct tdb_context *tdb); -int tdb_lockall_read(struct tdb_context *tdb); -int tdb_lockall_read_nonblock(struct tdb_context *tdb); -int tdb_unlockall_read(struct tdb_context *tdb); -int tdb_lockall_mark(struct tdb_context *tdb); -int tdb_lockall_unmark(struct tdb_context *tdb); -const char *tdb_name(struct tdb_context *tdb); -int tdb_fd(struct tdb_context *tdb); -tdb_log_func tdb_log_fn(struct tdb_context *tdb); -void *tdb_get_logging_private(struct tdb_context *tdb); -int tdb_transaction_start(struct tdb_context *tdb); -int tdb_transaction_commit(struct tdb_context *tdb); -int tdb_transaction_cancel(struct tdb_context *tdb); -int tdb_transaction_recover(struct tdb_context *tdb); -int tdb_get_seqnum(struct tdb_context *tdb); -int tdb_hash_size(struct tdb_context *tdb); -size_t tdb_map_size(struct tdb_context *tdb); -int tdb_get_flags(struct tdb_context *tdb); -void tdb_add_flags(struct tdb_context *tdb, unsigned flag); -void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); -void tdb_enable_seqnum(struct tdb_context *tdb); -void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); - -/* Low level locking functions: use with care */ -int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key); - -void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr); - -/* Debug functions. Not used in production. */ -void tdb_dump_all(struct tdb_context *tdb); -int tdb_printfreelist(struct tdb_context *tdb); -int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); -int tdb_wipe_all(struct tdb_context *tdb); -int tdb_freelist_size(struct tdb_context *tdb); - -extern TDB_DATA tdb_null; - -#ifdef __cplusplus -} -#endif - -#endif /* tdb.h */ diff --git a/tdb/install-sh b/tdb/install-sh deleted file mode 100755 index 58719246f0..0000000000 --- a/tdb/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -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=: - 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 diff --git a/tdb/libtdb.m4 b/tdb/libtdb.m4 deleted file mode 100644 index 1e17a7a4f2..0000000000 --- a/tdb/libtdb.m4 +++ /dev/null @@ -1,30 +0,0 @@ -dnl find the tdb sources. This is meant to work both for -dnl tdb standalone builds, and builds of packages using tdb -tdbdir="" -tdbpaths="$srcdir $srcdir/lib/tdb $srcdir/tdb $srcdir/../tdb" -for d in $tdbpaths; do - if test -f "$d/common/tdb.c"; then - tdbdir="$d" - AC_SUBST(tdbdir) - break; - fi -done -if test x"$tdbdir" = "x"; then - AC_MSG_ERROR([cannot find tdb source in $tdbpaths]) -fi -TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" -TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o" -AC_SUBST(TDB_OBJ) -AC_SUBST(LIBREPLACEOBJ) - -TDB_LIBS="" -AC_SUBST(TDB_LIBS) - -TDB_CFLAGS="-I$tdbdir/include" -AC_SUBST(TDB_CFLAGS) - -AC_CHECK_FUNCS(mmap pread pwrite getpagesize utime) -AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h) - -AC_HAVE_DECL(pread, [#include ]) -AC_HAVE_DECL(pwrite, [#include ]) diff --git a/tdb/python.mk b/tdb/python.mk deleted file mode 100644 index 12e8217df9..0000000000 --- a/tdb/python.mk +++ /dev/null @@ -1,10 +0,0 @@ -[PYTHON::swig_tdb] -LIBRARY_REALNAME = _tdb.$(SHLIBEXT) -PUBLIC_DEPENDENCIES = LIBTDB DYNCONFIG - -swig_tdb_OBJ_FILES = $(tdbsrcdir)/tdb_wrap.o - -$(eval $(call python_py_module_template,tdb.py,$(tdbsrcdir)/tdb.py)) - -$(swig_tdb_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) - diff --git a/tdb/python/tdbdump.py b/tdb/python/tdbdump.py deleted file mode 100644 index d759d771c8..0000000000 --- a/tdb/python/tdbdump.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/python -# Trivial reimplementation of tdbdump in Python - -import tdb, sys - -if len(sys.argv) < 2: - print "Usage: tdbdump.py " - sys.exit(1) - -db = tdb.Tdb(sys.argv[1]) -for (k, v) in db.iteritems(): - print "{\nkey(%d) = %r\ndata(%d) = %r\n}" % (len(k), k, len(v), v) diff --git a/tdb/python/tests/simple.py b/tdb/python/tests/simple.py deleted file mode 100644 index 7147718c91..0000000000 --- a/tdb/python/tests/simple.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/python -# Some simple tests for the Python bindings for TDB -# Note that this tests the interface of the Python bindings -# It does not test tdb itself. -# -# Copyright (C) 2007-2008 Jelmer Vernooij -# Published under the GNU LGPLv3 or later - -import tdb -from unittest import TestCase -import os, tempfile - - -class OpenTdbTests(TestCase): - def test_nonexistant_read(self): - self.assertRaises(IOError, tdb.Tdb, "/some/nonexistant/file", 0, tdb.DEFAULT, os.O_RDWR) - - -class SimpleTdbTests(TestCase): - def setUp(self): - super(SimpleTdbTests, self).setUp() - self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) - self.assertNotEqual(None, self.tdb) - - def tearDown(self): - del self.tdb - - def test_repr(self): - self.assertTrue(repr(self.tdb).startswith("Tdb('")) - - def test_lockall(self): - self.tdb.lock_all() - - def test_max_dead(self): - self.tdb.max_dead = 20 - - def test_unlockall(self): - self.tdb.lock_all() - self.tdb.unlock_all() - - def test_lockall_read(self): - self.tdb.read_lock_all() - self.tdb.read_unlock_all() - - def test_reopen(self): - self.tdb.reopen() - - def test_store(self): - self.tdb.store("bar", "bla") - self.assertEquals("bla", self.tdb.get("bar")) - - def test_getitem(self): - self.tdb["bar"] = "foo" - self.tdb.reopen() - self.assertEquals("foo", self.tdb["bar"]) - - def test_delete(self): - self.tdb["bar"] = "foo" - del self.tdb["bar"] - self.assertRaises(KeyError, lambda: self.tdb["bar"]) - - def test_contains(self): - self.tdb["bla"] = "bloe" - self.assertTrue("bla" in self.tdb) - - def test_keyerror(self): - self.assertRaises(KeyError, lambda: self.tdb["bla"]) - - def test_hash_size(self): - self.tdb.hash_size - - def test_map_size(self): - self.tdb.map_size - - def test_name(self): - self.tdb.name - - def test_iterator(self): - self.tdb["bla"] = "1" - self.tdb["brainslug"] = "2" - self.assertEquals(["bla", "brainslug"], list(self.tdb)) - - def test_items(self): - self.tdb["bla"] = "1" - self.tdb["brainslug"] = "2" - self.assertEquals([("bla", "1"), ("brainslug", "2")], self.tdb.items()) - - def test_iteritems(self): - self.tdb["bloe"] = "2" - self.tdb["bla"] = "25" - i = self.tdb.iteritems() - self.assertEquals(set([("bla", "25"), ("bloe", "2")]), - set([i.next(), i.next()])) - - def test_transaction_cancel(self): - self.tdb["bloe"] = "2" - self.tdb.transaction_start() - self.tdb["bloe"] = "1" - self.tdb.transaction_cancel() - self.assertEquals("2", self.tdb["bloe"]) - - def test_transaction_commit(self): - self.tdb["bloe"] = "2" - self.tdb.transaction_start() - self.tdb["bloe"] = "1" - self.tdb.transaction_commit() - self.assertEquals("1", self.tdb["bloe"]) - - def test_iterator(self): - self.tdb["bloe"] = "2" - self.tdb["bla"] = "hoi" - i = iter(self.tdb) - self.assertEquals(set(["bloe", "bla"]), set([i.next(), i.next()])) - - def test_keys(self): - self.tdb["bloe"] = "2" - self.tdb["bla"] = "25" - self.assertEquals(["bla", "bloe"], self.tdb.keys()) - - def test_iterkeys(self): - self.tdb["bloe"] = "2" - self.tdb["bla"] = "25" - i = self.tdb.iterkeys() - self.assertEquals(set(["bloe", "bla"]), set([i.next(), i.next()])) - - def test_values(self): - self.tdb["bloe"] = "2" - self.tdb["bla"] = "25" - self.assertEquals(["25", "2"], self.tdb.values()) - - def test_itervalues(self): - self.tdb["bloe"] = "2" - self.tdb["bla"] = "25" - i = self.tdb.itervalues() - self.assertEquals(set(["25", "2"]), set([i.next(), i.next()])) - - def test_clear(self): - self.tdb["bloe"] = "2" - self.tdb["bla"] = "25" - self.assertEquals(2, len(self.tdb)) - self.tdb.clear() - self.assertEquals(0, len(self.tdb)) - - def test_len(self): - self.assertEquals(0, len(self.tdb)) - self.tdb["entry"] = "value" - self.assertEquals(1, len(self.tdb)) - - -if __name__ == '__main__': - import unittest - unittest.TestProgram() diff --git a/tdb/rules.mk b/tdb/rules.mk deleted file mode 100644 index 7b765625df..0000000000 --- a/tdb/rules.mk +++ /dev/null @@ -1,21 +0,0 @@ -.SUFFIXES: .i _wrap.c - -.i_wrap.c: - $(SWIG) -O -Wall -python -keyword $< - -showflags:: - @echo 'tdb will be compiled with flags:' - @echo ' CFLAGS = $(CFLAGS)' - @echo ' CPPFLAGS = $(CPPFLAGS)' - @echo ' LDFLAGS = $(LDFLAGS)' - @echo ' LIBS = $(LIBS)' - -.SUFFIXES: .c .o - -.c.o: - @echo Compiling $*.c - @mkdir -p `dirname $@` - @$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@ - -distclean:: - rm -f *~ */*~ diff --git a/tdb/tdb.i b/tdb/tdb.i deleted file mode 100644 index 3d8b697732..0000000000 --- a/tdb/tdb.i +++ /dev/null @@ -1,323 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Swig interface to tdb. - - Copyright (C) 2004-2006 Tim Potter - Copyright (C) 2007 Jelmer Vernooij - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -%define DOCSTRING -"TDB is a simple key-value database similar to GDBM that supports multiple writers." -%enddef - -%module(docstring=DOCSTRING) tdb - -%{ - -/* This symbol is used in both includes.h and Python.h which causes an - annoying compiler warning. */ - -#ifdef HAVE_FSTAT -#undef HAVE_FSTAT -#endif - -/* Include tdb headers */ -#include -#include -#include -#include - -typedef TDB_CONTEXT tdb; -%} - -/* The tdb functions will crash if a NULL tdb context is passed */ - -%import exception.i -%import stdint.i - -%typemap(check,noblock=1) TDB_CONTEXT* { - if ($1 == NULL) - SWIG_exception(SWIG_ValueError, - "tdb context must be non-NULL"); -} - -/* In and out typemaps for the TDB_DATA structure. This is converted to - and from the Python string type which can contain arbitrary binary - data.. */ - -%typemap(in,noblock=1) TDB_DATA { - if ($input == Py_None) { - $1.dsize = 0; - $1.dptr = NULL; - } else if (!PyString_Check($input)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - $1.dsize = PyString_Size($input); - $1.dptr = (uint8_t *)PyString_AsString($input); - } -} - -%typemap(out,noblock=1) TDB_DATA { - if ($1.dptr == NULL && $1.dsize == 0) { - $result = Py_None; - } else { - $result = PyString_FromStringAndSize((const char *)$1.dptr, $1.dsize); - free($1.dptr); - } -} - -/* Treat a mode_t as an unsigned integer */ -typedef int mode_t; - -/* flags to tdb_store() */ -%constant int REPLACE = TDB_REPLACE; -%constant int INSERT = TDB_INSERT; -%constant int MODIFY = TDB_MODIFY; - -/* flags for tdb_open() */ -%constant int DEFAULT = TDB_DEFAULT; -%constant int CLEAR_IF_FIRST = TDB_CLEAR_IF_FIRST; -%constant int INTERNAL = TDB_INTERNAL; -%constant int NOLOCK = TDB_NOLOCK; -%constant int NOMMAP = TDB_NOMMAP; -%constant int CONVERT = TDB_CONVERT; -%constant int BIGENDIAN = TDB_BIGENDIAN; - -enum TDB_ERROR { - TDB_SUCCESS=0, - TDB_ERR_CORRUPT, - TDB_ERR_IO, - TDB_ERR_LOCK, - TDB_ERR_OOM, - TDB_ERR_EXISTS, - TDB_ERR_NOLOCK, - TDB_ERR_LOCK_TIMEOUT, - TDB_ERR_NOEXIST, - TDB_ERR_EINVAL, - TDB_ERR_RDONLY -}; - -%rename(lock_all) tdb_context::lockall; -%rename(unlock_all) tdb_context::unlockall; - -%rename(read_lock_all) tdb_context::lockall_read; -%rename(read_unlock_all) tdb_context::unlockall_read; - -%typemap(default,noblock=1) int tdb_flags { - $1 = TDB_DEFAULT; -} - -%typemap(default,noblock=1) int flags { - $1 = O_RDWR; -} - -%typemap(default,noblock=1) int hash_size { - $1 = 0; -} - -%typemap(default,noblock=1) mode_t mode { - $1 = 0600; -} - -%typemap(default,noblock=1) int flag { - $1 = TDB_REPLACE; -} - -%rename(Tdb) tdb_context; -%feature("docstring") tdb_context "A TDB file."; -%typemap(out,noblock=1) tdb * { - /* Throw an IOError exception from errno if tdb_open() returns NULL */ - if ($1 == NULL) { - PyErr_SetFromErrno(PyExc_IOError); - SWIG_fail; - } - $result = SWIG_NewPointerObj($1, $1_descriptor, 0); -} - -typedef struct tdb_context { - %extend { - %feature("docstring") tdb "S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600)\n" - "Open a TDB file."; - tdb(const char *name, int hash_size, int tdb_flags, int flags, mode_t mode) { - return tdb_open(name, hash_size, tdb_flags, flags, mode); - } - %feature("docstring") error "S.error() -> int\n" - "Find last error number returned by operation on this TDB."; - enum TDB_ERROR error(); - ~tdb() { tdb_close($self); } - %feature("docstring") close "S.close() -> None\n" - "Close the TDB file."; - int close(); - int append(TDB_DATA key, TDB_DATA new_dbuf); - %feature("docstring") errorstr "S.errorstr() -> errorstring\n" - "Obtain last error message."; - const char *errorstr(); - %rename(get) fetch; - %feature("docstring") fetch "S.fetch(key) -> value\n" - "Fetch a value."; - TDB_DATA fetch(TDB_DATA key); - %feature("docstring") delete "S.delete(key) -> None\n" - "Delete an entry."; - int delete(TDB_DATA key); - %feature("docstring") store "S.store(key, value, flag=TDB_REPLACE) -> None\n" - "Store an entry."; - int store(TDB_DATA key, TDB_DATA dbuf, int flag); - %feature("docstring") exists "S.exists(key) -> bool\n" - "Check whether key exists in this database."; - int exists(TDB_DATA key); - %feature("docstring") firstkey "S.firstkey() -> data\n" - "Return the first key in this database."; - TDB_DATA firstkey(); - %feature("docstring") nextkey "S.nextkey(prev) -> data\n" - "Return the next key in this database."; - TDB_DATA nextkey(TDB_DATA key); - %feature("docstring") lockall "S.lockall() -> bool"; - int lockall(); - %feature("docstring") unlockall "S.unlockall() -> bool"; - int unlockall(); - %feature("docstring") unlockall "S.lockall_read() -> bool"; - int lockall_read(); - %feature("docstring") unlockall "S.unlockall_read() -> bool"; - int unlockall_read(); - %feature("docstring") reopen "S.reopen() -> bool\n" - "Reopen this file."; - int reopen(); - %feature("docstring") transaction_start "S.transaction_start() -> None\n" - "Start a new transaction."; - int transaction_start(); - %feature("docstring") transaction_commit "S.transaction_commit() -> None\n" - "Commit the currently active transaction."; - int transaction_commit(); - %feature("docstring") transaction_cancel "S.transaction_cancel() -> None\n" - "Cancel the currently active transaction."; - int transaction_cancel(); - int transaction_recover(); - %feature("docstring") hash_size "S.hash_size() -> int"; - int hash_size(); - %feature("docstring") map_size "S.map_size() -> int"; - size_t map_size(); - %feature("docstring") get_flags "S.get_flags() -> int"; - int get_flags(); - %feature("docstring") set_max_dead "S.set_max_dead(int) -> None"; - void set_max_dead(int max_dead); - %feature("docstring") name "S.name() -> path\n" \ - "Return filename of this TDB file."; - const char *name(); - } - - %pythoncode { - def __repr__(self): - return "Tdb('%s')" % self.name() - - # Random access to keys, values - def __getitem__(self, key): - result = self.get(key) - if result is None: - raise KeyError, '%s: %s' % (key, self.errorstr()) - return result - - def __setitem__(self, key, item): - if self.store(key, item) == -1: - raise IOError, self.errorstr() - - def __delitem__(self, key): - if not self.exists(key): - raise KeyError, '%s: %s' % (key, self.errorstr()) - self.delete(key) - - def __contains__(self, key): - return self.exists(key) != 0 - - def has_key(self, key): - return self.exists(key) != 0 - - def fetch_uint32(self, key): - data = self.get(key) - if data is None: - return None - import struct - return struct.unpack("" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -import types -try: - _object = types.ObjectType - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 -del types - - -def _swig_setattr_nondynamic_method(set): - def set_attr(self,name,value): - if (name == "thisown"): return self.this.own(value) - if hasattr(self,name) or (name == "this"): - set(self,name,value) - else: - raise AttributeError("You cannot add attributes to %s" % self) - return set_attr - - -REPLACE = _tdb.REPLACE -INSERT = _tdb.INSERT -MODIFY = _tdb.MODIFY -DEFAULT = _tdb.DEFAULT -CLEAR_IF_FIRST = _tdb.CLEAR_IF_FIRST -INTERNAL = _tdb.INTERNAL -NOLOCK = _tdb.NOLOCK -NOMMAP = _tdb.NOMMAP -CONVERT = _tdb.CONVERT -BIGENDIAN = _tdb.BIGENDIAN -TDB_SUCCESS = _tdb.TDB_SUCCESS -TDB_ERR_CORRUPT = _tdb.TDB_ERR_CORRUPT -TDB_ERR_IO = _tdb.TDB_ERR_IO -TDB_ERR_LOCK = _tdb.TDB_ERR_LOCK -TDB_ERR_OOM = _tdb.TDB_ERR_OOM -TDB_ERR_EXISTS = _tdb.TDB_ERR_EXISTS -TDB_ERR_NOLOCK = _tdb.TDB_ERR_NOLOCK -TDB_ERR_LOCK_TIMEOUT = _tdb.TDB_ERR_LOCK_TIMEOUT -TDB_ERR_NOEXIST = _tdb.TDB_ERR_NOEXIST -TDB_ERR_EINVAL = _tdb.TDB_ERR_EINVAL -TDB_ERR_RDONLY = _tdb.TDB_ERR_RDONLY -class Tdb(object): - """A TDB file.""" - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def __init__(self, *args, **kwargs): - """ - S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600) - Open a TDB file. - """ - _tdb.Tdb_swiginit(self,_tdb.new_Tdb(*args, **kwargs)) - def error(*args, **kwargs): - """ - S.error() -> int - Find last error number returned by operation on this TDB. - """ - return _tdb.Tdb_error(*args, **kwargs) - - __swig_destroy__ = _tdb.delete_Tdb - def close(*args, **kwargs): - """ - S.close() -> None - Close the TDB file. - """ - return _tdb.Tdb_close(*args, **kwargs) - - def errorstr(*args, **kwargs): - """ - S.errorstr() -> errorstring - Obtain last error message. - """ - return _tdb.Tdb_errorstr(*args, **kwargs) - - def get(*args, **kwargs): - """ - S.fetch(key) -> value - Fetch a value. - """ - return _tdb.Tdb_get(*args, **kwargs) - - def delete(*args, **kwargs): - """ - S.delete(key) -> None - Delete an entry. - """ - return _tdb.Tdb_delete(*args, **kwargs) - - def store(*args, **kwargs): - """ - S.store(key, value, flag=TDB_REPLACE) -> None - Store an entry. - """ - return _tdb.Tdb_store(*args, **kwargs) - - def exists(*args, **kwargs): - """ - S.exists(key) -> bool - Check whether key exists in this database. - """ - return _tdb.Tdb_exists(*args, **kwargs) - - def firstkey(*args, **kwargs): - """ - S.firstkey() -> data - Return the first key in this database. - """ - return _tdb.Tdb_firstkey(*args, **kwargs) - - def nextkey(*args, **kwargs): - """ - S.nextkey(prev) -> data - Return the next key in this database. - """ - return _tdb.Tdb_nextkey(*args, **kwargs) - - def lock_all(*args, **kwargs): - """S.lockall() -> bool""" - return _tdb.Tdb_lock_all(*args, **kwargs) - - def unlock_all(*args, **kwargs): - """S.unlockall() -> bool""" - return _tdb.Tdb_unlock_all(*args, **kwargs) - - def reopen(*args, **kwargs): - """ - S.reopen() -> bool - Reopen this file. - """ - return _tdb.Tdb_reopen(*args, **kwargs) - - def transaction_start(*args, **kwargs): - """ - S.transaction_start() -> None - Start a new transaction. - """ - return _tdb.Tdb_transaction_start(*args, **kwargs) - - def transaction_commit(*args, **kwargs): - """ - S.transaction_commit() -> None - Commit the currently active transaction. - """ - return _tdb.Tdb_transaction_commit(*args, **kwargs) - - def transaction_cancel(*args, **kwargs): - """ - S.transaction_cancel() -> None - Cancel the currently active transaction. - """ - return _tdb.Tdb_transaction_cancel(*args, **kwargs) - - def hash_size(*args, **kwargs): - """S.hash_size() -> int""" - return _tdb.Tdb_hash_size(*args, **kwargs) - - def map_size(*args, **kwargs): - """S.map_size() -> int""" - return _tdb.Tdb_map_size(*args, **kwargs) - - def get_flags(*args, **kwargs): - """S.get_flags() -> int""" - return _tdb.Tdb_get_flags(*args, **kwargs) - - def set_max_dead(*args, **kwargs): - """S.set_max_dead(int) -> None""" - return _tdb.Tdb_set_max_dead(*args, **kwargs) - - def name(*args, **kwargs): - """ - S.name() -> path - Return filename of this TDB file. - """ - return _tdb.Tdb_name(*args, **kwargs) - - def __repr__(self): - return "Tdb('%s')" % self.name() - - - def __getitem__(self, key): - result = self.get(key) - if result is None: - raise KeyError, '%s: %s' % (key, self.errorstr()) - return result - - def __setitem__(self, key, item): - if self.store(key, item) == -1: - raise IOError, self.errorstr() - - def __delitem__(self, key): - if not self.exists(key): - raise KeyError, '%s: %s' % (key, self.errorstr()) - self.delete(key) - - def __contains__(self, key): - return self.exists(key) != 0 - - def has_key(self, key): - return self.exists(key) != 0 - - def fetch_uint32(self, key): - data = self.get(key) - if data is None: - return None - import struct - return struct.unpack(" 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - - - -/* Python.h has to appear first */ -#include - -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic CAPI SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "4" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the swig runtime code. - In 99.9% of the cases, swig just needs to declare them as 'static'. - - But only do this if is strictly necessary, ie, if you have problems - with your compiler or so. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 -#define SWIG_CAST_NEW_MEMORY 0x2 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The swig conversion methods, as ConvertPtr, return and integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old swig versions, you usually write code as: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit as: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - that seems to be the same, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - requires also to SWIG_ConvertPtr to return new result values, as - - int SWIG_ConvertPtr(obj, ptr,...) { - if () { - if () { - *ptr = ; - return SWIG_NEWOBJ; - } else { - *ptr = ; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - swig errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows to return the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() - - - */ -#define SWIG_OK (0) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *, int *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store information on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (int)((l1 - f1) - (l2 - f2)); -} - -/* - Check type equivalence in a name list like ||... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like ||... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCompare(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* think of this as a c++ template<> or a scheme macro */ -#define SWIG_TypeCheck_Template(comparison, ty) \ - if (ty) { \ - swig_cast_info *iter = ty->cast; \ - while (iter) { \ - if (comparison) { \ - if (iter == ty->cast) return iter; \ - /* Move iter to the top of the linked list */ \ - iter->prev->next = iter->next; \ - if (iter->next) \ - iter->next->prev = iter->prev; \ - iter->next = ty->cast; \ - iter->prev = 0; \ - if (ty->cast) ty->cast->prev = iter; \ - ty->cast = iter; \ - return iter; \ - } \ - iter = iter->next; \ - } \ - } \ - return 0 - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); -} - -/* Same as previous function, except strcmp is replaced with a pointer comparison */ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { - SWIG_TypeCheck_Template(iter->type == from, into); -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. We choose - to print the last name, as it is often (?) the most - specific. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - register size_t l = 0; - register size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - register size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - register int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - register size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - register const unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register char d = *(c++); - register unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -/* Add PyOS_snprintf for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# define PyOS_snprintf _snprintf -# else -# define PyOS_snprintf snprintf -# endif -#endif - -/* A crude PyString_FromFormat implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 - -#ifndef SWIG_PYBUFFER_SIZE -# define SWIG_PYBUFFER_SIZE 1024 -#endif - -static PyObject * -PyString_FromFormat(const char *fmt, ...) { - va_list ap; - char buf[SWIG_PYBUFFER_SIZE * 2]; - int res; - va_start(ap, fmt); - res = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); -} -#endif - -/* Add PyObject_Del for old Pythons */ -#if PY_VERSION_HEX < 0x01060000 -# define PyObject_Del(op) PyMem_DEL((op)) -#endif -#ifndef PyObject_DEL -# define PyObject_DEL PyObject_Del -#endif - -/* A crude PyExc_StopIteration exception for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# ifndef PyExc_StopIteration -# define PyExc_StopIteration PyExc_RuntimeError -# endif -# ifndef PyObject_GenericGetAttr -# define PyObject_GenericGetAttr 0 -# endif -#endif -/* Py_NotImplemented is defined in 2.1 and up. */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef Py_NotImplemented -# define Py_NotImplemented PyExc_RuntimeError -# endif -#endif - - -/* A crude PyString_AsStringAndSize implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef PyString_AsStringAndSize -# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} -# endif -#endif - -/* PySequence_Size for old Pythons */ -#if PY_VERSION_HEX < 0x02000000 -# ifndef PySequence_Size -# define PySequence_Size PySequence_Length -# endif -#endif - - -/* PyBool_FromLong for old Pythons */ -#if PY_VERSION_HEX < 0x02030000 -static -PyObject *PyBool_FromLong(long ok) -{ - PyObject *result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; -} -#endif - -/* Py_ssize_t for old Pythons */ -/* This code is as recommended by: */ -/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -# define PY_SSIZE_T_MIN INT_MIN -#endif - -/* ----------------------------------------------------------------------------- - * error manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject* -SWIG_Python_ErrorType(int code) { - PyObject* type = 0; - switch(code) { - case SWIG_MemoryError: - type = PyExc_MemoryError; - break; - case SWIG_IOError: - type = PyExc_IOError; - break; - case SWIG_RuntimeError: - type = PyExc_RuntimeError; - break; - case SWIG_IndexError: - type = PyExc_IndexError; - break; - case SWIG_TypeError: - type = PyExc_TypeError; - break; - case SWIG_DivisionByZero: - type = PyExc_ZeroDivisionError; - break; - case SWIG_OverflowError: - type = PyExc_OverflowError; - break; - case SWIG_SyntaxError: - type = PyExc_SyntaxError; - break; - case SWIG_ValueError: - type = PyExc_ValueError; - break; - case SWIG_SystemError: - type = PyExc_SystemError; - break; - case SWIG_AttributeError: - type = PyExc_AttributeError; - break; - default: - type = PyExc_RuntimeError; - } - return type; -} - - -SWIGRUNTIME void -SWIG_Python_AddErrorMsg(const char* mesg) -{ - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - - if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - PyErr_Clear(); - Py_XINCREF(type); - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - Py_DECREF(old_str); - Py_DECREF(value); - } else { - PyErr_SetString(PyExc_RuntimeError, mesg); - } -} - - - -#if defined(SWIG_PYTHON_NO_THREADS) -# if defined(SWIG_PYTHON_THREADS) -# undef SWIG_PYTHON_THREADS -# endif -#endif -#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ -# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) -# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ -# define SWIG_PYTHON_USE_GIL -# endif -# endif -# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ -# ifndef SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() -# endif -# ifdef __cplusplus /* C++ code */ - class SWIG_Python_Thread_Block { - bool status; - PyGILState_STATE state; - public: - void end() { if (status) { PyGILState_Release(state); status = false;} } - SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} - ~SWIG_Python_Thread_Block() { end(); } - }; - class SWIG_Python_Thread_Allow { - bool status; - PyThreadState *save; - public: - void end() { if (status) { PyEval_RestoreThread(save); status = false; }} - SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} - ~SWIG_Python_Thread_Allow() { end(); } - }; -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block -# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow -# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() -# else /* C code */ -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() -# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() -# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) -# endif -# else /* Old thread way, not implemented, user must provide it */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) -# define SWIG_PYTHON_THREAD_END_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# endif -# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) -# define SWIG_PYTHON_THREAD_END_ALLOW -# endif -# endif -#else /* No thread support */ -# define SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# define SWIG_PYTHON_THREAD_END_BLOCK -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# define SWIG_PYTHON_THREAD_END_ALLOW -#endif - -/* ----------------------------------------------------------------------------- - * Python API portion that goes into the runtime - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* ----------------------------------------------------------------------------- - * Constant declarations - * ----------------------------------------------------------------------------- */ - -/* Constant Types */ -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * ----------------------------------------------------------------------------- */ - -/* Common SWIG API */ - -/* for raw pointers */ -#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) -#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) -#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) -#define swig_owntype int - -/* for raw packed data */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - -/* for class or struct pointers */ -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) - -/* for C or C++ function pointers */ -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) - -/* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* Runtime API */ - -#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) PySwigClientData_New(obj) - -#define SWIG_SetErrorObj SWIG_Python_SetErrorObj -#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* Runtime API implementation */ - -/* Error manipulation */ - -SWIGINTERN void -SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetObject(errtype, obj); - Py_DECREF(obj); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -SWIGINTERN void -SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetString(errtype, (char *) msg); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) - -/* Set a constant value */ - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { - PyDict_SetItemString(d, (char*) name, obj); - Py_DECREF(obj); -} - -/* Append a value to the result obj */ - -SWIGINTERN PyObject* -SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { -#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyList_Check(result)) { - PyObject *o2 = result; - result = PyList_New(1); - PyList_SetItem(result, 0, o2); - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -#else - PyObject* o2; - PyObject* o3; - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyTuple_Check(result)) { - o2 = result; - result = PyTuple_New(1); - PyTuple_SET_ITEM(result, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SET_ITEM(o3, 0, obj); - o2 = result; - result = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return result; -#endif -} - -/* Unpack the argument tuple */ - -SWIGINTERN int -SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) -{ - if (!args) { - if (!min && !max) { - return 1; - } else { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", - name, (min == max ? "" : "at least "), (int)min); - return 0; - } - } - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - register Py_ssize_t l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), (int)min, (int)l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), (int)max, (int)l); - return 0; - } else { - register int i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -/* A functor is a function object with one single object argument */ -#if PY_VERSION_HEX >= 0x02020000 -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); -#else -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); -#endif - -/* - Helper for static pointer initialization for both C and C++ code, for example - static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); -*/ -#ifdef __cplusplus -#define SWIG_STATIC_POINTER(var) var -#else -#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var -#endif - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ - -/* Flags for new pointer objects */ -#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) -#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) - -#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* How to access Py_None */ -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# ifndef SWIG_PYTHON_NO_BUILD_NONE -# ifndef SWIG_PYTHON_BUILD_NONE -# define SWIG_PYTHON_BUILD_NONE -# endif -# endif -#endif - -#ifdef SWIG_PYTHON_BUILD_NONE -# ifdef Py_None -# undef Py_None -# define Py_None SWIG_Py_None() -# endif -SWIGRUNTIMEINLINE PyObject * -_SWIG_Py_None(void) -{ - PyObject *none = Py_BuildValue((char*)""); - Py_DECREF(none); - return none; -} -SWIGRUNTIME PyObject * -SWIG_Py_None(void) -{ - static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); - return none; -} -#endif - -/* The python void return value */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* PySwigClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; -} PySwigClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - PySwigClientData *data = (PySwigClientData *)ty->clientdata; - return data ? data->implicitconv : 0; -} - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_ExceptionType(swig_type_info *desc) { - PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; - PyObject *klass = data ? data->klass : 0; - return (klass ? klass : PyExc_RuntimeError); -} - - -SWIGRUNTIME PySwigClientData * -PySwigClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(data->klass); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); - } else { -#if (PY_VERSION_HEX < 0x02020000) - data->newraw = 0; -#else - data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); -#endif - if (data->newraw) { - Py_INCREF(data->newraw); - data->newargs = PyTuple_New(1); - PyTuple_SetItem(data->newargs, 0, obj); - } else { - data->newargs = obj; - } - Py_INCREF(data->newargs); - } - /* the destroy method, aka as the C++ delete method */ - data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); - if (PyErr_Occurred()) { - PyErr_Clear(); - data->destroy = 0; - } - if (data->destroy) { - int flags; - Py_INCREF(data->destroy); - flags = PyCFunction_GET_FLAGS(data->destroy); -#ifdef METH_O - data->delargs = !(flags & (METH_O)); -#else - data->delargs = 0; -#endif - } else { - data->delargs = 0; - } - data->implicitconv = 0; - return data; - } -} - -SWIGRUNTIME void -PySwigClientData_Del(PySwigClientData* data) -{ - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); -} - -/* =============== PySwigObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -} PySwigObject; - -SWIGRUNTIME PyObject * -PySwigObject_long(PySwigObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -PySwigObject_format(const char* fmt, PySwigObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { - PyObject *ofmt = PyString_FromString(fmt); - if (ofmt) { - res = PyString_Format(ofmt,args); - Py_DECREF(ofmt); - } - Py_DECREF(args); - } - } - return res; -} - -SWIGRUNTIME PyObject * -PySwigObject_oct(PySwigObject *v) -{ - return PySwigObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -PySwigObject_hex(PySwigObject *v) -{ - return PySwigObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -#ifdef METH_NOARGS -PySwigObject_repr(PySwigObject *v) -#else -PySwigObject_repr(PySwigObject *v, PyObject *args) -#endif -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *hex = PySwigObject_hex(v); - PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); - Py_DECREF(hex); - if (v->next) { -#ifdef METH_NOARGS - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); -#else - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); -#endif - PyString_ConcatAndDel(&repr,nrep); - } - return repr; -} - -SWIGRUNTIME int -PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ -#ifdef METH_NOARGS - PyObject *repr = PySwigObject_repr(v); -#else - PyObject *repr = PySwigObject_repr(v, NULL); -#endif - if (repr) { - fputs(PyString_AsString(repr), fp); - Py_DECREF(repr); - return 0; - } else { - return 1; - } -} - -SWIGRUNTIME PyObject * -PySwigObject_str(PySwigObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? - PyString_FromString(result) : 0; -} - -SWIGRUNTIME int -PySwigObject_compare(PySwigObject *v, PySwigObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigObject_Check(PyObject *op) { - return ((op)->ob_type == PySwigObject_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own); - -SWIGRUNTIME void -PySwigObject_dealloc(PyObject *v) -{ - PySwigObject *sobj = (PySwigObject *) v; - PyObject *next = sobj->next; - if (sobj->own == SWIG_POINTER_OWN) { - swig_type_info *ty = sobj->ty; - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - if (data->delargs) { - /* we need to create a temporal object to carry the destroy operation */ - PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); - res = SWIG_Python_CallFunctor(destroy, tmp); - Py_DECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - Py_XDECREF(res); - } -#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - else { - const char *name = SWIG_TypePrettyName(ty); - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); - } -#endif - } - Py_XDECREF(next); - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -PySwigObject_append(PyObject* v, PyObject* next) -{ - PySwigObject *sobj = (PySwigObject *) v; -#ifndef METH_O - PyObject *tmp = 0; - if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; - next = tmp; -#endif - if (!PySwigObject_Check(next)) { - return NULL; - } - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -#ifdef METH_NOARGS -PySwigObject_next(PyObject* v) -#else -PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_disown(PyObject *v) -#else -PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_acquire(PyObject *v) -#else -PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -PySwigObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; -#if (PY_VERSION_HEX < 0x02020000) - if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) -#else - if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) -#endif - { - return NULL; - } - else - { - PySwigObject *sobj = (PySwigObject *)v; - PyObject *obj = PyBool_FromLong(sobj->own); - if (val) { -#ifdef METH_NOARGS - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v); - } else { - PySwigObject_disown(v); - } -#else - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v,args); - } else { - PySwigObject_disown(v,args); - } -#endif - } - return obj; - } -} - -#ifdef METH_O -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#else -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#endif - -#if PY_VERSION_HEX < 0x02020000 -SWIGINTERN PyObject * -PySwigObject_getattr(PySwigObject *sobj,char *name) -{ - return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); -} -#endif - -SWIGRUNTIME PyTypeObject* -_PySwigObject_type(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods PySwigObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - (binaryfunc)0, /*nb_divide*/ - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0,/*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)PySwigObject_long, /*nb_int*/ - (unaryfunc)PySwigObject_long, /*nb_long*/ - (unaryfunc)0, /*nb_float*/ - (unaryfunc)PySwigObject_oct, /*nb_oct*/ - (unaryfunc)PySwigObject_hex, /*nb_hex*/ -#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ -#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ - 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ -#endif - }; - - static PyTypeObject pyswigobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigObject", /* tp_name */ - sizeof(PySwigObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigObject_dealloc, /* tp_dealloc */ - (printfunc)PySwigObject_print, /* tp_print */ -#if PY_VERSION_HEX < 0x02020000 - (getattrfunc)PySwigObject_getattr, /* tp_getattr */ -#else - (getattrfunc)0, /* tp_getattr */ -#endif - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigObject_compare, /* tp_compare */ - (reprfunc)PySwigObject_repr, /* tp_repr */ - &PySwigObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigObject_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigobject_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - swigobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigobject_type = tmp; - pyswigobject_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigobject_type; -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own) -{ - PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; - } - return (PyObject *)sobj; -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - swig_type_info *ty; - size_t size; -} PySwigPacked; - -SWIGRUNTIME int -PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->ty->name,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -PySwigPacked_repr(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return PyString_FromFormat("", result, v->ty->name); - } else { - return PyString_FromFormat("", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -PySwigPacked_str(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return PyString_FromFormat("%s%s", result, v->ty->name); - } else { - return PyString_FromString(v->ty->name); - } -} - -SWIGRUNTIME int -PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigPacked_Check(PyObject *op) { - return ((op)->ob_type == _PySwigPacked_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); -} - -SWIGRUNTIME void -PySwigPacked_dealloc(PyObject *v) -{ - if (PySwigPacked_Check(v)) { - PySwigPacked *sobj = (PySwigPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -_PySwigPacked_type(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject pyswigpacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigPacked", /* tp_name */ - sizeof(PySwigPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigPacked_dealloc, /* tp_dealloc */ - (printfunc)PySwigPacked_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigPacked_compare, /* tp_compare */ - (reprfunc)PySwigPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigpacked_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigpacked_type = tmp; - pyswigpacked_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigpacked_type; -} - -SWIGRUNTIME PyObject * -PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); - if (sobj) { - void *pack = malloc(size); - if (pack) { - memcpy(pack, ptr, size); - sobj->pack = pack; - sobj->ty = ty; - sobj->size = size; - } else { - PyObject_DEL((PyObject *) sobj); - sobj = 0; - } - } - return (PyObject *) sobj; -} - -SWIGRUNTIME swig_type_info * -PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (PySwigPacked_Check(obj)) { - PySwigPacked *sobj = (PySwigPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIMEINLINE PyObject * -_SWIG_This(void) -{ - return PyString_FromString("this"); -} - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); - return swig_this; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -SWIGRUNTIME PySwigObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - if (PySwigObject_Check(pyobj)) { - return (PySwigObject *) pyobj; - } else { - PyObject *obj = 0; -#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) - if (PyInstance_Check(pyobj)) { - obj = _PyInstance_Lookup(pyobj, SWIG_This()); - } else { - PyObject **dictptr = _PyObject_GetDictPtr(pyobj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; - } else { -#ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - } - } -#else - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } -#endif - if (obj && !PySwigObject_Check(obj)) { - /* a PyObject is called 'this', try to get the 'real this' - PySwigObject from it */ - return SWIG_Python_GetSwigThis(obj); - } - return (PySwigObject *)obj; - } -} - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own == SWIG_POINTER_OWN) { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - if (sobj) { - int oldown = sobj->own; - sobj->own = own; - return oldown; - } - } - return 0; -} - -/* Convert a pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { - if (!obj) return SWIG_ERROR; - if (obj == Py_None) { - if (ptr) *ptr = 0; - return SWIG_OK; - } else { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - if (own) - *own = 0; - while (sobj) { - void *vptr = sobj->ptr; - if (ty) { - swig_type_info *to = sobj->ty; - if (to == ty) { - /* no type cast needed */ - if (ptr) *ptr = vptr; - break; - } else { - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) { - sobj = (PySwigObject *)sobj->next; - } else { - if (ptr) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); - if (own) - *own = *own | SWIG_CAST_NEW_MEMORY; - } - } - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (own) - *own = *own | sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - return SWIG_OK; - } else { - int res = SWIG_ERROR; - if (flags & SWIG_POINTER_IMPLICIT_CONV) { - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - if (data && !data->implicitconv) { - PyObject *klass = data->klass; - if (klass) { - PyObject *impconv; - data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ - impconv = SWIG_Python_CallFunctor(klass, obj); - data->implicitconv = 0; - if (PyErr_Occurred()) { - PyErr_Clear(); - impconv = 0; - } - if (impconv) { - PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); - if (iobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - iobj->own = 0; - res = SWIG_AddCast(res); - res = SWIG_AddNewMask(res); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - } - return res; - } - } -} - -/* Convert a function ptr value */ - -SWIGRUNTIME int -SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { - if (!PyCFunction_Check(obj)) { - return SWIG_ConvertPtr(obj, ptr, ty, 0); - } else { - void *vptr = 0; - - /* here we get the method pointer for callbacks */ - const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; - if (desc) { - desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) return SWIG_ERROR; - } - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (tc) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - assert(!newmemory); /* newmemory handling not yet implemented */ - } else { - return SWIG_ERROR; - } - } else { - *ptr = vptr; - } - return SWIG_OK; - } -} - -/* Convert a packed value value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { - if (to != ty) { - /* check type cast? */ - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) return SWIG_ERROR; - } - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Create a new pointer object - * ----------------------------------------------------------------------------- */ - -/* - Create a new instance object, whitout calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) -{ -#if (PY_VERSION_HEX >= 0x02020000) - PyObject *inst = 0; - PyObject *newraw = data->newraw; - if (newraw) { - inst = PyObject_Call(newraw, data->newargs, NULL); - if (inst) { -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - PyDict_SetItem(dict, SWIG_This(), swig_this); - } - } -#else - PyObject *key = SWIG_This(); - PyObject_SetAttr(inst, key, swig_this); -#endif - } - } else { - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } - return inst; -#else -#if (PY_VERSION_HEX >= 0x02010000) - PyObject *inst; - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - return (PyObject *) inst; -#else - PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); - if (inst == NULL) { - return NULL; - } - inst->in_class = (PyClassObject *)data->newargs; - Py_INCREF(inst->in_class); - inst->in_dict = PyDict_New(); - if (inst->in_dict == NULL) { - Py_DECREF(inst); - return NULL; - } -#ifdef Py_TPFLAGS_HAVE_WEAKREFS - inst->in_weakreflist = NULL; -#endif -#ifdef Py_TPFLAGS_GC - PyObject_GC_Init(inst); -#endif - PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); - return (PyObject *) inst; -#endif -#endif -} - -SWIGRUNTIME void -SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) -{ - PyObject *dict; -#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - PyDict_SetItem(dict, SWIG_This(), swig_this); - return; - } -#endif - dict = PyObject_GetAttrString(inst, (char*)"__dict__"); - PyDict_SetItem(dict, SWIG_This(), swig_this); - Py_DECREF(dict); -} - - -SWIGINTERN PyObject * -SWIG_Python_InitShadowInstance(PyObject *args) { - PyObject *obj[2]; - if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { - return NULL; - } else { - PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); - if (sthis) { - PySwigObject_append((PyObject*) sthis, obj[1]); - } else { - SWIG_Python_SetSwigThis(obj[0], obj[1]); - } - return SWIG_Py_Void(); - } -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { - if (!ptr) { - return SWIG_Py_Void(); - } else { - int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - PyObject *robj = PySwigObject_New(ptr, type, own); - PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; - if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - if (inst) { - Py_DECREF(robj); - robj = inst; - } - } - return robj; - } -} - -/* Create a new packed object */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void) { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - } - return (swig_module_info *) type_pointer; -} - -#if PY_MAJOR_VERSION < 2 -/* PyModule_AddObject function was introduced in Python 2.0. The following function - is copied out of Python/modsupport.c in python version 2.3.4 */ -SWIGINTERN int -PyModule_AddObject(PyObject *m, char *name, PyObject *o) -{ - PyObject *dict; - if (!PyModule_Check(m)) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs module as first arg"); - return SWIG_ERROR; - } - if (!o) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs non-NULL value"); - return SWIG_ERROR; - } - - dict = PyModule_GetDict(m); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); - return SWIG_ERROR; - } - if (PyDict_SetItemString(dict, name, o)) - return SWIG_ERROR; - Py_DECREF(o); - return SWIG_OK; -} -#endif - -SWIGRUNTIME void -SWIG_Python_DestroyModule(void *vptr) -{ - swig_module_info *swig_module = (swig_module_info *) vptr; - swig_type_info **types = swig_module->types; - size_t i; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - PySwigClientData *data = (PySwigClientData *) ty->clientdata; - if (data) PySwigClientData_Del(data); - } - } - Py_DECREF(SWIG_This()); -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ - - PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - swig_empty_runtime_method_table); - PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -} - -/* The python cached type query */ -SWIGRUNTIME PyObject * -SWIG_Python_TypeCache(void) { - static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); - return cache; -} - -SWIGRUNTIME swig_type_info * -SWIG_Python_TypeQuery(const char *type) -{ - PyObject *cache = SWIG_Python_TypeCache(); - PyObject *key = PyString_FromString(type); - PyObject *obj = PyDict_GetItem(cache, key); - swig_type_info *descriptor; - if (obj) { - descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); - } else { - swig_module_info *swig_module = SWIG_Python_GetModule(); - descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); - if (descriptor) { - obj = PyCObject_FromVoidPtr(descriptor, NULL); - PyDict_SetItem(cache, key, obj); - Py_DECREF(obj); - } - } - Py_DECREF(key); - return descriptor; -} - -/* - For backward compatibility only -*/ -#define SWIG_POINTER_EXCEPTION 0 -#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - -SWIGRUNTIME int -SWIG_Python_AddErrMesg(const char* mesg, int infront) -{ - if (PyErr_Occurred()) { - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); - } else { - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - } - Py_DECREF(old_str); - } - return 1; - } else { - return 0; - } -} - -SWIGRUNTIME int -SWIG_Python_ArgFail(int argnum) -{ - if (PyErr_Occurred()) { - /* add information about failing argument */ - char mesg[256]; - PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - -SWIGRUNTIMEINLINE const char * -PySwigObject_GetDesc(PyObject *self) -{ - PySwigObject *v = (PySwigObject *)self; - swig_type_info *ty = v ? v->ty : 0; - return ty ? ty->str : (char*)""; -} - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (obj && PySwigObject_Check(obj)) { - const char *otype = (const char *) PySwigObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", - type, otype); - return; - } - } else -#endif - { - const char *otype = (obj ? obj->ob_type->tp_name : 0); - if (otype) { - PyObject *str = PyObject_Str(obj); - const char *cstr = str ? PyString_AsString(str) : 0; - if (cstr) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", - type, otype, cstr); - } else { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", - type, otype); - } - Py_XDECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); - if (flags & SWIG_POINTER_EXCEPTION) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - SWIG_Python_ArgFail(argnum); - } - } - return result; -} - - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - - -#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) - -#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_TDB_DATA swig_types[0] -#define SWIGTYPE_p_char swig_types[1] -#define SWIGTYPE_p_int swig_types[2] -#define SWIGTYPE_p_long_long swig_types[3] -#define SWIGTYPE_p_short swig_types[4] -#define SWIGTYPE_p_signed_char swig_types[5] -#define SWIGTYPE_p_tdb_context swig_types[6] -#define SWIGTYPE_p_unsigned_char swig_types[7] -#define SWIGTYPE_p_unsigned_int swig_types[8] -#define SWIGTYPE_p_unsigned_long_long swig_types[9] -#define SWIGTYPE_p_unsigned_short swig_types[10] -static swig_type_info *swig_types[12]; -static swig_module_info swig_module = {swig_types, 11, 0, 0, 0, 0}; -#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) -#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) - -/* -------- TYPES TABLE (END) -------- */ - -#if (PY_VERSION_HEX <= 0x02000000) -# if !defined(SWIG_PYTHON_CLASSIC) -# error "This python version requires swig to be run with the '-classic' option" -# endif -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodern' option" -#endif -#if (PY_VERSION_HEX <= 0x02020000) -# error "This python version requires swig to be run with the '-nomodernargs' option" -#endif -#ifndef METH_O -# error "This python version requires swig to be run with the '-nofastunpack' option" -#endif -#ifdef SWIG_TypeQuery -# undef SWIG_TypeQuery -#endif -#define SWIG_TypeQuery SWIG_Python_TypeQuery - -/*----------------------------------------------- - @(target):= _tdb.so - ------------------------------------------------*/ -#define SWIG_init init_tdb - -#define SWIG_name "_tdb" - -#define SWIGVERSION 0x010335 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - - -/* This symbol is used in both includes.h and Python.h which causes an - annoying compiler warning. */ - -#ifdef HAVE_FSTAT -#undef HAVE_FSTAT -#endif - -/* Include tdb headers */ -#include -#include -#include -#include - -typedef TDB_CONTEXT tdb; - - - #define SWIG_From_long PyInt_FromLong - - -SWIGINTERNINLINE PyObject * -SWIG_From_int (int value) -{ - return SWIG_From_long (value); -} - - -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} - - -SWIGINTERN int -SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -{ - if (PyString_Check(obj)) { - char *cstr; Py_ssize_t len; - PyString_AsStringAndSize(obj, &cstr, &len); - if (cptr) { - if (alloc) { - /* - In python the user should not be able to modify the inner - string representation. To warranty that, if you define - SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string - buffer is always returned. - - The default behavior is just to return the pointer value, - so, be careful. - */ -#if defined(SWIG_PYTHON_SAFE_CSTRINGS) - if (*alloc != SWIG_OLDOBJ) -#else - if (*alloc == SWIG_NEWOBJ) -#endif - { - *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); - *alloc = SWIG_NEWOBJ; - } - else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } else { - *cptr = PyString_AsString(obj); - } - } - if (psize) *psize = len + 1; - return SWIG_OK; - } else { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} - - - - - -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif - - -SWIGINTERN int -SWIG_AsVal_double (PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; - } else if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -#endif - return res; -} - - -#include - - -#include - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (int)(v); - } - } - return res; -} - -SWIGINTERN tdb *new_tdb(char const *name,int hash_size,int tdb_flags,int flags,mode_t mode){ - return tdb_open(name, hash_size, tdb_flags, flags, mode); - } -SWIGINTERN void delete_tdb(tdb *self){ tdb_close(self); } - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtrAndSize(const char* carray, size_t size) -{ - if (carray) { - if (size > INT_MAX) { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - return pchar_descriptor ? - SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); - } else { - return PyString_FromStringAndSize(carray, (int)(size)); - } - } else { - return SWIG_Py_Void(); - } -} - - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtr(const char *cptr) -{ - return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); -} - - -SWIGINTERNINLINE PyObject* -SWIG_From_unsigned_SS_long (unsigned long value) -{ - return (value > LONG_MAX) ? - PyLong_FromUnsignedLong(value) : PyInt_FromLong((long)(value)); -} - - -SWIGINTERNINLINE PyObject * -SWIG_From_size_t (size_t value) -{ - return SWIG_From_unsigned_SS_long ((unsigned long)(value)); -} - -#ifdef __cplusplus -extern "C" { -#endif -SWIGINTERN PyObject *_wrap_new_Tdb(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - int arg2 ; - int arg3 ; - int arg4 ; - mode_t arg5 ; - tdb *result = 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - int val2 ; - int ecode2 = 0 ; - int val3 ; - int ecode3 = 0 ; - int val4 ; - int ecode4 = 0 ; - int val5 ; - int ecode5 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - char * kwnames[] = { - (char *) "name",(char *) "hash_size",(char *) "tdb_flags",(char *) "flags",(char *) "mode", NULL - }; - - arg2 = 0; - arg3 = TDB_DEFAULT; - arg4 = O_RDWR; - arg5 = 0600; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOOO:new_Tdb",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "new_Tdb" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = (char *)(buf1); - if (obj1) { - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_Tdb" "', argument " "2"" of type '" "int""'"); - } - arg2 = (int)(val2); - } - if (obj2) { - ecode3 = SWIG_AsVal_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_Tdb" "', argument " "3"" of type '" "int""'"); - } - arg3 = (int)(val3); - } - if (obj3) { - ecode4 = SWIG_AsVal_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "new_Tdb" "', argument " "4"" of type '" "int""'"); - } - arg4 = (int)(val4); - } - if (obj4) { - ecode5 = SWIG_AsVal_int(obj4, &val5); - if (!SWIG_IsOK(ecode5)) { - SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "new_Tdb" "', argument " "5"" of type '" "mode_t""'"); - } - arg5 = (mode_t)(val5); - } - result = (tdb *)new_tdb((char const *)arg1,arg2,arg3,arg4,arg5); - /* Throw an IOError exception from errno if tdb_open() returns NULL */ - if (result == NULL) { - PyErr_SetFromErrno(PyExc_IOError); - SWIG_fail; - } - resultobj = SWIG_NewPointerObj(result, SWIGTYPE_p_tdb_context, 0); - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_error(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - enum TDB_ERROR result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_error" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (enum TDB_ERROR)tdb_error(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_Tdb(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Tdb" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - delete_tdb(arg1); - - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_close(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_close" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_close(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_append(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - TDB_DATA arg2 ; - TDB_DATA arg3 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "key",(char *) "new_dbuf", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:Tdb_append",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_append" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - if (obj1 == Py_None) { - (&arg2)->dsize = 0; - (&arg2)->dptr = NULL; - } else if (!PyString_Check(obj1)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - } - if (obj2 == Py_None) { - (&arg3)->dsize = 0; - (&arg3)->dptr = NULL; - } else if (!PyString_Check(obj2)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg3)->dsize = PyString_Size(obj2); - (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); - } - result = (int)tdb_append(arg1,arg2,arg3); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_errorstr(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_errorstr" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (char *)tdb_errorstr(arg1); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - TDB_DATA arg2 ; - TDB_DATA result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "key", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_get",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_get" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - if (obj1 == Py_None) { - (&arg2)->dsize = 0; - (&arg2)->dptr = NULL; - } else if (!PyString_Check(obj1)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - } - result = tdb_fetch(arg1,arg2); - if ((&result)->dptr == NULL && (&result)->dsize == 0) { - resultobj = Py_None; - } else { - resultobj = PyString_FromStringAndSize((const char *)(&result)->dptr, (&result)->dsize); - free((&result)->dptr); - } - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_delete(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - TDB_DATA arg2 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "key", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_delete",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_delete" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - if (obj1 == Py_None) { - (&arg2)->dsize = 0; - (&arg2)->dptr = NULL; - } else if (!PyString_Check(obj1)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - } - result = (int)tdb_delete(arg1,arg2); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_store(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - TDB_DATA arg2 ; - TDB_DATA arg3 ; - int arg4 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - int val4 ; - int ecode4 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "key",(char *) "dbuf",(char *) "flag", NULL - }; - - arg4 = TDB_REPLACE; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:Tdb_store",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_store" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - if (obj1 == Py_None) { - (&arg2)->dsize = 0; - (&arg2)->dptr = NULL; - } else if (!PyString_Check(obj1)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - } - if (obj2 == Py_None) { - (&arg3)->dsize = 0; - (&arg3)->dptr = NULL; - } else if (!PyString_Check(obj2)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg3)->dsize = PyString_Size(obj2); - (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); - } - if (obj3) { - ecode4 = SWIG_AsVal_int(obj3, &val4); - if (!SWIG_IsOK(ecode4)) { - SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Tdb_store" "', argument " "4"" of type '" "int""'"); - } - arg4 = (int)(val4); - } - result = (int)tdb_store(arg1,arg2,arg3,arg4); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_exists(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - TDB_DATA arg2 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "key", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_exists",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_exists" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - if (obj1 == Py_None) { - (&arg2)->dsize = 0; - (&arg2)->dptr = NULL; - } else if (!PyString_Check(obj1)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - } - result = (int)tdb_exists(arg1,arg2); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_firstkey(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - TDB_DATA result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_firstkey" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = tdb_firstkey(arg1); - if ((&result)->dptr == NULL && (&result)->dsize == 0) { - resultobj = Py_None; - } else { - resultobj = PyString_FromStringAndSize((const char *)(&result)->dptr, (&result)->dsize); - free((&result)->dptr); - } - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_nextkey(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - TDB_DATA arg2 ; - TDB_DATA result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "key", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_nextkey",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_nextkey" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - if (obj1 == Py_None) { - (&arg2)->dsize = 0; - (&arg2)->dptr = NULL; - } else if (!PyString_Check(obj1)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } else { - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - } - result = tdb_nextkey(arg1,arg2); - if ((&result)->dptr == NULL && (&result)->dsize == 0) { - resultobj = Py_None; - } else { - resultobj = PyString_FromStringAndSize((const char *)(&result)->dptr, (&result)->dsize); - free((&result)->dptr); - } - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_lock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_lock_all" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_lockall(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_unlock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_unlock_all" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_unlockall(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_read_lock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_read_lock_all" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_lockall_read(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_read_unlock_all(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_read_unlock_all" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_unlockall_read(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_reopen(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_reopen" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_reopen(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_transaction_start(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_start" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_transaction_start(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_transaction_commit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_commit" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_transaction_commit(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_transaction_cancel(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_cancel" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_transaction_cancel(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_transaction_recover(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_transaction_recover" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_transaction_recover(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_hash_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_hash_size" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_hash_size(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_map_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - size_t result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_map_size" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = tdb_map_size(arg1); - resultobj = SWIG_From_size_t((size_t)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_get_flags(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int result; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_get_flags" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (int)tdb_get_flags(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_set_max_dead(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - int arg2 ; - void *argp1 = 0 ; - int res1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "max_dead", NULL - }; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Tdb_set_max_dead",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_set_max_dead" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Tdb_set_max_dead" "', argument " "2"" of type '" "int""'"); - } - arg2 = (int)(val2); - tdb_set_max_dead(arg1,arg2); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Tdb_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - tdb *arg1 = (tdb *) 0 ; - char *result = 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - PyObject *swig_obj[1] ; - - if (!args) SWIG_fail; - swig_obj[0] = args; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_tdb_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Tdb_name" "', argument " "1"" of type '" "tdb *""'"); - } - arg1 = (tdb *)(argp1); - result = (char *)tdb_name(arg1); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *Tdb_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_tdb_context, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *Tdb_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - -static PyMethodDef SwigMethods[] = { - { (char *)"new_Tdb", (PyCFunction) _wrap_new_Tdb, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600)\n" - "Open a TDB file.\n" - ""}, - { (char *)"Tdb_error", (PyCFunction)_wrap_Tdb_error, METH_O, (char *)"\n" - "S.error() -> int\n" - "Find last error number returned by operation on this TDB.\n" - ""}, - { (char *)"delete_Tdb", (PyCFunction)_wrap_delete_Tdb, METH_O, NULL}, - { (char *)"Tdb_close", (PyCFunction)_wrap_Tdb_close, METH_O, (char *)"\n" - "S.close() -> None\n" - "Close the TDB file.\n" - ""}, - { (char *)"Tdb_append", (PyCFunction) _wrap_Tdb_append, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"Tdb_errorstr", (PyCFunction)_wrap_Tdb_errorstr, METH_O, (char *)"\n" - "S.errorstr() -> errorstring\n" - "Obtain last error message.\n" - ""}, - { (char *)"Tdb_get", (PyCFunction) _wrap_Tdb_get, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.fetch(key) -> value\n" - "Fetch a value.\n" - ""}, - { (char *)"Tdb_delete", (PyCFunction) _wrap_Tdb_delete, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.delete(key) -> None\n" - "Delete an entry.\n" - ""}, - { (char *)"Tdb_store", (PyCFunction) _wrap_Tdb_store, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.store(key, value, flag=TDB_REPLACE) -> None\n" - "Store an entry.\n" - ""}, - { (char *)"Tdb_exists", (PyCFunction) _wrap_Tdb_exists, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.exists(key) -> bool\n" - "Check whether key exists in this database.\n" - ""}, - { (char *)"Tdb_firstkey", (PyCFunction)_wrap_Tdb_firstkey, METH_O, (char *)"\n" - "S.firstkey() -> data\n" - "Return the first key in this database.\n" - ""}, - { (char *)"Tdb_nextkey", (PyCFunction) _wrap_Tdb_nextkey, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.nextkey(prev) -> data\n" - "Return the next key in this database.\n" - ""}, - { (char *)"Tdb_lock_all", (PyCFunction)_wrap_Tdb_lock_all, METH_O, (char *)"S.lockall() -> bool"}, - { (char *)"Tdb_unlock_all", (PyCFunction)_wrap_Tdb_unlock_all, METH_O, (char *)"S.unlockall() -> bool"}, - { (char *)"Tdb_read_lock_all", (PyCFunction)_wrap_Tdb_read_lock_all, METH_O, NULL}, - { (char *)"Tdb_read_unlock_all", (PyCFunction)_wrap_Tdb_read_unlock_all, METH_O, NULL}, - { (char *)"Tdb_reopen", (PyCFunction)_wrap_Tdb_reopen, METH_O, (char *)"\n" - "S.reopen() -> bool\n" - "Reopen this file.\n" - ""}, - { (char *)"Tdb_transaction_start", (PyCFunction)_wrap_Tdb_transaction_start, METH_O, (char *)"\n" - "S.transaction_start() -> None\n" - "Start a new transaction.\n" - ""}, - { (char *)"Tdb_transaction_commit", (PyCFunction)_wrap_Tdb_transaction_commit, METH_O, (char *)"\n" - "S.transaction_commit() -> None\n" - "Commit the currently active transaction.\n" - ""}, - { (char *)"Tdb_transaction_cancel", (PyCFunction)_wrap_Tdb_transaction_cancel, METH_O, (char *)"\n" - "S.transaction_cancel() -> None\n" - "Cancel the currently active transaction.\n" - ""}, - { (char *)"Tdb_transaction_recover", (PyCFunction)_wrap_Tdb_transaction_recover, METH_O, NULL}, - { (char *)"Tdb_hash_size", (PyCFunction)_wrap_Tdb_hash_size, METH_O, (char *)"S.hash_size() -> int"}, - { (char *)"Tdb_map_size", (PyCFunction)_wrap_Tdb_map_size, METH_O, (char *)"S.map_size() -> int"}, - { (char *)"Tdb_get_flags", (PyCFunction)_wrap_Tdb_get_flags, METH_O, (char *)"S.get_flags() -> int"}, - { (char *)"Tdb_set_max_dead", (PyCFunction) _wrap_Tdb_set_max_dead, METH_VARARGS | METH_KEYWORDS, (char *)"S.set_max_dead(int) -> None"}, - { (char *)"Tdb_name", (PyCFunction)_wrap_Tdb_name, METH_O, (char *)"\n" - "S.name() -> path\n" - "Return filename of this TDB file.\n" - ""}, - { (char *)"Tdb_swigregister", Tdb_swigregister, METH_VARARGS, NULL}, - { (char *)"Tdb_swiginit", Tdb_swiginit, METH_VARARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_TDB_DATA = {"_p_TDB_DATA", "TDB_DATA *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *|mode_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_tdb_context = {"_p_tdb_context", "struct tdb_context *|tdb *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_TDB_DATA, - &_swigt__p_char, - &_swigt__p_int, - &_swigt__p_long_long, - &_swigt__p_short, - &_swigt__p_signed_char, - &_swigt__p_tdb_context, - &_swigt__p_unsigned_char, - &_swigt__p_unsigned_int, - &_swigt__p_unsigned_long_long, - &_swigt__p_unsigned_short, -}; - -static swig_cast_info _swigc__p_TDB_DATA[] = { {&_swigt__p_TDB_DATA, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_tdb_context[] = { {&_swigt__p_tdb_context, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_TDB_DATA, - _swigc__p_char, - _swigc__p_int, - _swigc__p_long_long, - _swigc__p_short, - _swigc__p_signed_char, - _swigc__p_tdb_context, - _swigc__p_unsigned_char, - _swigc__p_unsigned_int, - _swigc__p_unsigned_long_long, - _swigc__p_unsigned_short, -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { -{0, 0, 0, 0.0, 0, 0}}; - -#ifdef __cplusplus -} -#endif -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned staticly to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - - -SWIGRUNTIME void -SWIG_InitializeModule(void *clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int found, init; - - clientdata = clientdata; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - init = 1; - } else { - init = 0; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - module_head = &swig_module; - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - found=0; - iter=module_head; - do { - if (iter==&swig_module) { - found=1; - break; - } - iter=iter->next; - } while (iter!= module_head); - - /* if the is found in the list, then all is done and we may leave */ - if (found) return; - /* otherwise we must add out module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* When multiple interpeters are used, a module could have already been initialized in - a different interpreter, but not yet have a pointer in this interpreter. - In this case, we do not want to continue adding types... everything should be - set up already */ - if (init == 0) return; - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %d\n", swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ - /* c-mode */ -#endif -} -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - /* Python-specific SWIG API */ -#define SWIG_newvarlink() SWIG_Python_newvarlink() -#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) -#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) - - /* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - - typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; - } swig_globalvar; - - typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; - } swig_varlinkobject; - - SWIGINTERN PyObject * - swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { - return PyString_FromString(""); - } - - SWIGINTERN PyObject * - swig_varlink_str(swig_varlinkobject *v) { - PyObject *str = PyString_FromString("("); - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - PyString_ConcatAndDel(&str,PyString_FromString(var->name)); - if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); - } - PyString_ConcatAndDel(&str,PyString_FromString(")")); - return str; - } - - SWIGINTERN int - swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { - PyObject *str = swig_varlink_str(v); - fprintf(fp,"Swig global variables "); - fprintf(fp,"%s\n", PyString_AsString(str)); - Py_DECREF(str); - return 0; - } - - SWIGINTERN void - swig_varlink_dealloc(swig_varlinkobject *v) { - swig_globalvar *var = v->vars; - while (var) { - swig_globalvar *n = var->next; - free(var->name); - free(var); - var = n; - } - } - - SWIGINTERN PyObject * - swig_varlink_getattr(swig_varlinkobject *v, char *n) { - PyObject *res = NULL; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->get_attr)(); - break; - } - var = var->next; - } - if (res == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN int - swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - int res = 1; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->set_attr)(p); - break; - } - var = var->next; - } - if (res == 1 && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN PyTypeObject* - swig_varlink_type(void) { - static char varlink__doc__[] = "Swig var link object"; - static PyTypeObject varlink_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* Number of items in variable part (ob_size) */ - (char *)"swigvarlink", /* Type name (tp_name) */ - sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ - 0, /* Itemsize (tp_itemsize) */ - (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ - (printfunc) swig_varlink_print, /* Print (tp_print) */ - (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ - (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)swig_varlink_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - varlink__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - varlink_type = tmp; - varlink_type.ob_type = &PyType_Type; - type_init = 1; - } - return &varlink_type; - } - - /* Create a variable linking object for use later */ - SWIGINTERN PyObject * - SWIG_Python_newvarlink(void) { - swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); - if (result) { - result->vars = 0; - } - return ((PyObject*) result); - } - - SWIGINTERN void - SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v = (swig_varlinkobject *) p; - swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - if (gv) { - size_t size = strlen(name)+1; - gv->name = (char *)malloc(size); - if (gv->name) { - strncpy(gv->name,name,size); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - } - } - v->vars = gv; - } - - SWIGINTERN PyObject * - SWIG_globals(void) { - static PyObject *_SWIG_globals = 0; - if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); - return _SWIG_globals; - } - - /* ----------------------------------------------------------------------------- - * constants/methods manipulation - * ----------------------------------------------------------------------------- */ - - /* Install Constants */ - SWIGINTERN void - SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { - PyObject *obj = 0; - size_t i; - for (i = 0; constants[i].type; ++i) { - switch(constants[i].type) { - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); - break; - case SWIG_PY_BINARY: - obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d, constants[i].name, obj); - Py_DECREF(obj); - } - } - } - - /* -----------------------------------------------------------------------------*/ - /* Fix SwigMethods to carry the callback ptrs when needed */ - /* -----------------------------------------------------------------------------*/ - - SWIGINTERN void - SWIG_Python_FixMethods(PyMethodDef *methods, - swig_const_info *const_table, - swig_type_info **types, - swig_type_info **types_initial) { - size_t i; - for (i = 0; methods[i].ml_name; ++i) { - const char *c = methods[i].ml_doc; - if (c && (c = strstr(c, "swig_ptr: "))) { - int j; - swig_const_info *ci = 0; - const char *name = c + 10; - for (j = 0; const_table[j].type; ++j) { - if (strncmp(const_table[j].name, name, - strlen(const_table[j].name)) == 0) { - ci = &(const_table[j]); - break; - } - } - if (ci) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { - strncpy(buff, methods[i].ml_doc, ldoc); - buff += ldoc; - strncpy(buff, "swig_ptr: ", 10); - buff += 10; - SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); - methods[i].ml_doc = ndoc; - } - } - } - } - } - } - -#ifdef __cplusplus -} -#endif - -/* -----------------------------------------------------------------------------* - * Partial Init method - * -----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" -#endif -SWIGEXPORT void SWIG_init(void) { - PyObject *m, *d; - - /* Fix SwigMethods to carry the callback ptrs when needed */ - SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); - - m = Py_InitModule((char *) SWIG_name, SwigMethods); - d = PyModule_GetDict(m); - - SWIG_InitializeModule(0); - SWIG_InstallConstants(d,swig_const_table); - - - SWIG_Python_SetConstant(d, "REPLACE",SWIG_From_int((int)(TDB_REPLACE))); - SWIG_Python_SetConstant(d, "INSERT",SWIG_From_int((int)(TDB_INSERT))); - SWIG_Python_SetConstant(d, "MODIFY",SWIG_From_int((int)(TDB_MODIFY))); - SWIG_Python_SetConstant(d, "DEFAULT",SWIG_From_int((int)(TDB_DEFAULT))); - SWIG_Python_SetConstant(d, "CLEAR_IF_FIRST",SWIG_From_int((int)(TDB_CLEAR_IF_FIRST))); - SWIG_Python_SetConstant(d, "INTERNAL",SWIG_From_int((int)(TDB_INTERNAL))); - SWIG_Python_SetConstant(d, "NOLOCK",SWIG_From_int((int)(TDB_NOLOCK))); - SWIG_Python_SetConstant(d, "NOMMAP",SWIG_From_int((int)(TDB_NOMMAP))); - SWIG_Python_SetConstant(d, "CONVERT",SWIG_From_int((int)(TDB_CONVERT))); - SWIG_Python_SetConstant(d, "BIGENDIAN",SWIG_From_int((int)(TDB_BIGENDIAN))); - SWIG_Python_SetConstant(d, "TDB_SUCCESS",SWIG_From_int((int)(TDB_SUCCESS))); - SWIG_Python_SetConstant(d, "TDB_ERR_CORRUPT",SWIG_From_int((int)(TDB_ERR_CORRUPT))); - SWIG_Python_SetConstant(d, "TDB_ERR_IO",SWIG_From_int((int)(TDB_ERR_IO))); - SWIG_Python_SetConstant(d, "TDB_ERR_LOCK",SWIG_From_int((int)(TDB_ERR_LOCK))); - SWIG_Python_SetConstant(d, "TDB_ERR_OOM",SWIG_From_int((int)(TDB_ERR_OOM))); - SWIG_Python_SetConstant(d, "TDB_ERR_EXISTS",SWIG_From_int((int)(TDB_ERR_EXISTS))); - SWIG_Python_SetConstant(d, "TDB_ERR_NOLOCK",SWIG_From_int((int)(TDB_ERR_NOLOCK))); - SWIG_Python_SetConstant(d, "TDB_ERR_LOCK_TIMEOUT",SWIG_From_int((int)(TDB_ERR_LOCK_TIMEOUT))); - SWIG_Python_SetConstant(d, "TDB_ERR_NOEXIST",SWIG_From_int((int)(TDB_ERR_NOEXIST))); - SWIG_Python_SetConstant(d, "TDB_ERR_EINVAL",SWIG_From_int((int)(TDB_ERR_EINVAL))); - SWIG_Python_SetConstant(d, "TDB_ERR_RDONLY",SWIG_From_int((int)(TDB_ERR_RDONLY))); -} - diff --git a/tdb/tools/tdbbackup.c b/tdb/tools/tdbbackup.c deleted file mode 100644 index 6f3ca48314..0000000000 --- a/tdb/tools/tdbbackup.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - - This program is meant for backup/restore of tdb databases. Typical usage would be: - tdbbackup *.tdb - when Samba shuts down cleanly, which will make a backup of all the local databases - to *.bak files. Then on Samba startup you would use: - tdbbackup -v *.tdb - and this will check the databases for corruption and if corruption is detected then - the backup will be restored. - - You may also like to do a backup on a regular basis while Samba is - running, perhaps using cron. - - The reason this program is needed is to cope with power failures - while Samba is running. A power failure could lead to database - corruption and Samba will then not start correctly. - - Note that many of the databases in Samba are transient and thus - don't need to be backed up, so you can optimise the above a little - by only running the backup on the critical databases. - - */ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -#ifdef HAVE_GETOPT_H -#include -#endif - -static int failed; - -static char *add_suffix(const char *name, const char *suffix) -{ - char *ret; - int len = strlen(name) + strlen(suffix) + 1; - ret = (char *)malloc(len); - if (!ret) { - fprintf(stderr,"Out of memory!\n"); - exit(1); - } - snprintf(ret, len, "%s%s", name, suffix); - return ret; -} - -static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; - - if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { - fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new)); - failed = 1; - return 1; - } - return 0; -} - - -static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - return 0; -} - -/* - carefully backup a tdb, validating the contents and - only doing the backup if its OK - this function is also used for restore -*/ -static int backup_tdb(const char *old_name, const char *new_name, int hash_size) -{ - TDB_CONTEXT *tdb; - TDB_CONTEXT *tdb_new; - char *tmp_name; - struct stat st; - int count1, count2; - - tmp_name = add_suffix(new_name, ".tmp"); - - /* stat the old tdb to find its permissions */ - if (stat(old_name, &st) != 0) { - perror(old_name); - free(tmp_name); - return 1; - } - - /* open the old tdb */ - tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); - if (!tdb) { - printf("Failed to open %s\n", old_name); - free(tmp_name); - return 1; - } - - /* create the new tdb */ - unlink(tmp_name); - tdb_new = tdb_open(tmp_name, - hash_size ? hash_size : tdb_hash_size(tdb), - TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, - st.st_mode & 0777); - if (!tdb_new) { - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* lock the old tdb */ - if (tdb_lockall(tdb) != 0) { - fprintf(stderr,"Failed to lock %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - failed = 0; - - /* traverse and copy */ - count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); - if (count1 < 0 || failed) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* close the old tdb */ - tdb_close(tdb); - - /* close the new tdb and re-open read-only */ - tdb_close(tdb_new); - tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); - if (!tdb_new) { - fprintf(stderr,"failed to reopen %s\n", tmp_name); - unlink(tmp_name); - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* traverse the new tdb to confirm */ - count2 = tdb_traverse(tdb_new, test_fn, NULL); - if (count2 != count1) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* make sure the new tdb has reached stable storage */ - fsync(tdb_fd(tdb_new)); - - /* close the new tdb and rename it to .bak */ - tdb_close(tdb_new); - if (rename(tmp_name, new_name) != 0) { - perror(new_name); - free(tmp_name); - return 1; - } - - free(tmp_name); - - return 0; -} - -/* - verify a tdb and if it is corrupt then restore from *.bak -*/ -static int verify_tdb(const char *fname, const char *bak_name) -{ - TDB_CONTEXT *tdb; - int count = -1; - - /* open the tdb */ - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - - /* traverse the tdb, then close it */ - if (tdb) { - count = tdb_traverse(tdb, test_fn, NULL); - tdb_close(tdb); - } - - /* count is < 0 means an error */ - if (count < 0) { - printf("restoring %s\n", fname); - return backup_tdb(bak_name, fname, 0); - } - - printf("%s : %d records\n", fname, count); - - return 0; -} - -/* - see if one file is newer than another -*/ -static int file_newer(const char *fname1, const char *fname2) -{ - struct stat st1, st2; - if (stat(fname1, &st1) != 0) { - return 0; - } - if (stat(fname2, &st2) != 0) { - return 1; - } - return (st1.st_mtime > st2.st_mtime); -} - -static void usage(void) -{ - printf("Usage: tdbbackup [options] \n\n"); - printf(" -h this help message\n"); - printf(" -s suffix set the backup suffix\n"); - printf(" -v verify mode (restore if corrupt)\n"); - printf(" -n hashsize set the new hash size for the backup\n"); -} - - - int main(int argc, char *argv[]) -{ - int i; - int ret = 0; - int c; - int verify = 0; - int hashsize = 0; - const char *suffix = ".bak"; - - while ((c = getopt(argc, argv, "vhs:n:")) != -1) { - switch (c) { - case 'h': - usage(); - exit(0); - case 'v': - verify = 1; - break; - case 's': - suffix = optarg; - break; - case 'n': - hashsize = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc < 1) { - usage(); - exit(1); - } - - for (i=0; i. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -static void print_data(TDB_DATA d) -{ - unsigned char *p = (unsigned char *)d.dptr; - int len = d.dsize; - while (len--) { - if (isprint(*p) && !strchr("\"\\", *p)) { - fputc(*p, stdout); - } else { - printf("\\%02X", *p); - } - p++; - } -} - -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("{\n"); - printf("key(%d) = \"", (int)key.dsize); - print_data(key); - printf("\"\n"); - printf("data(%d) = \"", (int)dbuf.dsize); - print_data(dbuf); - printf("\"\n"); - printf("}\n"); - return 0; -} - -static int dump_tdb(const char *fname, const char *keyname) -{ - TDB_CONTEXT *tdb; - TDB_DATA key, value; - - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - if (!tdb) { - printf("Failed to open %s\n", fname); - return 1; - } - - if (!keyname) { - tdb_traverse(tdb, traverse_fn, NULL); - } else { - key.dptr = discard_const_p(uint8_t,keyname); - key.dsize = strlen( keyname); - value = tdb_fetch(tdb, key); - if (!value.dptr) { - return 1; - } else { - print_data(value); - free(value.dptr); - } - } - - return 0; -} - -static void usage( void) -{ - printf( "Usage: tdbdump [options] \n\n"); - printf( " -h this help message\n"); - printf( " -k keyname dumps value of keyname\n"); -} - - int main(int argc, char *argv[]) -{ - char *fname, *keyname=NULL; - int c; - - if (argc < 2) { - printf("Usage: tdbdump \n"); - exit(1); - } - - while ((c = getopt( argc, argv, "hk:")) != -1) { - switch (c) { - case 'h': - usage(); - exit( 0); - case 'k': - keyname = optarg; - break; - default: - usage(); - exit( 1); - } - } - - fname = argv[optind]; - - return dump_tdb(fname, keyname); -} diff --git a/tdb/tools/tdbtest.c b/tdb/tools/tdbtest.c deleted file mode 100644 index 416bc50a5b..0000000000 --- a/tdb/tools/tdbtest.c +++ /dev/null @@ -1,265 +0,0 @@ -/* a test program for tdb - the trivial database */ - -#include "replace.h" -#include "tdb.h" -#include "system/filesys.h" -#include "system/time.h" - -#include - - -#define DELETE_PROB 7 -#define STORE_PROB 5 - -static struct tdb_context *db; -static GDBM_FILE gdbm; - -struct timeval tp1,tp2; - -static void _start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double _end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -static void fatal(const char *why) -{ - perror(why); - exit(1); -} - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -} - -static void compare_db(void) -{ - TDB_DATA d, key, nextkey; - datum gd, gkey, gnextkey; - - key = tdb_firstkey(db); - while (key.dptr) { - d = tdb_fetch(db, key); - gkey.dptr = key.dptr; - gkey.dsize = key.dsize; - - gd = gdbm_fetch(gdbm, gkey); - - if (!gd.dptr) fatal("key not in gdbm"); - if (gd.dsize != d.dsize) fatal("data sizes differ"); - if (memcmp(gd.dptr, d.dptr, d.dsize)) { - fatal("data differs"); - } - - nextkey = tdb_nextkey(db, key); - free(key.dptr); - free(d.dptr); - free(gd.dptr); - key = nextkey; - } - - gkey = gdbm_firstkey(gdbm); - while (gkey.dptr) { - gd = gdbm_fetch(gdbm, gkey); - key.dptr = gkey.dptr; - key.dsize = gkey.dsize; - - d = tdb_fetch(db, key); - - if (!d.dptr) fatal("key not in db"); - if (d.dsize != gd.dsize) fatal("data sizes differ"); - if (memcmp(d.dptr, gd.dptr, gd.dsize)) { - fatal("data differs"); - } - - gnextkey = gdbm_nextkey(gdbm, gkey); - free(gkey.dptr); - free(gd.dptr); - free(d.dptr); - gkey = gnextkey; - } -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -static int do_command(void); -const char *cmdname; -char *arg1, *arg2; -size_t arg1len, arg2len; -int bIterate = 0; -char *line; -TDB_DATA iterate_kbuf; -char cmdline[1024]; -static int disable_mmap; - -enum commands { - CMD_CREATE_TDB, - CMD_OPEN_TDB, - CMD_ERASE, - CMD_DUMP, - CMD_INSERT, - CMD_MOVE, - CMD_STORE, - CMD_SHOW, - CMD_KEYS, - CMD_HEXKEYS, - CMD_DELETE, - CMD_LIST_HASH_FREE, - CMD_LIST_FREE, - CMD_INFO, - CMD_MMAP, - CMD_SPEED, - CMD_FIRST, - CMD_NEXT, - CMD_SYSTEM, - CMD_QUIT, - CMD_HELP -}; - -typedef struct { - const char *name; - enum commands cmd; -} COMMAND_TABLE; - -COMMAND_TABLE cmd_table[] = { - {"create", CMD_CREATE_TDB}, - {"open", CMD_OPEN_TDB}, - {"erase", CMD_ERASE}, - {"dump", CMD_DUMP}, - {"insert", CMD_INSERT}, - {"move", CMD_MOVE}, - {"store", CMD_STORE}, - {"show", CMD_SHOW}, - {"keys", CMD_KEYS}, - {"hexkeys", CMD_HEXKEYS}, - {"delete", CMD_DELETE}, - {"list", CMD_LIST_HASH_FREE}, - {"free", CMD_LIST_FREE}, - {"info", CMD_INFO}, - {"speed", CMD_SPEED}, - {"mmap", CMD_MMAP}, - {"first", CMD_FIRST}, - {"1", CMD_FIRST}, - {"next", CMD_NEXT}, - {"n", CMD_NEXT}, - {"quit", CMD_QUIT}, - {"q", CMD_QUIT}, - {"!", CMD_SYSTEM}, - {NULL, CMD_HELP} -}; - -struct timeval tp1,tp2; - -static void _start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double _end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -/* a tdb tool for manipulating a tdb database */ - -static TDB_CONTEXT *tdb; - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); - -static void print_asc(const char *buf,int len) -{ - int i; - - /* We're probably printing ASCII strings so don't try to display - the trailing NULL character. */ - - if (buf[len - 1] == 0) - len--; - - for (i=0;i8) printf(" "); - while (n--) printf(" "); - - n = i%16; - if (n > 8) n = 8; - print_asc(&buf[i-(i%16)],n); printf(" "); - n = (i%16) - n; - if (n>0) print_asc(&buf[i-n],n); - printf("\n"); - } -} - -static void help(void) -{ - printf("\n" -"tdbtool: \n" -" create dbname : create a database\n" -" open dbname : open an existing database\n" -" erase : erase the database\n" -" dump : dump the database as strings\n" -" keys : dump the database keys as strings\n" -" hexkeys : dump the database keys as hex values\n" -" info : print summary info about the database\n" -" insert key data : insert a record\n" -" move key file : move a record to a destination tdb\n" -" store key data : store a record (replace)\n" -" show key : show a record by key\n" -" delete key : delete a record by key\n" -" list : print the database hash table and freelist\n" -" free : print the database freelist\n" -" ! command : execute system command\n" -" 1 | first : print the first record\n" -" n | next : print the next record\n" -" q | quit : terminate\n" -" \\n : repeat 'next' command\n" -"\n"); -} - -static void terror(const char *why) -{ - printf("%s\n", why); -} - -static void create_tdb(const char *tdbname) -{ - if (tdb) tdb_close(tdb); - tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST | (disable_mmap?TDB_NOMMAP:0), - O_RDWR | O_CREAT | O_TRUNC, 0600); - if (!tdb) { - printf("Could not create %s: %s\n", tdbname, strerror(errno)); - } -} - -static void open_tdb(const char *tdbname) -{ - if (tdb) tdb_close(tdb); - tdb = tdb_open(tdbname, 0, disable_mmap?TDB_NOMMAP:0, O_RDWR, 0600); - if (!tdb) { - printf("Could not open %s: %s\n", tdbname, strerror(errno)); - } -} - -static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { - terror("insert failed"); - } -} - -static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - if ((data == NULL) || (datalen == 0)) { - terror("need data"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - printf("Storing key:\n"); - print_rec(tdb, key, dbuf, NULL); - - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { - terror("store failed"); - } -} - -static void show_tdb(char *keyname, size_t keylen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - terror("fetch failed"); - return; - } - - print_rec(tdb, key, dbuf, NULL); - - free( dbuf.dptr ); - - return; -} - -static void delete_tdb(char *keyname, size_t keylen) -{ - TDB_DATA key; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - if (tdb_delete(tdb, key) != 0) { - terror("delete failed"); - } -} - -static void move_rec(char *keyname, size_t keylen, char* tdbname) -{ - TDB_DATA key, dbuf; - TDB_CONTEXT *dst_tdb; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - if ( !tdbname ) { - terror("need destination tdb name"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - terror("fetch failed"); - return; - } - - print_rec(tdb, key, dbuf, NULL); - - dst_tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600); - if ( !dst_tdb ) { - terror("unable to open destination tdb"); - return; - } - - if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { - terror("failed to move record"); - } - else - printf("record moved\n"); - - tdb_close( dst_tdb ); - - return; -} - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("\nkey %d bytes\n", (int)key.dsize); - print_asc((const char *)key.dptr, key.dsize); - printf("\ndata %d bytes\n", (int)dbuf.dsize); - print_data((const char *)dbuf.dptr, dbuf.dsize); - return 0; -} - -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("key %d bytes: ", (int)key.dsize); - print_asc((const char *)key.dptr, key.dsize); - printf("\n"); - return 0; -} - -static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("key %d bytes\n", (int)key.dsize); - print_data((const char *)key.dptr, key.dsize); - printf("\n"); - return 0; -} - -static int total_bytes; - -static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - total_bytes += dbuf.dsize; - return 0; -} - -static void info_tdb(void) -{ - int count; - total_bytes = 0; - if ((count = tdb_traverse(tdb, traverse_fn, NULL)) == -1) - printf("Error = %s\n", tdb_errorstr(tdb)); - else - printf("%d records totalling %d bytes\n", count, total_bytes); -} - -static void speed_tdb(const char *tlimit) -{ - unsigned timelimit = tlimit?atoi(tlimit):0; - double t; - int ops=0; - if (timelimit == 0) timelimit = 10; - printf("Testing traverse speed for %u seconds\n", timelimit); - _start_timer(); - while ((t=_end_timer()) < timelimit) { - tdb_traverse(tdb, traverse_fn, NULL); - printf("%10.3f ops/sec\r", (++ops)/t); - } - printf("\n"); -} - -static void toggle_mmap(void) -{ - disable_mmap = !disable_mmap; - if (disable_mmap) { - printf("mmap is disabled\n"); - } else { - printf("mmap is enabled\n"); - } -} - -static char *tdb_getline(const char *prompt) -{ - static char thisline[1024]; - char *p; - fputs(prompt, stdout); - thisline[0] = 0; - p = fgets(thisline, sizeof(thisline)-1, stdin); - if (p) p = strchr(p, '\n'); - if (p) *p = 0; - return p?thisline:NULL; -} - -static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - return tdb_delete(the_tdb, key); -} - -static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_firstkey(the_tdb); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) terror("fetch failed"); - else { - print_rec(the_tdb, *pkey, dbuf, NULL); - } -} - -static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_nextkey(the_tdb, *pkey); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) - terror("fetch failed"); - else - print_rec(the_tdb, *pkey, dbuf, NULL); -} - -static int do_command(void) -{ - COMMAND_TABLE *ctp = cmd_table; - enum commands mycmd = CMD_HELP; - int cmd_len; - - if (cmdname && strlen(cmdname) == 0) { - mycmd = CMD_NEXT; - } else { - while (ctp->name) { - cmd_len = strlen(ctp->name); - if (strncmp(ctp->name,cmdname,cmd_len) == 0) { - mycmd = ctp->cmd; - break; - } - ctp++; - } - } - - switch (mycmd) { - case CMD_CREATE_TDB: - bIterate = 0; - create_tdb(arg1); - return 0; - case CMD_OPEN_TDB: - bIterate = 0; - open_tdb(arg1); - return 0; - case CMD_SYSTEM: - /* Shell command */ - system(arg1); - return 0; - case CMD_QUIT: - return 1; - default: - /* all the rest require a open database */ - if (!tdb) { - bIterate = 0; - terror("database not open"); - help(); - return 0; - } - switch (mycmd) { - case CMD_ERASE: - bIterate = 0; - tdb_traverse(tdb, do_delete_fn, NULL); - return 0; - case CMD_DUMP: - bIterate = 0; - tdb_traverse(tdb, print_rec, NULL); - return 0; - case CMD_INSERT: - bIterate = 0; - insert_tdb(arg1, arg1len,arg2,arg2len); - return 0; - case CMD_MOVE: - bIterate = 0; - move_rec(arg1,arg1len,arg2); - return 0; - case CMD_STORE: - bIterate = 0; - store_tdb(arg1,arg1len,arg2,arg2len); - return 0; - case CMD_SHOW: - bIterate = 0; - show_tdb(arg1, arg1len); - return 0; - case CMD_KEYS: - tdb_traverse(tdb, print_key, NULL); - return 0; - case CMD_HEXKEYS: - tdb_traverse(tdb, print_hexkey, NULL); - return 0; - case CMD_DELETE: - bIterate = 0; - delete_tdb(arg1,arg1len); - return 0; - case CMD_LIST_HASH_FREE: - tdb_dump_all(tdb); - return 0; - case CMD_LIST_FREE: - tdb_printfreelist(tdb); - return 0; - case CMD_INFO: - info_tdb(); - return 0; - case CMD_SPEED: - speed_tdb(arg1); - return 0; - case CMD_MMAP: - toggle_mmap(); - return 0; - case CMD_FIRST: - bIterate = 1; - first_record(tdb, &iterate_kbuf); - return 0; - case CMD_NEXT: - if (bIterate) - next_record(tdb, &iterate_kbuf); - return 0; - case CMD_HELP: - help(); - return 0; - case CMD_CREATE_TDB: - case CMD_OPEN_TDB: - case CMD_SYSTEM: - case CMD_QUIT: - /* - * unhandled commands. cases included here to avoid compiler - * warnings. - */ - return 0; - } - } - - return 0; -} - -static char *convert_string(char *instring, size_t *sizep) -{ - size_t length = 0; - char *outp, *inp; - char temp[3]; - - - outp = inp = instring; - - while (*inp) { - if (*inp == '\\') { - inp++; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[0] = *inp++; - temp[1] = '\0'; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[1] = *inp++; - temp[2] = '\0'; - } - *outp++ = (char)strtol((const char *)temp,NULL,16); - } else { - *outp++ = *inp++; - } - } else { - *outp++ = *inp++; - } - length++; - } - *sizep = length; - return instring; -} - -int main(int argc, char *argv[]) -{ - cmdname = ""; - arg1 = NULL; - arg1len = 0; - arg2 = NULL; - arg2len = 0; - - if (argv[1]) { - cmdname = "open"; - arg1 = argv[1]; - do_command(); - cmdname = ""; - arg1 = NULL; - } - - switch (argc) { - case 1: - case 2: - /* Interactive mode */ - while ((cmdname = tdb_getline("tdb> "))) { - arg2 = arg1 = NULL; - if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { - arg1++; - arg2 = arg1; - while (*arg2) { - if (*arg2 == ' ') { - *arg2++ = '\0'; - break; - } - if ((*arg2++ == '\\') && (*arg2 == ' ')) { - arg2++; - } - } - } - if (arg1) arg1 = convert_string(arg1,&arg1len); - if (arg2) arg2 = convert_string(arg2,&arg2len); - if (do_command()) break; - } - break; - case 5: - arg2 = convert_string(argv[4],&arg2len); - case 4: - arg1 = convert_string(argv[3],&arg1len); - case 3: - cmdname = argv[2]; - default: - do_command(); - break; - } - - if (tdb) tdb_close(tdb); - - return 0; -} diff --git a/tdb/tools/tdbtorture.c b/tdb/tools/tdbtorture.c deleted file mode 100644 index 9265cf07aa..0000000000 --- a/tdb/tools/tdbtorture.c +++ /dev/null @@ -1,318 +0,0 @@ -/* this tests tdb by doing lots of ops from several simultaneous - writers - that stresses the locking code. -*/ - -#include "replace.h" -#include "system/time.h" -#include "system/wait.h" -#include "system/filesys.h" -#include "tdb.h" - -#ifdef HAVE_GETOPT_H -#include -#endif - - -#define REOPEN_PROB 30 -#define DELETE_PROB 8 -#define STORE_PROB 4 -#define APPEND_PROB 6 -#define TRANSACTION_PROB 10 -#define LOCKSTORE_PROB 5 -#define TRAVERSE_PROB 20 -#define TRAVERSE_READ_PROB 20 -#define CULL_PROB 100 -#define KEYLEN 3 -#define DATALEN 100 - -static struct tdb_context *db; -static int in_transaction; -static int error_count; - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) -{ - va_list ap; - - error_count++; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -#if 0 - { - char *ptr; - asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); - system(ptr); - free(ptr); - } -#endif -} - -static void fatal(const char *why) -{ - perror(why); - error_count++; -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i - - -ldb - - - -

tdb

- -TDB is a Trivial Database. In concept, it is very much like GDBM, and BSD's DB -except that it allows multiple simultaneous writers and uses locking -internally to keep writers from trampling on each other. TDB is also extremely -small. - -

Discussion and bug reports

- -tdb does not currently have its own mailing list or bug tracking -system. For now, please use the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -

Download

- -You can download the latest release either via rsync or git.
-
-To fetch via git see the following guide:
-Using Git for Samba Development
-Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/tdb directory.
-
-To fetch via rsync use these commands: - -
-  rsync -Pavz samba.org::ftp/unpacked/tdb .
-  rsync -Pavz samba.org::ftp/unpacked/libreplace .
-
- -and build in tdb. It will find the replace library in the directory -above automatically. - - - -- cgit