]> git.sur5r.net Git - openldap/blob - tests/progs/slapd-addel.c
add missing "-F" option in usage
[openldap] / tests / progs / slapd-addel.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2005 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
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.
10  *
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>.
14  */
15 /* ACKNOWLEDGEMENTS:
16  * This work was initially developed by Kurt Spanier for inclusion
17  * in OpenLDAP Software.
18  */
19  
20 #include "portable.h"
21
22 #include <stdio.h>
23
24 #include <ac/stdlib.h>
25
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>
32
33 #define LDAP_DEPRECATED 1
34 #include <ldap.h>
35
36 #define LOOPS   100
37 #define RETRIES 0
38
39 static char *
40 get_add_entry( char *filename, LDAPMod ***mods );
41
42 static void
43 do_addel( char *uri, char *host, int port, char *manager, char *passwd,
44         char *dn, LDAPMod **attrs, int maxloop, int maxretries, int delay,
45         int friendly );
46
47 static void
48 usage( char *name )
49 {
50         fprintf( stderr,
51                 "usage: %s "
52                 "-H <uri> | ([-h <host>] -p <port>) "
53                 "-D <manager> "
54                 "-w <passwd> "
55                 "-f <addfile> "
56                 "[-l <loops>] "
57                 "[-r <maxretries>] "
58                 "[-t <delay>] "
59                 "[-F]\n",
60                         name );
61         exit( EXIT_FAILURE );
62 }
63
64 int
65 main( int argc, char **argv )
66 {
67         int             i;
68         char            *host = "localhost";
69         char            *uri = NULL;
70         int             port = -1;
71         char            *manager = NULL;
72         char            *passwd = NULL;
73         char            *filename = NULL;
74         char            *entry = NULL;
75         int             loops = LOOPS;
76         int             retries = RETRIES;
77         int             delay = 0;
78         int             friendly = 0;
79         LDAPMod         **attrs = NULL;
80
81         while ( (i = getopt( argc, argv, "FH:h:p:D:w:f:l:r:t:" )) != EOF ) {
82                 switch( i ) {
83                 case 'F':
84                         friendly++;
85                         break;
86                         
87                 case 'H':               /* the server's URI */
88                         uri = strdup( optarg );
89                         break;
90
91                 case 'h':               /* the servers host */
92                         host = strdup( optarg );
93                         break;
94
95                 case 'p':               /* the servers port */
96                         port = atoi( optarg );
97                         break;
98
99                 case 'D':               /* the servers manager */
100                         manager = strdup( optarg );
101                         break;
102
103                 case 'w':               /* the server managers password */
104                         passwd = strdup( optarg );
105                         break;
106
107                 case 'f':               /* file with entry search request */
108                         filename = strdup( optarg );
109                         break;
110
111                 case 'l':               /* the number of loops */
112                         loops = atoi( optarg );
113                         break;
114
115                 case 'r':               /* number of retries */
116                         retries = atoi( optarg );
117                         break;
118
119                 case 't':               /* delay in seconds */
120                         delay = atoi( optarg );
121                         break;
122
123                 default:
124                         usage( argv[0] );
125                         break;
126                 }
127         }
128
129         if (( filename == NULL ) || ( port == -1 && uri == NULL ) ||
130                                 ( manager == NULL ) || ( passwd == NULL ))
131                 usage( argv[0] );
132
133         entry = get_add_entry( filename, &attrs );
134         if (( entry == NULL ) || ( *entry == '\0' )) {
135
136                 fprintf( stderr, "%s: invalid entry DN in file \"%s\".\n",
137                                 argv[0], filename );
138                 exit( EXIT_FAILURE );
139
140         }
141
142         if (( attrs == NULL ) || ( *attrs == '\0' )) {
143
144                 fprintf( stderr, "%s: invalid attrs in file \"%s\".\n",
145                                 argv[0], filename );
146                 exit( EXIT_FAILURE );
147
148         }
149
150         do_addel( uri, host, port, manager, passwd, entry, attrs,
151                         loops, retries, delay, friendly );
152
153         exit( EXIT_SUCCESS );
154 }
155
156
157 static void
158 addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
159 {
160     LDAPMod             **pmods;
161     int                 i, j;
162     struct berval       *bvp;
163
164     pmods = *pmodsp;
165     modop |= LDAP_MOD_BVALUES;
166
167     i = 0;
168     if ( pmods != NULL ) {
169                 for ( ; pmods[ i ] != NULL; ++i ) {
170                 if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 &&
171                         pmods[ i ]->mod_op == modop ) {
172                                 break;
173                 }
174                 }
175     }
176
177     if ( pmods == NULL || pmods[ i ] == NULL ) {
178                 if (( pmods = (LDAPMod **)realloc( pmods, (i + 2) *
179                         sizeof( LDAPMod * ))) == NULL ) {
180                         perror( "realloc" );
181                         exit( EXIT_FAILURE );
182                 }
183                 *pmodsp = pmods;
184                 pmods[ i + 1 ] = NULL;
185                 if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod )))
186                         == NULL ) {
187                         perror( "calloc" );
188                         exit( EXIT_FAILURE );
189                 }
190                 pmods[ i ]->mod_op = modop;
191                 if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) {
192                 perror( "strdup" );
193                 exit( EXIT_FAILURE );
194                 }
195     }
196
197     if ( value != NULL ) {
198                 j = 0;
199                 if ( pmods[ i ]->mod_bvalues != NULL ) {
200                 for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
201                                 ;
202                 }
203                 }
204                 if (( pmods[ i ]->mod_bvalues =
205                         (struct berval **)ber_memrealloc( pmods[ i ]->mod_bvalues,
206                         (j + 2) * sizeof( struct berval * ))) == NULL ) {
207                         perror( "ber_realloc" );
208                         exit( EXIT_FAILURE );
209                 }
210                 pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
211                 if (( bvp = (struct berval *)ber_memalloc( sizeof( struct berval )))
212                         == NULL ) {
213                         perror( "malloc" );
214                         exit( EXIT_FAILURE );
215                 }
216                 pmods[ i ]->mod_bvalues[ j ] = bvp;
217
218             bvp->bv_len = vlen;
219             if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
220                         perror( "malloc" );
221                         exit( EXIT_FAILURE );
222             }
223             AC_MEMCPY( bvp->bv_val, value, vlen );
224             bvp->bv_val[ vlen ] = '\0';
225     }
226 }
227
228
229 static char *
230 get_add_entry( char *filename, LDAPMod ***mods )
231 {
232         FILE    *fp;
233         char    *entry = NULL;
234
235         if ( (fp = fopen( filename, "r" )) != NULL ) {
236                 char  line[BUFSIZ];
237
238                 if ( fgets( line, BUFSIZ, fp )) {
239                         char *nl;
240
241                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
242                                 *nl = '\0';
243                         entry = strdup( line );
244
245                 }
246
247                 while ( fgets( line, BUFSIZ, fp )) {
248                         char    *nl;
249                         char    *value;
250
251                         if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
252                                 *nl = '\0';
253
254                         if ( *line == '\0' ) break;
255                         if ( !( value = strchr( line, ':' ))) break;
256
257                         *value++ = '\0'; 
258                         while ( *value && isspace( (unsigned char) *value ))
259                                 value++;
260
261                         addmodifyop( mods, LDAP_MOD_ADD, line, value, strlen( value ));
262
263                 }
264                 fclose( fp );
265         }
266
267         return( entry );
268 }
269
270
271 static void
272 do_addel(
273         char *uri,
274         char *host,
275         int port,
276         char *manager,
277         char *passwd,
278         char *entry,
279         LDAPMod **attrs,
280         int maxloop,
281         int maxretries,
282         int delay,
283         int friendly
284 )
285 {
286         LDAP    *ld = NULL;
287         int     i = 0, do_retry = maxretries;
288         pid_t   pid = getpid();
289         int     rc = LDAP_SUCCESS;
290
291 retry:;
292         if ( uri ) {
293                 ldap_initialize( &ld, uri );
294         } else {
295                 ld = ldap_init( host, port );
296         }
297         if ( ld == NULL ) {
298                 perror( "ldap_init" );
299                 exit( EXIT_FAILURE );
300         }
301
302         {
303                 int version = LDAP_VERSION3;
304                 (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
305                         &version ); 
306         }
307
308         if ( do_retry == maxretries ) {
309                 fprintf( stderr, "PID=%ld - Add/Delete(%d): entry=\"%s\".\n",
310                         (long) pid, maxloop, entry );
311         }
312
313         rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
314         if ( rc != LDAP_SUCCESS ) {
315                 ldap_perror( ld, "ldap_bind" );
316                 switch ( rc ) {
317                 case LDAP_BUSY:
318                 case LDAP_UNAVAILABLE:
319                         if ( do_retry > 0 ) {
320                                 do_retry--;
321                                 if ( delay != 0 ) {
322                                     sleep( delay );
323                                 }
324                                 goto retry;
325                         }
326                 /* fallthru */
327                 default:
328                         break;
329                 }
330                 exit( EXIT_FAILURE );
331         }
332
333         for ( ; i < maxloop; i++ ) {
334
335                 /* add the entry */
336                 rc = ldap_add_s( ld, entry, attrs );
337                 if ( rc != LDAP_SUCCESS ) {
338                         ldap_perror( ld, "ldap_add" );
339                         switch ( rc ) {
340                         case LDAP_ALREADY_EXISTS:
341                                 /* NOTE: this likely means
342                                  * the delete failed
343                                  * during the previous round... */
344                                 if ( !friendly ) {
345                                         goto done;
346                                 }
347                                 break;
348
349                         case LDAP_BUSY:
350                         case LDAP_UNAVAILABLE:
351                                 if ( do_retry > 0 ) {
352                                         do_retry--;
353                                         goto retry;
354                                 }
355                                 /* fall thru */
356
357                         default:
358                                 goto done;
359                         }
360                 }
361
362 #if 0
363                 /* wait a second for the add to really complete */
364                 /* This masks some race conditions though. */
365                 sleep( 1 );
366 #endif
367
368                 /* now delete the entry again */
369                 rc = ldap_delete_s( ld, entry );
370                 if ( rc != LDAP_SUCCESS ) {
371                         ldap_perror( ld, "ldap_delete" );
372                         switch ( rc ) {
373                         case LDAP_NO_SUCH_OBJECT:
374                                 /* NOTE: this likely means
375                                  * the add failed
376                                  * during the previous round... */
377                                 if ( !friendly ) {
378                                         goto done;
379                                 }
380                                 break;
381
382                         case LDAP_BUSY:
383                         case LDAP_UNAVAILABLE:
384                                 if ( do_retry > 0 ) {
385                                         do_retry--;
386                                         goto retry;
387                                 }
388                                 /* fall thru */
389
390                         default:
391                                 goto done;
392                         }
393                 }
394         }
395
396 done:;
397         fprintf( stderr, " PID=%ld - Add/Delete done (%d).\n", (long) pid, rc );
398
399         ldap_unbind( ld );
400 }
401
402