]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-tester.c
Update lutil_lockf (aka: ldap_lockf) to hide implementation in
[openldap] / tests / progs / slapd-tester.c
1 #include "portable.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #include <ac/string.h>
7 #include <ac/ctype.h>
8 #include <ac/socket.h>
9 #include <ac/unistd.h>
10 #include <ac/wait.h>
11 #include <dirent.h>
12
13 #include <sys/param.h>
14
15 #include "ldapconfig.h"
16
17
18 #define SEARCHCMD               "slapd-search"
19 #define READCMD                 "slapd-read"
20 #define ADDCMD                  "slapd-addel"
21 #define MAXARGS         100
22 #define MAXREQS                 20
23 #define LOOPS                   "100"
24
25 #define TSEARCHFILE             "do_search.0"
26 #define TREADFILE               "do_read.0"
27 #define TADDFILE                "do_add."
28
29 static char *get_file_name( char *dirname, char *filename );
30 static int  get_search_filters( char *filename, char *filters[] );
31 static int  get_read_entries( char *filename, char *entries[] );
32 static void fork_child( char *prog, char *args[] );
33 static void     wait4kids( int nkidval );
34
35 static int      maxkids = 20;
36 static int      nkids;
37
38 static void
39 usage( char *name )
40 {
41         fprintf( stderr, "usage: %s [-h <host>] -p <port> -D <manager> -w <passwd> -d <datadir> -b <baseDN> [-j <maxchild>] [-l <loops>] -P <progdir>\n", name );
42         exit( 1 );
43 }
44
45 int
46 main( int argc, char **argv )
47 {
48         int             i, j;
49         char            *host = "localhost";
50         char            *port = NULL;
51         char            *manager = NULL;
52         char            *passwd = NULL;
53         char            *dirname = NULL;
54         char        *sbase = NULL;
55         char            *progdir = NULL;
56         char            *loops = LOOPS;
57         DIR                     *datadir;
58         struct dirent   *file;
59         char            *sfile = NULL;
60         char            *sreqs[MAXREQS];
61         int         snum = 0;
62         char            *rfile = NULL;
63         char            *rreqs[MAXREQS];
64         int         rnum = 0;
65         char            *afiles[MAXREQS];
66         int         anum = 0;
67         char            *sargs[MAXARGS];
68         int                     sanum;
69         char            scmd[MAXPATHLEN];
70         char            *rargs[MAXARGS];
71         int                     ranum;
72         char            rcmd[MAXPATHLEN];
73         char            *aargs[MAXARGS];
74         int                     aanum;
75         char            acmd[MAXPATHLEN];
76
77         while ( (i = getopt( argc, argv, "h:p:D:w:b:d:j:l:P:" )) != EOF ) {
78                 switch( i ) {
79                         case 'h':               /* slapd host */
80                                 host = strdup( optarg );
81                         break;
82
83                         case 'p':               /* the servers port number */
84                                 port = strdup( optarg );
85                                 break;
86
87                         case 'D':               /* slapd manager */
88                                 manager = strdup( optarg );
89                         break;
90
91                         case 'w':               /* the managers passwd */
92                                 passwd = strdup( optarg );
93                                 break;
94
95                         case 'b':               /* the base DN */
96                                 sbase = strdup( optarg );
97                                 break;
98
99                         case 'd':               /* data directory */
100                                 dirname = strdup( optarg );
101                         break;
102
103                         case 'P':               /* prog directory */
104                                 progdir = strdup( optarg );
105                         break;
106
107                         case 'j':               /* the number of parallel clients */
108                                 maxkids = atoi( optarg );
109                                 break;
110
111                         case 'l':               /* the number of loops per client */
112                                 loops = strdup( optarg );
113                                 break;
114
115                         default:
116                                 usage( argv[0] );
117                                 break;
118                 }
119         }
120
121         if (( dirname == NULL ) || ( sbase == NULL ) || ( port == NULL ) ||
122                         ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL ))
123                 usage( argv[0] );
124
125         /* get the file list */
126         if ( ( datadir = opendir( dirname )) == NULL ) {
127
128                 fprintf( stderr, "%s: couldn't open data directory \"%s\".\n",
129                                         argv[0], dirname );
130                 exit( 1 );
131
132         }
133
134         /*  look for search, read, and add/delete files */
135         for ( file = readdir( datadir ); file; file = readdir( datadir )) {
136
137                 if ( !strcasecmp( file->d_name, TSEARCHFILE )) {
138                         sfile = get_file_name( dirname, file->d_name );
139                         continue;
140                 } else if ( !strcasecmp( file->d_name, TREADFILE )) {
141                         rfile = get_file_name( dirname, file->d_name );
142                         continue;
143                 } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE ))
144                         && ( anum < MAXREQS )) {
145                         afiles[anum++] = get_file_name( dirname, file->d_name );
146                         continue;
147                 }
148         }
149
150         /* look for search requests */
151         if ( sfile ) {
152                 snum = get_search_filters( sfile, sreqs );
153         }
154
155         /* look for read requests */
156         if ( rfile ) {
157                 rnum = get_read_entries( rfile, rreqs );
158         }
159
160         /*
161          * generate the search clients
162          */
163
164         sanum = 0;
165         sprintf( scmd, "%s%s%s", progdir, DEFAULT_DIRSEP, SEARCHCMD );
166         sargs[sanum++] = scmd;
167         sargs[sanum++] = "-h";
168         sargs[sanum++] = host;
169         sargs[sanum++] = "-p";
170         sargs[sanum++] = port;
171         sargs[sanum++] = "-b";
172         sargs[sanum++] = sbase;
173         sargs[sanum++] = "-l";
174         sargs[sanum++] = loops;
175         sargs[sanum++] = "-f";
176         sargs[sanum++] = NULL;          /* will hold the search request */
177         sargs[sanum++] = NULL;
178
179         /*
180          * generate the read clients
181          */
182
183         ranum = 0;
184         sprintf( rcmd, "%s%s%s", progdir, DEFAULT_DIRSEP, READCMD );
185         rargs[ranum++] = rcmd;
186         rargs[ranum++] = "-h";
187         rargs[ranum++] = host;
188         rargs[ranum++] = "-p";
189         rargs[ranum++] = port;
190         rargs[ranum++] = "-l";
191         rargs[ranum++] = loops;
192         rargs[ranum++] = "-e";
193         rargs[ranum++] = NULL;          /* will hold the read entry */
194         rargs[ranum++] = NULL;
195
196         /*
197          * generate the add/delete clients
198          */
199
200         aanum = 0;
201         sprintf( acmd, "%s%s%s", progdir, DEFAULT_DIRSEP, ADDCMD );
202         aargs[aanum++] = acmd;
203         aargs[aanum++] = "-h";
204         aargs[aanum++] = host;
205         aargs[aanum++] = "-p";
206         aargs[aanum++] = port;
207         aargs[aanum++] = "-D";
208         aargs[aanum++] = manager;
209         aargs[aanum++] = "-w";
210         aargs[aanum++] = passwd;
211         aargs[aanum++] = "-l";
212         aargs[aanum++] = loops;
213         aargs[aanum++] = "-f";
214         aargs[aanum++] = NULL;          /* will hold the add data file */
215         aargs[aanum++] = NULL;
216
217         for ( j = 0; j < MAXREQS; j++ ) {
218
219                 if ( j < snum ) {
220
221                         sargs[sanum - 2] = sreqs[j];
222                         fork_child( scmd, sargs );
223
224                 }
225
226                 if ( j < rnum ) {
227
228                         rargs[ranum - 2] = rreqs[j];
229                         fork_child( rcmd, rargs );
230
231                 }
232
233                 if ( j < anum ) {
234
235                         aargs[aanum - 2] = afiles[j];
236                         fork_child( acmd, aargs );
237
238                 }
239
240         }
241
242         wait4kids( -1 );
243
244         exit( 0 );
245 }
246
247 static char *
248 get_file_name( char *dirname, char *filename )
249 {
250         char buf[MAXPATHLEN];
251
252         sprintf( buf, "%s%s%s", dirname, DEFAULT_DIRSEP, filename );
253         return( strdup( buf ));
254 }
255
256
257 static int
258 get_search_filters( char *filename, char *filters[] )
259 {
260         FILE    *fp;
261         int     filter = 0;
262
263         if ( (fp = fopen( filename, "r" )) != NULL ) {
264                 char  line[BUFSIZ];
265
266                 while (( filter < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
267                         char *nl;
268
269                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
270                                 *nl = '\0';
271                         filters[filter++] = strdup( line );
272
273                 }
274                 fclose( fp );
275         }
276
277         return( filter );
278 }
279
280
281 static int
282 get_read_entries( char *filename, char *entries[] )
283 {
284         FILE    *fp;
285         int     entry = 0;
286
287         if ( (fp = fopen( filename, "r" )) != NULL ) {
288                 char  line[BUFSIZ];
289
290                 while (( entry < MAXREQS ) && ( fgets( line, BUFSIZ, fp ))) {
291                         char *nl;
292
293                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
294                                 *nl = '\0';
295                         entries[entry++] = strdup( line );
296
297                 }
298                 fclose( fp );
299         }
300
301         return( entry );
302 }
303
304
305 static void
306 fork_child( char *prog, char *args[] )
307 {
308         int     pid;
309
310         wait4kids( maxkids );
311
312         switch ( pid = fork() ) {
313         case 0:         /* child */
314                 execvp( prog, args );
315                 fprintf( stderr, "%s: ", prog );
316                 perror( "execv" );
317                 exit( -1 );
318                 break;
319
320         case -1:        /* trouble */
321                 fprintf( stderr, "Could not fork to run %s\n", prog );
322                 perror( "fork" );
323                 break;
324
325         default:        /* parent */
326                 nkids++;
327                 break;
328         }
329 }
330
331 static void
332 wait4kids( int nkidval )
333 {
334         int             status;
335         unsigned char   *p;
336
337         while ( nkids >= nkidval ) {
338                 wait( &status );
339                 p = (unsigned char *) &status;
340                 if ( p[sizeof(int) - 1] == 0177 ) {
341                         fprintf( stderr,
342                             "stopping: child stopped with signal %d\n",
343                             p[sizeof(int) - 2] );
344                 } else if ( p[sizeof(int) - 1] != 0 ) {
345                         fprintf( stderr, 
346                             "stopping: child terminated with signal %d\n",
347                             p[sizeof(int) - 1] );
348                         exit( p[sizeof(int) - 1] );
349                 } else if ( p[sizeof(int) - 2] != 0 ) {
350                         fprintf( stderr, 
351                             "stopping: child exited with status %d\n",
352                             p[sizeof(int) - 2] );
353                         exit( p[sizeof(int) - 2] );
354                 } else {
355                         nkids--;
356                 }
357         }
358 }