]> git.sur5r.net Git - openldap/blobdiff - tests/progs/slapd-addel.c
don't use -u: it's not portable (ITS#3969)
[openldap] / tests / progs / slapd-addel.c
index d2adaae55eb9cf901e9c71b61dcc045dc5115d78..082a7aa3d530e4ab770ca9d34304971ba74aeef4 100644 (file)
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1999-2005 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Kurt Spanier for inclusion
+ * in OpenLDAP Software.
+ */
 #include "portable.h"
 
 #include <stdio.h>
-#include <stdlib.h>
 
-#include <ac/string.h>
+#include <ac/stdlib.h>
+
 #include <ac/ctype.h>
+#include <ac/param.h>
 #include <ac/socket.h>
+#include <ac/string.h>
 #include <ac/unistd.h>
 #include <ac/wait.h>
 
-#include <sys/param.h>
-
-#include "lber.h"
-#include "ldap.h"
+#define LDAP_DEPRECATED 1
+#include <ldap.h>
 
 #define LOOPS  100
+#define RETRIES        0
 
 static char *
 get_add_entry( char *filename, LDAPMod ***mods );
 
 static void
-do_addel( char *host, int port, char *manager, char *passwd,
-       char *dn, LDAPMod **attrs, int maxloop );
+do_addel( char *uri, char *host, int port, char *manager, char *passwd,
+       char *dn, LDAPMod **attrs, int maxloop, int maxretries, int delay );
 
 static void
 usage( char *name )
 {
-       fprintf( stderr, "usage: %s [-h <host>] -p port -D <managerDN> -w <passwd> -f <addfile> [-l <loops>]\n",
+        fprintf( stderr,
+               "usage: %s "
+               "-H <uri> | ([-h <host>] -p <port>) "
+               "-D <manager> "
+               "-w <passwd> "
+               "-f <addfile> "
+               "[-l <loops>] "
+               "[-r <maxretries>] "
+               "[-t <delay>]\n",
                        name );
-       exit( 1 );
+       exit( EXIT_FAILURE );
 }
 
 int
 main( int argc, char **argv )
 {
-       int             i, j;
-       char        *host = "localhost";
-       int                     port = -1;
+       int             i;
+       char            *host = "localhost";
+       char            *uri = NULL;
+       int             port = -1;
        char            *manager = NULL;
        char            *passwd = NULL;
        char            *filename = NULL;
        char            *entry = NULL;
-       int                     loops = LOOPS;
-       LDAPMod     **attrs = NULL;
+       int             loops = LOOPS;
+       int             retries = RETRIES;
+       int             delay = 0;
+       LDAPMod         **attrs = NULL;
 
-       while ( (i = getopt( argc, argv, "h:p:D:w:f:l:" )) != EOF ) {
+       while ( (i = getopt( argc, argv, "H:h:p:D:w:f:l:r:t:" )) != EOF ) {
                switch( i ) {
-                       case 'h':               /* the servers host */
-                               host = strdup( optarg );
+               case 'H':               /* the server's URI */
+                       uri = strdup( optarg );
                        break;
 
-                       case 'p':               /* the servers port */
-                               port = atoi( optarg );
-                               break;
+               case 'h':               /* the servers host */
+                       host = strdup( optarg );
+                       break;
 
-                       case 'D':               /* the servers manager */
-                               manager = strdup( optarg );
+               case 'p':               /* the servers port */
+                       port = atoi( optarg );
                        break;
 
-                       case 'w':               /* the server managers password */
-                               passwd = strdup( optarg );
+               case 'D':               /* the servers manager */
+                       manager = strdup( optarg );
                        break;
 
-                       case 'f':               /* file with entry search request */
-                               filename = strdup( optarg );
-                               break;
+               case 'w':               /* the server managers password */
+                       passwd = strdup( optarg );
+                       break;
 
-                       case 'l':               /* the number of loops */
-                               loops = atoi( optarg );
-                               break;
+               case 'f':               /* file with entry search request */
+                       filename = strdup( optarg );
+                       break;
 
-                       default:
-                               usage( argv[0] );
-                               break;
+               case 'l':               /* the number of loops */
+                       loops = atoi( optarg );
+                       break;
+
+               case 'r':               /* number of retries */
+                       retries = atoi( optarg );
+                       break;
+
+               case 't':               /* delay in seconds */
+                       delay = atoi( optarg );
+                       break;
+
+               default:
+                       usage( argv[0] );
+                       break;
                }
        }
 
-       if (( filename == NULL ) || ( port == -1 ) ||
+       if (( filename == NULL ) || ( port == -1 && uri == NULL ) ||
                                ( manager == NULL ) || ( passwd == NULL ))
                usage( argv[0] );
 
@@ -85,7 +128,7 @@ main( int argc, char **argv )
 
                fprintf( stderr, "%s: invalid entry DN in file \"%s\".\n",
                                argv[0], filename );
-               exit( 1 );
+               exit( EXIT_FAILURE );
 
        }
 
@@ -93,20 +136,17 @@ main( int argc, char **argv )
 
                fprintf( stderr, "%s: invalid attrs in file \"%s\".\n",
                                argv[0], filename );
-               exit( 1 );
+               exit( EXIT_FAILURE );
 
        }
 
-       do_addel( host, port, manager, passwd, entry, attrs, loops );
+       do_addel( uri, host, port, manager, passwd, entry, attrs,
+                       loops, retries, delay );
 
-       exit( 0 );
+       exit( EXIT_SUCCESS );
 }
 
 
-#define safe_realloc( ptr, size )   ( ptr == NULL ? malloc( size ) : \
-                               realloc( ptr, size ))
-
-
 static void
 addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
 {
@@ -128,22 +168,22 @@ addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
     }
 
     if ( pmods == NULL || pmods[ i ] == NULL ) {
-               if (( pmods = (LDAPMod **)safe_realloc( pmods, (i + 2) *
+               if (( pmods = (LDAPMod **)realloc( pmods, (i + 2) *
                        sizeof( LDAPMod * ))) == NULL ) {
-                       perror( "safe_realloc" );
-                       exit( 1 );
+                       perror( "realloc" );
+                       exit( EXIT_FAILURE );
                }
                *pmodsp = pmods;
                pmods[ i + 1 ] = NULL;
                if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod )))
                        == NULL ) {
                        perror( "calloc" );
-                       exit( 1 );
+                       exit( EXIT_FAILURE );
                }
                pmods[ i ]->mod_op = modop;
                if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) {
                perror( "strdup" );
-               exit( 1 );
+               exit( EXIT_FAILURE );
                }
     }
 
@@ -155,25 +195,25 @@ addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen )
                }
                }
                if (( pmods[ i ]->mod_bvalues =
-                       (struct berval **)safe_realloc( pmods[ i ]->mod_bvalues,
+                       (struct berval **)ber_memrealloc( pmods[ i ]->mod_bvalues,
                        (j + 2) * sizeof( struct berval * ))) == NULL ) {
-                       perror( "safe_realloc" );
-                       exit( 1 );
+                       perror( "ber_realloc" );
+                       exit( EXIT_FAILURE );
                }
                pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
-               if (( bvp = (struct berval *)malloc( sizeof( struct berval )))
+               if (( bvp = (struct berval *)ber_memalloc( sizeof( struct berval )))
                        == NULL ) {
                        perror( "malloc" );
-                       exit( 1 );
+                       exit( EXIT_FAILURE );
                }
                pmods[ i ]->mod_bvalues[ j ] = bvp;
 
            bvp->bv_len = vlen;
            if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
                        perror( "malloc" );
-                       exit( 1 );
+                       exit( EXIT_FAILURE );
            }
-           SAFEMEMCPY( bvp->bv_val, value, vlen );
+           AC_MEMCPY( bvp->bv_val, value, vlen );
            bvp->bv_val[ vlen ] = '\0';
     }
 }
@@ -223,58 +263,98 @@ get_add_entry( char *filename, LDAPMod ***mods )
 
 static void
 do_addel(
+       char *uri,
        char *host,
        int port,
        char *manager,
        char *passwd,
        char *entry,
        LDAPMod **attrs,
-       int maxloop
+       int maxloop,
+       int maxretries,
+       int delay
 )
 {
-       LDAP    *ld;
-       int     i;
+       LDAP    *ld = NULL;
+       int     i = 0, do_retry = maxretries;
        pid_t   pid = getpid();
+       int     rc = LDAP_SUCCESS;
 
-       if (( ld = ldap_init( host, port )) == NULL ) {
+retry:;
+       if ( uri ) {
+               ldap_initialize( &ld, uri );
+       } else {
+               ld = ldap_init( host, port );
+       }
+       if ( ld == NULL ) {
                perror( "ldap_init" );
-               exit( 1 );
+               exit( EXIT_FAILURE );
        }
 
-       if ( ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE )
-                               != LDAP_SUCCESS ) {
-               ldap_perror( ld, "ldap_bind" );
-                exit( 1 );
+       {
+               int version = LDAP_VERSION3;
+               (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+                       &version ); 
        }
 
+       if ( do_retry == maxretries ) {
+               fprintf( stderr, "PID=%ld - Add/Delete(%d): entry=\"%s\".\n",
+                       (long) pid, maxloop, entry );
+       }
 
-       fprintf( stderr, "PID=%ld - Add/Delete(%d): entry=\"%s\".\n",
-                                       (long) pid, maxloop, entry );
+       rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
+       if ( rc != LDAP_SUCCESS ) {
+               ldap_perror( ld, "ldap_bind" );
+               switch ( rc ) {
+               case LDAP_BUSY:
+               case LDAP_UNAVAILABLE:
+                       if ( do_retry > 0 ) {
+                               do_retry--;
+                               if ( delay != 0 ) {
+                                   sleep( delay );
+                               }
+                               goto retry;
+                       }
+               /* fallthru */
+               default:
+                       break;
+               }
+               exit( EXIT_FAILURE );
+       }
 
-       for ( i = 0; i < maxloop; i++ ) {
+       for ( ; i < maxloop; i++ ) {
 
                /* add the entry */
-               if ( ldap_add_s( ld, entry, attrs ) != LDAP_SUCCESS ) {
-
+               rc = ldap_add_s( ld, entry, attrs );
+               if ( rc != LDAP_SUCCESS ) {
                        ldap_perror( ld, "ldap_add" );
+                       if ( rc == LDAP_BUSY && do_retry > 0 ) {
+                               do_retry--;
+                               goto retry;
+                       }
                        break;
 
                }
 
+#if 0
                /* wait a second for the add to really complete */
+               /* This masks some race conditions though. */
                sleep( 1 );
+#endif
 
                /* now delete the entry again */
-               if ( ldap_delete_s( ld, entry ) != LDAP_SUCCESS ) {
-
+               rc = ldap_delete_s( ld, entry );
+               if ( rc != LDAP_SUCCESS ) {
                        ldap_perror( ld, "ldap_delete" );
+                       if ( rc == LDAP_BUSY && do_retry > 0 ) {
+                               do_retry--;
+                               goto retry;
+                       }
                        break;
-
                }
-
        }
 
-       fprintf( stderr, " PID=%ld - Add/Delete done.\n", (long) pid );
+       fprintf( stderr, " PID=%ld - Add/Delete done (%d).\n", (long) pid, rc );
 
        ldap_unbind( ld );
 }