#! /bin/sh
# $OpenLDAP$
-# from OpenLDAP: pkg/ldap/configure.in,v 1.417 2002/05/13 16:48:37 kurt Exp
+# from OpenLDAP: pkg/ldap/configure.in,v 1.418 2002/05/13 18:16:47 kurt Exp
# Copyright 1998-2002 The OpenLDAP Foundation. All Rights Reserved.
#
#if SASL_VERSION_MAJOR == 1 && SASL_VERSION_MINOR >= 5
char *__sasl_compat = "1.5.x okay";
#elif SASL_VERSION_MAJOR == 2 && SASL_VERSION_MINOR > 1
- __sasl_compat "2.2+ or better okay";
+ __sasl_compat "2.2+ or better okay (we guess)";
#elif SASL_VERSION_MAJOR == 2 && SASL_VERSION_MINOR == 1 \
&& SASL_VERSION_STEP >=3
__sasl_compat = "2.1.3+ or better okay";
read \
recv \
recvfrom \
+ recvmsg \
setpwfile \
setgid \
setegid \
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:21822: checking for $ac_func" >&5
+echo "configure:21823: checking for $ac_func" >&5
if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 21827 "configure"
+#line 21828 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:21851: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:21852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
for ac_func in getopt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:21879: checking for $ac_func" >&5
+echo "configure:21880: checking for $ac_func" >&5
if eval "test \"\${ac_cv_func_$ac_func+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 21884 "configure"
+#line 21885 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:21908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:21909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
# Check Configuration
echo $ac_n "checking declaration of sys_errlist""... $ac_c" 1>&6
-echo "configure:21941: checking declaration of sys_errlist" >&5
+echo "configure:21942: checking declaration of sys_errlist" >&5
if eval "test \"\${ol_cv_dcl_sys_errlist+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 21947 "configure"
+#line 21948 "configure"
#include "confdefs.h"
#include <stdio.h>
char *c = (char *) *sys_errlist
; return 0; }
EOF
-if { (eval echo configure:21960: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:21961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ol_cv_dcl_sys_errlist=yes
ol_cv_have_sys_errlist=yes
echo $ac_n "checking existence of sys_errlist""... $ac_c" 1>&6
-echo "configure:21983: checking existence of sys_errlist" >&5
+echo "configure:21984: checking existence of sys_errlist" >&5
if eval "test \"\${ol_cv_have_sys_errlist+set}\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 21989 "configure"
+#line 21990 "configure"
#include "confdefs.h"
#include <errno.h>
int main() {
char *c = (char *) *sys_errlist
; return 0; }
EOF
-if { (eval echo configure:21996: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:21997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ol_cv_have_sys_errlist=yes
else
read \
recv \
recvfrom \
+ recvmsg \
setpwfile \
setgid \
setegid \
/* Define if you have the recvfrom function. */
#undef HAVE_RECVFROM
+/* Define if you have the recvmsg function. */
+#undef HAVE_RECVMSG
+
/* Define if you have the sched_yield function. */
#undef HAVE_SCHED_YIELD
/* Define if you have the recvfrom function. */
/* #undef HAVE_RECVFROM */
+/* Define if you have the recvmsg function. */
+/* #undef HAVE_RECVMSG */
+
/* Define if you have the sched_yield function. */
/* #undef HAVE_SCHED_YIELD */
Operation *o;
/* no abandon command defined - just kill the process handling it */
- if ( si->si_abandon == NULL ) {
+ if ( IS_NULLCMD( si->si_abandon ) ) {
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
pid = -1;
LDAP_STAILQ_FOREACH( o, &conn->c_ops, o_next ) {
FILE *rfp, *wfp;
int len;
- if ( si->si_add == NULL ) {
+ if ( IS_NULLCMD( si->si_add ) ) {
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
"add not implemented", NULL, NULL );
return( -1 );
FILE *rfp, *wfp;
int rc;
- if ( si->si_bind == NULL ) {
+ if ( IS_NULLCMD( si->si_bind ) ) {
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
"bind not implemented", NULL, NULL );
return( -1 );
struct shellinfo *si = (struct shellinfo *) be->be_private;
FILE *rfp, *wfp;
- if ( si->si_compare == NULL ) {
+ if ( IS_NULLCMD( si->si_compare ) ) {
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
"compare not implemented", NULL, NULL );
return( -1 );
#include "slap.h"
#include "shell.h"
+#ifdef SHELL_SURROGATE_PARENT
+
+static struct berval make_cmd_info(
+ char **args
+)
+{
+ struct berval ret = { 0, 0 };
+ int i;
+ ber_len_t offset;
+ for( i = 0; args[i] != NULL; i++ )
+ ret.bv_len += strlen( args[i] ) + 1;
+ ret.bv_val = ch_malloc( ret.bv_len );
+ offset = 0;
+ for( i = 0; args[i] != NULL; i++ ) {
+ strcpy( ret.bv_val + offset, args[i] );
+ offset += strlen( args[i] ) + 1;
+ }
+ return ret;
+}
+
+#endif /* SHELL_SURROGATE_PARENT */
+
int
shell_back_db_config(
BackendDB *be,
fname, lineno );
return( 1 );
}
- si->si_bind = charray_dup( &argv[1] );
+ si->si_bind = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for unbinds */
} else if ( strcasecmp( argv[0], "unbind" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_unbind = charray_dup( &argv[1] );
+ si->si_unbind = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for searches */
} else if ( strcasecmp( argv[0], "search" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_search = charray_dup( &argv[1] );
+ si->si_search = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for compares */
} else if ( strcasecmp( argv[0], "compare" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_compare = charray_dup( &argv[1] );
+ si->si_compare = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for modifies */
} else if ( strcasecmp( argv[0], "modify" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_modify = charray_dup( &argv[1] );
+ si->si_modify = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for modrdn */
} else if ( strcasecmp( argv[0], "modrdn" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_modrdn = charray_dup( &argv[1] );
+ si->si_modrdn = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for add */
} else if ( strcasecmp( argv[0], "add" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_add = charray_dup( &argv[1] );
+ si->si_add = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for delete */
} else if ( strcasecmp( argv[0], "delete" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_delete = charray_dup( &argv[1] );
+ si->si_delete = MAKE_CMD_INFO( &argv[1] );
/* command + args to exec for abandon */
} else if ( strcasecmp( argv[0], "abandon" ) == 0 ) {
fname, lineno );
return( 1 );
}
- si->si_abandon = charray_dup( &argv[1] );
+ si->si_abandon = MAKE_CMD_INFO( &argv[1] );
/* anything else */
} else {
struct shellinfo *si = (struct shellinfo *) be->be_private;
FILE *rfp, *wfp;
- if ( si->si_delete == NULL ) {
+ if ( IS_NULLCMD( si->si_delete ) ) {
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
"delete not implemented", NULL, NULL );
return( -1 );
#include <stdio.h>
+#include <ac/errno.h>
#include <ac/string.h>
#include <ac/socket.h>
#include <ac/unistd.h>
#include "slap.h"
#include "shell.h"
+#ifdef SHELL_SURROGATE_PARENT
+
+#include <sys/uio.h>
+
+/* Use several socketpairs to the surrogate parent, because *
+ * a single communication channel to it could be a bottleneck */
+ldap_pvt_thread_mutex_t shell_surrogate_fd_mutex[2];
+int shell_surrogate_fd[2] = { -1, -1 };
+/* Index to shell_surrogate_fd, and its mutex */
+ldap_pvt_thread_mutex_t shell_surrogate_index_mutex;
+static int shell_surrogate_index = 1;
+
+pid_t shell_surrogate_pid = -1;
+
+#define nread( fd, buf, len ) n_rw( 0, fd, buf, len )
+#define nwrite( fd, buf, len ) n_rw( 1, fd, buf, len )
+
+static int
+n_rw(
+ int do_write,
+ int fd,
+ void *buf,
+ int len
+)
+{
+ int ret = 0, i;
+ while( len ) {
+ for(;;) {
+ i = (do_write
+ ? write( fd, buf, len )
+ : read( fd, buf, len ));
+ if( i < 0 ) {
+ if( errno == EINTR )
+ continue;
+ if( ret == 0 )
+ ret = -1;
+ }
+ break;
+ }
+ if( i <= 0 )
+ break;
+ ret += i;
+ buf = (char *)buf + i;
+ len -= i;
+ }
+ return ret;
+}
+
+void
+make_surrogate_parent( void )
+{
+ int pair[2][2], io[2], i, j, p, argc;
+ ber_len_t len, buflen, offset;
+ char *buf, **argv;
+ pid_t pid;
+
+ if( socketpair( AF_LOCAL, SOCK_STREAM, 0, pair[0] ) < 0 ||
+ socketpair( AF_LOCAL, SOCK_STREAM, 0, pair[1] ) < 0 ) {
+ Debug( LDAP_DEBUG_ANY, "socketpair failed\n", 0, 0, 0 );
+ exit( EXIT_FAILURE );
+ }
+ fflush( NULL );
+ switch( fork() ) {
+ case -1:
+ Debug( LDAP_DEBUG_ANY, "fork failed\n", 0, 0, 0 );
+ exit( EXIT_FAILURE );
+ case 0:
+ break;
+ default:
+ shell_surrogate_fd[0] = pair[0][0];
+ shell_surrogate_fd[1] = pair[1][0];
+ close( pair[0][1] );
+ close( pair[1][1] );
+ return;
+ }
+
+ /* Close unused file descriptors */
+ for( i = 3, j = 32; j && i < 1024; i++ )
+ if( i != pair[0][1] && i != pair[1][1] && close( i ) < 0 )
+ --j;
+ else if( j < 32 )
+ j = 32;
+
+ /* Surrogate parent running */
+
+ buflen = 0;
+ buf = NULL;
+ argc = 0;
+ argv = NULL;
+ p = 0;
+
+ for(;;) {
+ /* Read file descriptors io[] from socket */
+ static char dummy;
+ static struct iovec iov = { &dummy, 1 };
+ struct msghdr msg;
+# ifdef CMSG_SPACE
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof(io))];
+ } control_un;
+ struct cmsghdr *cmptr;
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof(control_un.control);
+# else
+ msg.msg_accrights = (caddr_t) io;
+ msg.msg_accrightslen = sizeof(io);
+# endif
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ switch( recvmsg( pair[p][1], &msg, MSG_WAITALL ) ) {
+ case -1:
+ if( errno == EINTR )
+ continue;
+ _exit( EXIT_FAILURE );
+ case 0:
+ _exit( EXIT_SUCCESS );
+ }
+# ifdef CMSG_SPACE
+ if( (cmptr = CMSG_FIRSTHDR(&msg)) == NULL ||
+ cmptr->cmsg_len != CMSG_LEN(sizeof(io)) ||
+ cmptr->cmsg_level != SOL_SOCKET ||
+ cmptr->cmsg_type != SCM_RIGHTS ) {
+ fputs( "bad descriptor message received\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+ memcpy( io, CMSG_DATA( cmptr ), sizeof(io) );
+# else
+ if( msg.msg_accrightslen != sizeof(io) ) {
+ fputs( "bad descriptor message received\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+# endif
+
+ /* Read length of arguments and then arguments from socket */
+ if( nread( pair[p][1], &len, sizeof(len) ) != sizeof(len) ) {
+ fputs( "bad descriptor message received\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+ if( buflen < len ) {
+ buf = realloc( buf, buflen = len );
+ if( buf == NULL ) {
+ fputs( "realloc failed\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+ }
+ if( nread( pair[p][1], buf, len ) != len ) {
+ fputs( "bad descriptor message received\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+ i = 0;
+ offset = 0;
+ while( offset < len ) {
+ if( i >= argc-1 ) {
+ argc += i + 10;
+ argv = realloc( argv, argc * sizeof(*argv) );
+ if( argv == NULL ) {
+ fputs( "realloc failed\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+ }
+ argv[i++] = buf + offset;
+ offset += strlen( buf + offset ) + 1;
+ }
+ argv[i] = NULL;
+
+ /* Run program */
+ pid = fork();
+ switch( pid )
+ {
+ case 0: /* child */
+ if( dup2( io[0], 0 ) == -1 || dup2( io[1], 1 ) == -1 ) {
+ fputs( "dup2 failed\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+ close( io[0] );
+ close( io[1] );
+ close( pair[0][1] );
+ close( pair[1][1] );
+ execv( argv[0], argv );
+
+ fputs( "execv failed\n", stderr );
+ exit( EXIT_FAILURE );
+
+ case -1: /* trouble */
+ fputs( "fork failed\n", stderr );
+ break;
+
+ default: /* parent */
+ close( io[0] );
+ close( io[1] );
+ break;
+ }
+ if( nwrite( pair[p][1], &pid,
+ sizeof(pid_t) ) != sizeof(pid_t) ) {
+ fputs( "could not send pid\n", stderr );
+ exit( EXIT_FAILURE );
+ }
+ p ^= 1;
+ }
+}
+#endif /* SHELL_SURROGATE_PARENT */
+
pid_t
forkandexec(
- char **args,
+ Cmd_info args,
FILE **rfp,
FILE **wfp
)
{
- int p2c[2], c2p[2];
+ int p2c[2] = { -1, -1 }, c2p[2];
pid_t pid;
if ( pipe( p2c ) != 0 || pipe( c2p ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "pipe failed\n", 0, 0, 0 );
+ close( p2c[0] );
+ close( p2c[1] );
return( -1 );
}
* parent *rfp <- c2p[0] | c2p[1] <- stdout child
*/
-#ifdef HAVE_THR
- switch ( (pid = fork1()) )
-#else
- switch ( (pid = fork()) )
-#endif
+#ifdef SHELL_SURROGATE_PARENT
+
{
- case 0: /* child */
+ int io[2] = { p2c[0], c2p[1] }, i, c;
+ static char dummy = '\0';
+ static struct iovec iov = { &dummy, 1 };
+ struct msghdr msg;
+# ifdef CMSG_SPACE
+ union {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE(sizeof(io))];
+ } control_un;
+ struct cmsghdr *cmptr;
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof(control_un.control);
+ cmptr = CMSG_FIRSTHDR(&msg);
+ cmptr->cmsg_len = CMSG_LEN(sizeof(io));
+ cmptr->cmsg_level = SOL_SOCKET;
+ cmptr->cmsg_type = SCM_RIGHTS;
+ memcpy( CMSG_DATA(cmptr), io, sizeof(io) );
+# else
+ msg.msg_accrights = (caddr_t) io;
+ msg.msg_accrightslen = sizeof(io);
+# endif
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ ldap_pvt_thread_mutex_lock( &shell_surrogate_index_mutex );
+ i = shell_surrogate_index ^= 1;
+ ldap_pvt_thread_mutex_unlock( &shell_surrogate_index_mutex );
+ ldap_pvt_thread_mutex_lock( &shell_surrogate_fd_mutex[i] );
+ c = (sendmsg( shell_surrogate_fd[i], &msg, 0 ) == 1 &&
+ nwrite( shell_surrogate_fd[i], &args.bv_len,
+ sizeof(args.bv_len) ) == sizeof(args.bv_len) &&
+ nwrite( shell_surrogate_fd[i], args.bv_val,
+ args.bv_len ) == args.bv_len &&
+ nread( shell_surrogate_fd[i], &pid,
+ sizeof(pid) ) == sizeof(pid));
+ ldap_pvt_thread_mutex_unlock( &shell_surrogate_fd_mutex[i] );
+ close( p2c[0] );
+ close( c2p[1] );
+ if ( !c ) {
+ Debug( LDAP_DEBUG_ANY, "process creation failed\n", 0, 0, 0 );
+ close( p2c[1] );
+ close( c2p[0] );
+ close( shell_surrogate_fd[0] );
+ close( shell_surrogate_fd[1] );
+ shell_surrogate_fd[0] =
+ shell_surrogate_fd[1] = -1;
+ return( -1 );
+ }
+ }
+
+#else /* !SHELL_SURROGATE_PARENT */
+
+ fflush( NULL );
+# ifdef HAVE_THR
+ pid = fork1();
+# else
+ pid = fork();
+# endif
+ if ( pid == 0 ) { /* child */
/*
* child could deadlock here due to resources locked
* by our parent
*
- * If so, configure --without-threads or implement forking
- * via a surrogate parent.
+ * If so, configure --without-threads.
*/
- close( p2c[1] );
- close( c2p[0] );
if ( dup2( p2c[0], 0 ) == -1 || dup2( c2p[1], 1 ) == -1 ) {
Debug( LDAP_DEBUG_ANY, "dup2 failed\n", 0, 0, 0 );
exit( EXIT_FAILURE );
}
-
+ }
+ close( p2c[0] );
+ close( c2p[1] );
+ if ( pid <= 0 ) {
+ close( p2c[1] );
+ close( c2p[0] );
+ }
+ switch ( pid ) {
+ case 0:
execv( args[0], args );
Debug( LDAP_DEBUG_ANY, "execv failed\n", 0, 0, 0 );
case -1: /* trouble */
Debug( LDAP_DEBUG_ANY, "fork failed\n", 0, 0, 0 );
return( -1 );
-
- default: /* parent */
- close( p2c[0] );
- close( c2p[1] );
- break;
}
+#endif /* SHELL_SURROGATE_PARENT */
+
+ /* parent */
if ( (*rfp = fdopen( c2p[0], "r" )) == NULL || (*wfp = fdopen( p2c[1],
"w" )) == NULL ) {
Debug( LDAP_DEBUG_ANY, "fdopen failed\n", 0, 0, 0 );
#include <stdio.h>
#include <ac/socket.h>
+#include <ac/unistd.h>
#include "slap.h"
#include "shell.h"
bi->bi_open = 0;
bi->bi_config = 0;
bi->bi_close = 0;
- bi->bi_destroy = 0;
+ bi->bi_destroy = shell_back_destroy;
bi->bi_db_init = shell_back_db_init;
bi->bi_db_config = shell_back_db_config;
bi->bi_connection_init = 0;
bi->bi_connection_destroy = 0;
+#ifdef SHELL_SURROGATE_PARENT
+ ldap_pvt_thread_mutex_init( &shell_surrogate_index_mutex );
+ ldap_pvt_thread_mutex_init( &shell_surrogate_fd_mutex[0] );
+ ldap_pvt_thread_mutex_init( &shell_surrogate_fd_mutex[1] );
+#endif
+
+ return 0;
+}
+
+int
+shell_back_destroy(
+ BackendInfo *bi
+)
+{
+#ifdef SHELL_SURROGATE_PARENT
+ ldap_pvt_thread_mutex_destroy( &shell_surrogate_index_mutex );
+ ldap_pvt_thread_mutex_destroy( &shell_surrogate_fd_mutex[0] );
+ ldap_pvt_thread_mutex_destroy( &shell_surrogate_fd_mutex[1] );
+ if ( shell_surrogate_fd[0] >= 0 ) {
+ close( shell_surrogate_fd[0] );
+ close( shell_surrogate_fd[1] );
+ }
+ if ( shell_surrogate_pid >= 0 )
+ kill( shell_surrogate_pid, SIGTERM );
+#endif
+
return 0;
}
{
struct shellinfo *si;
+#ifdef SHELL_SURROGATE_PARENT
+ if ( shell_surrogate_fd[0] < 0 )
+ make_surrogate_parent();
+#endif
+
si = (struct shellinfo *) ch_calloc( 1, sizeof(struct shellinfo) );
be->be_private = si;
FILE *rfp, *wfp;
int i;
- if ( si->si_modify == NULL ) {
+ if ( IS_NULLCMD( si->si_modify ) ) {
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
"modify not implemented", NULL, NULL );
return( -1 );
struct shellinfo *si = (struct shellinfo *) be->be_private;
FILE *rfp, *wfp;
- if ( si->si_modrdn == NULL ) {
+ if ( IS_NULLCMD( si->si_modrdn ) ) {
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
"modrdn not implemented", NULL, NULL );
return( -1 );
)
{
struct shellinfo *si = (struct shellinfo *) be->be_private;
- int i;
FILE *rfp, *wfp;
AttributeName *an;
- if ( si->si_search == NULL ) {
+ if ( IS_NULLCMD( si->si_search ) ) {
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
"search not implemented", NULL, NULL );
return( -1 );
LDAP_BEGIN_DECL
+#if defined(HAVE_RECVMSG) && !defined(NO_THREADS)
+# define SHELL_SURROGATE_PARENT
+#endif
+
+#ifdef SHELL_SURROGATE_PARENT
+
+extern ldap_pvt_thread_mutex_t shell_surrogate_index_mutex;
+extern ldap_pvt_thread_mutex_t shell_surrogate_fd_mutex[2];
+extern int shell_surrogate_fd[2];
+extern pid_t shell_surrogate_pid;
+
+typedef struct berval Cmd_info;
+#define MAKE_CMD_INFO(args) make_cmd_info( args )
+#define IS_NULLCMD(cmd) ((cmd).bv_val == NULL)
+
+extern void make_surrogate_parent LDAP_P(( void ));
+
+#else /* !SHELL_SURROGATE_PARENT */
+
+typedef char **Cmd_info;
+#define MAKE_CMD_INFO(args) charray_dup( args )
+#define IS_NULLCMD(cmd) ((cmd) == NULL)
+
+#endif /* SHELL_SURROGATE_PARENT */
+
struct shellinfo {
- char **si_bind; /* cmd + args to exec for bind */
- char **si_unbind; /* cmd + args to exec for unbind */
- char **si_search; /* cmd + args to exec for search */
- char **si_compare; /* cmd + args to exec for compare */
- char **si_modify; /* cmd + args to exec for modify */
- char **si_modrdn; /* cmd + args to exec for modrdn */
- char **si_add; /* cmd + args to exec for add */
- char **si_delete; /* cmd + args to exec for delete */
- char **si_abandon; /* cmd + args to exec for abandon */
+ Cmd_info si_bind; /* cmd + args to exec for bind */
+ Cmd_info si_unbind; /* cmd + args to exec for unbind */
+ Cmd_info si_search; /* cmd + args to exec for search */
+ Cmd_info si_compare; /* cmd + args to exec for compare */
+ Cmd_info si_modify; /* cmd + args to exec for modify */
+ Cmd_info si_modrdn; /* cmd + args to exec for modrdn */
+ Cmd_info si_add; /* cmd + args to exec for add */
+ Cmd_info si_delete; /* cmd + args to exec for delete */
+ Cmd_info si_abandon; /* cmd + args to exec for abandon */
};
struct slap_backend_db;
struct slap_op;
extern pid_t forkandexec LDAP_P((
- char **args,
+ Cmd_info args,
FILE **rfp,
FILE **wfp));
struct shellinfo *si = (struct shellinfo *) be->be_private;
FILE *rfp, *wfp;
- if ( si->si_unbind == NULL ) {
+ if ( IS_NULLCMD( si->si_unbind ) ) {
return 0;
}