3 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
10 #include <ac/stdlib.h>
13 #include <ac/dirent.h>
15 #include <ac/socket.h>
16 #include <ac/string.h>
17 #include <ac/unistd.h>
21 #include "ldap_defaults.h"
24 #define SEARCHCMD "slapd-search"
25 #define READCMD "slapd-read"
26 #define ADDCMD "slapd-addel"
31 #define TSEARCHFILE "do_search.0"
32 #define TREADFILE "do_read.0"
33 #define TADDFILE "do_add."
35 static char *get_file_name( char *dirname, char *filename );
36 static int get_search_filters( char *filename, char *filters[] );
37 static int get_read_entries( char *filename, char *entries[] );
38 static void fork_child( char *prog, char **args );
39 static void wait4kids( int nkidval );
41 static int maxkids = 20;
45 static HANDLE *children;
46 static char argbuf[BUFSIZ];
47 #define ArgDup(x) strdup(strcat(strcat(strcpy(argbuf,"\""),x),"\""))
49 #define ArgDup(x) strdup(x)
55 fprintf( stderr, "usage: %s [-h <host>] -p <port> -D <manager> -w <passwd> -d <datadir> -b <baseDN> [-j <maxchild>] [-l <loops>] -P <progdir>\n", name );
60 main( int argc, char **argv )
63 char *host = "localhost";
79 char *afiles[MAXREQS];
83 char scmd[MAXPATHLEN];
86 char rcmd[MAXPATHLEN];
89 char acmd[MAXPATHLEN];
91 while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:P:" )) != EOF ) {
93 case 'h': /* slapd host */
94 host = strdup( optarg );
97 case 'p': /* the servers port number */
98 port = strdup( optarg );
101 case 'D': /* slapd manager */
102 manager = ArgDup( optarg );
105 case 'w': /* the managers passwd */
106 passwd = ArgDup( optarg );
109 case 'b': /* the base DN */
110 sbase = ArgDup( optarg );
113 case 'd': /* data directory */
114 dirname = strdup( optarg );
117 case 'P': /* prog directory */
118 progdir = strdup( optarg );
121 case 'j': /* the number of parallel clients */
122 maxkids = atoi( optarg );
125 case 'l': /* the number of loops per client */
126 loops = strdup( optarg );
135 if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
136 ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
140 children = malloc( maxkids * sizeof(HANDLE) );
142 /* get the file list */
143 if ( ( datadir = opendir( dirname )) == NULL ) {
145 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
147 exit( EXIT_FAILURE );
151 /* look for search, read, and add/delete files */
152 for ( file = readdir( datadir ); file; file = readdir( datadir )) {
154 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
155 sfile = get_file_name( dirname, file->d_name );
157 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
158 rfile = get_file_name( dirname, file->d_name );
160 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
161 && ( anum < MAXREQS )) {
162 afiles[anum++] = get_file_name( dirname, file->d_name );
169 /* look for search requests */
171 snum = get_search_filters( sfile, sreqs );
174 /* look for read requests */
176 rnum = get_read_entries( rfile, rreqs );
180 * generate the search clients
184 snprintf( scmd, sizeof scmd, "%s" LDAP_DIRSEP SEARCHCMD,
186 sargs[sanum++] = scmd;
187 sargs[sanum++] = "-h";
188 sargs[sanum++] = host;
189 sargs[sanum++] = "-p";
190 sargs[sanum++] = port;
191 sargs[sanum++] = "-b";
192 sargs[sanum++] = sbase;
193 sargs[sanum++] = "-l";
194 sargs[sanum++] = loops;
195 sargs[sanum++] = "-f";
196 sargs[sanum++] = NULL; /* will hold the search request */
197 sargs[sanum++] = NULL;
200 * generate the read clients
204 snprintf( rcmd, sizeof rcmd, "%s" LDAP_DIRSEP READCMD,
206 rargs[ranum++] = rcmd;
207 rargs[ranum++] = "-h";
208 rargs[ranum++] = host;
209 rargs[ranum++] = "-p";
210 rargs[ranum++] = port;
211 rargs[ranum++] = "-l";
212 rargs[ranum++] = loops;
213 rargs[ranum++] = "-e";
214 rargs[ranum++] = NULL; /* will hold the read entry */
215 rargs[ranum++] = NULL;
218 * generate the add/delete clients
222 snprintf( acmd, sizeof acmd, "%s" LDAP_DIRSEP ADDCMD,
224 aargs[aanum++] = acmd;
225 aargs[aanum++] = "-h";
226 aargs[aanum++] = host;
227 aargs[aanum++] = "-p";
228 aargs[aanum++] = port;
229 aargs[aanum++] = "-D";
230 aargs[aanum++] = manager;
231 aargs[aanum++] = "-w";
232 aargs[aanum++] = passwd;
233 aargs[aanum++] = "-l";
234 aargs[aanum++] = loops;
235 aargs[aanum++] = "-f";
236 aargs[aanum++] = NULL; /* will hold the add data file */
237 aargs[aanum++] = NULL;
239 for ( j = 0; j < MAXREQS; j++ ) {
243 sargs[sanum - 2] = sreqs[j];
244 fork_child( scmd, sargs );
250 rargs[ranum - 2] = rreqs[j];
251 fork_child( rcmd, rargs );
257 aargs[aanum - 2] = afiles[j];
258 fork_child( acmd, aargs );
266 exit( EXIT_SUCCESS );
270 get_file_name( char *dirname, char *filename )
272 char buf[MAXPATHLEN];
274 snprintf( buf, sizeof buf, "%s" LDAP_DIRSEP "%s",
276 return( strdup( buf ));
281 get_search_filters( char *filename, char *filters[] )
286 if ( (fp = fopen( filename, "r" )) != NULL ) {
289 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
292 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
294 filters[filter++] = ArgDup( line );
305 get_read_entries( char *filename, char *entries[] )
310 if ( (fp = fopen( filename, "r" )) != NULL ) {
313 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
316 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
318 entries[entry++] = ArgDup( line );
329 fork_child( char *prog, char **args )
333 wait4kids( maxkids );
335 switch ( pid = fork() ) {
338 /* The __LIBASCII execvp only handles ASCII "prog",
339 * we still need to translate the arg vec ourselves.
341 { char *arg2[MAXREQS];
344 for (i=0; args[i]; i++) {
345 arg2[i] = ArgDup(args[i]);
351 execvp( prog, args );
352 fprintf( stderr, "%s: ", prog );
354 exit( EXIT_FAILURE );
357 case -1: /* trouble */
358 fprintf( stderr, "Could not fork to run %s\n", prog );
362 default: /* parent */
369 wait4kids( int nkidval )
373 while ( nkids >= nkidval ) {
376 if ( WIFSTOPPED(status) ) {
378 "stopping: child stopped with signal %d\n",
379 (int) WSTOPSIG(status) );
381 } else if ( WIFSIGNALED(status) ) {
383 "stopping: child terminated with signal %d%s\n",
384 (int) WTERMSIG(status),
386 WCOREDUMP(status) ? ", core dumped" : ""
391 exit( WEXITSTATUS(status) );
393 } else if ( WEXITSTATUS(status) != 0 ) {
395 "stopping: child exited with status %d\n",
396 (int) WEXITSTATUS(status) );
397 exit( WEXITSTATUS(status) );
407 wait4kids( int nkidval )
411 while ( nkids >= nkidval ) {
412 rc = WaitForMultipleObjects( nkids, children, FALSE, INFINITE );
413 for ( i=rc - WAIT_OBJECT_0; i<nkids-1; i++)
414 children[i] = children[i+1];
420 fork_child( char *prog, char **args )
424 wait4kids( maxkids );
426 rc = _spawnvp( _P_NOWAIT, prog, args );
429 fprintf( stderr, "%s: ", prog );
432 children[nkids++] = (HANDLE)rc;