]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-tester.c
Revert unnecessary change in previous commit
[openldap] / tests / progs / slapd-tester.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 #include "portable.h"
7
8 #include <stdio.h>
9
10 #include <ac/stdlib.h>
11
12 #include <ac/ctype.h>
13 #include <ac/dirent.h>
14 #include <ac/param.h>
15 #include <ac/socket.h>
16 #include <ac/string.h>
17 #include <ac/unistd.h>
18 #include <ac/wait.h>
19
20
21 #include "ldap_defaults.h"
22
23
24 #define SEARCHCMD               "slapd-search"
25 #define READCMD                 "slapd-read"
26 #define ADDCMD                  "slapd-addel"
27 #define MAXARGS         100
28 #define MAXREQS                 20
29 #define LOOPS                   "100"
30
31 #define TSEARCHFILE             "do_search.0"
32 #define TREADFILE               "do_read.0"
33 #define TADDFILE                "do_add."
34
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 );
40
41 static int      maxkids = 20;
42 static int      nkids;
43
44 #ifdef HAVE_WINSOCK
45 static HANDLE   *children;
46 static char argbuf[BUFSIZ];
47 #define ArgDup(x) strdup(strcat(strcat(strcpy(argbuf,"\""),x),"\""))
48 #else
49 #define ArgDup(x) strdup(x)
50 #endif
51
52 static void
53 usage( char *name )
54 {
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 );
56         exit( EXIT_FAILURE );
57 }
58
59 int
60 main( int argc, char **argv )
61 {
62         int             i, j;
63         char            *host = "localhost";
64         char            *port = NULL;
65         char            *manager = NULL;
66         char            *passwd = NULL;
67         char            *dirname = NULL;
68         char        *sbase = NULL;
69         char            *progdir = NULL;
70         char            *loops = LOOPS;
71         DIR                     *datadir;
72         struct dirent   *file;
73         char            *sfile = NULL;
74         char            *sreqs[MAXREQS];
75         int         snum = 0;
76         char            *rfile = NULL;
77         char            *rreqs[MAXREQS];
78         int         rnum = 0;
79         char            *afiles[MAXREQS];
80         int         anum = 0;
81         char            *sargs[MAXARGS];
82         int                     sanum;
83         char            scmd[MAXPATHLEN];
84         char            *rargs[MAXARGS];
85         int                     ranum;
86         char            rcmd[MAXPATHLEN];
87         char            *aargs[MAXARGS];
88         int                     aanum;
89         char            acmd[MAXPATHLEN];
90
91         while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:P:" )) != EOF ) {
92                 switch( i ) {
93                         case 'h':               /* slapd host */
94                                 host = strdup( optarg );
95                         break;
96
97                         case 'p':               /* the servers port number */
98                                 port = strdup( optarg );
99                                 break;
100
101                         case 'D':               /* slapd manager */
102                                 manager = ArgDup( optarg );
103                         break;
104
105                         case 'w':               /* the managers passwd */
106                                 passwd = ArgDup( optarg );
107                                 break;
108
109                         case 'b':               /* the base DN */
110                                 sbase = ArgDup( optarg );
111                                 break;
112
113                         case 'd':               /* data directory */
114                                 dirname = strdup( optarg );
115                         break;
116
117                         case 'P':               /* prog directory */
118                                 progdir = strdup( optarg );
119                         break;
120
121                         case 'j':               /* the number of parallel clients */
122                                 maxkids = atoi( optarg );
123                                 break;
124
125                         case 'l':               /* the number of loops per client */
126                                 loops = strdup( optarg );
127                                 break;
128
129                         default:
130                                 usage( argv[0] );
131                                 break;
132                 }
133         }
134
135         if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
136                         ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
137                 usage( argv[0] );
138
139 #ifdef HAVE_WINSOCK
140         children = malloc( maxkids * sizeof(HANDLE) );
141 #endif
142         /* get the file list */
143         if ( ( datadir = opendir( dirname )) == NULL ) {
144
145                 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
146                                         argv[0], dirname );
147                 exit( EXIT_FAILURE );
148
149         }
150
151         /*  look for search, read, and add/delete files */
152         for ( file = readdir( datadir ); file; file = readdir( datadir )) {
153
154                 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
155                         sfile = get_file_name( dirname, file->d_name );
156                         continue;
157                 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
158                         rfile = get_file_name( dirname, file->d_name );
159                         continue;
160                 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
161                         && ( anum < MAXREQS )) {
162                         afiles[anum++] = get_file_name( dirname, file->d_name );
163                         continue;
164                 }
165         }
166
167         closedir( datadir );
168
169         /* look for search requests */
170         if ( sfile ) {
171                 snum = get_search_filters( sfile, sreqs );
172         }
173
174         /* look for read requests */
175         if ( rfile ) {
176                 rnum = get_read_entries( rfile, rreqs );
177         }
178
179         /*
180          * generate the search clients
181          */
182
183         sanum = 0;
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;
197
198         /*
199          * generate the read clients
200          */
201
202         ranum = 0;
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;
214
215         /*
216          * generate the add/delete clients
217          */
218
219         aanum = 0;
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;
235
236         for ( j = 0; j < MAXREQS; j++ ) {
237
238                 if ( j < snum ) {
239
240                         sargs[sanum - 2] = sreqs[j];
241                         fork_child( scmd, sargs );
242
243                 }
244
245                 if ( j < rnum ) {
246
247                         rargs[ranum - 2] = rreqs[j];
248                         fork_child( rcmd, rargs );
249
250                 }
251
252                 if ( j < anum ) {
253
254                         aargs[aanum - 2] = afiles[j];
255                         fork_child( acmd, aargs );
256
257                 }
258
259         }
260
261         wait4kids( -1 );
262
263         exit( EXIT_SUCCESS );
264 }
265
266 static char *
267 get_file_name( char *dirname, char *filename )
268 {
269         char buf[MAXPATHLEN];
270
271         sprintf( buf, "%s%s%s", dirname, LDAP_DIRSEP, filename );
272         return( strdup( buf ));
273 }
274
275
276 static int
277 get_search_filters( char *filename, char *filters[] )
278 {
279         FILE    *fp;
280         int     filter = 0;
281
282         if ( (fp = fopen( filename, "r" )) != NULL ) {
283                 char  line[BUFSIZ];
284
285                 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
286                         char *nl;
287
288                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
289                                 *nl = '\0';
290                         filters[filter++] = ArgDup( line );
291
292                 }
293                 fclose( fp );
294         }
295
296         return( filter );
297 }
298
299
300 static int
301 get_read_entries( char *filename, char *entries[] )
302 {
303         FILE    *fp;
304         int     entry = 0;
305
306         if ( (fp = fopen( filename, "r" )) != NULL ) {
307                 char  line[BUFSIZ];
308
309                 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
310                         char *nl;
311
312                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
313                                 *nl = '\0';
314                         entries[entry++] = ArgDup( line );
315
316                 }
317                 fclose( fp );
318         }
319
320         return( entry );
321 }
322
323 #ifndef HAVE_WINSOCK
324 static void
325 fork_child( char *prog, char *args[] )
326 {
327         pid_t   pid;
328
329         wait4kids( maxkids );
330
331         switch ( pid = fork() ) {
332         case 0:         /* child */
333                 execvp( prog, args );
334                 fprintf( stderr, "%s: ", prog );
335                 perror( "execv" );
336                 exit( EXIT_FAILURE );
337                 break;
338
339         case -1:        /* trouble */
340                 fprintf( stderr, "Could not fork to run %s\n", prog );
341                 perror( "fork" );
342                 break;
343
344         default:        /* parent */
345                 nkids++;
346                 break;
347         }
348 }
349
350 static void
351 wait4kids( int nkidval )
352 {
353         int             status;
354
355         while ( nkids >= nkidval ) {
356                 wait( &status );
357
358                 if ( WIFSTOPPED(status) ) {
359                         fprintf( stderr,
360                             "stopping: child stopped with signal %d\n",
361                             (int) WSTOPSIG(status) );
362
363                 } else if ( WIFSIGNALED(status) ) {
364                         fprintf( stderr, 
365                             "stopping: child terminated with signal %d%s\n",
366                             (int) WTERMSIG(status),
367 #ifdef WCOREDUMP
368                                 WCOREDUMP(status) ? ", core dumped" : ""
369 #else
370                                 ""
371 #endif
372                                 );
373                         exit( WEXITSTATUS(status)  );
374
375                 } else if ( WEXITSTATUS(status) != 0 ) {
376                         fprintf( stderr, 
377                             "stopping: child exited with status %d\n",
378                             (int) WEXITSTATUS(status) );
379                         exit( WEXITSTATUS(status) );
380
381                 } else {
382                         nkids--;
383                 }
384         }
385 }
386 #else
387
388 static void
389 wait4kids( int nkidval )
390 {
391         int rc, i;
392
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];
397                 nkids--;
398         }
399 }
400
401 static void
402 fork_child( char *prog, char *args[] )
403 {
404         int rc;
405
406         wait4kids( maxkids );
407
408         rc = _spawnvp( _P_NOWAIT, prog, args );
409
410         if ( rc == -1 ) {
411                 fprintf( stderr, "%s: ", prog );
412                 perror("spawnvp");
413         } else {
414                 children[nkids++] = (HANDLE)rc;
415         }
416 }
417 #endif