3 * Copyright 1998-2003 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 )
64 char *host = "localhost";
80 char *afiles[MAXREQS];
84 char scmd[MAXPATHLEN];
87 char rcmd[MAXPATHLEN];
90 char acmd[MAXPATHLEN];
92 while ( (i = getopt( argc, argv, "H:h:p:D:w:b:d:j:l:P:" )) != EOF ) {
94 case 'H': /* slapd uri */
95 uri = strdup( optarg );
98 case 'h': /* slapd host */
99 host = strdup( optarg );
102 case 'p': /* the servers port number */
103 port = strdup( optarg );
106 case 'D': /* slapd manager */
107 manager = ArgDup( optarg );
110 case 'w': /* the managers passwd */
111 passwd = ArgDup( optarg );
114 case 'b': /* the base DN */
115 sbase = ArgDup( optarg );
118 case 'd': /* data directory */
119 dirname = strdup( optarg );
122 case 'P': /* prog directory */
123 progdir = strdup( optarg );
126 case 'j': /* the number of parallel clients */
127 maxkids = atoi( optarg );
130 case 'l': /* the number of loops per client */
131 loops = strdup( optarg );
140 if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL && uri == NULL ) ||
141 ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
145 children = malloc( maxkids * sizeof(HANDLE) );
147 /* get the file list */
148 if ( ( datadir = opendir( dirname )) == NULL ) {
150 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
152 exit( EXIT_FAILURE );
156 /* look for search, read, and add/delete files */
157 for ( file = readdir( datadir ); file; file = readdir( datadir )) {
159 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
160 sfile = get_file_name( dirname, file->d_name );
162 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
163 rfile = get_file_name( dirname, file->d_name );
165 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
166 && ( anum < MAXREQS )) {
167 afiles[anum++] = get_file_name( dirname, file->d_name );
174 /* look for search requests */
176 snum = get_search_filters( sfile, sreqs );
179 /* look for read requests */
181 rnum = get_read_entries( rfile, rreqs );
185 * generate the search clients
189 snprintf( scmd, sizeof scmd, "%s" LDAP_DIRSEP SEARCHCMD,
191 sargs[sanum++] = scmd;
193 sargs[sanum++] = "-H";
194 sargs[sanum++] = uri;
196 sargs[sanum++] = "-h";
197 sargs[sanum++] = host;
198 sargs[sanum++] = "-p";
199 sargs[sanum++] = port;
201 sargs[sanum++] = "-b";
202 sargs[sanum++] = sbase;
203 sargs[sanum++] = "-l";
204 sargs[sanum++] = loops;
205 sargs[sanum++] = "-f";
206 sargs[sanum++] = NULL; /* will hold the search request */
207 sargs[sanum++] = NULL;
210 * generate the read clients
214 snprintf( rcmd, sizeof rcmd, "%s" LDAP_DIRSEP READCMD,
216 rargs[ranum++] = rcmd;
218 rargs[ranum++] = "-H";
219 rargs[ranum++] = uri;
221 rargs[ranum++] = "-h";
222 rargs[ranum++] = host;
223 rargs[ranum++] = "-p";
224 rargs[ranum++] = port;
226 rargs[ranum++] = "-l";
227 rargs[ranum++] = loops;
228 rargs[ranum++] = "-e";
229 rargs[ranum++] = NULL; /* will hold the read entry */
230 rargs[ranum++] = NULL;
233 * generate the add/delete clients
237 snprintf( acmd, sizeof acmd, "%s" LDAP_DIRSEP ADDCMD,
239 aargs[aanum++] = acmd;
241 aargs[aanum++] = "-H";
242 aargs[aanum++] = uri;
244 aargs[aanum++] = "-h";
245 aargs[aanum++] = host;
246 aargs[aanum++] = "-p";
247 aargs[aanum++] = port;
249 aargs[aanum++] = "-D";
250 aargs[aanum++] = manager;
251 aargs[aanum++] = "-w";
252 aargs[aanum++] = passwd;
253 aargs[aanum++] = "-l";
254 aargs[aanum++] = loops;
255 aargs[aanum++] = "-f";
256 aargs[aanum++] = NULL; /* will hold the add data file */
257 aargs[aanum++] = NULL;
259 for ( j = 0; j < MAXREQS; j++ ) {
263 sargs[sanum - 2] = sreqs[j];
264 fork_child( scmd, sargs );
270 rargs[ranum - 2] = rreqs[j];
271 fork_child( rcmd, rargs );
277 aargs[aanum - 2] = afiles[j];
278 fork_child( acmd, aargs );
286 exit( EXIT_SUCCESS );
290 get_file_name( char *dirname, char *filename )
292 char buf[MAXPATHLEN];
294 snprintf( buf, sizeof buf, "%s" LDAP_DIRSEP "%s",
296 return( strdup( buf ));
301 get_search_filters( char *filename, char *filters[] )
306 if ( (fp = fopen( filename, "r" )) != NULL ) {
309 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
312 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
314 filters[filter++] = ArgDup( line );
325 get_read_entries( char *filename, char *entries[] )
330 if ( (fp = fopen( filename, "r" )) != NULL ) {
333 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
336 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
338 entries[entry++] = ArgDup( line );
349 fork_child( char *prog, char **args )
353 wait4kids( maxkids );
355 switch ( pid = fork() ) {
358 /* The __LIBASCII execvp only handles ASCII "prog",
359 * we still need to translate the arg vec ourselves.
361 { char *arg2[MAXREQS];
364 for (i=0; args[i]; i++) {
365 arg2[i] = ArgDup(args[i]);
371 execvp( prog, args );
372 fprintf( stderr, "%s: ", prog );
374 exit( EXIT_FAILURE );
377 case -1: /* trouble */
378 fprintf( stderr, "Could not fork to run %s\n", prog );
382 default: /* parent */
389 wait4kids( int nkidval )
393 while ( nkids >= nkidval ) {
396 if ( WIFSTOPPED(status) ) {
398 "stopping: child stopped with signal %d\n",
399 (int) WSTOPSIG(status) );
401 } else if ( WIFSIGNALED(status) ) {
403 "stopping: child terminated with signal %d%s\n",
404 (int) WTERMSIG(status),
406 WCOREDUMP(status) ? ", core dumped" : ""
411 exit( WEXITSTATUS(status) );
413 } else if ( WEXITSTATUS(status) != 0 ) {
415 "stopping: child exited with status %d\n",
416 (int) WEXITSTATUS(status) );
417 exit( WEXITSTATUS(status) );
427 wait4kids( int nkidval )
431 while ( nkids >= nkidval ) {
432 rc = WaitForMultipleObjects( nkids, children, FALSE, INFINITE );
433 for ( i=rc - WAIT_OBJECT_0; i<nkids-1; i++)
434 children[i] = children[i+1];
440 fork_child( char *prog, char **args )
444 wait4kids( maxkids );
446 rc = _spawnvp( _P_NOWAIT, prog, args );
449 fprintf( stderr, "%s: ", prog );
452 children[nkids++] = (HANDLE)rc;