10 #include <ac/unistd.h>
13 #ifdef HAVE_SYS_PARAM_H
14 #include <sys/param.h>
17 #include "ldapconfig.h"
20 #define SEARCHCMD "slapd-search"
21 #define READCMD "slapd-read"
22 #define ADDCMD "slapd-addel"
27 #define TSEARCHFILE "do_search.0"
28 #define TREADFILE "do_read.0"
29 #define TADDFILE "do_add."
31 static char *get_file_name( char *dirname, char *filename );
32 static int get_search_filters( char *filename, char *filters[] );
33 static int get_read_entries( char *filename, char *entries[] );
34 static void fork_child( char *prog, char *args[] );
35 static void wait4kids( int nkidval );
37 static int maxkids = 20;
43 fprintf( stderr, "usage: %s [-h <host>] -p <port> -D <manager> -w <passwd> -d <datadir> -b <baseDN> [-j <maxchild>] [-l <loops>] -P <progdir>\n", name );
48 main( int argc, char **argv )
51 char *host = "localhost";
67 char *afiles[MAXREQS];
71 char scmd[MAXPATHLEN];
74 char rcmd[MAXPATHLEN];
77 char acmd[MAXPATHLEN];
79 while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:P:" )) != EOF ) {
81 case 'h': /* slapd host */
82 host = strdup( optarg );
85 case 'p': /* the servers port number */
86 port = strdup( optarg );
89 case 'D': /* slapd manager */
90 manager = strdup( optarg );
93 case 'w': /* the managers passwd */
94 passwd = strdup( optarg );
97 case 'b': /* the base DN */
98 sbase = strdup( optarg );
101 case 'd': /* data directory */
102 dirname = strdup( optarg );
105 case 'P': /* prog directory */
106 progdir = strdup( optarg );
109 case 'j': /* the number of parallel clients */
110 maxkids = atoi( optarg );
113 case 'l': /* the number of loops per client */
114 loops = strdup( optarg );
123 if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
124 ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
127 /* get the file list */
128 if ( ( datadir = opendir( dirname )) == NULL ) {
130 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
136 /* look for search, read, and add/delete files */
137 for ( file = readdir( datadir ); file; file = readdir( datadir )) {
139 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
140 sfile = get_file_name( dirname, file->d_name );
142 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
143 rfile = get_file_name( dirname, file->d_name );
145 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
146 && ( anum < MAXREQS )) {
147 afiles[anum++] = get_file_name( dirname, file->d_name );
154 /* look for search requests */
156 snum = get_search_filters( sfile, sreqs );
159 /* look for read requests */
161 rnum = get_read_entries( rfile, rreqs );
165 * generate the search clients
169 sprintf( scmd, "%s%s%s", progdir, DIRSEP, SEARCHCMD );
170 sargs[sanum++] = scmd;
171 sargs[sanum++] = "-h";
172 sargs[sanum++] = host;
173 sargs[sanum++] = "-p";
174 sargs[sanum++] = port;
175 sargs[sanum++] = "-b";
176 sargs[sanum++] = sbase;
177 sargs[sanum++] = "-l";
178 sargs[sanum++] = loops;
179 sargs[sanum++] = "-f";
180 sargs[sanum++] = NULL; /* will hold the search request */
181 sargs[sanum++] = NULL;
184 * generate the read clients
188 sprintf( rcmd, "%s%s%s", progdir, DIRSEP, READCMD );
189 rargs[ranum++] = rcmd;
190 rargs[ranum++] = "-h";
191 rargs[ranum++] = host;
192 rargs[ranum++] = "-p";
193 rargs[ranum++] = port;
194 rargs[ranum++] = "-l";
195 rargs[ranum++] = loops;
196 rargs[ranum++] = "-e";
197 rargs[ranum++] = NULL; /* will hold the read entry */
198 rargs[ranum++] = NULL;
201 * generate the add/delete clients
205 sprintf( acmd, "%s%s%s", progdir, DIRSEP, ADDCMD );
206 aargs[aanum++] = acmd;
207 aargs[aanum++] = "-h";
208 aargs[aanum++] = host;
209 aargs[aanum++] = "-p";
210 aargs[aanum++] = port;
211 aargs[aanum++] = "-D";
212 aargs[aanum++] = manager;
213 aargs[aanum++] = "-w";
214 aargs[aanum++] = passwd;
215 aargs[aanum++] = "-l";
216 aargs[aanum++] = loops;
217 aargs[aanum++] = "-f";
218 aargs[aanum++] = NULL; /* will hold the add data file */
219 aargs[aanum++] = NULL;
221 for ( j = 0; j < MAXREQS; j++ ) {
225 sargs[sanum - 2] = sreqs[j];
226 fork_child( scmd, sargs );
232 rargs[ranum - 2] = rreqs[j];
233 fork_child( rcmd, rargs );
239 aargs[aanum - 2] = afiles[j];
240 fork_child( acmd, aargs );
252 get_file_name( char *dirname, char *filename )
254 char buf[MAXPATHLEN];
256 sprintf( buf, "%s%s%s", dirname, DIRSEP, filename );
257 return( strdup( buf ));
262 get_search_filters( char *filename, char *filters[] )
267 if ( (fp = fopen( filename, "r" )) != NULL ) {
270 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
273 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
275 filters[filter++] = strdup( line );
286 get_read_entries( char *filename, char *entries[] )
291 if ( (fp = fopen( filename, "r" )) != NULL ) {
294 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
297 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
299 entries[entry++] = strdup( line );
310 fork_child( char *prog, char *args[] )
314 wait4kids( maxkids );
316 switch ( pid = fork() ) {
318 execvp( prog, args );
319 fprintf( stderr, "%s: ", prog );
324 case -1: /* trouble */
325 fprintf( stderr, "Could not fork to run %s\n", prog );
329 default: /* parent */
336 wait4kids( int nkidval )
340 while ( nkids >= nkidval ) {
343 if ( WIFSTOPPED(status) ) {
345 "stopping: child stopped with signal %d\n",
346 (int) WSTOPSIG(status) );
348 } else if ( WIFSIGNALED(status) ) {
350 "stopping: child terminated with signal %d%s\n",
351 (int) WTERMSIG(status),
353 WCOREDUMP(status) ? ", core dumped" : ""
358 exit( WEXITSTATUS(status) );
360 } else if ( WEXITSTATUS(status) != 0 ) {
362 "stopping: child exited with status %d\n",
363 (int) WEXITSTATUS(status) );
364 exit( WEXITSTATUS(status) );