]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-tester.c
fix formatting
[openldap] / tests / progs / slapd-tester.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 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 static void
45 usage( char *name )
46 {
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 );
48         exit( EXIT_FAILURE );
49 }
50
51 int
52 main( int argc, char **argv )
53 {
54         int             i, j;
55         char            *host = "localhost";
56         char            *port = NULL;
57         char            *manager = NULL;
58         char            *passwd = NULL;
59         char            *dirname = NULL;
60         char        *sbase = NULL;
61         char            *progdir = NULL;
62         char            *loops = LOOPS;
63         DIR                     *datadir;
64         struct dirent   *file;
65         char            *sfile = NULL;
66         char            *sreqs[MAXREQS];
67         int         snum = 0;
68         char            *rfile = NULL;
69         char            *rreqs[MAXREQS];
70         int         rnum = 0;
71         char            *afiles[MAXREQS];
72         int         anum = 0;
73         char            *sargs[MAXARGS];
74         int                     sanum;
75         char            scmd[MAXPATHLEN];
76         char            *rargs[MAXARGS];
77         int                     ranum;
78         char            rcmd[MAXPATHLEN];
79         char            *aargs[MAXARGS];
80         int                     aanum;
81         char            acmd[MAXPATHLEN];
82
83         while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:P:" )) != EOF ) {
84                 switch( i ) {
85                         case 'h':               /* slapd host */
86                                 host = strdup( optarg );
87                         break;
88
89                         case 'p':               /* the servers port number */
90                                 port = strdup( optarg );
91                                 break;
92
93                         case 'D':               /* slapd manager */
94                                 manager = strdup( optarg );
95                         break;
96
97                         case 'w':               /* the managers passwd */
98                                 passwd = strdup( optarg );
99                                 break;
100
101                         case 'b':               /* the base DN */
102                                 sbase = strdup( optarg );
103                                 break;
104
105                         case 'd':               /* data directory */
106                                 dirname = strdup( optarg );
107                         break;
108
109                         case 'P':               /* prog directory */
110                                 progdir = strdup( optarg );
111                         break;
112
113                         case 'j':               /* the number of parallel clients */
114                                 maxkids = atoi( optarg );
115                                 break;
116
117                         case 'l':               /* the number of loops per client */
118                                 loops = strdup( optarg );
119                                 break;
120
121                         default:
122                                 usage( argv[0] );
123                                 break;
124                 }
125         }
126
127         if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
128                         ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
129                 usage( argv[0] );
130
131         /* get the file list */
132         if ( ( datadir = opendir( dirname )) == NULL ) {
133
134                 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
135                                         argv[0], dirname );
136                 exit( EXIT_FAILURE );
137
138         }
139
140         /*  look for search, read, and add/delete files */
141         for ( file = readdir( datadir ); file; file = readdir( datadir )) {
142
143                 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
144                         sfile = get_file_name( dirname, file->d_name );
145                         continue;
146                 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
147                         rfile = get_file_name( dirname, file->d_name );
148                         continue;
149                 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
150                         && ( anum < MAXREQS )) {
151                         afiles[anum++] = get_file_name( dirname, file->d_name );
152                         continue;
153                 }
154         }
155
156         closedir( datadir );
157
158         /* look for search requests */
159         if ( sfile ) {
160                 snum = get_search_filters( sfile, sreqs );
161         }
162
163         /* look for read requests */
164         if ( rfile ) {
165                 rnum = get_read_entries( rfile, rreqs );
166         }
167
168         /*
169          * generate the search clients
170          */
171
172         sanum = 0;
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;
186
187         /*
188          * generate the read clients
189          */
190
191         ranum = 0;
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;
203
204         /*
205          * generate the add/delete clients
206          */
207
208         aanum = 0;
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;
224
225         for ( j = 0; j < MAXREQS; j++ ) {
226
227                 if ( j < snum ) {
228
229                         sargs[sanum - 2] = sreqs[j];
230                         fork_child( scmd, sargs );
231
232                 }
233
234                 if ( j < rnum ) {
235
236                         rargs[ranum - 2] = rreqs[j];
237                         fork_child( rcmd, rargs );
238
239                 }
240
241                 if ( j < anum ) {
242
243                         aargs[aanum - 2] = afiles[j];
244                         fork_child( acmd, aargs );
245
246                 }
247
248         }
249
250         wait4kids( -1 );
251
252         exit( EXIT_SUCCESS );
253 }
254
255 static char *
256 get_file_name( char *dirname, char *filename )
257 {
258         char buf[MAXPATHLEN];
259
260         sprintf( buf, "%s%s%s", dirname, LDAP_DIRSEP, filename );
261         return( strdup( buf ));
262 }
263
264
265 static int
266 get_search_filters( char *filename, char *filters[] )
267 {
268         FILE    *fp;
269         int     filter = 0;
270
271         if ( (fp = fopen( filename, "r" )) != NULL ) {
272                 char  line[BUFSIZ];
273
274                 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
275                         char *nl;
276
277                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
278                                 *nl = '\0';
279                         filters[filter++] = strdup( line );
280
281                 }
282                 fclose( fp );
283         }
284
285         return( filter );
286 }
287
288
289 static int
290 get_read_entries( char *filename, char *entries[] )
291 {
292         FILE    *fp;
293         int     entry = 0;
294
295         if ( (fp = fopen( filename, "r" )) != NULL ) {
296                 char  line[BUFSIZ];
297
298                 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
299                         char *nl;
300
301                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
302                                 *nl = '\0';
303                         entries[entry++] = strdup( line );
304
305                 }
306                 fclose( fp );
307         }
308
309         return( entry );
310 }
311
312
313 static void
314 fork_child( char *prog, char *args[] )
315 {
316         pid_t   pid;
317
318         wait4kids( maxkids );
319
320         switch ( pid = fork() ) {
321         case 0:         /* child */
322                 execvp( prog, args );
323                 fprintf( stderr, "%s: ", prog );
324                 perror( "execv" );
325                 exit( EXIT_FAILURE );
326                 break;
327
328         case -1:        /* trouble */
329                 fprintf( stderr, "Could not fork to run %s\n", prog );
330                 perror( "fork" );
331                 break;
332
333         default:        /* parent */
334                 nkids++;
335                 break;
336         }
337 }
338
339 static void
340 wait4kids( int nkidval )
341 {
342         int             status;
343
344         while ( nkids >= nkidval ) {
345                 wait( &status );
346
347                 if ( WIFSTOPPED(status) ) {
348                         fprintf( stderr,
349                             "stopping: child stopped with signal %d\n",
350                             (int) WSTOPSIG(status) );
351
352                 } else if ( WIFSIGNALED(status) ) {
353                         fprintf( stderr, 
354                             "stopping: child terminated with signal %d%s\n",
355                             (int) WTERMSIG(status),
356 #ifdef WCOREDUMP
357                                 WCOREDUMP(status) ? ", core dumped" : ""
358 #else
359                                 ""
360 #endif
361                                 );
362                         exit( WEXITSTATUS(status)  );
363
364                 } else if ( WEXITSTATUS(status) != 0 ) {
365                         fprintf( stderr, 
366                             "stopping: child exited with status %d\n",
367                             (int) WEXITSTATUS(status) );
368                         exit( WEXITSTATUS(status) );
369
370                 } else {
371                         nkids--;
372                 }
373         }
374 }