Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • openldap/openldap
  • hyc/openldap
  • ryan/openldap
  • iboukris/openldap
  • ondra/openldap
  • sshanks-kx/openldap
  • blaggacao/openldap
  • pbrezina/openldap
  • quanah/openldap
  • dragos_h/openldap
  • lorenz/openldap
  • tsaarni/openldap
  • fei.ding/openldap
  • orent/openldap
  • arrowplum/openldap
  • barchiesi/openldap
  • jotik/openldap
  • hamano/openldap
  • ingovoss/openldap
  • henson/openldap
  • jlrine2/openldap
  • howeverAT/openldap
  • nivanova/openldap
  • orbea/openldap
  • rdubner/openldap
  • smckinney/openldap
  • jklowden/openldap
  • dpa-openldap/openldap
  • rouzier/openldap
  • orgads/openldap
  • ffontaine/openldap
  • jiaqingz/openldap
  • dcoutadeur/openldap
  • begeragus/openldap
  • pubellit/openldap
  • glandium/openldap
  • facboy/openldap
  • thesamesam/openldap
  • Johan/openldap
  • fkooman/openldap
  • gburd/openldap
  • h-homma/openldap
  • sgallagher/openldap
  • ahmed_zaki/openldap
  • gnoe/openldap
  • mid/openldap
  • clan/openldap
47 results
Show changes
Showing with 2155 additions and 3340 deletions
## Copyright 1998,1999 The OpenLDAP Foundation
## COPYING RESTRICTIONS APPLY. See COPYRIGHT File in top level directory
## of this package for details.
##---------------------------------------------------------------------------
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Makefile Template for Server Modules
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
##---------------------------------------------------------------------------
#
# Makefile Template for Server Modules
#
LIBRARY = $(LIBBASE).la
LIBSTAT = lib$(LIBBASE).a
LTFLAGS = --only-$(LINKAGE)
MKDEPFLAG = -l
.SUFFIXES: .c .o .lo
.c.lo:
$(LTCOMPILE_MOD) $<
all-no lint-no 5lint-no depend-no install-no: FORCE
@echo "run configure with $(BUILD_OPT) to make $(LIBBASE)"
all-common: all-$(BUILD_MOD)
version.c: $(OBJS)
version.c: Makefile
$(RM) $@
$(MKVERSION) $(LIBBASE) > $@
version.lo: version.c $(OBJS)
$(LIBRARY): version.lo
$(LTLIBLINK) -module -rpath $(moduledir) -o $@ $(OBJS) version.lo
$(LTLINK_MOD) -module -o $@ $(OBJS) version.lo $(LINK_LIBS)
$(LIBSTAT): version.lo
$(AR) ruv $@ `echo $(OBJS) | sed 's/\.lo/.o/g'` version.o
......@@ -45,8 +63,8 @@ all-local-lib:
all-yes: $(LIBSTAT) all-local-lib FORCE
install-mod: $(LIBRARY)
@-$(MKDIR) $(moduledir)
$(LTINSTALL) $(INSTALLFLAGS) -m 755 $(LIBRARY) $(moduledir)
@-$(MKDIR) $(DESTDIR)$(moduledir)
$(LTINSTALL) $(INSTALLFLAGS) -m 755 $(LIBRARY) $(DESTDIR)$(moduledir)
install-local-lib:
install-yes: install-local-lib FORCE
......@@ -70,12 +88,5 @@ depend-yes depend-mod: depend-local-lib FORCE
veryclean-local-lib:
veryclean-lib: clean-lib veryclean-local-lib
COMPILE = $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) $(CFLAGS) -c
MKDEPFLAG = -l
.SUFFIXES: .c .o .lo
.c.lo:
$(COMPILE) $<
Makefile: $(top_srcdir)/build/mod.mk
dnl Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
dnl COPYING RESTRICTIONS APPLY, See COPYRIGHT file
dnl
dnl OpenLDAP Autoconf Macros
dnl $OpenLDAP$
dnl This work is part of OpenLDAP Software <http://www.openldap.org/>.
dnl
dnl Copyright 1998-2024 The OpenLDAP Foundation.
dnl All rights reserved.
dnl
dnl Redistribution and use in source and binary forms, with or without
dnl modification, are permitted only as authorized by the OpenLDAP
dnl Public License.
dnl
dnl A copy of this license is available in the file LICENSE in the
dnl top-level directory of the distribution or, alternatively, at
dnl <http://www.OpenLDAP.org/license.html>.
dnl
dnl --------------------------------------------------------------------
dnl Restricted form of AC_ARG_ENABLE that limits user options
dnl
dnl $1 = option name
dnl $2 = help-string
dnl $3 = default value (auto)
dnl $3 = default value (auto). "--" means do not set it by default
dnl $4 = allowed values (auto yes no)
dnl $5 = overridden default
AC_DEFUN([OL_ARG_ENABLE], [# OpenLDAP --enable-$1
AC_ARG_ENABLE($1,[$2 (]ifelse($3,,auto,$3)[)],[
pushdef([ol_DefVal],ifelse($3,,auto,$3))
AC_ARG_ENABLE($1,ifelse($4,,[$2],[$2] translit([$4],[ ],[|])) ifelse($3,--,,@<:@ol_DefVal@:>@),[
ol_arg=invalid
for ol_val in ifelse($4,,[auto yes no],[$4]) ; do
if test "$enableval" = "$ol_val" ; then
......@@ -22,11 +34,27 @@ AC_DEFUN([OL_ARG_ENABLE], [# OpenLDAP --enable-$1
AC_MSG_ERROR(bad value $enableval for --enable-$1)
fi
ol_enable_$1="$ol_arg"
],
[ ol_enable_$1=ifelse($3,,"auto","$3")])dnl
dnl AC_VERBOSE(OpenLDAP -enable-$1 $ol_enable_$1)
]ifelse($3,--,,[,
[ ol_enable_$1=ifelse($5,,ol_DefVal,[${]$5[:-]ol_DefVal[}])]]))dnl
dnl AC_MSG_RESULT([OpenLDAP -enable-$1 $ol_enable_$1])
popdef([ol_DefVal])
# end --enable-$1
])dnl
AC_DEFUN([OL_ARG_ENABLE_BK], [
Backends="$Backends $1"
Bk_help_$1="$2"
OL_ARG_ENABLE($1, [AS_HELP_STRING([--enable-$1], [enable $2])], $3, $4, $5)
])dnl
AC_DEFUN([OL_ARG_ENABLE_OV], [
Overlays="$Overlays $1"
Ov_help_$1="$2"
OL_ARG_ENABLE($1, [AS_HELP_STRING([--enable-$1], [$2])], $3, $4, $5)
])dnl
AC_DEFUN([OL_ARG_ENABLE_PW], [
Pwmods="$Pwmods $1"
Pw_help_$1="$2"
OL_ARG_ENABLE($1, [AS_HELP_STRING([--enable-$1], [$2])], $3, $4, $5)
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Restricted form of AC_ARG_WITH that limits user options
......@@ -36,7 +64,7 @@ dnl $2 = help-string
dnl $3 = default value (no)
dnl $4 = allowed values (yes or no)
AC_DEFUN([OL_ARG_WITH], [# OpenLDAP --with-$1
AC_ARG_WITH($1,[$2 (]ifelse($3,,yes,$3)[)],[
AC_ARG_WITH($1,[$2 @<:@]ifelse($3,,yes,$3)@:>@,[
ol_arg=invalid
for ol_val in ifelse($4,,[yes no],[$4]) ; do
if test "$withval" = "$ol_val" ; then
......@@ -49,35 +77,9 @@ AC_DEFUN([OL_ARG_WITH], [# OpenLDAP --with-$1
ol_with_$1="$ol_arg"
],
[ ol_with_$1=ifelse($3,,"no","$3")])dnl
dnl AC_VERBOSE(OpenLDAP --with-$1 $ol_with_$1)
dnl AC_MSG_RESULT([OpenLDAP --with-$1 $ol_with_$1])
# end --with-$1
])dnl
dnl
dnl ====================================================================
dnl check if hard links are supported.
dnl
AC_DEFUN([OL_PROG_LN_H], [# test for ln hardlink support
AC_MSG_CHECKING(whether ln works)
AC_CACHE_VAL(ol_cv_prog_LN_H,
[rm -f conftest.src conftest.dst
echo "conftest" > conftest.src
if ln conftest.src conftest.dst 2>/dev/null
then
ol_cv_prog_LN_H="ln"
else
ol_cv_prog_LN_H="cp"
fi
rm -f conftest.src conftest.dst
])dnl
LN_H="$ol_cv_prog_LN_H"
if test "$ol_cv_prog_LN_H" = "ln"; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AC_SUBST(LN_H)dnl
])dnl
dnl
dnl ====================================================================
dnl Check for dependency generation flag
AC_DEFUN([OL_MKDEPEND], [# test for make depend flag
......@@ -93,7 +95,7 @@ if test -z "${MKDEP}"; then
noCode;
EOF
if AC_TRY_COMMAND($OL_MKDEP $flag conftest.c) \
| egrep '^conftest\.'"${ac_objext}" >/dev/null 2>&1
| grep '^conftest\.'"${ac_objext}" >/dev/null 2>&1
then
if test ! -f conftest."${ac_object}" ; then
ol_cv_mkdep=$flag
......@@ -104,6 +106,7 @@ EOF
done
rm -f conftest*
])
test "$ol_cv_mkdep" = no && OL_MKDEP=":"
else
cc_cv_mkdep=yes
OL_MKDEP_FLAGS="${MKDEP_FLAGS}"
......@@ -121,28 +124,37 @@ dnl ====================================================================
dnl Check if system uses EBCDIC instead of ASCII
AC_DEFUN([OL_CPP_EBCDIC], [# test for EBCDIC
AC_CACHE_CHECK([for EBCDIC],ol_cv_cpp_ebcdic,[
AC_TRY_CPP([
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
#if !('M' == 0xd4)
#include <__ASCII__/generate_error.h>
#endif
],
[ol_cv_cpp_ebcdic=yes],
[ol_cv_cpp_ebcdic=no])])
]])],[ol_cv_cpp_ebcdic=yes],[ol_cv_cpp_ebcdic=no])])
if test $ol_cv_cpp_ebcdic = yes ; then
AC_DEFINE(HAVE_EBCDIC,1, [define if system uses EBCDIC instead of ASCII])
fi
])
dnl
dnl --------------------------------------------------------------------
dnl Check for MSVC
AC_DEFUN([OL_MSVC],
[AC_REQUIRE_CPP()dnl
AC_CACHE_CHECK([whether we are using MS Visual C++], ol_cv_msvc,
[AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
#ifndef _MSC_VER
#include <__FOO__/generate_error.h>
#endif
]])],[ol_cv_msvc=yes],[ol_cv_msvc=no])])])
dnl --------------------------------------------------------------------
dnl OpenLDAP version of STDC header check w/ EBCDIC support
AC_DEFUN(OL_HEADER_STDC,
AC_DEFUN([OL_HEADER_STDC],
[AC_REQUIRE_CPP()dnl
AC_REQUIRE([OL_CPP_EBCDIC])dnl
AC_CACHE_CHECK([for ANSI C header files], ol_cv_header_stdc,
[AC_TRY_CPP([#include <stdlib.h>
[AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>], ol_cv_header_stdc=yes, ol_cv_header_stdc=no)
#include <float.h>]])],[ol_cv_header_stdc=yes],[ol_cv_header_stdc=no])
if test $ol_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
......@@ -156,7 +168,8 @@ fi
if test $ol_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
AC_TRY_RUN([#include <ctype.h>
AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <ctype.h>
#include <stdlib.h>
#ifndef HAVE_EBCDIC
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
......@@ -170,7 +183,7 @@ AC_TRY_RUN([#include <ctype.h>
int main () { int i; for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
], , ol_cv_header_stdc=no, :)
]])],[],[ol_cv_header_stdc=no],[:])
fi])
if test $ol_cv_header_stdc = yes; then
AC_DEFINE(STDC_HEADERS)
......@@ -179,406 +192,205 @@ ac_cv_header_stdc=disable
])
dnl
dnl ====================================================================
dnl Check if struct passwd has pw_gecos
AC_DEFUN([OL_STRUCT_PASSWD_PW_GECOS], [# test for pw_gecos in struct passwd
AC_CACHE_CHECK([struct passwd for pw_gecos],ol_cv_struct_passwd_pw_gecos,[
AC_TRY_COMPILE([#include <pwd.h>],[
struct passwd pwd;
pwd.pw_gecos = pwd.pw_name;
],
[ol_cv_struct_passwd_pw_gecos=yes],
[ol_cv_struct_passwd_pw_gecos=no])])
if test $ol_cv_struct_passwd_pw_gecos = yes ; then
AC_DEFINE(HAVE_PW_GECOS,1, [define if struct passwd has pw_gecos])
fi
])
dnl
dnl --------------------------------------------------------------------
dnl Check if struct passwd has pw_passwd
AC_DEFUN([OL_STRUCT_PASSWD_PW_PASSWD], [# test for pw_passwd in struct passwd
AC_CACHE_CHECK([struct passwd for pw_passwd],ol_cv_struct_passwd_pw_passwd,[
AC_TRY_COMPILE([#include <pwd.h>],[
struct passwd pwd;
pwd.pw_passwd = pwd.pw_name;
],
[ol_cv_struct_passwd_pw_passwd=yes],
[ol_cv_struct_passwd_pw_passwd=no])])
if test $ol_cv_struct_passwd_pw_passwd = yes ; then
AC_DEFINE(HAVE_PW_PASSWD,1, [define if struct passwd has pw_passwd])
fi
])
dnl
dnl ====================================================================
dnl Check if db.h is Berkeley DB2
dnl
dnl defines ol_cv_header_db2 to 'yes' or 'no'
dnl
dnl uses:
dnl AC_CHECK_HEADERS(db.h)
dnl
AC_DEFUN([OL_HEADER_BERKELEY_DB2],
[AC_CHECK_HEADERS(db.h)
if test $ac_cv_header_db_h = yes ; then
AC_CACHE_CHECK([if db.h is DB2], [ol_cv_header_db2],[
AC_EGREP_CPP(__db_version_2,[
# include <db.h>
/* this check could be improved */
# ifdef DB_VERSION_MAJOR
# if DB_VERSION_MAJOR == 2
__db_version_2
# endif
# endif
], ol_cv_header_db2=yes, ol_cv_header_db2=no)])
else
ol_cv_header_db2=no
fi
])dnl
dnl --------------------------------------------------------------------
dnl Check if Berkeley DB2 library exists
dnl Check for dbopen in standard libraries or -ldb
dnl
dnl defines ol_cv_lib_db2 to '-ldb' or 'no'
dnl
dnl uses:
dnl AC_CHECK_LIB(db,db_open)
dnl
AC_DEFUN([OL_LIB_BERKELEY_DB2],
[AC_CACHE_CHECK([for DB2 library], [ol_cv_lib_db2],
[ ol_LIBS="$LIBS"
AC_CHECK_LIB(db,db_open,[ol_cv_lib_db2=-ldb],[ol_cv_lib_db2=no])
LIBS="$ol_LIBS"
])
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Check if Berkeley db2 exists
dnl
dnl defines ol_cv_berkeley_db2 to 'yes' or 'no'
dnl
dnl uses:
dnl OL_LIB_BERKELEY_DB2
dnl OL_HEADER_BERKELEY_DB2
dnl
AC_DEFUN([OL_BERKELEY_DB2],
[AC_REQUIRE([OL_LIB_BERKELEY_DB2])
AC_REQUIRE([OL_HEADER_BERKELEY_DB2])
AC_CACHE_CHECK([for Berkeley DB2], [ol_cv_berkeley_db2], [
if test "$ol_cv_lib_db2" = no -o "$ol_cv_header_db2" = no ; then
ol_cv_berkeley_db2=no
else
ol_cv_berkeley_db2=yes
fi
])
if test $ol_cv_berkeley_db2 = yes ; then
AC_DEFINE(HAVE_BERKELEY_DB2,1, [define if Berkeley DBv2 is available])
fi
])dnl
dnl
dnl ====================================================================
dnl Check for db.h/db_185.h is Berkeley DB
dnl
dnl defines ol_cv_header_db to 'yes' or 'no'
dnl
dnl uses:
dnl OL_HEADER_BERKELEY_DB2
dnl AC_CHECK_HEADERS(db_185.h)
dnl
AC_DEFUN([OL_HEADER_BERKELEY_DB],
[AC_REQUIRE([OL_HEADER_BERKELEY_DB2])
AC_CHECK_HEADERS(db_185.h)
if test "$ol_cv_header_db2" = yes ; then
dnl db.h is db2!
ol_cv_header_db=$ac_cv_header_db_185_h
else
ol_cv_header_db=$ac_cv_header_db_h
fi
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Check if Berkeley DB library exists
dnl Check for dbopen in standard libraries or -ldb
dnl
dnl defines ol_cv_lib_db to 'yes' or '-ldb' or 'no'
dnl 'yes' implies dbopen is in $LIBS
dnl
dnl uses:
dnl AC_CHECK_FUNC(dbopen)
dnl AC_CHECK_LIB(db,dbopen)
dnl
AC_DEFUN([OL_LIB_BERKELEY_DB],
[AC_CACHE_CHECK([for Berkeley DB library], [ol_cv_lib_db],
dnl DNS resolver macros
AC_DEFUN([OL_RESOLVER_TRY],
[if test $ol_cv_lib_resolver = no ; then
AC_CACHE_CHECK([for resolver link (]ifelse($2,,default,$2)[)],[$1],
[
AC_CHECK_HEADERS(db1/db.h)
ol_LIBS="$LIBS"
AC_CHECK_FUNC(dbopen,[ol_cv_lib_db=yes], [
AC_CHECK_LIB(db1,dbopen,[ol_cv_lib_db=-ldb1],[
AC_CHECK_LIB(db,dbopen,[ol_cv_lib_db=-ldb],
[ol_cv_lib_db=no])
])
])
LIBS="$ol_LIBS"
])
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Check if Berkeley DB exists
dnl
dnl defines ol_cv_berkeley_db to 'yes' or 'no'
dnl
dnl uses:
dnl OL_LIB_BERKELEY_DB
dnl OL_HEADER_BERKELEY_DB
dnl
AC_DEFUN([OL_BERKELEY_DB],
[AC_REQUIRE([OL_LIB_BERKELEY_DB])
AC_REQUIRE([OL_HEADER_BERKELEY_DB])
AC_CACHE_CHECK([for Berkeley DB], [ol_cv_berkeley_db], [
if test "$ol_cv_lib_db" = no -o "$ol_cv_header_db" = no ; then
ol_cv_berkeley_db=no
else
ol_cv_berkeley_db=yes
fi
])
if test $ol_cv_berkeley_db = yes ; then
AC_DEFINE(HAVE_BERKELEY_DB,1, [define if Berkeley DB is available])
fi
])dnl
dnl
dnl ====================================================================
dnl Check if GDBM library exists
dnl Check for gdbm_open in standard libraries or -lgdbm
dnl
dnl defines ol_cv_lib_gdbm to 'yes' or '-lgdbm' or 'no'
dnl 'yes' implies gdbm_open is in $LIBS
dnl
dnl uses:
dnl AC_CHECK_FUNC(gdbm_open)
dnl AC_CHECK_LIB(gdbm,gdbm_open)
dnl
AC_DEFUN([OL_LIB_GDBM],
[AC_CACHE_CHECK(for GDBM library, [ol_cv_lib_gdbm],
[ ol_LIBS="$LIBS"
AC_CHECK_FUNC(gdbm_open,[ol_cv_lib_gdbm=yes], [
AC_CHECK_LIB(gdbm,gdbm_open,[ol_cv_lib_gdbm=-lgdbm],[ol_cv_lib_gdbm=no])
])
LIBS="$ol_LIBS"
])
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Check if GDBM exists
dnl
dnl defines ol_cv_gdbm to 'yes' or 'no'
dnl
dnl uses:
dnl OL_LIB_GDBM
dnl AC_CHECK_HEADERS(gdbm.h)
dnl
AC_DEFUN([OL_GDBM],
[AC_REQUIRE([OL_LIB_GDBM])
AC_CHECK_HEADERS(gdbm.h)
AC_CACHE_CHECK(for db, [ol_cv_gdbm], [
if test $ol_cv_lib_gdbm = no -o $ac_cv_header_gdbm_h = no ; then
ol_cv_gdbm=no
else
ol_cv_gdbm=yes
fi
])
if test $ol_cv_gdbm = yes ; then
AC_DEFINE(HAVE_GDBM,1, [define if GNU DBM is available])
fi
])dnl
dnl
dnl ====================================================================
dnl Check if MDBM library exists
dnl Check for mdbm_open in standard libraries or -lmdbm
dnl
dnl defines ol_cv_lib_mdbm to 'yes' or '-lmdbm' or 'no'
dnl 'yes' implies mdbm_open is in $LIBS
dnl
dnl uses:
dnl AC_CHECK_FUNC(mdbm_set_chain)
dnl AC_CHECK_LIB(mdbm,mdbm_set_chain)
dnl
AC_DEFUN([OL_LIB_MDBM],
[AC_CACHE_CHECK(for MDBM library, [ol_cv_lib_mdbm],
[ ol_LIBS="$LIBS"
AC_CHECK_FUNC(mdbm_set_chain,[ol_cv_lib_mdbm=yes], [
AC_CHECK_LIB(mdbm,mdbm_set_chain,[ol_cv_lib_mdbm=-lmdbm],[ol_cv_lib_mdbm=no])
])
ol_RESOLVER_LIB=ifelse($2,,,$2)
ol_LIBS=$LIBS
LIBS="$ol_RESOLVER_LIB $LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_ARPA_NAMESER_H
# include <arpa/nameser.h>
#endif
#ifdef HAVE_RESOLV_H
# include <resolv.h>
#endif
]], [[{
int len, status;
char *request = NULL;
unsigned char reply[64*1024];
unsigned char host[64*1024];
unsigned char *p;
#ifdef NS_HFIXEDSZ
/* Bind 8/9 interface */
len = res_query(request, ns_c_in, ns_t_srv, reply, sizeof(reply));
#else
/* Bind 4 interface */
# ifndef T_SRV
# define T_SRV 33
# endif
len = res_query(request, C_IN, T_SRV, reply, sizeof(reply));
#endif
p = reply;
#ifdef NS_HFIXEDSZ
/* Bind 8/9 interface */
p += NS_HFIXEDSZ;
#elif defined(HFIXEDSZ)
/* Bind 4 interface w/ HFIXEDSZ */
p += HFIXEDSZ;
#else
/* Bind 4 interface w/o HFIXEDSZ */
p += sizeof(HEADER);
#endif
status = dn_expand( reply, reply+len, p, host, sizeof(host));
}]])],[$1=yes],[$1=no])
LIBS="$ol_LIBS"
])
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Check if MDBM exists
dnl
dnl defines ol_cv_mdbm to 'yes' or 'no'
dnl
dnl uses:
dnl OL_LIB_MDBM
dnl AC_CHECK_HEADERS(mdbm.h)
dnl
AC_DEFUN([OL_MDBM],
[AC_REQUIRE([OL_LIB_MDBM])
AC_CHECK_HEADERS(mdbm.h)
AC_CACHE_CHECK(for db, [ol_cv_mdbm], [
if test $ol_cv_lib_mdbm = no -o $ac_cv_header_mdbm_h = no ; then
ol_cv_mdbm=no
else
ol_cv_mdbm=yes
if test $$1 = yes ; then
ol_cv_lib_resolver=ifelse($2,,yes,$2)
fi
fi
])
if test $ol_cv_mdbm = yes ; then
AC_DEFINE(HAVE_MDBM,1, [define if MDBM is available])
fi
])dnl
dnl
dnl ====================================================================
dnl Check if NDBM library exists
dnl Check for dbm_open in standard libraries or -lndbm or -ldbm
dnl
dnl defines ol_cv_lib_ndbm to 'yes' or '-lndbm' or -ldbm or 'no'
dnl 'yes' implies ndbm_open is in $LIBS
dnl
dnl uses:
dnl AC_CHECK_FUNC(dbm_open)
dnl AC_CHECK_LIB(ndbm,dbm_open)
dnl AC_CHECK_LIB(dbm,dbm_open)
dnl
dnl restrictions:
dnl should also check SVR4 case: dbm_open() in -lucb but that
dnl would requiring dealing with -L/usr/ucblib
dnl
AC_DEFUN([OL_LIB_NDBM],
[AC_CACHE_CHECK(for NDBM library, [ol_cv_lib_ndbm],
[ ol_LIBS="$LIBS"
AC_CHECK_FUNC(dbm_open,[ol_cv_lib_ndbm=yes], [
AC_CHECK_LIB(ndbm,dbm_open,[ol_cv_lib_ndbm=-lndbm], [
AC_CHECK_LIB(dbm,dbm_open,[ol_cv_lib_ndbm=-ldbm],
[ol_cv_lib_ndbm=no])dnl
])
])
LIBS="$ol_LIBS"
])
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Check if NDBM exists
dnl
dnl defines ol_cv_ndbm to 'yes' or 'no'
dnl
dnl uses:
dnl OL_LIB_NDBM
dnl AC_CHECK_HEADERS(ndbm.h)
dnl
dnl restrictions:
dnl Doesn't handle SVR4 case (see above)
dnl
AC_DEFUN([OL_NDBM],
[AC_REQUIRE([OL_LIB_NDBM])
AC_CHECK_HEADERS(ndbm.h)
AC_CACHE_CHECK(for db, [ol_cv_ndbm], [
if test $ol_cv_lib_ndbm = no -o $ac_cv_header_ndbm_h = no ; then
ol_cv_ndbm=no
else
ol_cv_ndbm=yes
fi
dnl Try to locate appropriate library
AC_DEFUN([OL_RESOLVER_LINK],
[ol_cv_lib_resolver=no
OL_RESOLVER_TRY(ol_cv_resolver_none)
OL_RESOLVER_TRY(ol_cv_resolver_resolv,[-lresolv])
OL_RESOLVER_TRY(ol_cv_resolver_bind,[-lbind])
])
if test $ol_cv_ndbm = yes ; then
AC_DEFINE(HAVE_NDBM,1, [define if NDBM is available])
fi
])dnl
dnl
dnl ====================================================================
dnl Check POSIX Thread version
dnl
dnl defines ol_cv_posix_version to 'final' or 'draft' or 'unknown'
dnl 'unknown' implies that the version could not be detected
dnl or that pthreads.h does exist. Existance of pthreads.h
dnl should be tested separately.
dnl defines ol_cv_pthread_version to 4, 5, 6, 7, 8, 10, depending on the
dnl version of the POSIX.4a Draft that is implemented.
dnl 10 == POSIX.4a Final == POSIX.1c-1996 for our purposes.
dnl Existence of pthread.h should be tested separately.
dnl
dnl tests:
dnl pthread_detach() was dropped in Draft 8, it is present
dnl in every other version
dnl PTHREAD_CREATE_UNDETACHED is only in Draft 7, it was called
dnl PTHREAD_CREATE_JOINABLE after that
dnl pthread_attr_create was renamed to pthread_attr_init in Draft 6.
dnl Draft 6-10 has _init, Draft 4-5 has _create.
dnl pthread_attr_default was dropped in Draft 6, only 4 and 5 have it
dnl PTHREAD_MUTEX_INITIALIZER was introduced in Draft 5. It's not
dnl interesting to us because we don't try to statically
dnl initialize mutexes. 5-10 has it.
dnl
dnl Draft 9 and 10 are equivalent for our purposes.
dnl
AC_DEFUN([OL_POSIX_THREAD_VERSION],
[AC_CACHE_CHECK([POSIX thread version],[ol_cv_pthread_version],[
AC_EGREP_CPP(pthread_version_final,[
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
# include <pthread.h>
/* this check could be improved */
# ifdef PTHREAD_ONCE_INIT
pthread_version_final
# endif
], ol_pthread_final=yes, ol_pthread_final=no)
AC_EGREP_CPP(pthread_version_draft4,[
]], [[
int i = PTHREAD_CREATE_JOINABLE;
]])],[
AC_EGREP_HEADER(pthread_detach,pthread.h,
ol_cv_pthread_version=10, ol_cv_pthread_version=8)],[
AC_EGREP_CPP(draft7,[
# include <pthread.h>
/* this check could be improved */
# ifdef pthread_once_init
pthread_version_draft4
# ifdef PTHREAD_CREATE_UNDETACHED
draft7
# endif
], ol_pthread_draft4=yes, ol_pthread_draft4=no)
if test $ol_pthread_final = yes -a $ol_pthread_draft4 = no; then
ol_cv_pthread_version=final
elif test $ol_pthread_final = no -a $ol_pthread_draft4 = yes; then
ol_cv_pthread_version=draft4
else
ol_cv_pthread_version=unknown
fi
], ol_cv_pthread_version=7, [
AC_EGREP_HEADER(pthread_attr_init,pthread.h,
ol_cv_pthread_version=6, [
AC_EGREP_CPP(draft5,[
# include <pthread.h>
#ifdef PTHREAD_MUTEX_INITIALIZER
draft5
#endif
], ol_cv_pthread_version=5, ol_cv_pthread_version=4) ]) ]) ])
])
])dnl
dnl
dnl --------------------------------------------------------------------
AC_DEFUN([OL_PTHREAD_TEST_INCLUDES],
[/* pthread test headers */
AC_DEFUN([OL_PTHREAD_TEST_INCLUDES], [[
/* pthread test headers */
#include <pthread.h>
#if HAVE_PTHREADS < 7
#include <errno.h>
#endif
#ifndef NULL
#define NULL (void*)0
#endif
#ifdef __STDC__
static void *task(void *p)
#else
static void *task(p)
void *p;
#endif
{
return (void *) (p == NULL);
}
])
AC_DEFUN([OL_PTHREAD_TEST_FUNCTION],[
]])
AC_DEFUN([OL_PTHREAD_TEST_FUNCTION],[[
/* pthread test function */
#ifndef PTHREAD_CREATE_DETACHED
#define PTHREAD_CREATE_DETACHED 1
#endif
pthread_t t;
int status;
int detach = PTHREAD_CREATE_DETACHED;
#if HAVE_PTHREADS > 4
/* Final pthreads */
pthread_attr_t attr;
status = pthread_attr_init(&attr);
if( status ) return status;
/* make sure pthread_create() isn't just a stub */
#if HAVE_PTHREADS_D4
status = pthread_create(&t, pthread_attr_default, task, NULL);
#if HAVE_PTHREADS < 7
status = pthread_attr_setdetachstate(&attr, &detach);
if( status < 0 ) status = errno;
#else
status = pthread_create(&t, NULL, task, NULL);
status = pthread_attr_setdetachstate(&attr, detach);
#endif
if( status ) return status;
status = pthread_create( &t, &attr, task, NULL );
#if HAVE_PTHREADS < 7
if( status < 0 ) status = errno;
#endif
if( status ) return status;
#else
/* Draft 4 pthreads */
status = pthread_create( &t, pthread_attr_default, task, NULL );
if( status ) return errno;
if( status ) exit( status );
/* give thread a chance to complete */
/* it should remain joinable and hence detachable */
sleep( 1 );
/* make sure pthread_detach() isn't just a stub */
#if HAVE_PTHREADS_D4
status = pthread_detach( &t );
#else
status = pthread_detach( t );
if( status ) return errno;
#endif
#ifdef HAVE_LINUX_THREADS
pthread_kill_other_threads_np();
#endif
exit( status );
])
return 0;
]])
AC_DEFUN([OL_PTHREAD_TEST_PROGRAM],
[OL_PTHREAD_TEST_INCLUDES
[AC_LANG_SOURCE([OL_PTHREAD_TEST_INCLUDES
#ifdef __STDC__
int main(int argc, char **argv)
#else
int main(argc, argv)
int argc;
char **argv;
#endif
{
OL_PTHREAD_TEST_FUNCTION
}
])
])])
dnl --------------------------------------------------------------------
AC_DEFUN([OL_PTHREAD_TRY], [# Pthread try link: $1 ($2)
if test "$ol_link_threads" = no ; then
......@@ -588,9 +400,11 @@ if test "$ol_link_threads" = no ; then
ol_LIBS="$LIBS"
LIBS="$1 $LIBS"
AC_TRY_RUN(OL_PTHREAD_TEST_PROGRAM,
[$2=yes], [$2=no],
[AC_TRY_LINK(OL_PTHREAD_TEST_INCLUDES,OL_PTHREAD_TEST_FUNCTION,
AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM],
[$2=yes],
[$2=no],
[AC_LINK_IFELSE([AC_LANG_PROGRAM(OL_PTHREAD_TEST_INCLUDES,
OL_PTHREAD_TEST_FUNCTION)],
[$2=yes], [$2=no])])
# restore the LIBS
......@@ -609,7 +423,7 @@ dnl Check GNU Pth pthread Header
dnl
dnl defines ol_cv_header linux_threads to 'yes' or 'no'
dnl 'no' implies pthreads.h is not LinuxThreads or pthreads.h
dnl doesn't exists. Existance of pthread.h should separately
dnl doesn't exist. Existence of pthread.h should separately
dnl checked.
dnl
AC_DEFUN([OL_HEADER_GNU_PTH_PTHREAD_H], [
......@@ -618,7 +432,7 @@ AC_DEFUN([OL_HEADER_GNU_PTH_PTHREAD_H], [
[AC_EGREP_CPP(__gnu_pth__,
[#include <pthread.h>
#ifdef _POSIX_THREAD_IS_GNU_PTH
__gnu_pth__
__gnu_pth__;
#endif
],
[ol_cv_header_gnu_pth_pthread_h=yes],
......@@ -626,11 +440,21 @@ AC_DEFUN([OL_HEADER_GNU_PTH_PTHREAD_H], [
])
])dnl
dnl ====================================================================
dnl Check for NT Threads
AC_DEFUN([OL_NT_THREADS], [
AC_CHECK_FUNC(_beginthread)
if test $ac_cv_func__beginthread = yes ; then
AC_DEFINE(HAVE_NT_THREADS,1,[if you have NT Threads])
ol_cv_nt_threads=yes
fi
])
dnl ====================================================================
dnl Check LinuxThreads Header
dnl
dnl defines ol_cv_header linux_threads to 'yes' or 'no'
dnl 'no' implies pthreads.h is not LinuxThreads or pthreads.h
dnl doesn't exists. Existance of pthread.h should separately
dnl doesn't exist. Existence of pthread.h should separately
dnl checked.
dnl
AC_DEFUN([OL_HEADER_LINUX_THREADS], [
......@@ -652,7 +476,7 @@ dnl defines ol_cv_sys_linux_threads to 'yes' or 'no'
dnl 'no' implies pthreads implementation is not LinuxThreads.
dnl
AC_DEFUN([OL_SYS_LINUX_THREADS], [
AC_CHECK_FUNC(pthread_kill_other_threads_np)
AC_CHECK_FUNCS(pthread_kill_other_threads_np)
AC_CACHE_CHECK([for LinuxThreads implementation],
[ol_cv_sys_linux_threads],
[ol_cv_sys_linux_threads=$ac_cv_func_pthread_kill_other_threads_np])
......@@ -664,11 +488,11 @@ AC_DEFUN([OL_LINUX_THREADS], [
AC_REQUIRE([OL_HEADER_LINUX_THREADS])
AC_REQUIRE([OL_SYS_LINUX_THREADS])
AC_CACHE_CHECK([for LinuxThreads consistency], [ol_cv_linux_threads], [
if test $ol_cv_header_linux_threads = yes -a \
$ol_cv_sys_linux_threads = yes; then
if test $ol_cv_header_linux_threads = yes &&
test $ol_cv_sys_linux_threads = yes; then
ol_cv_linux_threads=yes
elif test $ol_cv_header_linux_threads = no -a \
$ol_cv_sys_linux_threads = no; then
elif test $ol_cv_header_linux_threads = no &&
test $ol_cv_sys_linux_threads = no; then
ol_cv_linux_threads=no
else
ol_cv_linux_threads=error
......@@ -680,11 +504,11 @@ dnl ====================================================================
dnl Check for POSIX Regex
AC_DEFUN([OL_POSIX_REGEX], [
AC_CACHE_CHECK([for compatible POSIX regex],ol_cv_c_posix_regex,[
AC_TRY_RUN([
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <sys/types.h>
#include <regex.h>
static char *pattern, *string;
main()
int main(void)
{
int rc;
regex_t re;
......@@ -702,75 +526,107 @@ main()
regfree(&re);
return rc;
}],
[ol_cv_c_posix_regex=yes],
[ol_cv_c_posix_regex=no],
[ol_cv_c_posix_regex=cross])])
}]])],[ol_cv_c_posix_regex=yes],[ol_cv_c_posix_regex=no],[ol_cv_c_posix_regex=cross])])
])
dnl
dnl ====================================================================
dnl Check if toupper() requires islower() to be called first
AC_DEFUN([OL_C_UPPER_LOWER],
[AC_CACHE_CHECK([if toupper() requires islower()],ol_cv_c_upper_lower,[
AC_TRY_RUN([
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <ctype.h>
main()
#include <stdlib.h>
int main(void)
{
if ('C' == toupper('C'))
exit(0);
else
exit(1);
}],
[ol_cv_c_upper_lower=no],
[ol_cv_c_upper_lower=yes],
[ol_cv_c_upper_lower=safe])])
}]])],[ol_cv_c_upper_lower=no],[ol_cv_c_upper_lower=yes],[ol_cv_c_upper_lower=safe])])
if test $ol_cv_c_upper_lower != no ; then
AC_DEFINE(C_UPPER_LOWER,1, [define if toupper() requires islower()])
fi
])
dnl
dnl ====================================================================
dnl Error string checks
dnl
dnl Check for declaration of sys_errlist in one of stdio.h and errno.h.
dnl Declaration of sys_errlist on BSD4.4 interferes with our declaration.
dnl Reported by Keith Bostic.
AC_DEFUN([OL_SYS_ERRLIST],
[AC_CACHE_CHECK([declaration of sys_errlist],ol_cv_dcl_sys_errlist,[
AC_TRY_COMPILE([
[AC_CACHE_CHECK([existence of sys_errlist],ol_cv_have_sys_errlist,[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <errno.h>]], [[char *c = (char *) *sys_errlist]])],[ol_cv_have_sys_errlist=yes],[ol_cv_have_sys_errlist=no])])
if test $ol_cv_have_sys_errlist = yes ; then
AC_DEFINE(HAVE_SYS_ERRLIST,1,
[define if you actually have sys_errlist in your libs])
AC_CACHE_CHECK([declaration of sys_errlist],ol_cv_dcl_sys_errlist,[
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#include <sys/types.h>
#include <errno.h> ],
[char *c = (char *) *sys_errlist],
[ol_cv_dcl_sys_errlist=yes
ol_cv_have_sys_errlist=yes],
#include <errno.h>
#ifdef _WIN32
#include <stdlib.h>
#endif ]], [[char *c = (char *) *sys_errlist]])],[ol_cv_dcl_sys_errlist=yes],
[ol_cv_dcl_sys_errlist=no])])
#
# It's possible (for near-UNIX clones) that sys_errlist doesn't exist
if test $ol_cv_dcl_sys_errlist = no ; then
AC_DEFINE(DECL_SYS_ERRLIST,1,
[define if sys_errlist is not declared in stdio.h or errno.h])
AC_CACHE_CHECK([existence of sys_errlist],ol_cv_have_sys_errlist,[
AC_TRY_LINK([#include <errno.h>],
[char *c = (char *) *sys_errlist],
[ol_cv_have_sys_errlist=yes],
[ol_cv_have_sys_errlist=no])])
# It's possible (for near-UNIX clones) that sys_errlist doesn't exist
if test $ol_cv_dcl_sys_errlist = no ; then
AC_DEFINE(DECL_SYS_ERRLIST,1,
[define if sys_errlist is not declared in stdio.h or errno.h])
fi
fi
if test $ol_cv_have_sys_errlist = yes ; then
AC_DEFINE(HAVE_SYS_ERRLIST,1,
[define if you actually have sys_errlist in your libs])
])dnl
dnl
dnl ====================================================================
dnl glibc supplies a non-standard strerror_r if _GNU_SOURCE is defined.
dnl It's actually preferable to the POSIX version, if available.
AC_DEFUN([OL_NONPOSIX_STRERROR_R],
[AC_CACHE_CHECK([non-posix strerror_r],ol_cv_nonposix_strerror_r,[
AC_EGREP_CPP(strerror_r,[#include <string.h>],
ol_decl_strerror_r=yes, ol_decl_strerror_r=no)dnl
if test $ol_decl_strerror_r = yes ; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <string.h>]], [[ /* from autoconf 2.59 */
char buf[100];
char x = *strerror_r (0, buf, sizeof buf);
char *p = strerror_r (0, buf, sizeof buf);
]])],[ol_cv_nonposix_strerror_r=yes],[ol_cv_nonposix_strerror_r=no])
else
AC_RUN_IFELSE([AC_LANG_SOURCE([[
int main(void) {
char buf[100];
buf[0] = 0;
strerror_r( 1, buf, sizeof buf );
exit( buf[0] == 0 );
}
]])],[ol_cv_nonposix_strerror_r=yes],[ol_cv_nonposix_strerror_r=no],[ol_cv_nonposix_strerror_r=no])
fi
])
if test $ol_cv_nonposix_strerror_r = yes ; then
AC_DEFINE(HAVE_NONPOSIX_STRERROR_R,1,
[define if strerror_r returns char* instead of int])
fi
])dnl
dnl
AC_DEFUN([OL_STRERROR],
[AC_CHECK_FUNCS(strerror strerror_r)
ol_cv_func_strerror_r=no
if test "${ac_cv_func_strerror_r}" = yes ; then
OL_NONPOSIX_STRERROR_R
elif test "${ac_cv_func_strerror}" = no ; then
OL_SYS_ERRLIST
fi
])dnl
dnl ====================================================================
dnl Early MIPS compilers (used in Ultrix 4.2) don't like
dnl "int x; int *volatile a = &x; *a = 0;"
dnl -- borrowed from PDKSH
AC_DEFUN(OL_C_VOLATILE,
AC_DEFUN([OL_C_VOLATILE],
[AC_CACHE_CHECK(if compiler understands volatile, ol_cv_c_volatile,
[AC_TRY_COMPILE([int x, y, z;],
[volatile int a; int * volatile b = x ? &y : &z;
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int x, y, z;]], [[volatile int a; int * volatile b = x ? &y : &z;
/* Older MIPS compilers (eg., in Ultrix 4.2) don't like *b = 0 */
*b = 0;], ol_cv_c_volatile=yes, ol_cv_c_volatile=no)])
*b = 0;]])],[ol_cv_c_volatile=yes],[ol_cv_c_volatile=no])])
if test $ol_cv_c_volatile = yes; then
:
else
......@@ -781,60 +637,28 @@ dnl
dnl ====================================================================
dnl Look for fetch(3)
AC_DEFUN([OL_LIB_FETCH],
[ol=$LIBS
LIBS="-lfetch -lcom_err $LIBS"
[ol_LIBS=$LIBS
LIBS="-lfetch $LIBS"
AC_CACHE_CHECK([fetch(3) library],ol_cv_lib_fetch,[
AC_TRY_LINK([
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <stdio.h>
#include <fetch.h>],
[struct url *u = fetchParseURL("file:///"); ],
[ol_cv_lib_fetch=yes],
[ol_cv_lib_fetch=no])])
#include <fetch.h>]], [[struct url *u = fetchParseURL("file:///"); ]])],[ol_cv_lib_fetch=yes],[ol_cv_lib_fetch=no])])
LIBS=$ol_LIBS
if test $ol_cv_lib_fetch != no ; then
ol_link_fetch="-lfetch -lcom_err"
ol_link_fetch="-lfetch"
AC_DEFINE(HAVE_FETCH,1,
[define if you actually have FreeBSD fetch(3)])
fi
])dnl
dnl
dnl ====================================================================
dnl Define sig_atomic_t if not defined in signal.h
AC_DEFUN(OL_TYPE_SIG_ATOMIC_T,
[AC_CACHE_CHECK(for sig_atomic_t, ol_cv_type_sig_atomic_t,
[AC_TRY_COMPILE([#include <signal.h>], [sig_atomic_t atomic;],
ol_cv_type_sig_atomic_t=yes, ol_cv_type_sig_atomic_t=no)])
if test $ol_cv_type_sig_atomic_t = no; then
AC_DEFINE(sig_atomic_t,int,
[define to atomic type if sig_atomic_t is not available])
fi
])dnl
dnl
dnl ====================================================================
dnl Define socklen_t if not defined in sys/types.h or sys/socket.h
AC_DEFUN(OL_TYPE_SOCKLEN_T,
[AC_CACHE_CHECK(for socklen_t, ol_cv_type_socklen_t,
[AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
], [socklen_t len;],
ol_cv_type_socklen_t=yes, ol_cv_type_socklen_t=no)])
if test $ol_cv_type_socklen_t = no; then
AC_DEFINE(socklen_t, int,
[define to int if socklen_t is not available])
fi
])dnl
dnl
dnl ====================================================================
dnl Define inet_aton is available
AC_DEFUN(OL_FUNC_INET_ATON,
AC_DEFUN([OL_FUNC_INET_ATON],
[AC_CACHE_CHECK([for inet_aton()], ol_cv_func_inet_aton,
[AC_TRY_LINK([
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
......@@ -848,9 +672,8 @@ AC_DEFUN(OL_FUNC_INET_ATON,
# include <arpa/inet.h>
# endif
#endif
], [struct in_addr in;
int rc = inet_aton( "255.255.255.255", &in );],
ol_cv_func_inet_aton=yes, ol_cv_func_inet_aton=no)])
]], [[struct in_addr in;
int rc = inet_aton( "255.255.255.255", &in );]])],[ol_cv_func_inet_aton=yes],[ol_cv_func_inet_aton=no])])
if test $ol_cv_func_inet_aton != no; then
AC_DEFINE(HAVE_INET_ATON, 1,
[define to you inet_aton(3) is available])
......@@ -859,28 +682,38 @@ int rc = inet_aton( "255.255.255.255", &in );],
dnl
dnl ====================================================================
dnl check no of arguments for ctime_r
AC_DEFUN(OL_FUNC_CTIME_R_NARGS,
AC_DEFUN([OL_FUNC_CTIME_R_NARGS],
[AC_CACHE_CHECK(number of arguments of ctime_r, ol_cv_func_ctime_r_nargs,
[AC_TRY_COMPILE([#include <time.h>],
[time_t ti; char *buffer; ctime_r(&ti,buffer,32);],
ol_cv_func_ctime_r_nargs=3,
[AC_TRY_COMPILE([#include <time.h>],
[time_t ti; char *buffer; ctime_r(&ti,buffer);],
ol_cv_func_ctime_r_nargs=2,
ol_cv_func_ctime_r_nargs=0)])])
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[time_t ti; char *buffer; ctime_r(&ti,buffer,32);]])],[ol_cv_func_ctime_r_nargs3=yes],[ol_cv_func_ctime_r_nargs3=no])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[time_t ti; char *buffer; ctime_r(&ti,buffer);]])],[ol_cv_func_ctime_r_nargs2=yes],[ol_cv_func_ctime_r_nargs2=no])
if test $ol_cv_func_ctime_r_nargs3 = yes &&
test $ol_cv_func_ctime_r_nargs2 = no ; then
ol_cv_func_ctime_r_nargs=3
elif test $ol_cv_func_ctime_r_nargs3 = no &&
test $ol_cv_func_ctime_r_nargs2 = yes ; then
ol_cv_func_ctime_r_nargs=2
else
ol_cv_func_ctime_r_nargs=0
fi
])
if test $ol_cv_func_ctime_r_nargs -gt 1 ; then
AC_DEFINE_UNQUOTED(CTIME_R_NARGS, $ol_cv_func_ctime_r_nargs,
AC_DEFINE_UNQUOTED(CTIME_R_NARGS, $ol_cv_func_ctime_r_nargs,
[set to the number of arguments ctime_r() expects])
fi
])dnl
dnl
dnl --------------------------------------------------------------------
dnl check return type of ctime_r()
AC_DEFUN(OL_FUNC_CTIME_R_TYPE,
AC_DEFUN([OL_FUNC_CTIME_R_TYPE],
[AC_CACHE_CHECK(return type of ctime_r, ol_cv_func_ctime_r_type,
[AC_TRY_COMPILE([#include <time.h>],
[extern int (ctime_r)();],
ol_cv_func_ctime_r_type="int", ol_cv_func_ctime_r_type="charp")
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[extern int (ctime_r)();]])],[ol_cv_func_ctime_r_type="int"],[ol_cv_func_ctime_r_type="charp"])
])
if test $ol_cv_func_ctime_r_type = "int" ; then
AC_DEFINE(CTIME_R_RETURNS_INT,1, [define if ctime_r() returns int])
......@@ -888,31 +721,42 @@ AC_DEFUN(OL_FUNC_CTIME_R_TYPE,
])dnl
dnl ====================================================================
dnl check no of arguments for gethostbyname_r
AC_DEFUN(OL_FUNC_GETHOSTBYNAME_R_NARGS,
AC_DEFUN([OL_FUNC_GETHOSTBYNAME_R_NARGS],
[AC_CACHE_CHECK(number of arguments of gethostbyname_r,
ol_cv_func_gethostbyname_r_nargs,
[AC_TRY_COMPILE([#include <sys/types.h>
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define BUFSIZE (sizeof(struct hostent)+10)],
[struct hostent hent; char buffer[BUFSIZE];
#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent; char buffer[BUFSIZE];
int bufsize=BUFSIZE;int h_errno;
(void)gethostbyname_r("segovia.cs.purdue.edu", &hent,
buffer, bufsize, &h_errno);],
ol_cv_func_gethostbyname_r_nargs=5,
[AC_TRY_COMPILE([#include <sys/types.h>
buffer, bufsize, &h_errno);]])],[ol_cv_func_gethostbyname_r_nargs5=yes],[ol_cv_func_gethostbyname_r_nargs5=no])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define BUFSIZE (sizeof(struct hostent)+10)],
[struct hostent hent;struct hostent *rhent;
char buffer[BUFSIZE];
int bufsize=BUFSIZE;int h_errno;
(void)gethostbyname_r("localhost", &hent, buffer, bufsize,
&rhent, &h_errno);],
ol_cv_func_gethostbyname_r_nargs=6,
ol_cv_func_gethostbyname_r_nargs=0)])])
#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent;struct hostent *rhent;
char buffer[BUFSIZE];
int bufsize=BUFSIZE;int h_errno;
(void)gethostbyname_r("localhost", &hent, buffer, bufsize,
&rhent, &h_errno);]])],[ol_cv_func_gethostbyname_r_nargs6=yes],[ol_cv_func_gethostbyname_r_nargs6=no])
if test $ol_cv_func_gethostbyname_r_nargs5 = yes &&
test $ol_cv_func_gethostbyname_r_nargs6 = no ; then
ol_cv_func_gethostbyname_r_nargs=5
elif test $ol_cv_func_gethostbyname_r_nargs5 = no &&
test $ol_cv_func_gethostbyname_r_nargs6 = yes ; then
ol_cv_func_gethostbyname_r_nargs=6
else
ol_cv_func_gethostbyname_r_nargs=0
fi
])
if test $ol_cv_func_gethostbyname_r_nargs -gt 1 ; then
AC_DEFINE_UNQUOTED(GETHOSTBYNAME_R_NARGS,
$ol_cv_func_gethostbyname_r_nargs,
......@@ -921,36 +765,47 @@ AC_DEFUN(OL_FUNC_GETHOSTBYNAME_R_NARGS,
])dnl
dnl
dnl check no of arguments for gethostbyaddr_r
AC_DEFUN(OL_FUNC_GETHOSTBYADDR_R_NARGS,
AC_DEFUN([OL_FUNC_GETHOSTBYADDR_R_NARGS],
[AC_CACHE_CHECK(number of arguments of gethostbyaddr_r,
[ol_cv_func_gethostbyaddr_r_nargs],
[AC_TRY_COMPILE([#include <sys/types.h>
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define BUFSIZE (sizeof(struct hostent)+10)],
[struct hostent hent; char buffer[BUFSIZE];
#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent; char buffer[BUFSIZE];
struct in_addr add;
size_t alen=sizeof(struct in_addr);
int bufsize=BUFSIZE;int h_errno;
(void)gethostbyaddr_r( (void *)&(add.s_addr),
alen, AF_INET, &hent, buffer, bufsize, &h_errno);],
ol_cv_func_gethostbyaddr_r_nargs=7,
[AC_TRY_COMPILE([#include <sys/types.h>
alen, AF_INET, &hent, buffer, bufsize, &h_errno);]])],[ol_cv_func_gethostbyaddr_r_nargs7=yes],[ol_cv_func_gethostbyaddr_r_nargs7=no])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define BUFSIZE (sizeof(struct hostent)+10)],
[struct hostent hent;
struct hostent *rhent; char buffer[BUFSIZE];
struct in_addr add;
size_t alen=sizeof(struct in_addr);
int bufsize=BUFSIZE;int h_errno;
(void)gethostbyaddr_r( (void *)&(add.s_addr),
alen, AF_INET, &hent, buffer, bufsize,
&rhent, &h_errno);],
ol_cv_func_gethostbyaddr_r_nargs=8,
ol_cv_func_gethostbyaddr_r_nargs=0)])])
#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent;
struct hostent *rhent; char buffer[BUFSIZE];
struct in_addr add;
size_t alen=sizeof(struct in_addr);
int bufsize=BUFSIZE;int h_errno;
(void)gethostbyaddr_r( (void *)&(add.s_addr),
alen, AF_INET, &hent, buffer, bufsize,
&rhent, &h_errno);]])],[ol_cv_func_gethostbyaddr_r_nargs8=yes],[ol_cv_func_gethostbyaddr_r_nargs8=no])
if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes &&
test $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then
ol_cv_func_gethostbyaddr_r_nargs=7
elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no &&
test $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then
ol_cv_func_gethostbyaddr_r_nargs=8
else
ol_cv_func_gethostbyaddr_r_nargs=0
fi
])
if test $ol_cv_func_gethostbyaddr_r_nargs -gt 1 ; then
AC_DEFINE_UNQUOTED(GETHOSTBYADDR_R_NARGS,
$ol_cv_func_gethostbyaddr_r_nargs,
......@@ -958,3 +813,23 @@ AC_DEFUN(OL_FUNC_GETHOSTBYADDR_R_NARGS,
fi
])dnl
dnl
dnl --------------------------------------------------------------------
dnl Check for Cyrus SASL version compatibility
AC_DEFUN([OL_SASL_COMPAT],
[AC_CACHE_CHECK([Cyrus SASL library version], [ol_cv_sasl_compat],[
AC_EGREP_CPP(__sasl_compat,[
#ifdef HAVE_SASL_SASL_H
#include <sasl/sasl.h>
#else
#include <sasl.h>
#endif
/* Require 2.1.15+ */
#if SASL_VERSION_MAJOR == 2 && SASL_VERSION_MINOR > 1
char *__sasl_compat = "2.2+ or better okay (we guess)";
#elif SASL_VERSION_MAJOR == 2 && SASL_VERSION_MINOR == 1 \
&& SASL_VERSION_STEP >=15
char *__sasl_compat = "2.1.15+ or better okay";
#endif
], [ol_cv_sasl_compat=yes], [ol_cv_sasl_compat=no])])
])
## Copyright 1998,1999 The OpenLDAP Foundation
## COPYING RESTRICTIONS APPLY. See COPYRIGHT File in top level directory
## of this package for details.
##---------------------------------------------------------------------------
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Makefile Template for Programs
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
##---------------------------------------------------------------------------
#
# Makefile Template for Programs
#
all-common: $(PROGRAMS) FORCE
clean-common: FORCE
$(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o *.lo a.out core *.core .libs/*
$(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o *.lo a.out core *.core \
.libs/* *.exe
depend-common: FORCE
$(MKDEP) $(DEFS) $(DEFINES) $(SRCS)
......
#!/bin/sh
##
## GNU shtool -- The GNU Portable Shell Tool
## Copyright (c) 1994-2008 Ralf S. Engelschall <rse@engelschall.com>
##
## See http://www.gnu.org/software/shtool/ for more information.
## See ftp://ftp.gnu.org/gnu/shtool/ for latest version.
##
## Version: 2.0.8 (18-Jul-2008)
## Contents: 6/19 available modules
##
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
## USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
##
## NOTICE: Given that you include this file verbatim into your own
## source tree, you are justified in saying that it remains separate
## from your package, and that this way you are simply just using GNU
## shtool. So, in this situation, there is no requirement that your
## package itself is licensed under the GNU General Public License in
## order to take advantage of GNU shtool.
##
##
## Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]
##
## Available commands:
## echo Print string with optional construct expansion
## move Move files with simultaneous substitution
## install Install a program, script or datafile
## mkdir Make one or more directories
## mkln Make link with calculation of relative paths
## subst Apply sed(1) substitution operations
##
## Not available commands (because module was not built-in):
## mdate Pretty-print modification time of a file or dir
## table Pretty-print a field-separated list as a table
## prop Display progress with a running propeller
## mkshadow Make a shadow tree through symbolic links
## fixperm Fix file permissions inside a source tree
## rotate Logfile rotation
## tarball Roll distribution tarballs
## platform Platform Identification Utility
## arx Extended archive command
## slo Separate linker options by library class
## scpp Sharing C Pre-Processor
## version Maintain a version information file
## path Deal with program paths
##
# maximum Bourne-Shell compatibility
if [ ".$ZSH_VERSION" != . ] && (emulate sh) >/dev/null 2>&1; then
# reconfigure zsh(1)
emulate sh
NULLCMD=:
alias -g '${1+"$@"}'='"$@"'
elif [ ".$BASH_VERSION" != . ] && (set -o posix) >/dev/null 2>&1; then
# reconfigure bash(1)
set -o posix
fi
# maximum independence of NLS nuisances
for var in \
LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
LC_TELEPHONE LC_TIME
do
if (set +x; test -z "`(eval $var=C; export $var) 2>&1`"); then
eval $var=C; export $var
else
unset $var
fi
done
# initial command line handling
if [ $# -eq 0 ]; then
echo "$0:Error: invalid command line" 1>&2
echo "$0:Hint: run \`$0 -h' for usage" 1>&2
exit 1
fi
if [ ".$1" = ".-h" ] || [ ".$1" = ".--help" ]; then
echo "This is GNU shtool, version 2.0.8 (18-Jul-2008)"
echo 'Copyright (c) 1994-2008 Ralf S. Engelschall <rse@engelschall.com>'
echo 'Report bugs to <bug-shtool@gnu.org>'
echo ''
echo 'Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]'
echo ''
echo 'Available global <options>:'
echo ' -v, --version display shtool version information'
echo ' -h, --help display shtool usage help page (this one)'
echo ' -d, --debug display shell trace information'
echo ' -r, --recreate recreate this shtool script via shtoolize'
echo ''
echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
echo ' echo [-n|--newline] [-e|--expand] [<string> ...]'
echo ' move [-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve]'
echo ' <src-file> <dst-file>'
echo ' install [-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy]'
echo ' [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>]'
echo ' [-o|--owner <owner>] [-g|--group <group>] [-e|--exec'
echo ' <sed-cmd>] <file> [<file> ...] <path>'
echo ' mkdir [-t|--trace] [-f|--force] [-p|--parents] [-m|--mode'
echo ' <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir>'
echo ' [<dir> ...]'
echo ' mkln [-t|--trace] [-f|--force] [-s|--symbolic] <src-path>'
echo ' [<src-path> ...] <dst-path>'
echo ' subst [-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning]'
echo ' [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup'
echo ' <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>]'
echo ' [...]'
echo ''
echo 'Not available <cmd-name> (because module was not built-in):'
echo ' mdate [-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits]'
echo ' [-f|--field-sep <str>] [-o|--order <spec>] <path>'
echo ' table [-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns'
echo ' <cols>] [-s|--strip <strip>] <str><sep><str>...'
echo ' prop [-p|--prefix <str>]'
echo ' mkshadow [-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>'
echo ' fixperm [-v|--verbose] [-t|--trace] <path> [<path> ...]'
echo ' rotate [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files'
echo ' <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]'
echo ' [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]'
echo ' [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode'
echo ' <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate'
echo ' <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]'
echo ' tarball [-t|--trace] [-v|--verbose] [-o|--output <tarball>]'
echo ' [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user'
echo ' <user>] [-g|--group <group>] [-e|--exclude <pattern>]'
echo ' <path> [<path> ...]'
echo ' platform [-F|--format <format>] [-S|--sep <string>] [-C|--conc'
echo ' <string>] [-L|--lower] [-U|--upper] [-v|--verbose]'
echo ' [-c|--concise] [-n|--no-newline] [-t|--type <type>]'
echo ' [-V|--version] [-h|--help]'
echo ' arx [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>'
echo ' ...]'
echo ' slo [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>'
echo ' ...]'
echo ' scpp [-v|--verbose] [-p|--preserve] [-f|--filter <filter>]'
echo ' [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark'
echo ' <mark>] [-D|--define <dname>] [-C|--class <cname>]'
echo ' <file> [<file> ...]'
echo ' version [-l|--language <lang>] [-n|--name <name>] [-p|--prefix'
echo ' <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase'
echo ' <knob>] [-d|--display <type>] <file>'
echo ' path [-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename]'
echo ' [-m|--magic] [-p|--path <path>] <str> [<str> ...]'
echo ''
exit 0
fi
if [ ".$1" = ".-v" ] || [ ".$1" = ".--version" ]; then
echo "GNU shtool 2.0.8 (18-Jul-2008)"
exit 0
fi
if [ ".$1" = ".-r" ] || [ ".$1" = ".--recreate" ]; then
shtoolize -oshtool echo move install mkdir mkln subst
exit 0
fi
if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then
shift
set -x
fi
name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'`
case "$name" in
echo|move|install|mkdir|mkln|subst )
# implicit tool command selection
tool="$name"
;;
* )
# explicit tool command selection
tool="$1"
shift
;;
esac
arg_spec=""
opt_spec=""
gen_tmpfile=no
##
## DISPATCH INTO SCRIPT PROLOG
##
case $tool in
echo )
str_tool="echo"
str_usage="[-n|--newline] [-e|--expand] [<string> ...]"
arg_spec="0+"
opt_spec="n.e."
opt_alias="n:newline,e:expand"
opt_n=no
opt_e=no
;;
move )
str_tool="move"
str_usage="[-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve] <src-file> <dst-file>"
arg_spec="2="
opt_spec="v.t.e.p."
opt_alias="v:verbose,t:trace,e:expand,p:preserve"
opt_v=no
opt_t=no
opt_e=no
opt_p=no
;;
install )
str_tool="install"
str_usage="[-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy] [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] [-e|--exec <sed-cmd>] <file> [<file> ...] <path>"
arg_spec="1+"
opt_spec="v.t.d.c.C.s.m:o:g:e+"
opt_alias="v:verbose,t:trace,d:mkdir,c:copy,C:compare-copy,s:strip,m:mode,o:owner,g:group,e:exec"
opt_v=no
opt_t=no
opt_d=no
opt_c=no
opt_C=no
opt_s=no
opt_m="0755"
opt_o=""
opt_g=""
opt_e=""
;;
mkdir )
str_tool="mkdir"
str_usage="[-t|--trace] [-f|--force] [-p|--parents] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir> [<dir> ...]"
arg_spec="1+"
opt_spec="t.f.p.m:o:g:"
opt_alias="t:trace,f:force,p:parents,m:mode,o:owner,g:group"
opt_t=no
opt_f=no
opt_p=no
opt_m=""
opt_o=""
opt_g=""
;;
mkln )
str_tool="mkln"
str_usage="[-t|--trace] [-f|--force] [-s|--symbolic] <src-path> [<src-path> ...] <dst-path>"
arg_spec="2+"
opt_spec="t.f.s."
opt_alias="t:trace,f:force,s:symbolic"
opt_t=no
opt_f=no
opt_s=no
;;
subst )
str_tool="subst"
str_usage="[-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning] [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>] [...]"
gen_tmpfile=yes
arg_spec="0+"
opt_spec="v.t.n.w.q.s.i.b:e+f:"
opt_alias="v:verbose,t:trace,n:nop,w:warning,q:quiet,s:stealth,i:interactive,b:backup,e:exec,f:file"
opt_v=no
opt_t=no
opt_n=no
opt_w=no
opt_q=no
opt_s=no
opt_i=no
opt_b=""
opt_e=""
opt_f=""
;;
-* )
echo "$0:Error: unknown option \`$tool'" 2>&1
echo "$0:Hint: run \`$0 -h' for usage" 2>&1
exit 1
;;
* )
echo "$0:Error: unknown command \`$tool'" 2>&1
echo "$0:Hint: run \`$0 -h' for usage" 2>&1
exit 1
;;
esac
##
## COMMON UTILITY CODE
##
# commonly used ASCII values
ASC_TAB=" "
ASC_NL="
"
# determine name of tool
if [ ".$tool" != . ]; then
# used inside shtool script
toolcmd="$0 $tool"
toolcmdhelp="shtool $tool"
msgprefix="shtool:$tool"
else
# used as standalone script
toolcmd="$0"
toolcmdhelp="sh $0"
msgprefix="$str_tool"
fi
# parse argument specification string
eval `echo $arg_spec |\
sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
# parse option specification string
eval `echo h.$opt_spec |\
sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
# parse option alias string
eval `echo h:help,$opt_alias |\
sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
# iterate over argument line
opt_PREV=''
while [ $# -gt 0 ]; do
# special option stops processing
if [ ".$1" = ".--" ]; then
shift
break
fi
# determine option and argument
opt_ARG_OK=no
if [ ".$opt_PREV" != . ]; then
# merge previous seen option with argument
opt_OPT="$opt_PREV"
opt_ARG="$1"
opt_ARG_OK=yes
opt_PREV=''
else
# split argument into option and argument
case "$1" in
--[a-zA-Z0-9]*=*)
eval `echo "x$1" |\
sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
;;
--[a-zA-Z0-9]*)
opt_OPT=`echo "x$1" | cut -c4-`
opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
opt_ARG=''
;;
-[a-zA-Z0-9]*)
eval `echo "x$1" |\
sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
-e 's/";\(.*\)$/"; opt_ARG="\1"/'`
;;
-[a-zA-Z0-9])
opt_OPT=`echo "x$1" | cut -c3-`
opt_ARG=''
;;
*)
break
;;
esac
fi
# eat up option
shift
# determine whether option needs an argument
eval "opt_MODE=\$opt_MODE_${opt_OPT}"
if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
opt_PREV="$opt_OPT"
continue
fi
fi
# process option
case $opt_MODE in
'.' )
# boolean option
eval "opt_${opt_OPT}=yes"
;;
':' )
# option with argument (multiple occurrences override)
eval "opt_${opt_OPT}=\"\$opt_ARG\""
;;
'+' )
# option with argument (multiple occurrences append)
eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\""
;;
* )
echo "$msgprefix:Error: unknown option: \`$opt_OPT'" 1>&2
echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
exit 1
;;
esac
done
if [ ".$opt_PREV" != . ]; then
echo "$msgprefix:Error: missing argument to option \`$opt_PREV'" 1>&2
echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
exit 1
fi
# process help option
if [ ".$opt_h" = .yes ]; then
echo "Usage: $toolcmdhelp $str_usage"
exit 0
fi
# complain about incorrect number of arguments
case $arg_MODE in
'=' )
if [ $# -ne $arg_NUMS ]; then
echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2
exit 1
fi
;;
'+' )
if [ $# -lt $arg_NUMS ]; then
echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2
exit 1
fi
;;
esac
# establish a temporary file on request
if [ ".$gen_tmpfile" = .yes ]; then
# create (explicitly) secure temporary directory
if [ ".$TMPDIR" != . ]; then
tmpdir="$TMPDIR"
elif [ ".$TEMPDIR" != . ]; then
tmpdir="$TEMPDIR"
else
tmpdir="/tmp"
fi
tmpdir="$tmpdir/.shtool.$$"
( umask 077
rm -rf "$tmpdir" >/dev/null 2>&1 || true
mkdir "$tmpdir" >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$msgprefix:Error: failed to create temporary directory \`$tmpdir'" 1>&2
exit 1
fi
)
# create (implicitly) secure temporary file
tmpfile="$tmpdir/shtool.tmp"
touch "$tmpfile"
fi
# utility function: map string to lower case
util_lower () {
echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
}
# utility function: map string to upper case
util_upper () {
echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
# cleanup procedure
shtool_exit () {
rc="$1"
if [ ".$gen_tmpfile" = .yes ]; then
rm -rf "$tmpdir" >/dev/null 2>&1 || true
fi
exit $rc
}
##
## DISPATCH INTO SCRIPT BODY
##
case $tool in
echo )
##
## echo -- Print string with optional construct expansion
## Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
##
text="$*"
# check for broken escape sequence expansion
seo=''
bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
if [ ".$bytes" != .3 ]; then
bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'`
if [ ".$bytes" = .3 ]; then
seo='-E'
fi
fi
# check for existing -n option (to suppress newline)
minusn=''
bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
if [ ".$bytes" = .3 ]; then
minusn='-n'
fi
# determine terminal bold sequence
term_bold=''
term_norm=''
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[Bb]'`" != . ]; then
case $TERM in
# for the most important terminal types we directly know the sequences
xterm|xterm*|vt220|vt220*)
term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
;;
vt100|vt100*|cygwin)
term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
;;
# for all others, we try to use a possibly existing `tput' or `tcout' utility
* )
paths=`echo $PATH | sed -e 's/:/ /g'`
for tool in tput tcout; do
for dir in $paths; do
if [ -r "$dir/$tool" ]; then
for seq in bold md smso; do # 'smso' is last
bold="`$dir/$tool $seq 2>/dev/null`"
if [ ".$bold" != . ]; then
term_bold="$bold"
break
fi
done
if [ ".$term_bold" != . ]; then
for seq in sgr0 me rmso init reset; do # 'reset' is last
norm="`$dir/$tool $seq 2>/dev/null`"
if [ ".$norm" != . ]; then
term_norm="$norm"
break
fi
done
fi
break
fi
done
if [ ".$term_bold" != . ] && [ ".$term_norm" != . ]; then
break;
fi
done
;;
esac
if [ ".$term_bold" = . ] || [ ".$term_norm" = . ]; then
echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
term_bold=''
term_norm=''
fi
fi
# determine user name
username=''
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[uUgG]'`" != . ]; then
username="`(id -un) 2>/dev/null`"
if [ ".$username" = . ]; then
str="`(id) 2>/dev/null`"
if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then
username=`echo $str | sed -e 's/^uid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'`
fi
if [ ".$username" = . ]; then
username="$LOGNAME"
if [ ".$username" = . ]; then
username="$USER"
if [ ".$username" = . ]; then
username="`(whoami) 2>/dev/null |\
awk '{ printf("%s", $1); }'`"
if [ ".$username" = . ]; then
username="`(who am i) 2>/dev/null |\
awk '{ printf("%s", $1); }'`"
if [ ".$username" = . ]; then
username='unknown'
fi
fi
fi
fi
fi
fi
fi
# determine user id
userid=''
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%U'`" != . ]; then
userid="`(id -u) 2>/dev/null`"
if [ ".$userid" = . ]; then
userid="`(id -u ${username}) 2>/dev/null`"
if [ ".$userid" = . ]; then
str="`(id) 2>/dev/null`"
if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then
userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*$//'`
fi
if [ ".$userid" = . ]; then
userid=`(getent passwd ${username}) 2>/dev/null | \
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$userid" = . ]; then
userid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$userid" = . ]; then
userid=`(ypmatch "${username}" passwd; nismatch "${username}" passwd) 2>/dev/null | \
sed -e 'q' | sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$userid" = . ]; then
userid=`(nidump passwd . | grep "^${username}:") 2>/dev/null | \
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$userid" = . ]; then
userid='?'
fi
fi
fi
fi
fi
fi
fi
fi
# determine (primary) group id
groupid=''
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then
groupid="`(id -g ${username}) 2>/dev/null`"
if [ ".$groupid" = . ]; then
str="`(id) 2>/dev/null`"
if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then
groupid=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*//' -e 's/(.*$//'`
fi
if [ ".$groupid" = . ]; then
groupid=`(getent passwd ${username}) 2>/dev/null | \
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$groupid" = . ]; then
groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$groupid" = . ]; then
groupid=`(ypmatch "${username}" passwd; nismatch "${username}" passwd) 2>/dev/null | \
sed -e 'q' | sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$groupid" = . ]; then
groupid=`(nidump passwd . | grep "^${username}:") 2>/dev/null | \
sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
if [ ".$groupid" = . ]; then
groupid='?'
fi
fi
fi
fi
fi
fi
fi
# determine (primary) group name
groupname=''
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then
groupname="`(id -gn ${username}) 2>/dev/null`"
if [ ".$groupname" = . ]; then
str="`(id) 2>/dev/null`"
if [ ".`echo $str | grep 'gid[ ]*=[ ]*[0-9]*('`" != . ]; then
groupname=`echo $str | sed -e 's/^.*gid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'`
fi
if [ ".$groupname" = . ]; then
groupname=`(getent group) 2>/dev/null | \
grep "^[^:]*:[^:]*:${groupid}:" | \
sed -e 's/:.*$//'`
if [ ".$groupname" = . ]; then
groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
sed -e 's/:.*$//'`
if [ ".$groupname" = . ]; then
groupname=`(ypcat group; niscat group) 2>/dev/null | \
sed -e 'q' | grep "^[^:]*:[^:]*:${groupid}:" | \
sed -e 's/:.*$//'`
if [ ".$groupname" = . ]; then
groupname=`(nidump group .) 2>/dev/null | \
grep "^[^:]*:[^:]*:${groupid}:" | \
sed -e 's/:.*$//'`
if [ ".$groupname" = . ]; then
groupname='?'
fi
fi
fi
fi
fi
fi
fi
# determine host and domain name
hostname=''
domainname=''
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then
hostname="`(uname -n) 2>/dev/null |\
awk '{ printf("%s", $1); }'`"
if [ ".$hostname" = . ]; then
hostname="`(hostname) 2>/dev/null |\
awk '{ printf("%s", $1); }'`"
if [ ".$hostname" = . ]; then
hostname='unknown'
fi
fi
case $hostname in
*.* )
domainname=".`echo $hostname | cut -d. -f2-`"
hostname="`echo $hostname | cut -d. -f1`"
;;
esac
fi
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then
if [ ".$domainname" = . ]; then
if [ -f /etc/resolv.conf ]; then
domainname="`grep '^[ ]*domain' /etc/resolv.conf | sed -e 'q' |\
sed -e 's/.*domain//' \
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
-e 's/^\.//' -e 's/^/./' |\
awk '{ printf("%s", $1); }'`"
if [ ".$domainname" = . ]; then
domainname="`grep '^[ ]*search' /etc/resolv.conf | sed -e 'q' |\
sed -e 's/.*search//' \
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
-e 's/ .*//' -e 's/ .*//' \
-e 's/^\.//' -e 's/^/./' |\
awk '{ printf("%s", $1); }'`"
fi
fi
fi
fi
# determine current time
time_day=''
time_month=''
time_year=''
time_monthname=''
if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then
time_day=`date '+%d'`
time_month=`date '+%m'`
time_year=`date '+%Y' 2>/dev/null`
if [ ".$time_year" = . ]; then
time_year=`date '+%y'`
case $time_year in
[5-9][0-9]) time_year="19$time_year" ;;
[0-4][0-9]) time_year="20$time_year" ;;
esac
fi
case $time_month in
1|01) time_monthname='Jan' ;;
2|02) time_monthname='Feb' ;;
3|03) time_monthname='Mar' ;;
4|04) time_monthname='Apr' ;;
5|05) time_monthname='May' ;;
6|06) time_monthname='Jun' ;;
7|07) time_monthname='Jul' ;;
8|08) time_monthname='Aug' ;;
9|09) time_monthname='Sep' ;;
10) time_monthname='Oct' ;;
11) time_monthname='Nov' ;;
12) time_monthname='Dec' ;;
esac
fi
# expand special ``%x'' constructs
if [ ".$opt_e" = .yes ]; then
text=`echo $seo "$text" |\
sed -e "s/%B/${term_bold}/g" \
-e "s/%b/${term_norm}/g" \
-e "s/%u/${username}/g" \
-e "s/%U/${userid}/g" \
-e "s/%g/${groupname}/g" \
-e "s/%G/${groupid}/g" \
-e "s/%h/${hostname}/g" \
-e "s/%d/${domainname}/g" \
-e "s/%D/${time_day}/g" \
-e "s/%M/${time_month}/g" \
-e "s/%Y/${time_year}/g" \
-e "s/%m/${time_monthname}/g" 2>/dev/null`
fi
# create output
if [ .$opt_n = .no ]; then
echo $seo "$text"
else
# the harder part: echo -n is best, because
# awk may complain about some \xx sequences.
if [ ".$minusn" != . ]; then
echo $seo $minusn "$text"
else
echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
fi
fi
shtool_exit 0
;;
move )
##
## move -- Move files with simultaneous substitution
## Copyright (c) 1999-2008 Ralf S. Engelschall <rse@engelschall.com>
##
src="$1"
dst="$2"
# consistency checks
if [ ".$src" = . ] || [ ".$dst" = . ]; then
echo "$msgprefix:Error: Invalid arguments" 1>&2
shtool_exit 1
fi
if [ ".$src" = ".$dst" ]; then
echo "$msgprefix:Error: Source and destination files are the same" 1>&2
shtool_exit 1
fi
expsrc="$src"
if [ ".$opt_e" = .yes ]; then
expsrc="`echo $expsrc`"
fi
if [ ".$opt_e" = .yes ]; then
if [ ".`echo "$src" | sed -e 's;^.*\\*.*$;;'`" = ".$src" ]; then
echo "$msgprefix:Error: Source doesn't contain wildcard ('*'): $dst" 1>&2
shtool_exit 1
fi
if [ ".`echo "$dst" | sed -e 's;^.*%[1-9].*$;;'`" = ".$dst" ]; then
echo "$msgprefix:Error: Destination doesn't contain substitution ('%N'): $dst" 1>&2
shtool_exit 1
fi
if [ ".$expsrc" = ".$src" ]; then
echo "$msgprefix:Error: Sources not found or no asterisk : $src" 1>&2
shtool_exit 1
fi
else
if [ ! -r "$src" ]; then
echo "$msgprefix:Error: Source not found: $src" 1>&2
shtool_exit 1
fi
fi
# determine substitution patterns
if [ ".$opt_e" = .yes ]; then
srcpat=`echo "$src" | sed -e 's/\\./\\\\./g' -e 's/;/\\;/g' -e 's;\\*;\\\\(.*\\\\);g'`
dstpat=`echo "$dst" | sed -e 's;%\([1-9]\);\\\\\1;g'`
fi
# iterate over source(s)
for onesrc in $expsrc; do
if [ .$opt_e = .yes ]; then
onedst=`echo $onesrc | sed -e "s;$srcpat;$dstpat;"`
else
onedst="$dst"
fi
errorstatus=0
if [ ".$opt_v" = .yes ]; then
echo "$onesrc -> $onedst"
fi
if [ ".$opt_p" = .yes ]; then
if [ -r $onedst ]; then
if cmp -s $onesrc $onedst; then
if [ ".$opt_t" = .yes ]; then
echo "rm -f $onesrc" 1>&2
fi
rm -f $onesrc || errorstatus=$?
else
if [ ".$opt_t" = .yes ]; then
echo "mv -f $onesrc $onedst" 1>&2
fi
mv -f $onesrc $onedst || errorstatus=$?
fi
else
if [ ".$opt_t" = .yes ]; then
echo "mv -f $onesrc $onedst" 1>&2
fi
mv -f $onesrc $onedst || errorstatus=$?
fi
else
if [ ".$opt_t" = .yes ]; then
echo "mv -f $onesrc $onedst" 1>&2
fi
mv -f $onesrc $onedst || errorstatus=$?
fi
if [ $errorstatus -ne 0 ]; then
break;
fi
done
shtool_exit $errorstatus
;;
install )
##
## install -- Install a program, script or datafile
## Copyright (c) 1997-2008 Ralf S. Engelschall <rse@engelschall.com>
##
# special case: "shtool install -d <dir> [...]" internally
# maps to "shtool mkdir -f -p -m 755 <dir> [...]"
if [ "$opt_d" = yes ]; then
cmd="$0 mkdir -f -p -m 755"
if [ ".$opt_o" != . ]; then
cmd="$cmd -o '$opt_o'"
fi
if [ ".$opt_g" != . ]; then
cmd="$cmd -g '$opt_g'"
fi
if [ ".$opt_v" = .yes ]; then
cmd="$cmd -v"
fi
if [ ".$opt_t" = .yes ]; then
cmd="$cmd -t"
fi
for dir in "$@"; do
eval "$cmd $dir" || shtool_exit $?
done
shtool_exit 0
fi
# determine source(s) and destination
argc=$#
srcs=""
while [ $# -gt 1 ]; do
srcs="$srcs $1"
shift
done
dstpath="$1"
# type check for destination
dstisdir=0
if [ -d $dstpath ]; then
dstpath=`echo "$dstpath" | sed -e 's:/$::'`
dstisdir=1
fi
# consistency check for destination
if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then
echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2
shtool_exit 1
fi
# iterate over all source(s)
for src in $srcs; do
dst=$dstpath
# if destination is a directory, append the input filename
if [ $dstisdir = 1 ]; then
dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
dst="$dst/$dstfile"
fi
# check for correct arguments
if [ ".$src" = ".$dst" ]; then
echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2
continue
fi
if [ -d "$src" ]; then
echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2
continue
fi
# make a temp file name in the destination directory
dsttmp=`echo $dst |\
sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \
-e "s;\$;/#INST@$$#;"`
# verbosity
if [ ".$opt_v" = .yes ]; then
echo "$src -> $dst" 1>&2
fi
# copy or move the file name to the temp name
# (because we might be not allowed to change the source)
if [ ".$opt_C" = .yes ]; then
opt_c=yes
fi
if [ ".$opt_c" = .yes ]; then
if [ ".$opt_t" = .yes ]; then
echo "cp $src $dsttmp" 1>&2
fi
cp "$src" "$dsttmp" || shtool_exit $?
else
if [ ".$opt_t" = .yes ]; then
echo "mv $src $dsttmp" 1>&2
fi
mv "$src" "$dsttmp" || shtool_exit $?
fi
# adjust the target file
if [ ".$opt_e" != . ]; then
sed='sed'
OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
for e
do
sed="$sed -e '$e'"
done
cp "$dsttmp" "$dsttmp.old"
chmod u+w $dsttmp
eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $?
rm -f $dsttmp.old
fi
if [ ".$opt_s" = .yes ]; then
if [ ".$opt_t" = .yes ]; then
echo "strip $dsttmp" 1>&2
fi
${STRIP:-strip} $dsttmp || shtool_exit $?
fi
if [ ".$opt_o" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chown $opt_o $dsttmp" 1>&2
fi
chown $opt_o $dsttmp || shtool_exit $?
fi
if [ ".$opt_g" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chgrp $opt_g $dsttmp" 1>&2
fi
chgrp $opt_g $dsttmp || shtool_exit $?
fi
if [ ".$opt_m" != ".-" ]; then
if [ ".$opt_t" = .yes ]; then
echo "chmod $opt_m $dsttmp" 1>&2
fi
chmod $opt_m $dsttmp || shtool_exit $?
fi
# determine whether to do a quick install
# (has to be done _after_ the strip was already done)
quick=no
if [ ".$opt_C" = .yes ]; then
if [ -r $dst ]; then
if cmp -s "$src" "$dst"; then
quick=yes
fi
fi
fi
# finally, install the file to the real destination
if [ $quick = yes ]; then
if [ ".$opt_t" = .yes ]; then
echo "rm -f $dsttmp" 1>&2
fi
rm -f $dsttmp
else
if [ ".$opt_t" = .yes ]; then
echo "rm -f $dst && mv $dsttmp $dst" 1>&2
fi
rm -f $dst && mv $dsttmp $dst
fi
done
shtool_exit 0
;;
mkdir )
##
## mkdir -- Make one or more directories
## Copyright (c) 1996-2008 Ralf S. Engelschall <rse@engelschall.com>
##
errstatus=0
for p in ${1+"$@"}; do
# if the directory already exists...
if [ -d "$p" ]; then
if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
echo "$msgprefix:Error: directory already exists: $p" 1>&2
errstatus=1
break
else
continue
fi
fi
# if the directory has to be created...
if [ ".$opt_p" = .no ]; then
if [ ".$opt_t" = .yes ]; then
echo "mkdir $p" 1>&2
fi
mkdir $p || errstatus=$?
if [ ".$opt_o" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chown $opt_o $p" 1>&2
fi
chown $opt_o $p || errstatus=$?
fi
if [ ".$opt_g" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chgrp $opt_g $p" 1>&2
fi
chgrp $opt_g $p || errstatus=$?
fi
if [ ".$opt_m" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chmod $opt_m $p" 1>&2
fi
chmod $opt_m $p || errstatus=$?
fi
else
# the smart situation
set fnord `echo ":$p" |\
sed -e 's/^:\//%/' \
-e 's/^://' \
-e 's/\// /g' \
-e 's/^%/\//'`
shift
pathcomp=''
for d in ${1+"$@"}; do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp="./$pathcomp" ;;
esac
if [ ! -d "$pathcomp" ]; then
if [ ".$opt_t" = .yes ]; then
echo "mkdir $pathcomp" 1>&2
fi
mkdir $pathcomp || errstatus=$?
if [ ".$opt_o" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chown $opt_o $pathcomp" 1>&2
fi
chown $opt_o $pathcomp || errstatus=$?
fi
if [ ".$opt_g" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chgrp $opt_g $pathcomp" 1>&2
fi
chgrp $opt_g $pathcomp || errstatus=$?
fi
if [ ".$opt_m" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chmod $opt_m $pathcomp" 1>&2
fi
chmod $opt_m $pathcomp || errstatus=$?
fi
fi
pathcomp="$pathcomp/"
done
fi
done
shtool_exit $errstatus
;;
mkln )
##
## mkln -- Make link with calculation of relative paths
## Copyright (c) 1998-2008 Ralf S. Engelschall <rse@engelschall.com>
##
# determine source(s) and destination
args=$#
srcs=""
while [ $# -gt 1 ]; do
srcs="$srcs $1"
shift
done
dst="$1"
if [ ! -d $dst ]; then
if [ $args -gt 2 ]; then
echo "$msgprefix:Error: multiple sources not allowed when target isn't a directory" 1>&2
shtool_exit 1
fi
fi
# determine link options
lnopt=""
if [ ".$opt_f" = .yes ]; then
lnopt="$lnopt -f"
fi
if [ ".$opt_s" = .yes ]; then
lnopt="$lnopt -s"
fi
# iterate over sources
for src in $srcs; do
# determine if one of the paths is an absolute path,
# because then we _have_ to use an absolute symlink
oneisabs=0
srcisabs=0
dstisabs=0
case $src in
/* ) oneisabs=1; srcisabs=1 ;;
esac
case $dst in
/* ) oneisabs=1; dstisabs=1 ;;
esac
# split source and destination into dir and base name
if [ -d $src ]; then
srcdir=`echo $src | sed -e 's;/*$;;'`
srcbase=""
else
srcdir=`echo $src | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
srcbase=`echo $src | sed -e 's;.*/\([^/]*\)$;\1;'`
fi
if [ -d $dst ]; then
dstdir=`echo $dst | sed -e 's;/*$;;'`
dstbase=""
else
dstdir=`echo $dst | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
dstbase=`echo $dst | sed -e 's;.*/\([^/]*\)$;\1;'`
fi
# consistency check
if [ ".$dstdir" != . ]; then
if [ ! -d $dstdir ]; then
echo "$msgprefix:Error: destination directory not found: $dstdir" 1>&2
shtool_exit 1
fi
fi
# make sure the source is reachable from the destination
if [ $dstisabs = 1 ]; then
if [ $srcisabs = 0 ]; then
if [ ".$srcdir" = . ]; then
srcdir="`pwd | sed -e 's;/*$;;'`"
srcisabs=1
oneisabs=1
elif [ -d $srcdir ]; then
srcdir="`cd $srcdir; pwd | sed -e 's;/*$;;'`"
srcisabs=1
oneisabs=1
fi
fi
fi
# split away a common prefix
prefix=""
if [ ".$srcdir" = ".$dstdir" ] && [ ".$srcdir" != . ]; then
prefix="$srcdir/"
srcdir=""
dstdir=""
else
while [ ".$srcdir" != . ] && [ ".$dstdir" != . ]; do
presrc=`echo $srcdir | sed -e 's;^\([^/]*\)/.*;\1;'`
predst=`echo $dstdir | sed -e 's;^\([^/]*\)/.*;\1;'`
if [ ".$presrc" != ".$predst" ]; then
break
fi
prefix="$prefix$presrc/"
srcdir=`echo $srcdir | sed -e 's;^[^/]*/*;;'`
dstdir=`echo $dstdir | sed -e 's;^[^/]*/*;;'`
done
fi
# destination prefix is just the common prefix
dstpre="$prefix"
# determine source prefix which is the reverse directory
# step-up corresponding to the destination directory
srcpre=""
allow_relative_srcpre=no
if [ ".$prefix" != . ] && [ ".$prefix" != ./ ]; then
allow_relative_srcpre=yes
fi
if [ $oneisabs = 0 ]; then
allow_relative_srcpre=yes
fi
if [ ".$opt_s" != .yes ]; then
allow_relative_srcpre=no
fi
if [ ".$allow_relative_srcpre" = .yes ]; then
pl="$dstdir/"
OIFS="$IFS"; IFS='/'
for pe in $pl; do
[ ".$pe" = . ] && continue
[ ".$pe" = .. ] && continue
srcpre="../$srcpre"
done
IFS="$OIFS"
else
if [ $srcisabs = 1 ]; then
srcpre="$prefix"
fi
fi
# determine destination symlink name
if [ ".$dstbase" = . ]; then
if [ ".$srcbase" != . ]; then
dstbase="$srcbase"
else
dstbase=`echo "$prefix$srcdir" | sed -e 's;/*$;;' -e 's;.*/\([^/]*\)$;\1;'`
fi
fi
# now finalize source and destination directory paths
srcdir=`echo $srcdir | sed -e 's;\([^/]\)$;\1/;'`
dstdir=`echo $dstdir | sed -e 's;\([^/]\)$;\1/;'`
# run the final link command
if [ ".$opt_t" = .yes ]; then
echo "ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase"
fi
eval ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase
done
shtool_exit 0
;;
subst )
##
## subst -- Apply sed(1) substitution operations
## Copyright (c) 2001-2008 Ralf S. Engelschall <rse@engelschall.com>
##
# remember optional list of file(s)
files="$*"
files_num="$#"
# parameter consistency check
if [ $# -eq 0 ] && [ ".$opt_b" != . ]; then
echo "$msgprefix:Error: option -b cannot be applied to stdin" 1>&2
shtool_exit 1
fi
if [ $# -eq 0 ] && [ ".$opt_s" = .yes ]; then
echo "$msgprefix:Error: option -s cannot be applied to stdin" 1>&2
shtool_exit 1
fi
# build underlying sed(1) command
sedcmd='sed'
if [ ".$opt_e" != . ]; then
OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
for e
do
sedcmd="$sedcmd -e '$e'"
done
elif [ ".$opt_f" != . ]; then
if [ ! -f $opt_f ]; then
echo "$msgprefix:Error: command file \`$opt_f' not found or not a regular file" 1>&2
shtool_exit 1
fi
sedcmd="$sedcmd -f '$opt_f'"
else
echo "$msgprefix:Error: either -e option(s) or -f option required" 1>&2
shtool_exit 1
fi
# determine extension for original file
orig=".orig"
if [ ".$opt_b" != . ]; then
orig="$opt_b"
fi
# apply sed(1) operation(s)
if [ ".$files" != . ]; then
# apply operation(s) to files
substdone=no
for file in $files; do
test ".$file" = . && continue
if [ ! -f $file ]; then
echo "$msgprefix:Warning: file \`$file' not found or not a regular file" 1>&2
continue
fi
# handle interactive mode
if [ ".$opt_i" = .yes ]; then
eval "$sedcmd <$file >$file.new"
skip=no
if cmp $file $file.new >/dev/null 2>&1; then
rm -f $file.new
skip=yes
else
(diff -U1 $file $file.new >$tmpfile) 2>/dev/null
if [ ".`cat $tmpfile`" = . ]; then
(diff -C1 $file $file.new >$tmpfile) 2>/dev/null
if [ ".`cat $tmpfile`" = . ]; then
echo "$msgprefix:Warning: unable to show difference for file \`$file'" 1>&2
cp /dev/null $tmpfile
fi
fi
rm -f $file.new
cat $tmpfile
echo dummy | awk '{ printf("%s", TEXT); }' TEXT=">>> Apply [Y/n]: "
read input
if [ ".$input" != .Y ] &&\
[ ".$input" != .y ] &&\
[ ".$input" != . ]; then
skip=yes
fi
fi
if [ ".$skip" = .yes ]; then
if [ ".$opt_v" = .yes ]; then
echo "file \`$file' -- skipped" 1>&2
fi
continue
fi
fi
# apply sed(1) operation(s)
if [ ".$opt_v" = .yes ]; then
echo "patching \`$file'" 1>&2
fi
if [ ".$opt_t" = .yes ]; then
echo "\$ cp -p $file $file$orig"
echo "\$ chmod u+w $file"
echo "\$ $sedcmd <$file$orig >$file"
fi
if [ ".$opt_n" = .no ]; then
cp -p $file $file$orig
chmod u+w $file >/dev/null 2>&1 || true
eval "$sedcmd <$file$orig >$file"
fi
# optionally fix timestamp
if [ ".$opt_s" = .yes ]; then
if [ ".$opt_t" = .yes ]; then
echo "\$ touch -r $file$orig $file"
fi
if [ ".$opt_n" = .no ]; then
touch -r $file$orig $file
fi
fi
# optionally check whether any content change actually occurred
if [ ".$opt_q" = .no ]; then
if cmp $file$orig $file >/dev/null 2>&1; then
if [ ".$opt_w" = .yes ]; then
echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
fi
else
substdone=yes
fi
fi
# optionally remove preserved original file
if [ ".$opt_b" = . ]; then
if [ ".$opt_t" = .yes ]; then
echo "\$ rm -f $file$orig"
fi
if [ ".$opt_n" = .no ]; then
rm -f $file$orig
fi
fi
done
if [ ".$opt_q" = .no ] && [ ".$opt_w" = .no ]; then
if [ ".$substdone" = .no ]; then
if [ ".$files_num" = .1 ]; then
echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
else
echo "$msgprefix:Warning: substitution resulted in no content change on any file" 1>&2
fi
fi
fi
else
# apply operation(s) to stdin/stdout
if [ ".$opt_v" = .yes ]; then
echo "patching <stdin>" 1>&2
fi
if [ ".$opt_t" = .yes ]; then
echo "\$ $sedcmd"
fi
if [ ".$opt_n" = .no ]; then
eval "$sedcmd"
fi
fi
shtool_exit 0
;;
esac
shtool_exit 0
## Copyright 1998,1999 The OpenLDAP Foundation
## COPYING RESTRICTIONS APPLY. See COPYRIGHT File in top level directory
## of this package for details.
##---------------------------------------------------------------------------
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Makefile Template for Servers
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
##---------------------------------------------------------------------------
#
# Makefile Template for Servers
#
all-common: all-$(BUILD_SRV)
all-no lint-no 5lint-no depend-no install-no:
......@@ -37,7 +47,7 @@ lint-yes: lint-local-srv FORCE
clean-local-srv:
clean-srv: clean-local-srv FORCE
$(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o a.out core .libs/*
$(RM) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) *.o a.out core .libs/* *.exe
depend-local-srv:
depend-yes: depend-local-srv FORCE
......
## Copyright 1998,1999 The OpenLDAP Foundation, Redwood City, California, USA
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Redistribution and use in source and binary forms are permitted only
## as authorized by the OpenLDAP Public License. A copy of this
## license is available at http://www.OpenLDAP.org/license.html or
## in file LICENSE in the top-level directory of the distribution.
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
##---------------------------------------------------------------------------
#
# Top-level Makefile template
#
PACKAGE= @PACKAGE@
VERSION= @VERSION@
RELEASEDATE= @OPENLDAP_RELEASE_DATE@
@SET_MAKE@
SHELL = /bin/sh
......@@ -21,26 +31,36 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
ldap_subdir = @ldap_subdir@
bindir = $(TMPROOT)@bindir@
datadir = $(TMPROOT)@datadir@$(ldap_subdir)
includedir = $(TMPROOT)@includedir@
infodir = $(TMPROOT)@infodir@
libdir = $(TMPROOT)@libdir@
libexecdir = $(TMPROOT)@libexecdir@
localstatedir = $(TMPROOT)@localstatedir@
mandir = $(TMPROOT)@mandir@
moduledir = $(TMPROOT)@libexecdir@$(ldap_subdir)
sbindir = $(TMPROOT)@sbindir@
sharedstatedir = $(TMPROOT)@sharedstatedir@
sysconfdir = $(TMPROOT)@sysconfdir@$(ldap_subdir)
bindir = @bindir@
datarootdir = @datarootdir@
datadir = @datadir@$(ldap_subdir)
includedir = @includedir@
infodir = @infodir@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
moduledir = @libexecdir@$(ldap_subdir)
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@$(ldap_subdir)
schemadir = $(sysconfdir)/schema
systemdsystemunitdir = @systemdsystemunitdir@
PLAT = @PLAT@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
BUILD_LIBS_DYNAMIC = @BUILD_LIBS_DYNAMIC@
SHTOOL = $(top_srcdir)/build/shtool
INSTALL = $(SHTOOL) install -c
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA = $(INSTALL) -m 644
INSTALL_SCRIPT = $(INSTALL)
STRIP_OPTS = -s
LINT = lint
5LINT = 5lint
......@@ -53,35 +73,79 @@ MKDEP_CFLAGS = @OL_MKDEP_FLAGS@
MKVERSION = $(top_srcdir)/build/mkversion -v "$(VERSION)"
LIBTOOL = @LIBTOOL@
LIBVERSION = 0:0:0
LIBVERSION = @OPENLDAP_LIBVERSION@
LTVERSION = -version-info $(LIBVERSION)
LTLIBLINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LTVERSION)
LTLINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS)
# libtool --only flag for libraries: platform specific
NT_LTONLY_LIB = # --only-$(BUILD_LIBS_DYNAMIC)
LTONLY_LIB = $(@PLAT@_LTONLY_LIB)
# libtool --only flag for modules: depends on linkage of module
# The BUILD_MOD macro is defined in each backend Makefile.in file
LTONLY_yes = --tag=disable-shared
LTONLY_mod = --tag=disable-static
LTONLY_MOD = $(LTONLY_$(BUILD_MOD))
# platform-specific libtool flags
NT_LTFLAGS_LIB = -no-undefined -avoid-version -rpath $(libdir)
NT_LTFLAGS_MOD = -no-undefined -avoid-version -rpath $(moduledir)
UNIX_LTFLAGS_LIB = $(LTVERSION) -rpath $(libdir)
UNIX_LTFLAGS_MOD = $(LTVERSION) -rpath $(moduledir)
# libtool flags
LTFLAGS = $(@PLAT@_LTFLAGS)
LTFLAGS_LIB = $(@PLAT@_LTFLAGS_LIB)
LTFLAGS_MOD = $(@PLAT@_LTFLAGS_MOD)
# LIB_DEFS defined in liblber and libldap Makefile.in files.
# MOD_DEFS defined in backend Makefile.in files.
# platform-specific LINK_LIBS defined in various Makefile.in files.
# LINK_LIBS referenced in library and module link commands.
LINK_LIBS = $(MOD_LIBS) $(@PLAT@_LINK_LIBS)
# compiler options for versioned library symbol support
OL_VERSIONED_SYMBOLS = @OL_VERSIONED_SYMBOLS@
LTSTATIC = @LTSTATIC@
LTLINK = $(LIBTOOL) --mode=link \
$(CC) $(LTSTATIC) $(LT_CFLAGS) $(LDFLAGS) $(LTFLAGS)
LTCOMPILE_LIB = $(LIBTOOL) $(LTONLY_LIB) --mode=compile \
$(CC) $(LT_CFLAGS) $(LT_CPPFLAGS) $(LIB_DEFS) -c
LTLINK_LIB = $(LIBTOOL) $(LTONLY_LIB) --mode=link \
$(CC) $(LT_CFLAGS) $(LDFLAGS) $(LTFLAGS_LIB) $(SYMBOL_VERSION_FLAGS)
LTCOMPILE_MOD = $(LIBTOOL) $(LTONLY_MOD) --mode=compile \
$(CC) $(LT_CFLAGS) $(LT_CPPFLAGS) $(MOD_DEFS) -c
LTLINK_MOD = $(LIBTOOL) $(LTONLY_MOD) --mode=link \
$(CC) $(LT_CFLAGS) $(LDFLAGS) $(LTFLAGS_MOD)
LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
LTFINISH = $(LIBTOOL) --mode=finish
# Misc UNIX commands used in build environment
AR = ar
AWK = @AWK@
AR = @AR@
BASENAME = basename
CAT = cat
CHMOD = chmod
DATE = date
HOSTNAME = uname -n
LN = ln
LN_H = @LN_H@
LN_S = @LN_S@
ECHO = $(SHTOOL) echo
HOSTNAME = $(SHTOOL) echo -e "%h%d"
LN = $(SHTOOL) mkln
LN_H = $(LN)
LN_S = $(LN) -s
MAKEINFO = @MAKEINFO@
MKDIR = mkdir -p
MV = mv
MKDIR = $(SHTOOL) mkdir -p
MV = $(SHTOOL) move
PWD = pwd
RANLIB = @RANLIB@
RM = rm -f
SED = sed
# Misc UNIX commands used in programs
EDITOR = @EDITOR@
FINGER = @FINGER@
SENDMAIL = @SENDMAIL@
SUBST = $(SHTOOL) subst
# For manual pages
# MANCOMPRESS=@MANCOMPRESS@
......@@ -89,30 +153,37 @@ SENDMAIL = @SENDMAIL@
MANCOMPRESS=$(CAT)
MANCOMPRESSSUFFIX=
SOELIM=soelim
INCLUDEDIR= $(top_srcdir)/include
LDAP_INCPATH= -I$(LDAP_INCDIR) -I$(INCLUDEDIR)
LDAP_LIBADIR= $(top_builddir)/libraries
LDAP_LIBPATH= -L$(LDAP_LIBADIR)
LDAP_LIBDIR= $(top_builddir)/libraries
CLIENT_LIBS = @CLIENT_LIBS@
LUTIL_LIBS = @LUTIL_LIBS@
LDIF_LIBS = @LDIF_LIBS@
LDBM_LIBS = @LDBM_LIBS@
LTHREAD_LIBS = @LTHREAD_LIBS@
LDAP_LIBLBER_DEPEND = $(LDAP_LIBDIR)/liblber/liblber.la
LDAP_LIBLDAP_DEPEND = $(LDAP_LIBDIR)/libldap/libldap.la
LDAP_LIBLDIF_DEPEND = $(LDAP_LIBDIR)/libldif/libldif.a
LDAP_LIBLUTIL_DEPEND = $(LDAP_LIBDIR)/liblutil/liblutil.a
SLAPD_NDB_LIBS = @SLAPD_NDB_LIBS@
WT_LIBS = @WT_LIBS@
LEVENT_LIBS = @LEVENT_LIBS@
LDAP_LIBAVL_DEPEND = $(LDAP_LIBDIR)/libavl/libavl.a
LDAP_LIBLDBM_DEPEND = $(LDAP_LIBDIR)/libldbm/libldbm.a
LDAP_LIBLTHREAD_DEPEND = $(LDAP_LIBDIR)/libldap_r/libldap_r.la
LDAP_LIBLBER_LA = $(LDAP_LIBDIR)/liblber/liblber.la
LDAP_LIBLDAP_LA = $(LDAP_LIBDIR)/libldap/libldap.la
LDAP_LIBDEPEND = $(LDAP_LIBLDAP_DEPEND) $(LDAP_LIBLBER_DEPEND) \
$(LDAP_LIBLDIF_DEPEND) $(LDAP_LIBLUTIL_DEPEND)
SLAPD_LIBDEPEND = $(LDAP_LIBDEPEND) $(LDAP_LIBAVL_DEPEND) \
$(LDAP_LIBLDBM_DEPEND) $(LDAP_LIBLTHREAD_DEPEND)
LDAP_LIBREWRITE_A = $(LDAP_LIBDIR)/librewrite/librewrite.a
LDAP_LIBLUNICODE_A = $(LDAP_LIBDIR)/liblunicode/liblunicode.a
LDAP_LIBLUTIL_A = $(LDAP_LIBDIR)/liblutil/liblutil.a
LDAP_L = $(LDAP_LIBLUTIL_A) \
$(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA)
SLAPD_L = $(LDAP_LIBLUNICODE_A) $(LDAP_LIBREWRITE_A) \
$(LDAP_LIBLUTIL_A) $(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA)
LLOADD_L = $(LDAP_LIBLUTIL_A) $(LDAP_LIBLDAP_LA) \
$(LDAP_LIBLBER_LA)
WRAP_LIBS = @WRAP_LIBS@
# AutoConfig generated
AC_CC = @CC@
AC_CFLAGS = @CFLAGS@
......@@ -120,21 +191,23 @@ AC_DEFS = @CPPFLAGS@ # @DEFS@
AC_LDFLAGS = @LDFLAGS@
AC_LIBS = @LIBS@
KRB_LIBS = @KRB_LIBS@
SASL_LIBS = @SASL_LIBS@
TLS_LIBS = @TLS_LIBS@
SECURITY_LIBS = @SASL_LIBS@ @KRB_LIBS@ @TLS_LIBS@
AUTH_LIBS = @AUTH_LIBS@
ARGON2_LIBS = @ARGON2_LIBS@
SECURITY_LIBS = $(SASL_LIBS) $(TLS_LIBS) $(AUTH_LIBS)
MODULES_CPPFLAGS = @SLAPD_MODULES_CPPFLAGS@
MODULES_LDFLAGS = @SLAPD_MODULES_LDFLAGS@
MODULES_LIBS = @MODULES_LIBS@
PERL_CPPFLAGS = @SLAPD_PERL_CPPFLAGS@
PERL_LDFLAGS = @SLAPD_PERL_LDFLAGS@
TERMCAP_LIBS = @TERMCAP_LIBS@
SLAPD_PERL_LDFLAGS = @SLAPD_PERL_LDFLAGS@
SLAPD_SQL_LDFLAGS = @SLAPD_SQL_LDFLAGS@
SLAPD_SQL_INCLUDES = @SLAPD_SQL_INCLUDES@
SLAPD_SQL_LIBS = @SLAPD_SQL_LIBS@
LDAPD_LIBS = @LDAPD_LIBS@
SLAPD_LIBS = @SLAPD_LIBS@
SLURPD_LIBS = @SLURPD_LIBS@
SLAPD_LIBS = @SLAPD_LIBS@ @SLAPD_PERL_LDFLAGS@ @SLAPD_SQL_LDFLAGS@ @SLAPD_SQL_LIBS@ @SLAPD_SLP_LIBS@ @SLAPD_GMP_LIBS@
LLOADD_LIBS = @BALANCER_LIBS@ $(LEVENT_LIBS)
# Our Defaults
CC = $(AC_CC)
......@@ -143,6 +216,9 @@ CFLAGS = $(AC_CFLAGS) $(DEFS)
LDFLAGS = $(LDAP_LIBPATH) $(AC_LDFLAGS) $(XLDFLAGS)
LIBS = $(XLIBS) $(XXLIBS) $(AC_LIBS) $(XXXLIBS)
LT_CFLAGS = $(AC_CFLAGS)
LT_CPPFLAGS = $(DEFS)
all: all-common all-local FORCE
install: install-common install-local FORCE
clean: clean-common clean-local FORCE
......@@ -173,7 +249,11 @@ veryclean: FORCE
Makefile: Makefile.in $(top_srcdir)/build/top.mk
pathtest:
$(SHTOOL) --version
# empty rule for forcing rules
FORCE:
##---------------------------------------------------------------------------
2.0-devel
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 1998-2024 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
static const char copyright[] =
"Copyright 1998-2024 The OpenLDAP Foundation. All rights reserved.\n"
"COPYING RESTRICTIONS APPLY.\n";
#! /bin/sh
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
DIR=`dirname $0`
. $DIR/version.var
if test $ol_patch != X ; then
ol_version=${ol_major}.${ol_minor}.${ol_patch}
ol_type=Release
elif test $ol_minor != X ; then
ol_version=${ol_major}.${ol_minor}.${ol_patch}
ol_type=Engineering
else
ol_version=${ol_major}.${ol_minor}
ol_type=Devel
fi
ol_string="${ol_package} ${ol_version}-${ol_type}"
ol_api_lib_version="${ol_api_current}:${ol_api_revision}:${ol_api_age}"
echo OL_PACKAGE=\"${ol_package}\"
echo OL_MAJOR=$ol_major
echo OL_MINOR=$ol_minor
echo OL_PATCH=$ol_patch
echo OL_API_INC=$ol_api_inc
echo OL_API_LIB_VERSION=$ol_api_lib_version
echo OL_VERSION=$ol_version
echo OL_TYPE=$ol_type
echo OL_STRING=\"${ol_string}\"
echo OL_RELEASE_DATE=\"${ol_release_date}\"
#! /bin/sh
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
ol_package=OpenLDAP
ol_major=2
ol_minor=X
ol_patch=X
ol_api_inc=000000
ol_api_current=0
ol_api_revision=0
ol_api_age=0
ol_release_date="0000/00/00"
## Copyright 1998 The OpenLDAP Foundation, All Rights Reserved.
## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
# Clients Makefile.in for OpenLDAP
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Clients Makefile.in for OpenLDAP
## Copyright 1998-2024 The OpenLDAP Foundation.
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted only as authorized by the OpenLDAP
## Public License.
##
## A copy of this license is available in the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
SUBDIRS = tools
SUBDIRS= tools ud finger gopher mail500 fax500 rcpt500
PROGRAMS= rp500 fax500 xrpcomp.tmp
SRCS= main.c faxtotpc.c rp500.c
XSRCS=fax5version.c rpversion.c
FAX5OBJS = main.o faxtotpc.o
RPOBJS = rp500.o faxtotpc.o
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
XLIBS = -lldap -llber -llutil
XXLIBS = $(SECURITY_LIBS) $(LUTIL_LIBS)
rp500 : rpversion.o
$(LTLINK) -o $@ $(RPOBJS) rpversion.o $(LIBS)
fax500 : fax5version.o
$(LTLINK) -o $@ $(RPOBJS) fax5version.o $(LIBS)
rpversion.c: ${RPOBJS} $(LDAP_LIBDEPEND)
@-$(RM) $@
$(MKVERSION) rp500 > $@
fax5version.c: ${FAX5OBJS} $(LDAP_LIBDEPEND)
@-$(RM) $@
$(MKVERSION) fax500 > $@
xrpcomp.tmp: xrpcomp
$(SED) -e 's|%LIBEXECDIR%|$(libexecdir)|' $(srcdir)/xrpcomp > xrpcomp.tmp
install-local: $(PROGRAMS) FORCE
-$(MKDIR) $(libexecdir)
$(LTINSTALL) $(INSTALLFLAGS) -m 755 rp500 $(libexecdir)
$(LTINSTALL) $(INSTALLFLAGS) -m 755 fax500 $(libexecdir)
$(INSTALL) $(INSTALLFLAGS) -m 755 xrpcomp.tmp $(libexecdir)/xrpcomp
README file for fax500
xrpcomp
-------
This directory contains a modified version of the rpcomp program, used
with the Internet remote-printing experiment. More info on the experiment
can be found in /mrose/tpc on ftp.ics.uci.edu.
The xrpcomp program (it's a shell script) is like rpcomp, except that it
will look in X.500 if no fax recipients are found in the .rpdb file.
It still uses .rpdb to extract the originator information.
There are a couple of things in rp500.c you will want to tailor to use
xrpcomp at your site:
DAPUSER This is the user the rp500 program, called from
xrpcomp will bind to the directory as. It can
be set to NULL.
DEFAULT_BASE This is the search base rp500 will use when looking
in the directory for fax recipients.
DEFAULT_FILTERCONF
Where to find the ldapfilter.conf file. Should
make setting this automatic, but for now...
PHONE_PREFIX The prefix of phones in your local area. If
rp500 finds a fax number in the directory that is
not fully qualified, it will append as many of
these digits as necessary to make it fully
qualified. NB it assumes US-format numbers.
DEFAULT_LDAPHOST
The host running the default ldap server to
contact.
Things to note:
The rp500 program knows a little about the US phone number format, in
an attempt to deal with (evil) people who have not put fully qualified
international format (e.g. +1 ... ) phone numbers in their entry. If
your users do not have US-format phone numbers, you'll need to take a
look at the fax2email() routine in rp500.c and change it around a bit.
7/30/93 -- Tim
fax500
------
This directory also contains the fax500 program. fax500 is just like
mail500, except that it looks up the facsimileTelephoneNumber
attribute, constructs an appropriate "remote-printer@blah.tpc.int"
address, and send the mail there. For example, the facsimile number
"+1 313 555 1212" corresponds to the address
"remote-printer@2.1.2.1.5.5.5.3.1.3.1.tpc.int." For a complete
explanation of the Internet remote-printing experiment, look in
/mrose/tpc on ftp.ics.uci.edu, or send mail to tpc-faq@town.hall.org.
The general idea is that you can set things up so that mail sent to
"user@fax.domain" will get printed on the user's fax machine, if
they've entered a fax number in their X.500 entry.
NOTE: you will need to modify faxtotpc.c if you have any "abbreviated"
phone number capabilities. For example, our telephone switches allow
you to dial only the last 5 digits of campus telephone numbers. People,
therefore, tend to list the last 5 digits of their fax numbers. The
routine "munge_phone()" takes care of fixing up abbreviated phone
numbers. You may need to write your own code.
fax500 is not yet complete. In particular, the following work still needs
to be done:
- If the group entry itself has a fax number, don't send to all the members'
individual fax numbers. Instead, just send to the group's fax number.
- The -h flag for fax500 defines both the host name and the search base.
This causes problems because the host name we want is "fax.umich.edu"
but we need to search "umich.edu." The workaround is to add an
Associated Domain corresponding to the domain you want for your fax
service to each X.500 group which is to be accessible.
- We're working toward mail500 and fax500 being the same binary. Depending
on what argv[0] is, you'll get different behavior. Although this
binary should work just like mail500 if you name it "mail500" it's
not yet been tested.
- fax500 currently assumes that incoming messages are plain text, and
therefore constructs a destination address like
"remote-printer.user_name@2.1.2.1.5.5.5.3.1.3.1.tpc.int". If
the message is already MIME-compliant with an "application/remote-printing"
content type, we lose, since the remote-printing software assumes
that anything other than "remote-printer" on ther lhs of the address
means the message is plain text. Not sure about the solution to this.
- Regarding group support - typically, when we collect all the fax numbers
for a group, we'll end up either with (a) people who haven't registered
fax numbers, or (b) "email-only" group members who do not have entries
in X.500 (they only have an email address associated with the group).
The question is: what do you do with faxes for these folks? You could
(1) bounce to the sender (current behavior) or you could (2) send
email to the members with no fax numbers, informing them that someone
tried to send them a fax. I tend to prefer solution (2) for case (a),
and solution (1) for case (b).
- A configuration file-driven "munge_phone()" would be nice.
8/23/93 - Gordon
#ifndef FAX500_H
#define FAX500_H 1
/* in faxtotpc.c */
void strip_nonnum ( char *str );
char *remove_parens( char *ibuf, char *obuf );
char *munge_phone ( char *ibuf, char *obuf );
char *faxtotpc ( char *phone, char *userinfo );
#endif
/*
* Copyright (c) 1993 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
*
* Routines for parsing the facsimileTelephoneNumber field out of
* an X.500 entry and converting it to a "tpc.int" domain name.
*
* char *faxtotpc( char *str, char *userinfo)
*
* faxtotpc() returns a pointer to a string allocated with malloc(3).
*/
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/unistd.h>
#include "fax500.h"
#define TPCDOMAIN "tpc.int"
/*
* Remove everything from 'str' which is not a digit
*/
void
strip_nonnum( char *str )
{
char *p, *q;
p = q = str;
for (;;) {
if (*p == '\0') {
*q = *p;
return;
}
if (isdigit((u_char) *p)) {
*q = *p;
p++;
q++;
} else {
p++;
}
}
}
/*
* Remove anything of the form (blah) where
* "blah" contains a non-numeric character.
*/
char *
remove_parens( char *ibuf, char *obuf )
{
char *p = ibuf;
char *q = obuf;
while (*p != '\0') {
char *s;
char *t;
if (*p == '(') {
/* look for a closing paren */
if (( s = strchr(p, ')')) != NULL) {
/* Check the string between p and s */
/* for non-numeric characters */
t = p + 1;
while (t < s) {
if (!isdigit((u_char) *t)) {
/* garbage, delete */
p = s + 1;
t = p;
break;
}
t++;
}
/* when we get here, p points to the first */
/* thing we want to keep, t to the last. */
strncpy(q, p, t - p);
q += t - p;
p = t;
} else {
/* no closing paren, what to do? keep it */
*q = *p;
p++;
q++;
}
} else {
/* not a paren - copy out */
*q = *p;
p++;
q++;
}
}
*q = '\0'; /* terminate output string */
return(obuf);
}
/*
* Apply local fixups to phone numbers here. Replace this routine
* with code to expand common "abbreviations" for phone numbers. For
* example, on the U-M campus, it's only necessary to dial the last
* 5 digits of the telephone number, and hence people here tend to
* give only the last 5 digits of their fax numbers.
*
* Local U-M mods:
* If exactly 5 digits were provided, assume it's a campus
* phone number and prepend "1313nm" where "mn" are computed
* according to the following:
* first digit of
* 5-digit "Local"
* phone mn
* ----- --
* 3 76 e.g. "31234" -> "7631234"
* 4 76
* 7 74
* 6 93
* 8 99
*/
char *
munge_phone( char *ibuf, char *obuf )
{
#define UMAREACODE "1313"
char prefix[3];
if (strlen(ibuf) == 7) {
/* Assume local number w/o area code */
sprintf(obuf, "%s%s", UMAREACODE, ibuf);
return(obuf);
}
if (strlen(ibuf) == 10) {
/* Assume local number with area code */
sprintf(obuf, "%s%s", "1", ibuf);
return(obuf);
}
if (strlen(ibuf) != 5) {
/* Not 5 digits - leave alone */
strcpy(obuf, ibuf);
return(obuf);
}
switch (ibuf[0]) {
case '3' :
case '4' : strcpy(prefix, "76");
break;
case '7' : strcpy(prefix, "74");
break;
case '6' : strcpy(prefix, "93");
break;
case '8' : strcpy(prefix, "99");
break;
default : /* Unknown, leave alone */
strcpy(obuf, ibuf);
return(obuf);
}
sprintf(obuf, "%s%s%s", UMAREACODE, prefix, ibuf);
return(obuf);
}
/*
* Convert string to "tpc.int" domain name.
*/
char *
faxtotpc( char *phone, char *userinfo )
{
char *p;
char *q;
char ibuf[255];
char obuf[255];
/* nuke spaces */
strcpy(ibuf, phone);
for (p = ibuf, q = obuf; *p != '\0'; p++) {
if (*p != ' ') {
*q = *p;
q++;
}
}
*q = '\0';
strcpy(ibuf, obuf);
remove_parens(ibuf, obuf);
strcpy(ibuf, obuf);
/* Look for "+" - if followed by a number,
assume it's an international number and leave
it alone.
*/
if ((p = strchr(ibuf, '+')) != NULL) {
if (isdigit((u_char) *(p + 1))) {
/* strip any non-digits */
strip_nonnum(ibuf);
}
} else {
strip_nonnum(ibuf);
/* Apply local munges */
munge_phone(ibuf, obuf);
strcpy(ibuf, obuf);
}
/* Convert string of form abcd to remote-printer@d.c.b.a.tpc.int */
q = obuf;
for (p = ibuf + strlen(ibuf) - 1; p >= ibuf; p--) {
*q++ = *p;
*q++ = '.';
}
*q = '\0';
strcpy(ibuf, obuf);
strcpy(obuf, "remote-printer");
/* include userinfo if present */
if (userinfo != NULL && strlen(userinfo)) {
strcat(obuf, ".");
strcat(obuf, userinfo);
}
strcat(obuf, "@");
strcat(obuf, ibuf); /* tack on reversed phone number */
strcat(obuf, TPCDOMAIN); /* tack on domain name */
p = strdup(obuf);
return(p);
}
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/ctype.h>
#include <ac/errno.h>
#include <ac/signal.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/sysexits.h>
#include <ac/syslog.h>
#include <ac/time.h>
#include <ac/unistd.h>
#include <ac/wait.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#include <ldap.h>
#include "fax500.h"
#include "ldap_defaults.h"
#define USER 0
#define GROUP_ERRORS 1
#define GROUP_REQUEST 2
#define GROUP_MEMBERS 3
#define ERRORS "errors"
#define REQUEST "request"
#define MEMBERS "members"
LDAP *ld;
char *errorsfrom = NULL;
char *mailfrom = NULL;
char *host = NULL;
int hostlen = 0;
int identity;
#define MAIL500 1
#define FAX500 2
typedef struct errs {
int e_code;
#define E_USERUNKNOWN 1
#define E_AMBIGUOUS 2
#define E_NOEMAIL 3
#define E_NOREQUEST 4
#define E_NOERRORS 5
#define E_BADMEMBER 6
#define E_JOINMEMBERNOEMAIL 7
#define E_MEMBERNOEMAIL 8
#define E_NOFAXNUM 9
#define E_JOINMEMBERNOFAXNUM 10
#define E_MEMBERNOFAXNUM 11
#define E_FAXTOEMAILMBR 12
char *e_addr;
LDAPMessage *e_msg;
} Error;
typedef struct groupto {
char *g_dn;
char *g_errorsto;
char **g_members;
} Group;
typedef struct baseinfo {
char *b_dn; /* dn to start searching at */
char b_rdnpref; /* give rdn's preference when searching? */
char *b_filter[3]; /* filter to apply - name substituted for %s */
/* (up to three of them) */
} Base;
Base base[] =
{ "ou=People, o=University of Michigan, c=US", 0,
"uid=%s", "cn=%s", NULL,
"ou=System Groups, ou=Groups, o=University of Michigan, c=US", 1,
"(&(cn=%s)(associatedDomain=%h))", NULL, NULL,
"ou=User Groups, ou=Groups, o=University of Michigan, c=US", 1,
"(&(cn=%s)(associatedDomain=%h))", NULL, NULL,
NULL
};
char *sendmailargs[] = { FAX_SENDMAIL, "-oMrX.500", "-odi", "-oi", "-f", NULL, NULL };
static char *attrs[] = { "objectClass", "title", "postaladdress",
"telephoneNumber", "mail", "description",
"errorsTo", "rfc822ErrorsTo", "requestsTo",
"rfc822RequestsTo", "joinable", "cn", "member",
"facsimileTelephoneNumber", NULL };
static void do_address(char *name, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr, int type);
static int do_group(LDAPMessage *e, char *dn, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr);
static void do_group_members(LDAPMessage *e, char *dn, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr);
static void send_message(char **to);
static void send_errors(Error *err, int nerr);
static void do_noemailorfax(FILE *fp, Error *err, int namelen, int errtype);
static void do_ambiguous(FILE *fp, Error *err, int namelen);
static int count_values(char **list);
static void add_to(char ***list, int *nlist, char **new);
static int isgroup(LDAPMessage *e);
static void add_error(Error **err, int *nerr, int code, char *addr, LDAPMessage *msg);
static void add_group(char *dn, Group **list, int *nlist);
static void unbind_and_exit(int rc);
static int group_loop(char *dn);
static void send_group(Group *group, int ngroup);
static int has_attributes(LDAPMessage *e, char *attr1, char *attr2);
static char **get_attributes_mail_dn(LDAPMessage *e, char *attr1, char *attr2);
static char *canonical(char *s);
static int connect_to_x500 (void);
static void do_group_errors (LDAPMessage *e, char *dn, char ***to, int *nto, Error **err, int *nerr);
static void do_group_request (LDAPMessage *e, char *dn, char ***to, int *nto, Error **err, int *nerr);
static void add_member (char *gdn, char *dn, char ***to, int *nto, Group **togroups, int *ngroups, Error **err, int *nerr);
int
main ( int argc, char **argv )
{
char *myname;
char **tolist;
Error *errlist;
Group *togroups;
int numto, ngroups, numerr, nargs;
int i, j;
while ( (i = getopt( argc, argv, "f:h:m:" )) != EOF ) {
switch( i ) {
case 'f': /* who it's from & where errors should go */
mailfrom = strdup( optarg );
for ( j = 0; sendmailargs[j] != NULL; j++ ) {
if ( strcmp( sendmailargs[j], "-f" ) == 0 ) {
sendmailargs[j+1] = mailfrom;
break;
}
}
break;
case 'h': /* hostname */
host = strdup( optarg );
hostlen = strlen(host);
break;
/* mailer-daemon address - who we should */
case 'm': /* say errors come from */
errorsfrom = strdup( optarg );
break;
default:
syslog( LOG_ALERT, "unknown option" );
break;
}
}
if ( (myname = strrchr( argv[0], '/' )) == NULL )
myname = strdup( argv[0] );
else
myname = strdup( myname + 1 );
if (!strcmp(myname, "mail500")) {
identity = MAIL500;
} else if (!strcmp(myname, "fax500")) {
identity = FAX500;
} else {
/* I give up, I must be mail500 */
identity = MAIL500;
}
#ifdef SIGPIPE
(void) SIGNAL( SIGPIPE, SIG_IGN );
#endif
#ifdef LOG_MAIL
openlog( myname, OPENLOG_OPTIONS, LOG_MAIL );
#else
openlog( myname, OPENLOG_OPTIONS );
#endif
if ( mailfrom == NULL ) {
syslog( LOG_ALERT, "required argument -f not present" );
exit( EX_TEMPFAIL );
}
if ( errorsfrom == NULL ) {
syslog( LOG_ALERT, "required argument -m not present" );
exit( EX_TEMPFAIL );
}
if ( host == NULL ) {
syslog( LOG_ALERT, "required argument -h not present" );
exit( EX_TEMPFAIL );
}
if ( connect_to_x500() != 0 )
exit( EX_TEMPFAIL );
setuid( geteuid() );
/*
{
char buf[1024];
int i;
strcpy( buf, argv[0] );
for ( i = 1; i < argc; i++ ) {
strcat( buf, " " );
strcat( buf, argv[i] );
}
syslog( LOG_ALERT, "args: (%s)", buf );
}
*/
numto = 0;
add_to( &tolist, &numto, sendmailargs );
nargs = numto;
ngroups = numerr = 0;
togroups = NULL;
errlist = NULL;
for ( i = optind; i < argc; i++ ) {
char *s;
int type;
for ( j = 0; argv[i][j] != '\0'; j++ ) {
if ( argv[i][j] == '.' || argv[i][j] == '_' )
argv[i][j] = ' ';
}
type = USER;
if ( (s = strrchr( argv[i], '-' )) != NULL ) {
s++;
if ( strcmp( s, ERRORS ) == 0 ) {
type = GROUP_ERRORS;
*(--s) = '\0';
} else if ( strcmp( s, REQUEST ) == 0 ) {
type = GROUP_REQUEST;
*(--s) = '\0';
} else if ( strcmp( s, MEMBERS ) == 0 ) {
type = GROUP_MEMBERS;
*(--s) = '\0';
}
}
do_address( argv[i], &tolist, &numto, &togroups, &ngroups,
&errlist, &numerr, type );
}
/*
* If we have both errors and successful deliveries to make or if
* if there are any groups to deliver to, we basically need to read
* the message twice. So, we have to put it in a tmp file.
*/
if ( numerr > 0 && numto > nargs || ngroups > 0 ) {
FILE *fp;
char buf[BUFSIZ];
umask( 077 );
if ( (fp = tmpfile()) == NULL ) {
syslog( LOG_ALERT, "could not open tmp file" );
unbind_and_exit( EX_TEMPFAIL );
}
/* copy the message to a temp file */
while ( fgets( buf, sizeof(buf), stdin ) != NULL ) {
if ( fputs( buf, fp ) == EOF ) {
syslog( LOG_ALERT, "error writing tmpfile" );
unbind_and_exit( EX_TEMPFAIL );
}
}
if ( dup2( fileno( fp ), 0 ) == -1 ) {
syslog( LOG_ALERT, "could not dup2 tmpfile" );
unbind_and_exit( EX_TEMPFAIL );
}
fclose( fp );
}
/* deal with errors */
if ( numerr > 0 ) {
(void) rewind( stdin );
send_errors( errlist, numerr );
}
(void) ldap_unbind( ld );
/* send to groups with errorsTo */
if ( ngroups > 0 ) {
(void) rewind( stdin );
send_group( togroups, ngroups );
}
/* send to expanded aliases and groups w/o errorsTo */
if ( numto > nargs ) {
(void) rewind( stdin );
send_message( tolist );
}
return( EX_OK );
}
static int
connect_to_x500( void )
{
int sizelimit = FAX_MAXAMBIGUOUS;
int deref = LDAP_DEREF_ALWAYS;
if ( (ld = ldap_init( NULL, 0 )) == NULL ) {
syslog( LOG_ALERT, "ldap_init failed" );
return( -1 );
}
ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
syslog( LOG_ALERT, "ldap_simple_bind_s failed" );
return( -1 );
}
return( 0 );
}
static void
do_address(
char *name,
char ***to,
int *nto,
Group **togroups,
int *ngroups,
Error **err,
int *nerr,
int type
)
{
int rc, b, f, match;
LDAPMessage *e, *res;
struct timeval timeout;
char *dn;
char filter[1024];
char **mail;
char **fax;
/*
* Look up the name in X.500, add the appropriate addresses found
* to the to list, or to the err list in case of error. Groups are
* handled by the do_group routine, individuals are handled here.
* When looking up name, we follow the bases hierarchy, looking
* in base[0] first, then base[1], etc. For each base, there is
* a set of search filters to try, in order. If something goes
* wrong here trying to contact X.500, we exit with EX_TEMPFAIL.
* If the b_rdnpref flag is set, then we give preference to entries
* that matched name because it's their rdn, otherwise not.
*/
timeout.tv_sec = FAX_TIMEOUT;
timeout.tv_usec = 0;
for ( b = 0, match = 0; !match && base[b].b_dn != NULL; b++ ) {
for ( f = 0; base[b].b_filter[f] != NULL; f++ ) {
char *format, *p, *argv[3];
int argc;
for ( argc = 0; argc < 3; argc++ ) {
argv[argc] = NULL;
}
format = strdup( base[b].b_filter[f] );
for ( argc = 0, p = format; *p; p++ ) {
if ( *p == '%' ) {
switch ( *++p ) {
case 's': /* %s is the name */
argv[argc] = name;
break;
case 'h': /* %h is the host */
*p = 's';
argv[argc] = host;
break;
default:
syslog( LOG_ALERT,
"unknown format %c", *p );
break;
}
argc++;
}
}
/* three names ought to do... */
sprintf( filter, format, argv[0], argv[1], argv[2] );
free( format );
res = NULL;
rc = ldap_search_st( ld, base[b].b_dn,
LDAP_SCOPE_SUBTREE, filter, attrs, 0, &timeout,
&res );
/* some other trouble - try again later */
if ( rc != LDAP_SUCCESS &&
rc != LDAP_SIZELIMIT_EXCEEDED ) {
syslog( LOG_ALERT, "return %d from X.500", rc );
unbind_and_exit( EX_TEMPFAIL );
}
if ( (match = ldap_count_entries( ld, res )) != 0 )
break;
ldap_msgfree( res );
}
if ( match )
break;
}
/* trouble - try again later */
if ( match == -1 ) {
syslog( LOG_ALERT, "error parsing result from X.500" );
unbind_and_exit( EX_TEMPFAIL );
}
/* no matches - bounce with user unknown */
if ( match == 0 ) {
add_error( err, nerr, E_USERUNKNOWN, name, NULL );
return;
}
/* more than one match - bounce with ambiguous user? */
if ( match > 1 ) {
LDAPMessage *next, *tmpres = NULL;
char *dn;
char **xdn;
/* not giving rdn preference - bounce with ambiguous user */
if ( base[b].b_rdnpref == 0 ) {
add_error( err, nerr, E_AMBIGUOUS, name, res );
return;
}
/*
* giving rdn preference - see if any entries were matched
* because of their rdn. If so, collect them to deal with
* later (== 1 we deliver, > 1 we bounce).
*/
for ( e = ldap_first_entry( ld, res ); e != NULL; e = next ) {
next = ldap_next_entry( ld, e );
dn = ldap_get_dn( ld, e );
xdn = ldap_explode_dn( dn, 1 );
/* XXX bad, but how else can we do it? XXX */
if ( strcasecmp( xdn[0], name ) == 0 ) {
ldap_delete_result_entry( &res, e );
ldap_add_result_entry( &tmpres, e );
}
ldap_value_free( xdn );
free( dn );
}
/* nothing matched by rdn - go ahead and bounce */
if ( tmpres == NULL ) {
add_error( err, nerr, E_AMBIGUOUS, name, res );
return;
/* more than one matched by rdn - bounce with rdn matches */
} else if ( (match = ldap_count_entries( ld, tmpres )) > 1 ) {
add_error( err, nerr, E_AMBIGUOUS, name, tmpres );
return;
/* trouble... */
} else if ( match < 0 ) {
syslog( LOG_ALERT, "error parsing result from X.500" );
unbind_and_exit( EX_TEMPFAIL );
}
/* otherwise one matched by rdn - send to it */
ldap_msgfree( res );
res = tmpres;
}
/*
* if we get this far, it means that we found a single match for
* name. for a user, we deliver to the mail attribute or bounce
* with address and phone if no mail attr. for a group, we
* deliver to all members or bounce to rfc822ErrorsTo if no members.
*/
/* trouble */
if ( (e = ldap_first_entry( ld, res )) == NULL ) {
syslog( LOG_ALERT, "error parsing entry from X.500" );
unbind_and_exit( EX_TEMPFAIL );
}
dn = ldap_get_dn( ld, e );
if ( type == GROUP_ERRORS ) {
/* sent to group-errors - resend to [rfc822]ErrorsTo attr */
do_group_errors( e, dn, to, nto, err, nerr );
} else if ( type == GROUP_REQUEST ) {
/* sent to group-request - resend to [rfc822]RequestsTo attr */
do_group_request( e, dn, to, nto, err, nerr );
} else if ( type == GROUP_MEMBERS ) {
/* sent to group-members - expand */
do_group_members( e, dn, to, nto, togroups, ngroups, err,
nerr );
} else if ( isgroup( e ) ) {
/*
* sent to group - resend from [rfc822]ErrorsTo if it's there,
* otherwise, expand the group
*/
do_group( e, dn, to, nto, togroups, ngroups, err, nerr );
ldap_msgfree( res );
} else {
/*
* sent to user - mail attribute => add it to the to list,
* otherwise bounce
*/
switch (identity) {
case FAX500 :
if ( (mail = ldap_get_values( ld, e,
"facsimileTelephoneNumber" )) != NULL ) {
char *fdn;
char **ufn;
int i;
fdn = ldap_get_dn( ld, e );
ufn = ldap_explode_dn( fdn, 1 );
/* Convert spaces to underscores for rp */
for (i = 0; ufn[0][i] != '\0'; i++) {
if (ufn[0][i] == ' ') {
ufn[0][i] = '_';
}
}
*mail = faxtotpc(*mail, ufn[0]);
add_to(to, nto, mail);
if (fdn != NULL) {
free(fdn);
}
ldap_value_free( ufn );
ldap_value_free( mail );
ldap_msgfree( res );
} else {
add_error( err, nerr, E_NOFAXNUM,
name, res );
}
break;
case MAIL500 :
if ( (mail = ldap_get_values( ld, e, "mail" ))
!= NULL ) {
add_to( to, nto, mail );
ldap_value_free( mail );
ldap_msgfree( res );
} else {
add_error( err, nerr, E_NOEMAIL,
name, res );
}
break;
}
}
free( dn );
return;
}
static int
do_group(
LDAPMessage *e,
char *dn,
char ***to,
int *nto,
Group **togroups,
int *ngroups,
Error **err,
int *nerr
)
{
/*
* If this group has an rfc822ErrorsTo attribute, we need to
* arrange for errors involving this group to go there, not
* to the sender. Since sendmail only has the concept of a
* single sender, we arrange for errors to go to groupname-errors,
* which we then handle specially when (if) it comes back to us
* by expanding to all the rfc822ErrorsTo addresses. If it has no
* rfc822ErrorsTo attribute, we call do_group_members() to expand
* the group.
*/
if ( group_loop( dn ) ) {
return( -1 );
}
if ( has_attributes( e, "rfc822ErrorsTo", "errorsTo" ) ) {
add_group( dn, togroups, ngroups );
return( 0 );
}
do_group_members( e, dn, to, nto, togroups, ngroups, err, nerr );
return( 0 );
}
/* ARGSUSED */
static void
do_group_members(
LDAPMessage *e,
char *dn,
char ***to,
int *nto,
Group **togroups,
int *ngroups,
Error **err,
int *nerr
)
{
int i, rc;
char *ndn;
char **mail, **member, **joinable;
char filter[256];
LDAPMessage *ee, *res;
struct timeval timeout;
/*
* if all has gone according to plan, we've already arranged for
* errors to go to the [rfc822]ErrorsTo attributes (if they exist),
* so all we have to do here is arrange to send to the
* rfc822Mailbox attribute, the member attribute, and anyone who
* has joined the group by setting memberOfGroup equal to the
* group dn.
*/
/* add members in the group itself - mail attribute */
if ( (mail = ldap_get_values( ld, e, "mail" )) != NULL ) {
/*
* These are only email addresses - impossible
* to have a fax number
*/
switch (identity) {
case FAX500 :
/* XXX How do we want to inform sender that the */
/* group they sent to has email-only members? */
break;
case MAIL500 :
add_to( to, nto, mail );
break;
}
ldap_value_free( mail );
}
/* add members in the group itself - member attribute */
if ( (member = ldap_get_values( ld, e, "member" )) != NULL ) {
for ( i = 0; member[i] != NULL; i++ ) {
add_member( dn, member[i], to, nto, togroups,
ngroups, err, nerr );
}
ldap_value_free( member );
}
/* add members who have joined by setting memberOfGroup */
if ( (joinable = ldap_get_values( ld, e, "joinable" )) != NULL ) {
if ( strcasecmp( joinable[0], "FALSE" ) == 0 ) {
ldap_value_free( joinable );
return;
}
ldap_value_free( joinable );
sprintf( filter, "(memberOfGroup=%s)", dn );
timeout.tv_sec = FAX_TIMEOUT;
timeout.tv_usec = 0;
/* for each subtree to look in... */
{
int sizelimit = FAX_MAXMEMBERS;
ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
}
for ( i = 0; base[i].b_dn != NULL; i++ ) {
/* find entries that have joined this group... */
rc = ldap_search_st( ld, base[i].b_dn,
LDAP_SCOPE_SUBTREE, filter, attrs, 0, &timeout,
&res );
if ( rc == LDAP_SIZELIMIT_EXCEEDED ||
rc == LDAP_TIMELIMIT_EXCEEDED ) {
syslog( LOG_ALERT,
"group search limit exceeded %d", rc );
unbind_and_exit( EX_TEMPFAIL );
}
if ( rc != LDAP_SUCCESS ) {
syslog( LOG_ALERT, "group search bad return %d",
rc );
unbind_and_exit( EX_TEMPFAIL );
}
/* for each entry that has joined... */
for ( ee = ldap_first_entry( ld, res ); ee != NULL;
ee = ldap_next_entry( ld, ee ) ) {
if ( isgroup( ee ) ) {
ndn = ldap_get_dn( ld, ee );
if ( do_group( e, ndn, to, nto,
togroups, ngroups, err, nerr )
== -1 ) {
syslog( LOG_ALERT,
"group loop (%s) (%s)",
dn, ndn );
}
free( ndn );
continue;
}
/* add them to the to list */
switch (identity) {
case FAX500 :
if ( (mail = ldap_get_values( ld, ee,
"facsimileTelephoneNumber" ))
!= NULL ) {
char *fdn;
char **ufn;
int i;
fdn = ldap_get_dn( ld, ee );
ufn = ldap_explode_dn( fdn, 1 );
/*
* Convert spaces to
* underscores for rp
*/
for (i = 0; ufn[0][i] != '\0';
i++) {
if (ufn[0][i] == ' ') {
ufn[0][i] = '_';
}
}
*mail = faxtotpc(*mail, ufn[0]);
add_to(to, nto, mail);
ldap_value_free( mail );
ldap_msgfree( res );
} else {
ndn = ldap_get_dn( ld, ee );
add_error( err, nerr,
E_JOINMEMBERNOFAXNUM, ndn,
NULL );
free( ndn );
}
break;
case MAIL500 :
if ( (mail = ldap_get_values( ld, ee,
"mail" )) != NULL ) {
add_to( to, nto, mail );
ldap_value_free( mail );
/* else generate a bounce */
} else {
ndn = ldap_get_dn( ld, ee );
add_error( err, nerr,
E_JOINMEMBERNOEMAIL, ndn,
NULL );
free( ndn );
}
break;
}
}
ldap_msgfree( res );
}
{
int sizelimit = FAX_MAXAMBIGUOUS;
ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
}
}
return;
}
static void
add_member(
char *gdn,
char *dn,
char ***to,
int *nto,
Group **togroups,
int *ngroups,
Error **err,
int *nerr
)
{
char *ndn;
char **mail;
int rc;
LDAPMessage *res, *e;
struct timeval timeout;
timeout.tv_sec = FAX_TIMEOUT;
timeout.tv_usec = 0;
if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "(objectclass=*)",
attrs, 0, &timeout, &res )) != LDAP_SUCCESS ) {
if ( rc == LDAP_NO_SUCH_OBJECT ) {
add_error( err, nerr, E_BADMEMBER, dn, NULL );
return;
} else {
syslog( LOG_ALERT, "member search bad return %d", rc );
unbind_and_exit( EX_TEMPFAIL );
}
}
if ( (e = ldap_first_entry( ld, res )) == NULL ) {
syslog( LOG_ALERT, "member search error parsing entry" );
unbind_and_exit( EX_TEMPFAIL );
}
ndn = ldap_get_dn( ld, e );
/* allow groups within groups */
if ( isgroup( e ) ) {
if ( do_group( e, ndn, to, nto, togroups, ngroups, err, nerr )
== -1 ) {
syslog( LOG_ALERT, "group loop (%s) (%s)", gdn, ndn );
}
free( ndn );
return;
}
switch (identity) {
case FAX500 :
if ( (mail = ldap_get_values( ld, e,
"facsimileTelephoneNumber" )) != NULL ) {
char *fdn;
char **ufn;
int i;
fdn = ldap_get_dn( ld, e );
ufn = ldap_explode_dn( fdn, 1 );
/* Convert spaces to underscores for rp */
for (i = 0; ufn[0][i] != '\0'; i++) {
if (ufn[0][i] == ' ') {
ufn[0][i] = '_';
}
}
*mail = faxtotpc(*mail, ufn[0]);
add_to(to, nto, mail);
ldap_value_free( mail );
ldap_msgfree( res );
} else {
add_error( err, nerr, E_MEMBERNOFAXNUM, ndn, NULL );
}
break;
case MAIL500 :
/* send to the member's mail attribute */
if ( (mail = ldap_get_values( ld, e, "mail" )) != NULL ) {
add_to( to, nto, mail );
ldap_value_free( mail );
/* else generate a bounce */
} else {
add_error( err, nerr, E_MEMBERNOEMAIL, ndn, NULL );
}
free( ndn );
}
return;
}
static void
do_group_request(
LDAPMessage *e,
char *dn,
char ***to,
int *nto,
Error **err,
int *nerr
)
{
char **requeststo;
if ( (requeststo = get_attributes_mail_dn( e, "rfc822RequestsTo",
"requestsTo" )) != NULL ) {
add_to( to, nto, requeststo );
ldap_value_free( requeststo );
} else {
add_error( err, nerr, E_NOREQUEST, dn, NULL );
}
}
static void
do_group_errors(
LDAPMessage *e,
char *dn,
char ***to,
int *nto,
Error **err,
int *nerr
)
{
char **errorsto;
if ( (errorsto = get_attributes_mail_dn( e, "rfc822ErrorsTo",
"errorsTo" )) != NULL ) {
add_to( to, nto, errorsto );
ldap_value_free( errorsto );
} else {
add_error( err, nerr, E_NOERRORS, dn, NULL );
}
}
static void
send_message( char **to )
{
int pid;
#ifndef HAVE_WAITPID
WAITSTATUSTYPE status;
#endif
/* parent */
if ( (pid = fork()) != 0 ) {
#ifdef HAVE_WAITPID
waitpid( pid, (int *) NULL, 0 );
#else
wait4( pid, &status, WAIT_FLAGS, 0 );
#endif
/* child */
} else {
/* to includes sendmailargs */
execv( FAX_SENDMAIL, to );
syslog( LOG_ALERT, "execv failed" );
exit( EX_TEMPFAIL );
}
}
static void
send_group( Group *group, int ngroup )
{
int i, pid;
char **argv;
int argc;
char *iargv[7];
#ifndef HAVE_WAITPID
WAITSTATUSTYPE status;
#endif
for ( i = 0; i < ngroup; i++ ) {
(void) rewind( stdin );
iargv[0] = FAX_SENDMAIL;
iargv[1] = "-f";
iargv[2] = group[i].g_errorsto;
iargv[3] = "-oMrX.500";
iargv[4] = "-odi";
iargv[5] = "-oi";
iargv[6] = NULL;
argv = NULL;
argc = 0;
add_to( &argv, &argc, iargv );
add_to( &argv, &argc, group[i].g_members );
/* parent */
if ( (pid = fork()) != 0 ) {
#ifdef HAVE_WAITPID
waitpid( pid, (int *) NULL, 0 );
#else
wait4( pid, &status, WAIT_FLAGS, 0 );
#endif
/* child */
} else {
execv( FAX_SENDMAIL, argv );
syslog( LOG_ALERT, "execv failed" );
exit( EX_TEMPFAIL );
}
}
return;
}
static void
send_errors( Error *err, int nerr )
{
int i, namelen;
FILE *fp;
char buf[1024];
sprintf( buf, "%s -oMrX.500 -odi -oi -f %s %s", FAX_SENDMAIL, errorsfrom,
mailfrom );
if ( (fp = popen( buf, "w" )) == NULL ) {
syslog( LOG_ALERT, "could not popen sendmail for errs" );
return;
}
fprintf( fp, "To: %s\n", mailfrom );
fprintf( fp, "From: %s\n", errorsfrom );
fprintf( fp, "Subject: undeliverable mail\n" );
fprintf( fp, "\n" );
fprintf( fp, "The following errors occurred when trying to deliver the attached mail:\n" );
for ( i = 0; i < nerr; i++ ) {
namelen = strlen( err[i].e_addr );
fprintf( fp, "\n" );
switch ( err[i].e_code ) {
case E_USERUNKNOWN:
fprintf( fp, "%s: User unknown\n", err[i].e_addr );
break;
case E_BADMEMBER:
fprintf( fp, "%s: Group member does not exist\n",
err[i].e_addr );
break;
case E_NOREQUEST:
fprintf( fp, "%s: Group exists but has no request address\n",
err[i].e_addr );
break;
case E_NOERRORS:
fprintf( fp, "%s: Group exists but has no errors-to address\n",
err[i].e_addr );
break;
case E_AMBIGUOUS:
do_ambiguous( fp, &err[i], namelen );
break;
case E_NOEMAIL:
do_noemailorfax( fp, &err[i], namelen, E_NOEMAIL );
break;
case E_MEMBERNOEMAIL:
fprintf( fp, "%s: Group member exists but does not have an email address\n",
err[i].e_addr );
break;
case E_JOINMEMBERNOEMAIL:
fprintf( fp, "%s: User has joined group but does not have an email address\n",
err[i].e_addr );
break;
case E_NOFAXNUM:
do_noemailorfax( fp, &err[i], namelen, E_NOFAXNUM );
break;
case E_MEMBERNOFAXNUM:
fprintf( fp, "%s: Group member exists but does not have a fax number\n",
err[i].e_addr );
break;
case E_JOINMEMBERNOFAXNUM:
fprintf( fp, "%s: User has joined group but does not have a fax number\n",
err[i].e_addr );
break;
default:
syslog( LOG_ALERT, "unknown error %d", err[i].e_code );
unbind_and_exit( EX_TEMPFAIL );
break;
}
}
fprintf( fp, "\n------- The original message sent:\n\n" );
while ( fgets( buf, sizeof(buf), stdin ) != NULL ) {
fputs( buf, fp );
}
if ( pclose( fp ) == -1 ) {
syslog( LOG_ALERT, "pclose failed" );
unbind_and_exit( EX_TEMPFAIL );
}
return;
}
static void
do_noemailorfax( FILE *fp, Error *err, int namelen, int errtype )
{
int i, last;
char *dn, *rdn;
char **ufn, **vals;
if (errtype == E_NOFAXNUM) {
fprintf(fp, "%s: User has no facsimile number registered.\n",
err->e_addr );
} else if (errtype == E_NOEMAIL) {
fprintf(fp, "%s: User has no email address registered.\n",
err->e_addr );
}
fprintf( fp, "%*s Name, title, postal address and phone for '%s':\n\n",
namelen, " ", err->e_addr );
/* name */
dn = ldap_get_dn( ld, err->e_msg );
ufn = ldap_explode_dn( dn, 1 );
rdn = strdup( ufn[0] );
if ( strcasecmp( rdn, err->e_addr ) == 0 ) {
if ( (vals = ldap_get_values( ld, err->e_msg, "cn" ))
!= NULL ) {
for ( i = 0; vals[i]; i++ ) {
last = strlen( vals[i] ) - 1;
if ( isdigit((unsigned char) vals[i][last]) ) {
rdn = strdup( vals[i] );
break;
}
}
ldap_value_free( vals );
}
}
fprintf( fp, "%*s %s\n", namelen, " ", rdn );
free( dn );
free( rdn );
ldap_value_free( ufn );
/* titles or descriptions */
if ( (vals = ldap_get_values( ld, err->e_msg, "title" )) == NULL &&
(vals = ldap_get_values( ld, err->e_msg, "description" ))
== NULL ) {
fprintf( fp, "%*s No title or description registered\n",
namelen, " " );
} else {
for ( i = 0; vals[i] != NULL; i++ ) {
fprintf( fp, "%*s %s\n", namelen, " ", vals[i] );
}
ldap_value_free( vals );
}
/* postal address */
if ( (vals = ldap_get_values( ld, err->e_msg, "postalAddress" ))
== NULL ) {
fprintf( fp, "%*s No postal address registered\n", namelen,
" " );
} else {
fprintf( fp, "%*s ", namelen, " " );
for ( i = 0; vals[0][i] != '\0'; i++ ) {
if ( vals[0][i] == '$' ) {
fprintf( fp, "\n%*s ", namelen, " " );
while ( isspace((unsigned char) vals[0][i+1]) )
i++;
} else {
fprintf( fp, "%c", vals[0][i] );
}
}
fprintf( fp, "\n" );
ldap_value_free( vals );
}
/* telephone number */
if ( (vals = ldap_get_values( ld, err->e_msg, "telephoneNumber" ))
== NULL ) {
fprintf( fp, "%*s No phone number registered\n", namelen,
" " );
} else {
for ( i = 0; vals[i] != NULL; i++ ) {
fprintf( fp, "%*s %s\n", namelen, " ", vals[i] );
}
ldap_value_free( vals );
}
}
/* ARGSUSED */
static void
do_ambiguous( FILE *fp, Error *err, int namelen )
{
int i, last;
char *dn, *rdn;
char **ufn, **vals;
LDAPMessage *e;
i = ldap_result2error( ld, err->e_msg, 0 );
fprintf( fp, "%s: Ambiguous user. %s%d matches found:\n\n",
err->e_addr, i == LDAP_SIZELIMIT_EXCEEDED ? "First " : "",
ldap_count_entries( ld, err->e_msg ) );
for ( e = ldap_first_entry( ld, err->e_msg ); e != NULL;
e = ldap_next_entry( ld, e ) ) {
dn = ldap_get_dn( ld, e );
ufn = ldap_explode_dn( dn, 1 );
rdn = strdup( ufn[0] );
if ( strcasecmp( rdn, err->e_addr ) == 0 ) {
if ( (vals = ldap_get_values( ld, e, "cn" )) != NULL ) {
for ( i = 0; vals[i]; i++ ) {
last = strlen( vals[i] ) - 1;
if ( isdigit((unsigned char) vals[i][last]) ) {
rdn = strdup( vals[i] );
break;
}
}
ldap_value_free( vals );
}
}
if ( isgroup( e ) ) {
vals = ldap_get_values( ld, e, "description" );
} else {
vals = ldap_get_values( ld, e, "title" );
}
fprintf( fp, " %-20s %s\n", rdn, vals ? vals[0] : "" );
for ( i = 1; vals && vals[i] != NULL; i++ ) {
fprintf( fp, " %s\n", vals[i] );
}
free( dn );
free( rdn );
ldap_value_free( ufn );
if ( vals != NULL )
ldap_value_free( vals );
}
}
static int
count_values( char **list )
{
int i;
for ( i = 0; list && list[i] != NULL; i++ )
; /* NULL */
return( i );
}
static void
add_to( char ***list, int *nlist, char **new )
{
int i, nnew, oldnlist;
nnew = count_values( new );
oldnlist = *nlist;
if ( *list == NULL || *nlist == 0 ) {
*list = (char **) malloc( (nnew + 1) * sizeof(char *) );
*nlist = nnew;
} else {
*list = (char **) realloc( *list, *nlist * sizeof(char *) +
nnew * sizeof(char *) + sizeof(char *) );
*nlist += nnew;
}
for ( i = 0; i < nnew; i++ ) {
(*list)[i + oldnlist] = strdup( new[i] );
}
(*list)[*nlist] = NULL;
return;
}
static int
isgroup( LDAPMessage *e )
{
int i;
char **oclist;
oclist = ldap_get_values( ld, e, "objectClass" );
for ( i = 0; oclist[i] != NULL; i++ ) {
if ( strcasecmp( oclist[i], "rfc822MailGroup" ) == 0 ) {
ldap_value_free( oclist );
return( 1 );
}
}
ldap_value_free( oclist );
return( 0 );
}
static void
add_error( Error **err, int *nerr, int code, char *addr, LDAPMessage *msg )
{
if ( *nerr == 0 ) {
*err = (Error *) malloc( sizeof(Error) );
} else {
*err = (Error *) realloc( *err, (*nerr + 1) * sizeof(Error) );
}
(*err)[*nerr].e_code = code;
(*err)[*nerr].e_addr = strdup( addr );
(*err)[*nerr].e_msg = msg;
(*nerr)++;
return;
}
static void
add_group( char *dn, Group **list, int *nlist )
{
int i, namelen;
char **ufn;
for ( i = 0; i < *nlist; i++ ) {
if ( strcmp( dn, (*list)[i].g_dn ) == 0 ) {
syslog( LOG_ALERT, "group loop 2 detected (%s)", dn );
return;
}
}
ufn = ldap_explode_dn( dn, 1 );
namelen = strlen( ufn[0] );
if ( *nlist == 0 ) {
*list = (Group *) malloc( sizeof(Group) );
} else {
*list = (Group *) realloc( *list, (*nlist + 1) *
sizeof(Group) );
}
/* send errors to groupname-errors@host */
(*list)[*nlist].g_errorsto = (char *) malloc( namelen + sizeof(ERRORS)
+ hostlen + 2 );
sprintf( (*list)[*nlist].g_errorsto, "%s-%s@%s", ufn[0], ERRORS, host );
(void) canonical( (*list)[*nlist].g_errorsto );
/* send to groupname-members@host - make it a list for send_group */
(*list)[*nlist].g_members = (char **) malloc( 2 * sizeof(char *) );
(*list)[*nlist].g_members[0] = (char *) malloc( namelen +
sizeof(MEMBERS) + hostlen + 2 );
sprintf( (*list)[*nlist].g_members[0], "%s-%s@%s", ufn[0], MEMBERS,
host );
(void) canonical( (*list)[*nlist].g_members[0] );
(*list)[*nlist].g_members[1] = NULL;
/* save the group's dn so we can check for loops above */
(*list)[*nlist].g_dn = strdup( dn );
(*nlist)++;
ldap_value_free( ufn );
return;
}
static void
unbind_and_exit( int rc )
{
int i;
if ( (i = ldap_unbind( ld )) != LDAP_SUCCESS )
syslog( LOG_ALERT, "ldap_unbind failed %d\n", i );
exit( rc );
}
static char *
canonical( char *s )
{
char *saves = s;
for ( ; *s != '\0'; s++ ) {
if ( *s == ' ' )
*s = '.';
}
return( saves );
}
static int
group_loop( char *dn )
{
int i;
static char **groups;
static int ngroups;
for ( i = 0; i < ngroups; i++ ) {
if ( strcmp( dn, groups[i] ) == 0 )
return( 1 );
}
if ( ngroups == 0 )
groups = (char **) malloc( sizeof(char *) );
else
groups = (char **) realloc( groups,
(ngroups + 1) * sizeof(char *) );
groups[ngroups++] = strdup( dn );
return( 0 );
}
static int
has_attributes( LDAPMessage *e, char *attr1, char *attr2 )
{
char **attr;
if ( (attr = ldap_get_values( ld, e, attr1 )) != NULL ) {
ldap_value_free( attr );
return( 1 );
}
if ( (attr = ldap_get_values( ld, e, attr2 )) != NULL ) {
ldap_value_free( attr );
return( 1 );
}
return( 0 );
}
static char **
get_attributes_mail_dn( LDAPMessage *e, char *attr1, char *attr2 )
{
LDAPMessage *ee, *res;
char **vals, **dnlist, **mail;
int nto, i, rc;
struct timeval timeout;
vals = ldap_get_values( ld, e, attr1 );
for ( nto = 0; vals != NULL && vals[nto] != NULL; nto++ )
; /* NULL */
if ( (dnlist = ldap_get_values( ld, e, attr2 )) != NULL ) {
timeout.tv_sec = FAX_TIMEOUT;
timeout.tv_usec = 0;
for ( i = 0; dnlist[i] != NULL; i++ ) {
if ( (rc = ldap_search_st( ld, dnlist[i],
LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0,
&timeout, &res )) != LDAP_SUCCESS ) {
if ( rc != LDAP_NO_SUCH_OBJECT ) {
unbind_and_exit( EX_TEMPFAIL );
}
syslog( LOG_ALERT, "bad (%s) dn (%s)", attr2,
dnlist[i] );
continue;
}
if ( (ee = ldap_first_entry( ld, res )) == NULL ) {
syslog( LOG_ALERT, "error parsing x500 entry" );
continue;
}
if ( (mail = ldap_get_values( ld, ee, "mail" ))
!= NULL ) {
add_to( &vals, &nto, mail );
ldap_value_free( mail );
}
ldap_msgfree( res );
}
}
return( vals );
}
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/ctype.h>
#include <ac/signal.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/syslog.h>
#include <ac/time.h>
#include <ac/unistd.h>
#include <ac/wait.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#include <lber.h>
#include <ldap.h>
#include "fax500.h"
#include "ldap_defaults.h"
#define DEFAULT_PORT 79
#define DEFAULT_SIZELIMIT 50
int debug;
char *ldaphost = NULL;
char *base = NULL;
int deref = LDAP_DEREF_ALWAYS;
int sizelimit = DEFAULT_SIZELIMIT;
LDAPFiltDesc *filtd;
static void print_entry(LDAP *ld, LDAPMessage *e);
static void
usage( char *name )
{
fprintf( stderr, "usage: %s [-d debuglevel] [-x ldaphost] [-b searchbase] [-a] [-z sizelimit] [-f filterfile] searchstring\r\n", name );
exit( -1 );
}
int
main( int argc, char **argv )
{
int i, rc, matches;
char *filterfile = FILTERFILE;
char buf[10];
char *key;
LDAP *ld;
LDAPMessage *result, *e;
LDAPFiltDesc *filtd;
LDAPFiltInfo *fi;
static char *attrs[] = { "title", "o", "ou", "postalAddress",
"telephoneNumber", "mail",
"facsimileTelephoneNumber", NULL };
while ( (i = getopt( argc, argv, "ab:d:f:x:z:" )) != EOF ) {
switch( i ) {
case 'a': /* do not deref aliases when searching */
deref = LDAP_DEREF_FINDING;
break;
case 'b': /* search base */
base = strdup( optarg );
break;
case 'd': /* turn on debugging */
debug = atoi( optarg );
break;
case 'f': /* ldap filter file */
filterfile = strdup( optarg );
break;
case 'x': /* specify ldap host */
ldaphost = strdup( optarg );
break;
case 'z': /* size limit */
sizelimit = atoi( optarg );
break;
default:
usage( argv[0] );
}
}
if ( optind == argc ) {
usage( argv[0] );
}
key = argv[optind];
if ( (filtd = ldap_init_getfilter( filterfile )) == NULL ) {
fprintf( stderr, "Cannot open filter file (%s)\n", filterfile );
exit( -1 );
}
#ifdef SIGPIPE
(void) SIGNAL( SIGPIPE, SIG_IGN );
#endif
if ( (ld = ldap_init( ldaphost, 0 )) == NULL ) {
perror( "ldap_init" );
exit( -1 );
}
ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
fprintf( stderr, "X.500 is temporarily unavailable.\n" );
ldap_perror( ld, "ldap_simple_bind_s" );
exit( -1 );
}
result = NULL;
if ( strchr( key, ',' ) != NULL ) {
int ld_deref = LDAP_DEREF_FINDING;
ldap_set_option(ld, LDAP_OPT_DEREF, &ld_deref);
if ( (rc = ldap_ufn_search_s( ld, key, attrs, 0, &result ))
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED &&
rc != LDAP_TIMELIMIT_EXCEEDED )
{
ldap_perror( ld, "ldap_ufn_search_s" );
exit( -1 );
}
matches = ldap_count_entries( ld, result );
} else {
for ( fi = ldap_getfirstfilter( filtd, "rp500", key );
fi != NULL; fi = ldap_getnextfilter( filtd ) ) {
if ( (rc = ldap_search_s( ld, base, LDAP_SCOPE_SUBTREE,
fi->lfi_filter, attrs, 0, &result ))
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
&& rc != LDAP_TIMELIMIT_EXCEEDED )
{
ldap_perror( ld, "ldap_search" );
exit( -1 );
}
if ( (matches = ldap_count_entries( ld, result )) != 0
|| rc != LDAP_SUCCESS ) {
break;
}
}
}
if ( matches == 1 ) {
e = ldap_first_entry( ld, result );
print_entry( ld, e );
} else if ( matches > 1 ) {
fprintf( stderr, "%d %s matches for \"%s\":\r\n", matches,
fi->lfi_desc, key );
for ( i = 1, e = ldap_first_entry( ld, result ); e != NULL;
i++, e = ldap_next_entry( ld, e ) ) {
int j;
char *p, *dn, *rdn;
char **title;
dn = ldap_get_dn( ld, e );
rdn = dn;
if ( (p = strchr( dn, ',' )) != NULL )
*p = '\0';
while ( *rdn && *rdn != '=' )
rdn++;
if ( *rdn )
rdn++;
if ( strcasecmp( rdn, buf ) == 0 ) {
char **cn;
int i, last;
cn = ldap_get_values( ld, e, "cn" );
for ( i = 0; cn[i] != NULL; i++ ) {
last = strlen( cn[i] ) - 1;
if ( isdigit((unsigned char) cn[i][last]) ) {
rdn = strdup( cn[i] );
break;
}
}
}
title = ldap_get_values( ld, e, "title" );
fprintf( stderr, " %d: %-20s %s\r\n", i, rdn,
title ? title[0] : "" );
if ( title != NULL ) {
for ( j = 1; title[j] != NULL; j++ )
fprintf( stderr, " %-20s %s\r\n",
"", title[j] );
}
if ( title != NULL )
ldap_value_free( title );
free( dn );
}
if ( rc == LDAP_SIZELIMIT_EXCEEDED
|| rc == LDAP_TIMELIMIT_EXCEEDED ) {
fprintf( stderr, "(Size or time limit exceeded)\n" );
}
fprintf( stderr, "Enter the number of the person you want: ");
if ( fgets( buf, sizeof(buf), stdin ) == NULL
|| buf[0] == '\n' ) {
exit( EXIT_FAILURE );
}
i = atoi( buf ) - 1;
e = ldap_first_entry( ld, result );
for ( ; i > 0 && e != NULL; i-- ) {
e = ldap_next_entry( ld, e );
}
if ( e == NULL ) {
fprintf( stderr, "Invalid choice!\n" );
exit( EXIT_FAILURE );
}
print_entry( ld, e );
} else if ( matches == 0 ) {
fprintf( stderr, "No matches found for \"%s\"\n", key );
exit( EXIT_FAILURE );
} else {
fprintf( stderr, "Error return from ldap_count_entries\n" );
exit( -1 );
}
ldap_unbind( ld );
return( 0 );
}
static void
print_entry( LDAP *ld, LDAPMessage *e )
{
int i;
char *dn, *rdn;
char **ufn;
char **title, **dept, **addr, **phone, **fax, **mail;
char *faxmail, *org;
dn = ldap_get_dn( ld, e );
ufn = ldap_explode_dn( dn, 0 );
rdn = strchr( ufn[0], '=' ) + 1;
if ( (fax = ldap_get_values( ld, e, "facsimileTelephoneNumber" ))
== NULL ) {
fprintf( stderr, "Entry \"%s\" has no fax number.\n", dn );
exit( EXIT_FAILURE );
}
faxmail = faxtotpc( fax[0], NULL );
title = ldap_get_values( ld, e, "title" );
phone = ldap_get_values( ld, e, "telephoneNumber" );
mail = ldap_get_values( ld, e, "mail" );
dept = ldap_get_values( ld, e, "ou" );
addr = ldap_get_values( ld, e, "postalAddress" );
org = "";
for ( i = 0; ufn[i] != NULL; i++ ) {
if ( strncmp( "o=", ufn[i], 2 ) == 0 ) {
org = strdup( strchr( ufn[i], '=' ) + 1 );
break;
}
}
printf( "To: %s\n", faxmail );
printf( "Subject:\n" );
printf( "--------\n" );
printf( "#<application/remote-printing\n" );
printf( "Recipient: %s\r\n", rdn );
printf( "Title: %s\r\n", title ? title[0] : "" );
printf( "Organization: %s\r\n", org );
printf( "Department: %s\r\n", dept ? dept[0] : "" );
printf( "Telephone: %s\r\n", phone ? phone[0] : "" );
printf( "Facsimile: %s\r\n", fax ? fax[0] : "" );
printf( "Email: %s\r\n", mail ? mail[0] : "" );
}
#! /bin/sh
RP500=%LIBEXECDIR%/rp500
NAME="$1"
if [ -z "$NAME" ]; then
echo "usage: xrpcomp name [arguments for comp]" 2>&1
exit 1
fi
DB=".rpdb"
if [ ! -s "$DB" ]; then
DB="$HOME/.rpdb"
fi
if [ ! -s "$DB" ]; then
echo "unable to read $DB" 2>&1
exit 1
fi
C=/tmp/rp$$.comp S=/tmp/rp$$.sh O=/tmp/rp$$.orig
trap "rm -f $C $S $O" 0 1 2 3 13 15
cp /dev/null $S
gawk -v NAME="$NAME" -v S="$S" -v O="$O" '
function rev(f) {
s = ""
for (l = length(f); l > 0; l--)
s = s "." substr(f, l, 1)
return substr(s, 2, length(s) - 1)
}
BEGIN {
RS= ""; FS = "\n"
}
{
if (NR == 1) {
from = $2
gsub("Recipient[ ]*:", "Originator:", from);
orig = "\r\n" from
for (i = 3; i <= NF; i++)
orig = orig "\r\n" $i;
printf orig "\r\n" > O
}
if ($1 != NAME)
next
for (i = 2; i <= NF; i++) {
if (match($i, "Facsimile[ ]*:") > 0) {
fax = substr($i, RSTART+RLENGTH)
gsub("[ +-]", "", fax)
printf "ADDR=\"remote-printer@%s.tpc.int\"\n", rev(fax) > S
printf "To: remote-printer@%s.tpc.int\n", rev(fax)
printf "Subject:\n"
printf "--------\n"
printf "#<application/remote-printing\n"
recip = $2
for (i = 3; i <= NF; i++)
recip = recip "\r\n" $i;
printf "%s\r\n%s\r\n", recip, orig
printf "#\n"
exit(0)
}
}
}' < $DB > $C
. $S
if [ -z "$ADDR" ]; then
echo "recipient \"$NAME\" not in $DB, checking X.500..." 2>&1
$RP500 "$NAME" > $C
RC=$?
if [ $RC = 1 ]; then
exit 1
elif [ $RC = 0 ]; then
cat $O >> $C
echo "#" >> $C
else
echo "error searching X.500" 2>&1
exit 1
fi
fi
shift
comp -form $C $* -editor rpprompter
SRCS= main.c
XSRCS= version.c
OBJS= main.o
PROGRAMS= in.xfingerd
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
XLIBS = -lldap -llber -llutil
XXLIBS = $(SECURITY_LIBS) $(LUTIL_LIBS)
in.xfingerd : version.o
$(LTLINK) -o $@ version.o $(OBJS) $(LIBS)
version.c: ${OBJS} ${LDAP_LIBDEPEND}
@-$(RM) $@
$(MKVERSION) in.xfingerd > $@
install-local: $(PROGRAMS) FORCE
-$(MKDIR) $(libexecdir)
$(LTINSTALL) $(INSTALLFLAGS) -m 755 in.xfingerd $(libexecdir)
/*
* Copyright (c) 1990,1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/ctype.h>
#include <ac/signal.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/syslog.h>
#include <ac/time.h>
#include <ac/unistd.h>
#include <ac/wait.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#include <ldap.h>
#include <disptmpl.h>
#include "ldap_defaults.h"
int dosyslog = 1;
char *ldaphost = NULL;
int ldapport = 0;
char *base = NULL;
int deref;
char *filterfile = FILTERFILE;
char *templatefile = TEMPLATEFILE;
int rdncount = FINGER_RDNCOUNT;
static void do_query(void);
static void do_search(LDAP *ld, char *buf);
static void do_read(LDAP *ld, LDAPMessage *e);
static void
usage( char *name )
{
fprintf( stderr, "usage: %s [-l] [-x ldaphost] [-p ldapport] [-f filterfile] [-t templatefile] [-c rdncount]\r\n", name );
exit( EXIT_FAILURE );
}
int
main( int argc, char **argv )
{
int i;
char *myname;
struct hostent *hp;
struct sockaddr_in peername;
socklen_t peernamelen;
int interactive = 0;
deref = FINGER_DEREF;
while ( (i = getopt( argc, argv, "f:ilp:t:x:p:c:" )) != EOF ) {
switch( i ) {
case 'f': /* ldap filter file */
filterfile = strdup( optarg );
break;
case 'i': /* interactive */
interactive = 1;
break;
case 'l': /* don't do syslogging */
dosyslog = 0;
break;
case 't': /* ldap template file */
templatefile = strdup( optarg );
break;
case 'x': /* specify ldap host */
ldaphost = strdup( optarg );
break;
case 'p': /* specify ldap port */
ldapport = atoi( optarg );
break;
case 'c': /* specify number of DN components to show */
rdncount = atoi( optarg );
break;
default:
usage( argv[0] );
}
}
if ( !interactive ) {
peernamelen = sizeof(peername);
if ( getpeername( 0, (struct sockaddr *)&peername,
&peernamelen ) != 0 ) {
perror( "getpeername" );
exit( EXIT_FAILURE );
}
}
#ifdef FINGER_BANNER
if ( FINGER_BANNER != NULL && strcmp( FINGER_BANNER, "" ) != 0 ) {
printf( FINGER_BANNER );
fflush( stdout );
}
#endif
if ( (myname = strrchr( argv[0], '/' )) == NULL )
myname = strdup( argv[0] );
else
myname = strdup( myname + 1 );
#ifdef SIGPIPE
(void) SIGNAL( SIGPIPE, SIG_IGN );
#endif
if ( dosyslog ) {
#ifdef LOG_LOCAL4
openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL4 );
#else
openlog( myname, OPENLOG_OPTIONS );
#endif
}
if ( dosyslog && !interactive ) {
hp = gethostbyaddr( (char *) &peername.sin_addr.s_addr,
sizeof(peername.sin_addr.s_addr), AF_INET );
syslog( LOG_INFO, "connection from %s (%s)",
(hp == NULL) ? "unknown" : hp->h_name,
inet_ntoa( peername.sin_addr ) );
}
do_query();
return( 0 );
}
static void
do_query( void )
{
char buf[256];
int len, rc, tblsize;
struct timeval timeout;
fd_set readfds;
LDAP *ld;
if ( (ld = ldap_init( ldaphost, ldapport )) == NULL ) {
fprintf( stderr, FINGER_UNAVAILABLE );
perror( "ldap_init" );
exit( EXIT_FAILURE );
}
{
int limit = FINGER_SIZELIMIT;
ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &limit);
}
ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
if ( ldap_simple_bind_s( ld, NULL, NULL )
!= LDAP_SUCCESS )
{
fprintf( stderr, FINGER_UNAVAILABLE );
ldap_perror( ld, "ldap_simple_bind_s" );
exit( EXIT_FAILURE );
}
#ifdef HAVE_SYSCONF
tblsize = sysconf( _SC_OPEN_MAX );
#elif HAVE_GETDTABLESIZE
tblsize = getdtablesize();
#else
tblsize = FD_SETSIZE;
#endif
#ifdef FD_SETSIZE
if (tblsize > FD_SETSIZE) {
tblsize = FD_SETSIZE;
}
#endif /* FD_SETSIZE*/
timeout.tv_sec = FINGER_TIMEOUT;
timeout.tv_usec = 0;
FD_ZERO( &readfds );
FD_SET( fileno( stdin ), &readfds );
if ( (rc = select( tblsize, &readfds, 0, 0, &timeout )) <= 0 ) {
if ( rc < 0 )
perror( "select" );
else
fprintf( stderr, "connection timed out on input\r\n" );
exit( EXIT_FAILURE );
}
if ( fgets( buf, sizeof(buf), stdin ) == NULL )
exit( EXIT_FAILURE );
len = strlen( buf );
/* strip off \r \n */
if ( buf[len - 1] == '\n' ) {
buf[len - 1] = '\0';
len--;
}
if ( buf[len - 1] == '\r' ) {
buf[len - 1] = '\0';
len--;
}
if ( len == 0 ) {
printf( "No campus-wide login information available. Info for this machine only:\r\n" );
fflush( stdout );
execl( FINGER_CMD, FINGER_CMD, NULL );
} else {
char *p;
/* skip and ignore stinking /w */
if ( strncmp( buf, "/W ", 2 ) == 0 ) {
p = buf + 2;
} else {
p = buf;
}
for ( ; *p && isspace( (unsigned char) *p ); p++ )
; /* NULL */
do_search( ld, p );
}
}
static void
spaces2dots( char *s )
{
for ( ; *s; s++ ) {
if ( *s == ' ' ) {
*s = '.';
}
}
}
static void
do_search( LDAP *ld, char *buf )
{
char *dn, *rdn;
char **title;
int rc, matches, i, ufn;
struct timeval tv;
LDAPFiltDesc *fd;
LDAPFiltInfo *fi;
LDAPMessage *result, *e;
static char *attrs[] = { "cn", "title", "objectClass", "joinable",
#ifdef FINGER_SORT_ATTR
FINGER_SORT_ATTR,
#endif
0 };
ufn = 0;
#ifdef FINGER_UFN
if ( strchr( buf, ',' ) != NULL ) {
ldap_ufn_setprefix( ld, base );
tv.tv_sec = FINGER_TIMEOUT;
tv.tv_usec = 0;
ldap_ufn_timeout( (void *) &tv );
if ( (rc = ldap_ufn_search_s( ld, buf, attrs, 0, &result ))
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED ) {
fprintf( stderr, FINGER_UNAVAILABLE );
ldap_perror( ld, "ldap_search_st" );
exit( EXIT_FAILURE );
}
matches = ldap_count_entries( ld, result );
ufn = 1;
} else {
#endif
if ( (fd = ldap_init_getfilter( filterfile ))
== NULL ) {
fprintf( stderr, "Cannot open filter file (%s)\n",
filterfile );
exit( EXIT_FAILURE );
}
for ( fi = ldap_getfirstfilter( fd, "finger", buf );
fi != NULL;
fi = ldap_getnextfilter( fd ) )
{
tv.tv_sec = FINGER_TIMEOUT;
tv.tv_usec = 0;
if ( (rc = ldap_search_st( ld, base, LDAP_SCOPE_SUBTREE,
fi->lfi_filter, attrs, 0, &tv, &result ))
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
&& rc != LDAP_TIMELIMIT_EXCEEDED )
{
fprintf( stderr, FINGER_UNAVAILABLE );
ldap_perror( ld, "ldap_search_st" );
exit( EXIT_FAILURE );
}
if ( (matches = ldap_count_entries( ld, result )) != 0 )
break;
ldap_msgfree( result );
result = NULL;
}
#ifdef FINGER_UFN
}
#endif
if ( rc == LDAP_SIZELIMIT_EXCEEDED ) {
printf( "(Partial results - a size limit was exceeded)\r\n" );
} else if ( rc == LDAP_TIMELIMIT_EXCEEDED ) {
printf( "(Partial results - a time limit was exceeded)\r\n" );
}
if ( matches == 0 ) {
printf( FINGER_NOMATCH );
fflush( stdout );
} else if ( matches < 0 ) {
fprintf( stderr, "error return from ldap_count_entries\r\n" );
exit( EXIT_FAILURE );
} else if ( matches <= FINGER_LISTLIMIT ) {
printf( "%d %s match%s found for \"%s\":\r\n", matches,
ufn ? "UFN" : fi->lfi_desc, matches > 1 ? "es" : "", buf );
fflush( stdout );
for ( e = ldap_first_entry( ld, result ); e != NULL; ) {
do_read( ld, e );
e = ldap_next_entry( ld, e );
if ( e != NULL ) {
printf( "--------------------\r\n" );
}
}
} else {
printf( "%d %s matches for \"%s\":\r\n", matches,
ufn ? "UFN" : fi->lfi_desc, buf );
fflush( stdout );
#ifdef FINGER_SORT_ATTR
ldap_sort_entries( ld, &result, FINGER_SORT_ATTR, strcasecmp );
#endif
for ( e = ldap_first_entry( ld, result ); e != NULL;
e = ldap_next_entry( ld, e ) ) {
char *p;
dn = ldap_get_dn( ld, e );
rdn = dn;
if ( (p = strchr( dn, ',' )) != NULL )
*p = '\0';
while ( *rdn && *rdn != '=' )
rdn++;
if ( *rdn )
rdn++;
/* hack attack */
for ( i = 0; buf[i] != '\0'; i++ ) {
if ( buf[i] == '.' || buf[i] == '_' )
buf[i] = ' ';
}
if ( strcasecmp( rdn, buf ) == 0 ) {
char **cn;
int i, last;
cn = ldap_get_values( ld, e, "cn" );
for ( i = 0; cn[i] != NULL; i++ ) {
last = strlen( cn[i] ) - 1;
if (isdigit((unsigned char) cn[i][last])) {
rdn = strdup( cn[i] );
break;
}
}
}
title = ldap_get_values( ld, e, "title" );
spaces2dots( rdn );
printf( " %-20s %s\r\n", rdn,
title ? title[0] : "" );
if ( title != NULL ) {
for ( i = 1; title[i] != NULL; i++ )
printf( " %-20s %s\r\n", "",
title[i] );
}
fflush( stdout );
if ( title != NULL )
ldap_value_free( title );
free( dn );
}
}
if ( result != NULL ) {
ldap_msgfree( result );
}
ldap_unbind( ld );
}
static int
entry2textwrite( void *fp, char *buf, ber_len_t len )
{
return( fwrite( buf, len, 1, (FILE *)fp ) == 0 ? -1 : len );
}
static void
do_read( LDAP *ld, LDAPMessage *e )
{
static struct ldap_disptmpl *tmpllist;
static char *defattrs[] = { "mail", NULL };
static char *mailvals[] = FINGER_NOEMAIL;
static char **defvals[] = { mailvals, NULL };
ldap_init_templates( templatefile, &tmpllist );
if ( ldap_entry2text_search( ld, NULL, base, e, tmpllist, defattrs,
defvals, entry2textwrite, (void *)stdout, "\r\n", rdncount,
LDAP_DISP_OPT_DOSEARCHACTIONS ) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_entry2text_search" );
exit( EXIT_FAILURE );
}
if ( tmpllist != NULL ) {
ldap_free_templates( tmpllist );
}
}