3 * Copyright 1998-2000 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;
47 fprintf( stderr, "usage: %s [-h <host>] -p <port> -D <manager> -w <passwd> -d <datadir> -b <baseDN> [-j <maxchild>] [-l <loops>] -P <progdir>\n", name );
52 main( int argc, char **argv )
55 char *host = "localhost";
71 char *afiles[MAXREQS];
75 char scmd[MAXPATHLEN];
78 char rcmd[MAXPATHLEN];
81 char acmd[MAXPATHLEN];
83 while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:P:" )) != EOF ) {
85 case 'h': /* slapd host */
86 host = strdup( optarg );
89 case 'p': /* the servers port number */
90 port = strdup( optarg );
93 case 'D': /* slapd manager */
94 manager = strdup( optarg );
97 case 'w': /* the managers passwd */
98 passwd = strdup( optarg );
101 case 'b': /* the base DN */
102 sbase = strdup( optarg );
105 case 'd': /* data directory */
106 dirname = strdup( optarg );
109 case 'P': /* prog directory */
110 progdir = strdup( optarg );
113 case 'j': /* the number of parallel clients */
114 maxkids = atoi( optarg );
117 case 'l': /* the number of loops per client */
118 loops = strdup( optarg );
127 if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
128 ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
131 /* get the file list */
132 if ( ( datadir = opendir( dirname )) == NULL ) {
134 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
136 exit( EXIT_FAILURE );
140 /* look for search, read, and add/delete files */
141 for ( file = readdir( datadir ); file; file = readdir( datadir )) {
143 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
144 sfile = get_file_name( dirname, file->d_name );
146 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
147 rfile = get_file_name( dirname, file->d_name );
149 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
150 && ( anum < MAXREQS )) {
151 afiles[anum++] = get_file_name( dirname, file->d_name );
158 /* look for search requests */
160 snum = get_search_filters( sfile, sreqs );
163 /* look for read requests */
165 rnum = get_read_entries( rfile, rreqs );
169 * generate the search clients
173 sprintf( scmd, "%s%s%s", progdir, LDAP_DIRSEP, SEARCHCMD );
174 sargs[sanum++] = scmd;
175 sargs[sanum++] = "-h";
176 sargs[sanum++] = host;
177 sargs[sanum++] = "-p";
178 sargs[sanum++] = port;
179 sargs[sanum++] = "-b";
180 sargs[sanum++] = sbase;
181 sargs[sanum++] = "-l";
182 sargs[sanum++] = loops;
183 sargs[sanum++] = "-f";
184 sargs[sanum++] = NULL; /* will hold the search request */
185 sargs[sanum++] = NULL;
188 * generate the read clients
192 sprintf( rcmd, "%s%s%s", progdir, LDAP_DIRSEP, READCMD );
193 rargs[ranum++] = rcmd;
194 rargs[ranum++] = "-h";
195 rargs[ranum++] = host;
196 rargs[ranum++] = "-p";
197 rargs[ranum++] = port;
198 rargs[ranum++] = "-l";
199 rargs[ranum++] = loops;
200 rargs[ranum++] = "-e";
201 rargs[ranum++] = NULL; /* will hold the read entry */
202 rargs[ranum++] = NULL;
205 * generate the add/delete clients
209 sprintf( acmd, "%s%s%s", progdir, LDAP_DIRSEP, ADDCMD );
210 aargs[aanum++] = acmd;
211 aargs[aanum++] = "-h";
212 aargs[aanum++] = host;
213 aargs[aanum++] = "-p";
214 aargs[aanum++] = port;
215 aargs[aanum++] = "-D";
216 aargs[aanum++] = manager;
217 aargs[aanum++] = "-w";
218 aargs[aanum++] = passwd;
219 aargs[aanum++] = "-l";
220 aargs[aanum++] = loops;
221 aargs[aanum++] = "-f";
222 aargs[aanum++] = NULL; /* will hold the add data file */
223 aargs[aanum++] = NULL;
225 for ( j = 0; j < MAXREQS; j++ ) {
229 sargs[sanum - 2] = sreqs[j];
230 fork_child( scmd, sargs );
236 rargs[ranum - 2] = rreqs[j];
237 fork_child( rcmd, rargs );
243 aargs[aanum - 2] = afiles[j];
244 fork_child( acmd, aargs );
252 exit( EXIT_SUCCESS );
256 get_file_name( char *dirname, char *filename )
258 char buf[MAXPATHLEN];
260 sprintf( buf, "%s%s%s", dirname, LDAP_DIRSEP, filename );
261 return( strdup( buf ));
266 get_search_filters( char *filename, char *filters[] )
271 if ( (fp = fopen( filename, "r" )) != NULL ) {
274 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
277 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
279 filters[filter++] = strdup( line );
290 get_read_entries( char *filename, char *entries[] )
295 if ( (fp = fopen( filename, "r" )) != NULL ) {
298 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
301 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
303 entries[entry++] = strdup( line );
314 fork_child( char *prog, char *args[] )
318 wait4kids( maxkids );
320 switch ( pid = fork() ) {
322 execvp( prog, args );
323 fprintf( stderr, "%s: ", prog );
325 exit( EXIT_FAILURE );
328 case -1: /* trouble */
329 fprintf( stderr, "Could not fork to run %s\n", prog );
333 default: /* parent */
340 wait4kids( int nkidval )
344 while ( nkids >= nkidval ) {
347 if ( WIFSTOPPED(status) ) {
349 "stopping: child stopped with signal %d\n",
350 (int) WSTOPSIG(status) );
352 } else if ( WIFSIGNALED(status) ) {
354 "stopping: child terminated with signal %d%s\n",
355 (int) WTERMSIG(status),
357 WCOREDUMP(status) ? ", core dumped" : ""
362 exit( WEXITSTATUS(status) );
364 } else if ( WEXITSTATUS(status) != 0 ) {
366 "stopping: child exited with status %d\n",
367 (int) WEXITSTATUS(status) );
368 exit( WEXITSTATUS(status) );