mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-17 14:00:30 +08:00
Addition of a new Concurrency Test fro testing slapd performance and
correctness of locking schemas in backends. In back-bdb2 open NEXTID during startup and close at shutdown.
This commit is contained in:
parent
a71f328831
commit
39f0066db4
@ -32,7 +32,7 @@ Modify -lldap to be session-level multithreaded
|
||||
Port slapd (incl back-ldbm & tools) to NT
|
||||
MajorLDAP - Design and implement an LDAP-enabled mailing list manager
|
||||
Slapd-DB2 - Design and implement a backend to take full advantage
|
||||
of the latest DB2 features.
|
||||
of the latest DB2 features <ksp@openldap.org>.
|
||||
|
||||
|
||||
Medium projects
|
||||
|
@ -90,7 +90,6 @@ struct dbcache {
|
||||
int dbc_refcnt;
|
||||
int dbc_maxids;
|
||||
int dbc_maxindirect;
|
||||
time_t dbc_lastref;
|
||||
long dbc_blksize;
|
||||
char *dbc_name;
|
||||
LDBM dbc_db;
|
||||
@ -146,6 +145,11 @@ typedef struct _bdb2_txn_head {
|
||||
#define BDB2_DB_ID2CHILDREN_FILE 3
|
||||
#define BDB2_DB_OC_IDX_FILE 4
|
||||
|
||||
/* a file pointer for the NEXTID file
|
||||
(must be opened appropriately at backend
|
||||
entry and closed on leave */
|
||||
FILE *nextidFP;
|
||||
|
||||
/* is the default attribute index set to non-none */
|
||||
int withDefIDX;
|
||||
#define BDB2_WITH_DEF_IDX 1
|
||||
@ -187,9 +191,6 @@ struct ldbminfo {
|
||||
Avlnode *li_attrs;
|
||||
int li_dbcachesize;
|
||||
int li_dbcachewsync;
|
||||
struct dbcache li_dbcache[MAXDBCACHE];
|
||||
ldap_pvt_thread_mutex_t li_dbcache_mutex;
|
||||
ldap_pvt_thread_cond_t li_dbcache_cv;
|
||||
|
||||
/* a list of all files of the database */
|
||||
BDB2_TXN_HEAD li_txn_head;
|
||||
|
@ -128,26 +128,26 @@ bdb2i_index_read(
|
||||
realval = val;
|
||||
tmpval = NULL;
|
||||
if ( prefix != UNKNOWN_PREFIX ) {
|
||||
unsigned int len = strlen( val );
|
||||
unsigned int len = strlen( val );
|
||||
|
||||
if ( (len + 2) < sizeof(buf) ) {
|
||||
if ( (len + 2) < sizeof(buf) ) {
|
||||
realval = buf;
|
||||
} else {
|
||||
/* value + prefix + null */
|
||||
tmpval = (char *) ch_malloc( len + 2 );
|
||||
realval = tmpval;
|
||||
}
|
||||
realval[0] = prefix;
|
||||
strcpy( &realval[1], val );
|
||||
realval[0] = prefix;
|
||||
strcpy( &realval[1], val );
|
||||
}
|
||||
|
||||
key.dptr = realval;
|
||||
key.dsize = strlen( realval ) + 1;
|
||||
|
||||
idl = bdb2i_idl_fetch( be, db, key );
|
||||
if ( tmpval != NULL ) {
|
||||
free( tmpval );
|
||||
}
|
||||
if ( tmpval != NULL ) {
|
||||
free( tmpval );
|
||||
}
|
||||
|
||||
bdb2i_cache_close( be, db );
|
||||
|
||||
@ -168,7 +168,6 @@ add_value(
|
||||
{
|
||||
int rc;
|
||||
Datum key;
|
||||
ID_BLOCK *idl = NULL;
|
||||
char *tmpval = NULL;
|
||||
char *realval = val;
|
||||
char buf[BUFSIZ];
|
||||
@ -180,17 +179,17 @@ add_value(
|
||||
Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
|
||||
|
||||
if ( prefix != UNKNOWN_PREFIX ) {
|
||||
unsigned int len = strlen( val );
|
||||
unsigned int len = strlen( val );
|
||||
|
||||
if ( (len + 2) < sizeof(buf) ) {
|
||||
if ( (len + 2) < sizeof(buf) ) {
|
||||
realval = buf;
|
||||
} else {
|
||||
/* value + prefix + null */
|
||||
tmpval = (char *) ch_malloc( len + 2 );
|
||||
realval = tmpval;
|
||||
}
|
||||
realval[0] = prefix;
|
||||
strcpy( &realval[1], val );
|
||||
realval[0] = prefix;
|
||||
strcpy( &realval[1], val );
|
||||
}
|
||||
|
||||
key.dptr = realval;
|
||||
@ -202,10 +201,6 @@ add_value(
|
||||
free( tmpval );
|
||||
}
|
||||
|
||||
if( idl != NULL ) {
|
||||
bdb2i_idl_free( idl );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_yield();
|
||||
|
||||
/* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
|
||||
|
@ -177,8 +177,6 @@ bdb2i_back_db_init_internal(
|
||||
ldap_pvt_thread_mutex_init( &li->li_add_mutex );
|
||||
ldap_pvt_thread_mutex_init( &li->li_cache.c_mutex );
|
||||
ldap_pvt_thread_mutex_init( &li->li_nextid_mutex );
|
||||
ldap_pvt_thread_mutex_init( &li->li_dbcache_mutex );
|
||||
ldap_pvt_thread_cond_init( &li->li_dbcache_cv );
|
||||
|
||||
/* initialize the TP file head */
|
||||
if ( bdb2i_txn_head_init( &li->li_txn_head ) != 0 )
|
||||
|
@ -13,32 +13,29 @@
|
||||
#include "slap.h"
|
||||
#include "back-bdb2.h"
|
||||
|
||||
/* XXX the separate handling of the NEXTID file is in contrast to TP */
|
||||
/* the NEXTID file is beeing opened during database start-up */
|
||||
static ID
|
||||
next_id_read( BackendDB *be )
|
||||
{
|
||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
||||
FILE* fp = head->nextidFP;
|
||||
ID id;
|
||||
char buf[20];
|
||||
char* file = li->li_nextid_file;
|
||||
FILE* fp;
|
||||
|
||||
if ( (fp = fopen( file, "r" )) == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"next_id_read: could not open \"%s\"\n",
|
||||
file, 0, 0 );
|
||||
return NOID;
|
||||
}
|
||||
/* set the file pointer to the beginnig of the file */
|
||||
rewind( fp );
|
||||
|
||||
/* read the nextid */
|
||||
if ( fgets( buf, sizeof(buf), fp ) == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"next_id_read: could not fgets nextid from \"%s\"\n",
|
||||
file, 0, 0 );
|
||||
fclose( fp );
|
||||
li->li_nextid_file, 0, 0 );
|
||||
return NOID;
|
||||
}
|
||||
|
||||
id = atol( buf );
|
||||
fclose( fp );
|
||||
|
||||
if(id < 1) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
@ -50,31 +47,30 @@ next_id_read( BackendDB *be )
|
||||
return id;
|
||||
}
|
||||
|
||||
/* XXX the separate handling of the NEXTID file is in contrast to TP */
|
||||
/* the NEXTID file is beeing opened during database start-up */
|
||||
static int
|
||||
next_id_write( BackendDB *be, ID id )
|
||||
{
|
||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
||||
FILE* fp = head->nextidFP;
|
||||
char buf[20];
|
||||
char* file = li->li_nextid_file;
|
||||
FILE* fp;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if ( (fp = fopen( file, "w" )) == NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY, "next_id_write(%ld): could not open \"%s\"\n",
|
||||
id, file, 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
/* set the file pointer to the beginnig of the file */
|
||||
rewind( fp );
|
||||
|
||||
/* write the nextid */
|
||||
if ( fprintf( fp, "%ld\n", id ) == EOF ) {
|
||||
Debug( LDAP_DEBUG_ANY, "next_id_write(%ld): cannot fprintf\n",
|
||||
id, 0, 0 );
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if( fclose( fp ) != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "next_id_write %ld: cannot fclose\n",
|
||||
/* if forced flushing of files is in effect, do so */
|
||||
if( li->li_dbcachewsync && ( fflush( fp ) != 0 )) {
|
||||
Debug( LDAP_DEBUG_ANY, "next_id_write %ld: cannot fflush\n",
|
||||
id, 0, 0 );
|
||||
rc = -1;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ static void remove_old_locks( char *home );
|
||||
static void
|
||||
bdb2i_db_errcall( char *prefix, char *message )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY, "dbd2_db_errcall(): %s %s", prefix, message, 0 );
|
||||
Debug( LDAP_DEBUG_ANY, "bdb2_db_errcall(): %s %s", prefix, message, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,16 +39,10 @@ bdb2i_txn_head_init( BDB2_TXN_HEAD *head )
|
||||
static void
|
||||
bdb2i_init_db_file_cache( struct ldbminfo *li, BDB2_TXN_FILES *fileinfo )
|
||||
{
|
||||
time_t curtime;
|
||||
struct stat st;
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
ldap_pvt_thread_mutex_lock( ¤ttime_mutex );
|
||||
curtime = currenttime;
|
||||
ldap_pvt_thread_mutex_unlock( ¤ttime_mutex );
|
||||
|
||||
fileinfo->dbc_refcnt = 1;
|
||||
fileinfo->dbc_lastref = curtime;
|
||||
|
||||
sprintf( buf, "%s%s%s", li->li_directory, DEFAULT_DIRSEP,
|
||||
fileinfo->dbc_name );
|
||||
@ -66,6 +60,14 @@ bdb2i_init_db_file_cache( struct ldbminfo *li, BDB2_TXN_FILES *fileinfo )
|
||||
}
|
||||
|
||||
|
||||
/* create a DB file cache entry for a specified index attribute
|
||||
(if not already done); the function is called during config
|
||||
file read for all index'ed attributes; if "default" index with
|
||||
a non-none selection is given, this is remembered for run-time
|
||||
extension of the list of index files; the function is also
|
||||
called before add or modify operations to check for putative
|
||||
new "default" index files; at that time, files are also opened
|
||||
*/
|
||||
void
|
||||
bdb2i_txn_attr_config(
|
||||
struct ldbminfo *li,
|
||||
@ -158,11 +160,45 @@ bdb2i_txn_attr_config(
|
||||
}
|
||||
|
||||
|
||||
/* open the NEXTID file for read/write; if it does not exist,
|
||||
create it (access to the file must be preceeded by a rewind)
|
||||
*/
|
||||
static int
|
||||
bdb2i_open_nextid( struct ldbminfo *li )
|
||||
{
|
||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
||||
FILE *fp = NULL;
|
||||
char *file = li->li_nextid_file;
|
||||
|
||||
/* try to open the file for read and write */
|
||||
if ((( fp = fopen( file, "r+" )) == NULL ) &&
|
||||
(( fp = fopen( file, "w+" )) == NULL )) {
|
||||
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"bdb2i_open_nextid: could not open \"%s\"\n",
|
||||
file, 0, 0 );
|
||||
return( -1 );
|
||||
|
||||
}
|
||||
|
||||
/* the file is open for read/write */
|
||||
head->nextidFP = fp;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/* open all DB during startup of the backend (necessary due to TP)
|
||||
additional files may be opened during slapd life-time due to
|
||||
default indexes (must be configured in slapd.conf;
|
||||
see bdb2i_txn_attr_config)
|
||||
*/
|
||||
int
|
||||
bdb2i_txn_open_files( struct ldbminfo *li )
|
||||
{
|
||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
||||
BDB2_TXN_FILES *dbFile;
|
||||
int rc;
|
||||
|
||||
for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
|
||||
char fileName[MAXPATHLEN];
|
||||
@ -179,7 +215,7 @@ bdb2i_txn_open_files( struct ldbminfo *li )
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"bdb2i_txn_open_files(): couldn't open file \"%s\" -- FATAL.\n",
|
||||
dbFile->dbc_name, 0, 0 );
|
||||
return( 1 );
|
||||
return( -1 );
|
||||
|
||||
}
|
||||
|
||||
@ -191,10 +227,22 @@ bdb2i_txn_open_files( struct ldbminfo *li )
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
rc = bdb2i_open_nextid( li );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* close the NEXTID file */
|
||||
static void
|
||||
bdb2i_close_nextid( BDB2_TXN_HEAD *head )
|
||||
{
|
||||
fclose( head->nextidFP );
|
||||
head->nextidFP = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* close all DB files during shutdown of the backend */
|
||||
void
|
||||
bdb2i_txn_close_files( BackendDB *be )
|
||||
{
|
||||
@ -207,9 +255,15 @@ bdb2i_txn_close_files( BackendDB *be )
|
||||
ldbm_close( dbFile->dbc_db );
|
||||
|
||||
}
|
||||
|
||||
bdb2i_close_nextid( head );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* get the db_cache structure associated with a specified
|
||||
DB file (replaces the on-the-fly opening of files in cache_open()
|
||||
*/
|
||||
BDB2_TXN_FILES *
|
||||
bdb2i_get_db_file_cache( struct ldbminfo *li, char *name )
|
||||
{
|
||||
|
@ -4,7 +4,32 @@
|
||||
## tests Makefile.in for OpenLDAP
|
||||
BUILD_BDB2 = @BUILD_BDB2@
|
||||
|
||||
bdb2-local: FORCE
|
||||
SRC = slapd-tester.c slapd-search.c
|
||||
PROGRAMS = slapd-tester slapd-search slapd-read slapd-addel
|
||||
|
||||
LDAP_INCDIR= ../include
|
||||
LDAP_LIBDIR= ../libraries
|
||||
|
||||
XLIBS = -lldap_r -llber -llutil
|
||||
|
||||
build-tools: FORCE
|
||||
$(MAKE) $(MFLAGS) load-tools
|
||||
|
||||
load-tools: $(PROGRAMS)
|
||||
|
||||
slapd-tester: slapd-tester.o
|
||||
$(LTLINK) -o $@ slapd-tester.o
|
||||
|
||||
slapd-search: slapd-search.o $(LDAP_LIBLBER_DEPEND) $(LDAP_LIBLDAP_DEPEND)
|
||||
$(LTLINK) -o $@ slapd-search.o $(LDAP_LIBPATH) $(XLIBS)
|
||||
|
||||
slapd-read: slapd-read.o $(LDAP_LIBLBER_DEPEND) $(LDAP_LIBLDAP_DEPEND)
|
||||
$(LTLINK) -o $@ slapd-read.o $(LDAP_LIBPATH) $(XLIBS)
|
||||
|
||||
slapd-addel: slapd-addel.o $(LDAP_LIBLBER_DEPEND) $(LDAP_LIBLDAP_DEPEND)
|
||||
$(LTLINK) -o $@ slapd-addel.o $(LDAP_LIBPATH) $(XLIBS)
|
||||
|
||||
bdb2-local: build-tools FORCE
|
||||
@if test "$(BUILD_BDB2)" = "yes" ; then \
|
||||
$(LN_S) $(srcdir)/data . ; \
|
||||
echo "Initiating LDAP tests..." ; \
|
||||
@ -14,7 +39,7 @@ bdb2-local: FORCE
|
||||
echo "run configure with --enable-bdb2" ; \
|
||||
fi
|
||||
|
||||
all-local: FORCE
|
||||
all-local: build-tools FORCE
|
||||
@-$(LN_S) $(srcdir)/data .
|
||||
@echo "Initiating LDAP tests..."; \
|
||||
$(MKDIR) test-db test-repl ; \
|
||||
@ -22,8 +47,12 @@ all-local: FORCE
|
||||
|
||||
clean-local: FORCE
|
||||
$(RM) test-db/[!C]* test-repl/[!C]* *core
|
||||
$(RM) $(PROGRAMS)
|
||||
$(RM) *.o
|
||||
|
||||
veryclean-local: FORCE
|
||||
@-$(RM) data
|
||||
$(RM) -r test-db test-repl
|
||||
$(RM) $(PROGRAMS)
|
||||
$(RM) *.o
|
||||
|
||||
|
26
tests/data/do_add.1
Normal file
26
tests/data/do_add.1
Normal file
@ -0,0 +1,26 @@
|
||||
cn=James A Jones 2, ou=Alumni Association, ou=People, o=University of Michigan, c=US
|
||||
objectclass: top
|
||||
objectclass: person
|
||||
objectclass: organizationalPerson
|
||||
objectclass: newPilotPerson
|
||||
objectclass: umichPerson
|
||||
cn: James A Jones 2
|
||||
cn: James Jones
|
||||
cn: Jim Jones
|
||||
sn: Jones
|
||||
postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109
|
||||
seealso: cn=All Staff, ou=Groups, o=University of Michigan, c=US
|
||||
uid: jaj
|
||||
krbname: jaj@umich.edu
|
||||
userpassword: jaj
|
||||
nobatchupdates: TRUE
|
||||
onvacation: FALSE
|
||||
homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105
|
||||
homephone: +1 313 555 4772
|
||||
multilinedescription: Outstanding
|
||||
title: Mad Cow Researcher, UM Alumni Association
|
||||
pager: +1 313 555 3923
|
||||
mail: jaj@mail.alumni.umich.edu
|
||||
facsimiletelephonenumber: +1 313 555 4332
|
||||
telephonenumber: +1 313 555 0895
|
||||
|
5
tests/data/do_read.0
Normal file
5
tests/data/do_read.0
Normal file
@ -0,0 +1,5 @@
|
||||
cn=Barbara Jensen, ou=Information Technology Division, ou=People, o=University of Michigan, c=US
|
||||
cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
|
||||
ou=Groups, o=University of Michigan, c=US
|
||||
ou=Alumni Association, ou=People, o=University of Michigan, c=US
|
||||
cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Michigan, c=US
|
5
tests/data/do_search.0
Normal file
5
tests/data/do_search.0
Normal file
@ -0,0 +1,5 @@
|
||||
cn=Barbara Jensen
|
||||
cn=Bjorn Jensen
|
||||
cn=James A Jones 1
|
||||
cn=Bjorn Jensen
|
||||
cn=Alumni Assoc Staff
|
@ -13,6 +13,7 @@ argsfile ./test-db/slapd.args
|
||||
|
||||
backend bdb2
|
||||
home ./test-db
|
||||
mpoolsize 2100000
|
||||
|
||||
database bdb2
|
||||
cachesize 4
|
||||
|
@ -31,6 +31,7 @@ SLURPD=../servers/slurpd/slurpd
|
||||
LDAPSEARCH=../clients/tools/ldapsearch
|
||||
LDAPMODIFY=../clients/tools/ldapmodify
|
||||
LDAPADD=../clients/tools/ldapadd
|
||||
SLAPDTESTER=slapd-tester
|
||||
LVL=5
|
||||
PORT=9009
|
||||
SLAVEPORT=9010
|
||||
|
68
tests/scripts/test008-concurrency
Executable file
68
tests/scripts/test008-concurrency
Executable file
@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
SRCDIR="."
|
||||
else
|
||||
SRCDIR=$1; shift
|
||||
fi
|
||||
if [ $# -eq 1 ]; then
|
||||
BDB2=$1; shift
|
||||
fi
|
||||
|
||||
echo "running defines.sh $SRCDIR $BDB2"
|
||||
|
||||
. $SRCDIR/scripts/defines.sh $SRCDIR $BDB2
|
||||
|
||||
echo "Datadir is $DATADIR"
|
||||
|
||||
echo "Cleaning up in $DBDIR..."
|
||||
|
||||
rm -f $DBDIR/[!C]*
|
||||
|
||||
echo "Running ldif2ldbm to build slapd database..."
|
||||
$LDIF2LDBM -f $CONF -i $LDIF -e ../servers/slapd/tools
|
||||
RC=$?
|
||||
if [ $RC != 0 ]; then
|
||||
echo "ldif2ldbm failed!"
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT..."
|
||||
$SLAPD -f $CONF -p $PORT -d $LVL $TIMING > $MASTERLOG 2>&1 &
|
||||
PID=$!
|
||||
|
||||
echo "Waiting 5 seconds for slapd to start..."
|
||||
sleep 5
|
||||
|
||||
echo "Using tester for concurrent server access..."
|
||||
$SLAPDTESTER -b "$BASEDN" -d "$DATADIR" -h localhost -p $PORT -D "$MANAGERDN" -w $PASSWD -l 100
|
||||
RC=$?
|
||||
|
||||
if [ $RC != 0 ]; then
|
||||
echo "slapd-tester failed!"
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Using ldapsearch to retrieve all the entries..."
|
||||
$LDAPSEARCH -L -S "" -b "$BASEDN" -h localhost -p $PORT \
|
||||
'objectClass=*' > $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
|
||||
kill -HUP $PID
|
||||
|
||||
if [ $RC != 0 ]; then
|
||||
echo "ldapsearch failed!"
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Comparing retrieved entries to LDIF file used to create database"
|
||||
cmp $SEARCHOUT $LDIF
|
||||
if [ $? != 0 ]; then
|
||||
echo "comparison failed - database was not created correctly"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ">>>>> Test succeeded"
|
||||
|
||||
|
||||
exit 0
|
276
tests/slapd-addel.c
Normal file
276
tests/slapd-addel.c
Normal file
@ -0,0 +1,276 @@
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/string.h>
|
||||
#include <ac/ctype.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/unistd.h>
|
||||
#include <ac/wait.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "lber.h"
|
||||
#include "ldap.h"
|
||||
|
||||
#define LOOPS 100
|
||||
|
||||
static char *
|
||||
get_add_entry( char *filename, LDAPMod ***mods );
|
||||
|
||||
static void
|
||||
do_addel( char *host, int port, char *manager, char *passwd,
|
||||
char *dn, LDAPMod **attrs, int maxloop );
|
||||
|
||||
static void
|
||||
usage( char *name )
|
||||
{
|
||||
fprintf( stderr, "usage: %s [-h <host>] -p port -D <managerDN> -w <passwd> -f <addfile> [-l <loops>]\n",
|
||||
name );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int i, j;
|
||||
char *host = "localhost";
|
||||
int port = -1;
|
||||
char *manager = NULL;
|
||||
char *passwd = NULL;
|
||||
char *filename = NULL;
|
||||
char *entry = NULL;
|
||||
int loops = LOOPS;
|
||||
LDAPMod **attrs = NULL;
|
||||
|
||||
while ( (i = getopt( argc, argv, "h:p:D:w:f:l:" )) != EOF ) {
|
||||
switch( i ) {
|
||||
case 'h': /* the servers host */
|
||||
host = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'p': /* the servers port */
|
||||
port = atoi( optarg );
|
||||
break;
|
||||
|
||||
case 'D': /* the servers manager */
|
||||
manager = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'w': /* the server managers password */
|
||||
passwd = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'f': /* file with entry search request */
|
||||
filename = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'l': /* the number of loops */
|
||||
loops = atoi( optarg );
|
||||
break;
|
||||
|
||||
default:
|
||||
usage( argv[0] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (( filename == NULL ) || ( port == -1 ) ||
|
||||
( manager == NULL ) || ( passwd == NULL ))
|
||||
usage( argv[0] );
|
||||
|
||||
entry = get_add_entry( filename, &attrs );
|
||||
if (( entry == NULL ) || ( *entry == '\0' )) {
|
||||
|
||||
fprintf( stderr, "%s: invalid entry DN in file \"%s\".\n",
|
||||
argv[0], filename );
|
||||
exit( 1 );
|
||||
|
||||
}
|
||||
|
||||
if (( attrs == NULL ) || ( *attrs == '\0' )) {
|
||||
|
||||
fprintf( stderr, "%s: invalid attrs in file \"%s\".\n",
|
||||
argv[0], filename );
|
||||
exit( 1 );
|
||||
|
||||
}
|
||||
|
||||
do_addel( host, port, manager, passwd, entry, attrs, loops );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
|
||||
#define safe_realloc( ptr, size ) ( ptr == NULL ? malloc( size ) : \
|
||||
realloc( ptr, size ))
|
||||
|
||||
|
||||
static void
|
||||
addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
|
||||
{
|
||||
LDAPMod **pmods;
|
||||
int i, j;
|
||||
struct berval *bvp;
|
||||
|
||||
pmods = *pmodsp;
|
||||
modop |= LDAP_MOD_BVALUES;
|
||||
|
||||
i = 0;
|
||||
if ( pmods != NULL ) {
|
||||
for ( ; pmods[ i ] != NULL; ++i ) {
|
||||
if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 &&
|
||||
pmods[ i ]->mod_op == modop ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pmods == NULL || pmods[ i ] == NULL ) {
|
||||
if (( pmods = (LDAPMod **)safe_realloc( pmods, (i + 2) *
|
||||
sizeof( LDAPMod * ))) == NULL ) {
|
||||
perror( "safe_realloc" );
|
||||
exit( 1 );
|
||||
}
|
||||
*pmodsp = pmods;
|
||||
pmods[ i + 1 ] = NULL;
|
||||
if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod )))
|
||||
== NULL ) {
|
||||
perror( "calloc" );
|
||||
exit( 1 );
|
||||
}
|
||||
pmods[ i ]->mod_op = modop;
|
||||
if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) {
|
||||
perror( "strdup" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( value != NULL ) {
|
||||
j = 0;
|
||||
if ( pmods[ i ]->mod_bvalues != NULL ) {
|
||||
for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
|
||||
;
|
||||
}
|
||||
}
|
||||
if (( pmods[ i ]->mod_bvalues =
|
||||
(struct berval **)safe_realloc( pmods[ i ]->mod_bvalues,
|
||||
(j + 2) * sizeof( struct berval * ))) == NULL ) {
|
||||
perror( "safe_realloc" );
|
||||
exit( 1 );
|
||||
}
|
||||
pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
|
||||
if (( bvp = (struct berval *)malloc( sizeof( struct berval )))
|
||||
== NULL ) {
|
||||
perror( "malloc" );
|
||||
exit( 1 );
|
||||
}
|
||||
pmods[ i ]->mod_bvalues[ j ] = bvp;
|
||||
|
||||
bvp->bv_len = vlen;
|
||||
if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
|
||||
perror( "malloc" );
|
||||
exit( 1 );
|
||||
}
|
||||
SAFEMEMCPY( bvp->bv_val, value, vlen );
|
||||
bvp->bv_val[ vlen ] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
get_add_entry( char *filename, LDAPMod ***mods )
|
||||
{
|
||||
FILE *fp;
|
||||
char *entry = NULL;
|
||||
|
||||
if ( fp = fopen( filename, "r" )) {
|
||||
char line[BUFSIZ];
|
||||
|
||||
if ( fgets( line, BUFSIZ, fp )) {
|
||||
char *nl;
|
||||
|
||||
if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
|
||||
*nl = '\0';
|
||||
entry = strdup( line );
|
||||
|
||||
}
|
||||
|
||||
while ( fgets( line, BUFSIZ, fp )) {
|
||||
char *nl;
|
||||
char *value;
|
||||
|
||||
if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
|
||||
*nl = '\0';
|
||||
|
||||
if ( *line == '\0' ) break;
|
||||
if ( !( value = strchr( line, ':' ))) break;
|
||||
|
||||
*value++ = '\0';
|
||||
while ( *value && isblank( *value )) value++;
|
||||
|
||||
addmodifyop( mods, LDAP_MOD_ADD, line, value, strlen( value ));
|
||||
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
return( entry );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_addel(
|
||||
char *host,
|
||||
int port,
|
||||
char *manager,
|
||||
char *passwd,
|
||||
char *entry,
|
||||
LDAPMod **attrs,
|
||||
int maxloop
|
||||
)
|
||||
{
|
||||
LDAP *ld;
|
||||
int i;
|
||||
|
||||
if (( ld = ldap_init( host, port )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE )
|
||||
!= LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_bind" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
fprintf( stderr, "Add/Delete(%d): entry=\"%s\".\n", maxloop, entry );
|
||||
|
||||
for ( i = 0; i < maxloop; i++ ) {
|
||||
|
||||
/* add the entry */
|
||||
if ( ldap_add_s( ld, entry, attrs ) != LDAP_SUCCESS ) {
|
||||
|
||||
ldap_perror( ld, "ldap_add" );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* wait a second for the add to really complete */
|
||||
sleep( 1 );
|
||||
|
||||
/* now delete the entry again */
|
||||
if ( ldap_delete_s( ld, entry ) != LDAP_SUCCESS ) {
|
||||
|
||||
ldap_perror( ld, "ldap_delete" );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ldap_unbind( ld );
|
||||
}
|
||||
|
||||
|
117
tests/slapd-read.c
Normal file
117
tests/slapd-read.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/string.h>
|
||||
#include <ac/ctype.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/unistd.h>
|
||||
#include <ac/wait.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "lber.h"
|
||||
#include "ldap.h"
|
||||
|
||||
#define LOOPS 100
|
||||
|
||||
static void
|
||||
do_read( char *host, int port, char *entry, int maxloop );
|
||||
|
||||
static void
|
||||
usage( char *name )
|
||||
{
|
||||
fprintf( stderr, "usage: %s [-h <host>] -p port -e <entry> [-l <loops>]\n",
|
||||
name );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int i, j;
|
||||
char *host = "localhost";
|
||||
int port = -1;
|
||||
char *entry = NULL;
|
||||
int loops = LOOPS;
|
||||
|
||||
while ( (i = getopt( argc, argv, "h:p:e:l:" )) != EOF ) {
|
||||
switch( i ) {
|
||||
case 'h': /* the servers host */
|
||||
host = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'p': /* the servers port */
|
||||
port = atoi( optarg );
|
||||
break;
|
||||
|
||||
case 'e': /* file with entry search request */
|
||||
entry = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'l': /* the number of loops */
|
||||
loops = atoi( optarg );
|
||||
break;
|
||||
|
||||
default:
|
||||
usage( argv[0] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (( entry == NULL ) || ( port == -1 ))
|
||||
usage( argv[0] );
|
||||
|
||||
if ( *entry == '\0' ) {
|
||||
|
||||
fprintf( stderr, "%s: invalid EMPTY entry DN.\n",
|
||||
argv[0] );
|
||||
exit( 1 );
|
||||
|
||||
}
|
||||
|
||||
do_read( host, port, entry, loops );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_read( char *host, int port, char *entry, int maxloop )
|
||||
{
|
||||
LDAP *ld;
|
||||
int i;
|
||||
char *attrs[] = { "cn", "sn", NULL };
|
||||
char *filter = "(objectclass=*)";
|
||||
|
||||
if (( ld = ldap_init( host, port )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( ldap_bind_s( ld, NULL, NULL, LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_bind" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
fprintf( stderr, "Read(%d): entry=\"%s\".\n", maxloop, entry );
|
||||
|
||||
for ( i = 0; i < maxloop; i++ ) {
|
||||
LDAPMessage *res;
|
||||
|
||||
if ( ldap_search_s( ld, entry, LDAP_SCOPE_BASE,
|
||||
filter, attrs, 0, &res ) != LDAP_SUCCESS ) {
|
||||
|
||||
ldap_perror( ld, "ldap_read" );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
ldap_msgfree( res );
|
||||
}
|
||||
|
||||
ldap_unbind( ld );
|
||||
}
|
||||
|
||||
|
122
tests/slapd-search.c
Normal file
122
tests/slapd-search.c
Normal file
@ -0,0 +1,122 @@
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/string.h>
|
||||
#include <ac/ctype.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/unistd.h>
|
||||
#include <ac/wait.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "lber.h"
|
||||
#include "ldap.h"
|
||||
|
||||
#define LOOPS 100
|
||||
|
||||
static void
|
||||
do_search( char *host, int port, char *sbase, char *filter, int maxloop );
|
||||
|
||||
static void
|
||||
usage( char *name )
|
||||
{
|
||||
fprintf( stderr, "usage: %s [-h <host>] -p port -b <searchbase> -f <searchfiter> [-l <loops>]\n",
|
||||
name );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int i, j;
|
||||
char *host = "localhost";
|
||||
int port = -1;
|
||||
char *sbase = NULL;
|
||||
char *filter = NULL;
|
||||
int loops = LOOPS;
|
||||
|
||||
while ( (i = getopt( argc, argv, "h:p:b:f:l:" )) != EOF ) {
|
||||
switch( i ) {
|
||||
case 'h': /* the servers host */
|
||||
host = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'p': /* the servers port */
|
||||
port = atoi( optarg );
|
||||
break;
|
||||
|
||||
case 'b': /* file with search base */
|
||||
sbase = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'f': /* the search request */
|
||||
filter = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'l': /* number of loops */
|
||||
loops = atoi( optarg );
|
||||
break;
|
||||
|
||||
default:
|
||||
usage( argv[0] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (( sbase == NULL ) || ( filter == NULL ) || ( port == -1 ))
|
||||
usage( argv[0] );
|
||||
|
||||
if ( *filter == '\0' ) {
|
||||
|
||||
fprintf( stderr, "%s: invalid EMPTY search filter.\n",
|
||||
argv[0] );
|
||||
exit( 1 );
|
||||
|
||||
}
|
||||
|
||||
do_search( host, port, sbase, filter, loops );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_search( char *host, int port, char *sbase, char *filter, int maxloop )
|
||||
{
|
||||
LDAP *ld;
|
||||
int i;
|
||||
char *attrs[] = { "cn", "sn", NULL };
|
||||
|
||||
if (( ld = ldap_init( host, port )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( ldap_bind_s( ld, NULL, NULL, LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_bind" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
fprintf( stderr, "Search(%d): base=\"%s\", filter=\"%s\".\n",
|
||||
maxloop, sbase, filter );
|
||||
|
||||
for ( i = 0; i < maxloop; i++ ) {
|
||||
LDAPMessage *res;
|
||||
|
||||
if ( ldap_search_s( ld, sbase, LDAP_SCOPE_SUBTREE,
|
||||
filter, attrs, 0, &res ) != LDAP_SUCCESS ) {
|
||||
|
||||
ldap_perror( ld, "ldap_search" );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
ldap_msgfree( res );
|
||||
}
|
||||
|
||||
ldap_unbind( ld );
|
||||
}
|
||||
|
||||
|
352
tests/slapd-tester.c
Normal file
352
tests/slapd-tester.c
Normal file
@ -0,0 +1,352 @@
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/string.h>
|
||||
#include <ac/ctype.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/unistd.h>
|
||||
#include <ac/wait.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "ldapconfig.h"
|
||||
|
||||
|
||||
#define SEARCHCMD "slapd-search"
|
||||
#define READCMD "slapd-read"
|
||||
#define ADDCMD "slapd-addel"
|
||||
#define MAXARGS 100
|
||||
#define MAXREQS 20
|
||||
#define LOOPS "100"
|
||||
|
||||
#define TSEARCHFILE "do_search.0"
|
||||
#define TREADFILE "do_read.0"
|
||||
#define TADDFILE "do_add."
|
||||
|
||||
static char *get_file_name( char *dirname, char *filename );
|
||||
static int get_search_filters( char *filename, char *filters[] );
|
||||
static int get_read_entries( char *filename, char *entries[] );
|
||||
static void fork_child( char *prog, char *args[] );
|
||||
static void wait4kids( int nkidval );
|
||||
|
||||
static int maxkids = 20;
|
||||
static int nkids;
|
||||
|
||||
static void
|
||||
usage( char *name )
|
||||
{
|
||||
fprintf( stderr, "usage: %s [-h <host>] -p <port> -D <manager> -w <passwd> -d <datadir> -b <baseDN> [-j <maxchild>] [-l <loops>]\n", name );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int i, j;
|
||||
char *host = "localhost";
|
||||
char *port = NULL;
|
||||
char *manager = NULL;
|
||||
char *passwd = NULL;
|
||||
char *dirname = NULL;
|
||||
char *sbase = NULL;
|
||||
char *loops = LOOPS;
|
||||
DIR *datadir;
|
||||
struct dirent *file;
|
||||
char *sfile = NULL;
|
||||
char *sreqs[MAXREQS];
|
||||
int snum = 0;
|
||||
char *rfile = NULL;
|
||||
char *rreqs[MAXREQS];
|
||||
int rnum = 0;
|
||||
char *afiles[MAXREQS];
|
||||
int anum = 0;
|
||||
char *sargs[MAXARGS];
|
||||
int sanum;
|
||||
char scmd[MAXPATHLEN];
|
||||
char *rargs[MAXARGS];
|
||||
int ranum;
|
||||
char rcmd[MAXPATHLEN];
|
||||
char *aargs[MAXARGS];
|
||||
int aanum;
|
||||
char acmd[MAXPATHLEN];
|
||||
|
||||
while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:" )) != EOF ) {
|
||||
switch( i ) {
|
||||
case 'h': /* slapd host */
|
||||
host = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'p': /* the servers port number */
|
||||
port = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'D': /* slapd manager */
|
||||
manager = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'w': /* the managers passwd */
|
||||
passwd = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'b': /* the base DN */
|
||||
sbase = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'd': /* data directory */
|
||||
dirname = strdup( optarg );
|
||||
break;
|
||||
|
||||
case 'j': /* the number of parallel clients */
|
||||
maxkids = atoi( optarg );
|
||||
break;
|
||||
|
||||
case 'l': /* the number of loops per client */
|
||||
loops = strdup( optarg );
|
||||
break;
|
||||
|
||||
default:
|
||||
usage( argv[0] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
|
||||
( manager == NULL ) || ( passwd == NULL ))
|
||||
usage( argv[0] );
|
||||
|
||||
/* get the file list */
|
||||
if ( ( datadir = opendir( dirname )) == NULL ) {
|
||||
|
||||
fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
|
||||
argv[0], dirname );
|
||||
exit( 1 );
|
||||
|
||||
}
|
||||
|
||||
/* look for search, read, and add/delete files */
|
||||
for ( file = readdir( datadir ); file; file = readdir( datadir )) {
|
||||
|
||||
if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
|
||||
sfile = get_file_name( dirname, file->d_name );
|
||||
continue;
|
||||
} else if ( !strcasecmp( file->d_name, TREADFILE )) {
|
||||
rfile = get_file_name( dirname, file->d_name );
|
||||
continue;
|
||||
} else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
|
||||
&& ( anum < MAXREQS )) {
|
||||
afiles[anum++] = get_file_name( dirname, file->d_name );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* look for search requests */
|
||||
if ( sfile ) {
|
||||
snum = get_search_filters( sfile, sreqs );
|
||||
}
|
||||
|
||||
/* look for read requests */
|
||||
if ( rfile ) {
|
||||
rnum = get_read_entries( rfile, rreqs );
|
||||
}
|
||||
|
||||
/*
|
||||
* generate the search clients
|
||||
*/
|
||||
|
||||
sanum = 0;
|
||||
sprintf( scmd, "%s", SEARCHCMD );
|
||||
sargs[sanum++] = scmd;
|
||||
sargs[sanum++] = "-h";
|
||||
sargs[sanum++] = host;
|
||||
sargs[sanum++] = "-p";
|
||||
sargs[sanum++] = port;
|
||||
sargs[sanum++] = "-b";
|
||||
sargs[sanum++] = sbase;
|
||||
sargs[sanum++] = "-l";
|
||||
sargs[sanum++] = loops;
|
||||
sargs[sanum++] = "-f";
|
||||
sargs[sanum++] = NULL; /* will hold the search request */
|
||||
sargs[sanum++] = NULL;
|
||||
|
||||
/*
|
||||
* generate the read clients
|
||||
*/
|
||||
|
||||
ranum = 0;
|
||||
sprintf( rcmd, "%s", READCMD );
|
||||
rargs[ranum++] = rcmd;
|
||||
rargs[ranum++] = "-h";
|
||||
rargs[ranum++] = host;
|
||||
rargs[ranum++] = "-p";
|
||||
rargs[ranum++] = port;
|
||||
rargs[ranum++] = "-l";
|
||||
rargs[ranum++] = loops;
|
||||
rargs[ranum++] = "-e";
|
||||
rargs[ranum++] = NULL; /* will hold the read entry */
|
||||
rargs[ranum++] = NULL;
|
||||
|
||||
/*
|
||||
* generate the add/delete clients
|
||||
*/
|
||||
|
||||
aanum = 0;
|
||||
sprintf( acmd, "%s", ADDCMD );
|
||||
aargs[aanum++] = acmd;
|
||||
aargs[aanum++] = "-h";
|
||||
aargs[aanum++] = host;
|
||||
aargs[aanum++] = "-p";
|
||||
aargs[aanum++] = port;
|
||||
aargs[aanum++] = "-D";
|
||||
aargs[aanum++] = manager;
|
||||
aargs[aanum++] = "-w";
|
||||
aargs[aanum++] = passwd;
|
||||
aargs[aanum++] = "-l";
|
||||
aargs[aanum++] = loops;
|
||||
aargs[aanum++] = "-f";
|
||||
aargs[aanum++] = NULL; /* will hold the add data file */
|
||||
aargs[aanum++] = NULL;
|
||||
|
||||
for ( j = 0; j < MAXREQS; j++ ) {
|
||||
|
||||
if ( j < snum ) {
|
||||
|
||||
sargs[sanum - 2] = sreqs[j];
|
||||
fork_child( scmd, sargs );
|
||||
|
||||
}
|
||||
|
||||
if ( j < rnum ) {
|
||||
|
||||
rargs[ranum - 2] = rreqs[j];
|
||||
fork_child( rcmd, rargs );
|
||||
|
||||
}
|
||||
|
||||
if ( j < anum ) {
|
||||
|
||||
aargs[aanum - 2] = afiles[j];
|
||||
fork_child( acmd, aargs );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wait4kids( -1 );
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
static char *
|
||||
get_file_name( char *dirname, char *filename )
|
||||
{
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
sprintf( buf, "%s%s%s", dirname, DEFAULT_DIRSEP, filename );
|
||||
return( strdup( buf ));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_search_filters( char *filename, char *filters[] )
|
||||
{
|
||||
FILE *fp;
|
||||
int filter = 0;
|
||||
|
||||
if ( fp = fopen( filename, "r" )) {
|
||||
char line[BUFSIZ];
|
||||
|
||||
while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
|
||||
char *nl;
|
||||
|
||||
if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
|
||||
*nl = '\0';
|
||||
filters[filter++] = strdup( line );
|
||||
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
return( filter );
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_read_entries( char *filename, char *entries[] )
|
||||
{
|
||||
FILE *fp;
|
||||
int entry = 0;
|
||||
|
||||
if ( fp = fopen( filename, "r" )) {
|
||||
char line[BUFSIZ];
|
||||
|
||||
while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
|
||||
char *nl;
|
||||
|
||||
if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
|
||||
*nl = '\0';
|
||||
entries[entry++] = strdup( line );
|
||||
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
return( entry );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fork_child( char *prog, char *args[] )
|
||||
{
|
||||
int status, pid;
|
||||
|
||||
wait4kids( maxkids );
|
||||
|
||||
switch ( pid = fork() ) {
|
||||
case 0: /* child */
|
||||
execvp( prog, args );
|
||||
fprintf( stderr, "%s: ", prog );
|
||||
perror( "execv" );
|
||||
exit( -1 );
|
||||
break;
|
||||
|
||||
case -1: /* trouble */
|
||||
fprintf( stderr, "Could not fork to run %s\n", prog );
|
||||
perror( "fork" );
|
||||
break;
|
||||
|
||||
default: /* parent */
|
||||
nkids++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wait4kids( int nkidval )
|
||||
{
|
||||
int status;
|
||||
unsigned char *p;
|
||||
|
||||
while ( nkids >= nkidval ) {
|
||||
wait( &status );
|
||||
p = (unsigned char *) &status;
|
||||
if ( p[sizeof(int) - 1] == 0177 ) {
|
||||
fprintf( stderr,
|
||||
"stopping: child stopped with signal %d\n",
|
||||
p[sizeof(int) - 2] );
|
||||
} else if ( p[sizeof(int) - 1] != 0 ) {
|
||||
fprintf( stderr,
|
||||
"stopping: child terminated with signal %d\n",
|
||||
p[sizeof(int) - 1] );
|
||||
exit( p[sizeof(int) - 1] );
|
||||
} else if ( p[sizeof(int) - 2] != 0 ) {
|
||||
fprintf( stderr,
|
||||
"stopping: child exited with status %d\n",
|
||||
p[sizeof(int) - 2] );
|
||||
exit( p[sizeof(int) - 2] );
|
||||
} else {
|
||||
nkids--;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user