Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / openldap / dist / tests / progs / slapd-addel.c
blob0a83ca8d38236ca0d66413d76236115b4352c837
1 /* $OpenLDAP: pkg/ldap/tests/progs/slapd-addel.c,v 1.41.2.6 2008/04/14 21:43:13 quanah Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2008 The OpenLDAP Foundation.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
11 * A copy of this license is available in file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
15 /* ACKNOWLEDGEMENTS:
16 * This work was initially developed by Kurt Spanier for inclusion
17 * in OpenLDAP Software.
20 #include "portable.h"
22 #include <stdio.h>
24 #include "ac/stdlib.h"
26 #include "ac/ctype.h"
27 #include "ac/param.h"
28 #include "ac/socket.h"
29 #include "ac/string.h"
30 #include "ac/unistd.h"
31 #include "ac/wait.h"
33 #include "ldap.h"
34 #include "lutil.h"
36 #include "slapd-common.h"
38 #define LOOPS 100
39 #define RETRIES 0
41 static char *
42 get_add_entry( char *filename, LDAPMod ***mods );
44 static void
45 do_addel( char *uri, char *manager, struct berval *passwd,
46 char *dn, LDAPMod **attrs, int maxloop, int maxretries, int delay,
47 int friendly, int chaserefs );
49 static void
50 usage( char *name )
52 fprintf( stderr,
53 "usage: %s "
54 "-H <uri> | ([-h <host>] -p <port>) "
55 "-D <manager> "
56 "-w <passwd> "
57 "-f <addfile> "
58 "[-i <ignore>] "
59 "[-l <loops>] "
60 "[-L <outerloops>] "
61 "[-r <maxretries>] "
62 "[-t <delay>] "
63 "[-F] "
64 "[-C]\n",
65 name );
66 exit( EXIT_FAILURE );
69 int
70 main( int argc, char **argv )
72 int i;
73 char *host = "localhost";
74 char *uri = NULL;
75 int port = -1;
76 char *manager = NULL;
77 struct berval passwd = { 0, NULL };
78 char *filename = NULL;
79 char *entry = NULL;
80 int loops = LOOPS;
81 int outerloops = 1;
82 int retries = RETRIES;
83 int delay = 0;
84 int friendly = 0;
85 int chaserefs = 0;
86 LDAPMod **attrs = NULL;
88 tester_init( "slapd-addel", TESTER_ADDEL );
90 while ( ( i = getopt( argc, argv, "CD:Ff:H:h:i:L:l:p:r:t:w:" ) ) != EOF )
92 switch ( i ) {
93 case 'C':
94 chaserefs++;
95 break;
97 case 'F':
98 friendly++;
99 break;
101 case 'H': /* the server's URI */
102 uri = strdup( optarg );
103 break;
105 case 'h': /* the servers host */
106 host = strdup( optarg );
107 break;
109 case 'i':
110 /* ignored (!) by now */
111 break;
113 case 'p': /* the servers port */
114 if ( lutil_atoi( &port, optarg ) != 0 ) {
115 usage( argv[0] );
117 break;
119 case 'D': /* the servers manager */
120 manager = strdup( optarg );
121 break;
123 case 'w': /* the server managers password */
124 passwd.bv_val = strdup( optarg );
125 passwd.bv_len = strlen( optarg );
126 memset( optarg, '*', passwd.bv_len );
127 break;
129 case 'f': /* file with entry search request */
130 filename = strdup( optarg );
131 break;
133 case 'l': /* the number of loops */
134 if ( lutil_atoi( &loops, optarg ) != 0 ) {
135 usage( argv[0] );
137 break;
139 case 'L': /* the number of outerloops */
140 if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
141 usage( argv[0] );
143 break;
145 case 'r': /* number of retries */
146 if ( lutil_atoi( &retries, optarg ) != 0 ) {
147 usage( argv[0] );
149 break;
151 case 't': /* delay in seconds */
152 if ( lutil_atoi( &delay, optarg ) != 0 ) {
153 usage( argv[0] );
155 break;
157 default:
158 usage( argv[0] );
159 break;
163 if (( filename == NULL ) || ( port == -1 && uri == NULL ) ||
164 ( manager == NULL ) || ( passwd.bv_val == NULL ))
165 usage( argv[0] );
167 entry = get_add_entry( filename, &attrs );
168 if (( entry == NULL ) || ( *entry == '\0' )) {
170 fprintf( stderr, "%s: invalid entry DN in file \"%s\".\n",
171 argv[0], filename );
172 exit( EXIT_FAILURE );
176 if (( attrs == NULL ) || ( *attrs == '\0' )) {
178 fprintf( stderr, "%s: invalid attrs in file \"%s\".\n",
179 argv[0], filename );
180 exit( EXIT_FAILURE );
184 uri = tester_uri( uri, host, port );
186 for ( i = 0; i < outerloops; i++ ) {
187 do_addel( uri, manager, &passwd, entry, attrs,
188 loops, retries, delay, friendly, chaserefs );
191 exit( EXIT_SUCCESS );
195 static void
196 addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
198 LDAPMod **pmods;
199 int i, j;
200 struct berval *bvp;
202 pmods = *pmodsp;
203 modop |= LDAP_MOD_BVALUES;
205 i = 0;
206 if ( pmods != NULL ) {
207 for ( ; pmods[ i ] != NULL; ++i ) {
208 if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 &&
209 pmods[ i ]->mod_op == modop ) {
210 break;
215 if ( pmods == NULL || pmods[ i ] == NULL ) {
216 if (( pmods = (LDAPMod **)realloc( pmods, (i + 2) *
217 sizeof( LDAPMod * ))) == NULL ) {
218 tester_perror( "realloc", NULL );
219 exit( EXIT_FAILURE );
221 *pmodsp = pmods;
222 pmods[ i + 1 ] = NULL;
223 if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod )))
224 == NULL ) {
225 tester_perror( "calloc", NULL );
226 exit( EXIT_FAILURE );
228 pmods[ i ]->mod_op = modop;
229 if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) {
230 tester_perror( "strdup", NULL );
231 exit( EXIT_FAILURE );
235 if ( value != NULL ) {
236 j = 0;
237 if ( pmods[ i ]->mod_bvalues != NULL ) {
238 for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
242 if (( pmods[ i ]->mod_bvalues =
243 (struct berval **)ber_memrealloc( pmods[ i ]->mod_bvalues,
244 (j + 2) * sizeof( struct berval * ))) == NULL ) {
245 tester_perror( "ber_memrealloc", NULL );
246 exit( EXIT_FAILURE );
248 pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
249 if (( bvp = (struct berval *)ber_memalloc( sizeof( struct berval )))
250 == NULL ) {
251 tester_perror( "ber_memalloc", NULL );
252 exit( EXIT_FAILURE );
254 pmods[ i ]->mod_bvalues[ j ] = bvp;
256 bvp->bv_len = vlen;
257 if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
258 tester_perror( "malloc", NULL );
259 exit( EXIT_FAILURE );
261 AC_MEMCPY( bvp->bv_val, value, vlen );
262 bvp->bv_val[ vlen ] = '\0';
267 static char *
268 get_add_entry( char *filename, LDAPMod ***mods )
270 FILE *fp;
271 char *entry = NULL;
273 if ( (fp = fopen( filename, "r" )) != NULL ) {
274 char line[BUFSIZ];
276 if ( fgets( line, BUFSIZ, fp )) {
277 char *nl;
279 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
280 *nl = '\0';
281 nl = line;
282 if ( !strncasecmp( nl, "dn: ", 4 ))
283 nl += 4;
284 entry = strdup( nl );
288 while ( fgets( line, BUFSIZ, fp )) {
289 char *nl;
290 char *value;
292 if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
293 *nl = '\0';
295 if ( *line == '\0' ) break;
296 if ( !( value = strchr( line, ':' ))) break;
298 *value++ = '\0';
299 while ( *value && isspace( (unsigned char) *value ))
300 value++;
302 addmodifyop( mods, LDAP_MOD_ADD, line, value, strlen( value ));
305 fclose( fp );
308 return( entry );
312 static void
313 do_addel(
314 char *uri,
315 char *manager,
316 struct berval *passwd,
317 char *entry,
318 LDAPMod **attrs,
319 int maxloop,
320 int maxretries,
321 int delay,
322 int friendly,
323 int chaserefs )
325 LDAP *ld = NULL;
326 int i = 0, do_retry = maxretries;
327 int rc = LDAP_SUCCESS;
328 int version = LDAP_VERSION3;
330 retry:;
331 ldap_initialize( &ld, uri );
332 if ( ld == NULL ) {
333 tester_perror( "ldap_initialize", NULL );
334 exit( EXIT_FAILURE );
337 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
338 (void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
339 chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF );
341 if ( do_retry == maxretries ) {
342 fprintf( stderr, "PID=%ld - Add/Delete(%d): entry=\"%s\".\n",
343 (long) pid, maxloop, entry );
346 rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL );
347 if ( rc != LDAP_SUCCESS ) {
348 tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
349 switch ( rc ) {
350 case LDAP_BUSY:
351 case LDAP_UNAVAILABLE:
352 if ( do_retry > 0 ) {
353 do_retry--;
354 if ( delay != 0 ) {
355 sleep( delay );
357 goto retry;
359 /* fallthru */
360 default:
361 break;
363 exit( EXIT_FAILURE );
366 for ( ; i < maxloop; i++ ) {
368 /* add the entry */
369 rc = ldap_add_ext_s( ld, entry, attrs, NULL, NULL );
370 if ( rc != LDAP_SUCCESS ) {
371 tester_ldap_error( ld, "ldap_add_ext_s", NULL );
372 switch ( rc ) {
373 case LDAP_ALREADY_EXISTS:
374 /* NOTE: this likely means
375 * the delete failed
376 * during the previous round... */
377 if ( !friendly ) {
378 goto done;
380 break;
382 case LDAP_BUSY:
383 case LDAP_UNAVAILABLE:
384 if ( do_retry > 0 ) {
385 do_retry--;
386 goto retry;
388 /* fall thru */
390 default:
391 goto done;
395 #if 0
396 /* wait a second for the add to really complete */
397 /* This masks some race conditions though. */
398 sleep( 1 );
399 #endif
401 /* now delete the entry again */
402 rc = ldap_delete_ext_s( ld, entry, NULL, NULL );
403 if ( rc != LDAP_SUCCESS ) {
404 tester_ldap_error( ld, "ldap_delete_ext_s", NULL );
405 switch ( rc ) {
406 case LDAP_NO_SUCH_OBJECT:
407 /* NOTE: this likely means
408 * the add failed
409 * during the previous round... */
410 if ( !friendly ) {
411 goto done;
413 break;
415 case LDAP_BUSY:
416 case LDAP_UNAVAILABLE:
417 if ( do_retry > 0 ) {
418 do_retry--;
419 goto retry;
421 /* fall thru */
423 default:
424 goto done;
429 done:;
430 fprintf( stderr, " PID=%ld - Add/Delete done (%d).\n", (long) pid, rc );
432 ldap_unbind_ext( ld, NULL, NULL );