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 sprintf( scmd, "%s%s%s", progdir, LDAP_DIRSEP, SEARCHCMD );
185 sargs[sanum++] = scmd;
186 sargs[sanum++] = "-h";
187 sargs[sanum++] = host;
188 sargs[sanum++] = "-p";
189 sargs[sanum++] = port;
190 sargs[sanum++] = "-b";
191 sargs[sanum++] = sbase;
192 sargs[sanum++] = "-l";
193 sargs[sanum++] = loops;
194 sargs[sanum++] = "-f";
195 sargs[sanum++] = NULL; /* will hold the search request */
196 sargs[sanum++] = NULL;
199 * generate the read clients
203 sprintf( rcmd, "%s%s%s", progdir, LDAP_DIRSEP, READCMD );
204 rargs[ranum++] = rcmd;
205 rargs[ranum++] = "-h";
206 rargs[ranum++] = host;
207 rargs[ranum++] = "-p";
208 rargs[ranum++] = port;
209 rargs[ranum++] = "-l";
210 rargs[ranum++] = loops;
211 rargs[ranum++] = "-e";
212 rargs[ranum++] = NULL; /* will hold the read entry */
213 rargs[ranum++] = NULL;
216 * generate the add/delete clients
220 sprintf( acmd, "%s%s%s", progdir, LDAP_DIRSEP, ADDCMD );
221 aargs[aanum++] = acmd;
222 aargs[aanum++] = "-h";
223 aargs[aanum++] = host;
224 aargs[aanum++] = "-p";
225 aargs[aanum++] = port;
226 aargs[aanum++] = "-D";
227 aargs[aanum++] = manager;
228 aargs[aanum++] = "-w";
229 aargs[aanum++] = passwd;
230 aargs[aanum++] = "-l";
231 aargs[aanum++] = loops;
232 aargs[aanum++] = "-f";
233 aargs[aanum++] = NULL; /* will hold the add data file */
234 aargs[aanum++] = NULL;
236 for ( j = 0; j < MAXREQS; j++ ) {
240 sargs[sanum - 2] = sreqs[j];
241 fork_child( scmd, sargs );
247 rargs[ranum - 2] = rreqs[j];
248 fork_child( rcmd, rargs );
254 aargs[aanum - 2] = afiles[j];
255 fork_child( acmd, aargs );
263 exit( EXIT_SUCCESS );
267 get_file_name( char *dirname, char *filename )
269 char buf[MAXPATHLEN];
271 sprintf( buf, "%s%s%s", dirname, LDAP_DIRSEP, filename );
272 return( strdup( buf ));
277 get_search_filters( char *filename, char *filters[] )
282 if ( (fp = fopen( filename, "r" )) != NULL ) {
285 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
288 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
290 filters[filter++] = ArgDup( line );
301 get_read_entries( char *filename, char *entries[] )
306 if ( (fp = fopen( filename, "r" )) != NULL ) {
309 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
312 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
314 entries[entry++] = ArgDup( line );
325 fork_child( char *prog, char *args[] )
329 wait4kids( maxkids );
331 switch ( pid = fork() ) {
333 execvp( prog, args );
334 fprintf( stderr, "%s: ", prog );
336 exit( EXIT_FAILURE );
339 case -1: /* trouble */
340 fprintf( stderr, "Could not fork to run %s\n", prog );
344 default: /* parent */
351 wait4kids( int nkidval )
355 while ( nkids >= nkidval ) {
358 if ( WIFSTOPPED(status) ) {
360 "stopping: child stopped with signal %d\n",
361 (int) WSTOPSIG(status) );
363 } else if ( WIFSIGNALED(status) ) {
365 "stopping: child terminated with signal %d%s\n",
366 (int) WTERMSIG(status),
368 WCOREDUMP(status) ? ", core dumped" : ""
373 exit( WEXITSTATUS(status) );
375 } else if ( WEXITSTATUS(status) != 0 ) {
377 "stopping: child exited with status %d\n",
378 (int) WEXITSTATUS(status) );
379 exit( WEXITSTATUS(status) );
389 wait4kids( int nkidval )
393 while ( nkids >= nkidval ) {
394 rc = WaitForMultipleObjects( nkids, children, FALSE, INFINITE );
395 for ( i=rc - WAIT_OBJECT_0; i<nkids-1; i++)
396 children[i] = children[i+1];
402 fork_child( char *prog, char *args[] )
406 wait4kids( maxkids );
408 rc = _spawnvp( _P_NOWAIT, prog, args );
411 fprintf( stderr, "%s: ", prog );
414 children[nkids++] = (HANDLE)rc;