exit( EXIT_FAILURE );
}
+/* -S: just send requests without reading responses
+ * -SS: send all requests asynchronous and immediately start reading responses
+ * -SSS: send all requests asynchronous; then read responses
+ */
+static int swamp;
+
int
main( int argc, char **argv )
{
/* by default, tolerate referrals and no such object */
tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" );
- while ( (i = getopt( argc, argv, "ACD:e:Ff:H:h:i:L:l:p:r:t:T:w:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "ACD:e:Ff:H:h:i:L:l:p:r:St:T:w:" )) != EOF ) {
switch ( i ) {
case 'A':
noattrs++;
}
break;
+ case 'S':
+ swamp++;
+ break;
+
case 't': /* delay in seconds */
if ( lutil_atoi( &delay, optarg ) != 0 ) {
usage( argv[0] );
break;
}
- fprintf( stderr, " PID=%ld - Search done (%d).\n", (long) pid, rc );
+ fprintf( stderr, " PID=%ld - Read done (%d).\n", (long) pid, rc );
if ( ld != NULL ) {
ldap_unbind_ext( ld, NULL, NULL );
LDAP *ld = ldp ? *ldp : NULL;
int i = 0, do_retry = maxretries;
int rc = LDAP_SUCCESS;
- int version = LDAP_VERSION3;
+ int version = LDAP_VERSION3;
+ int *msgids = NULL, active = 0;
+
+ /* make room for msgid */
+ if ( swamp > 1 ) {
+ msgids = (int *)calloc( sizeof(int), maxloop );
+ }
retry:;
if ( ld == NULL ) {
}
}
- for ( ; i < maxloop; i++ ) {
- LDAPMessage *res = NULL;
+ if ( swamp > 1 ) {
+ do {
+ LDAPMessage *res = NULL;
+ int j, msgid;
+
+ if ( i < maxloop ) {
+ rc = ldap_search_ext( ld, entry, LDAP_SCOPE_BASE,
+ NULL, attrs, noattrs, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, &msgids[i] );
+
+ active++;
+#if 0
+ fprintf( stderr,
+ ">>> PID=%ld - Read maxloop=%d cnt=%d active=%d msgid=%d: "
+ "entry=\"%s\"\n",
+ (long) pid, maxloop, i, active, msgids[i],
+ entry );
+#endif
+ i++;
+
+ if ( rc ) {
+ char buf[BUFSIZ];
+ int first = tester_ignore_err( rc );
+ /* if ignore.. */
+ if ( first ) {
+ /* only log if first occurrence */
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
+ tester_ldap_error( ld, "ldap_search_ext", NULL );
+ }
+ continue;
+ }
+
+ /* busy needs special handling */
+ snprintf( buf, sizeof( buf ), "entry=\"%s\"\n", entry );
+ tester_ldap_error( ld, "ldap_search_ext", buf );
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
+ ldap_unbind_ext( ld, NULL, NULL );
+ ld = NULL;
+ do_retry--;
+ goto retry;
+ }
+ break;
+ }
+
+ if ( swamp > 2 ) {
+ continue;
+ }
+ }
- rc = ldap_search_ext_s( ld, entry, LDAP_SCOPE_BASE,
- NULL, attrs, noattrs, NULL, NULL, NULL,
- LDAP_NO_LIMIT, &res );
- if ( res != NULL ) {
- ldap_msgfree( res );
- }
+ rc = ldap_result( ld, LDAP_RES_ANY, 0, NULL, &res );
+ switch ( rc ) {
+ case -1:
+ /* gone really bad */
+#if 0
+ fprintf( stderr,
+ ">>> PID=%ld - Read maxloop=%d cnt=%d active=%d: "
+ "entry=\"%s\" ldap_result()=%d\n",
+ (long) pid, maxloop, i, active, entry, rc );
+#endif
+ goto cleanup;
+
+ case 0:
+ /* timeout (impossible) */
+ break;
+
+ case LDAP_RES_SEARCH_ENTRY:
+ case LDAP_RES_SEARCH_REFERENCE:
+ /* ignore */
+ break;
+
+ case LDAP_RES_SEARCH_RESULT:
+ /* just remove, no error checking (TODO?) */
+ msgid = ldap_msgid( res );
+ ldap_parse_result( ld, res, &rc, NULL, NULL, NULL, NULL, 1 );
+ res = NULL;
+
+ /* linear search, bah */
+ for ( j = 0; j < i; j++ ) {
+ if ( msgids[ j ] == msgid ) {
+ msgids[ j ] = -1;
+ active--;
+#if 0
+ fprintf( stderr,
+ "<<< PID=%ld - ReadDone maxloop=%d cnt=%d active=%d msgid=%d: "
+ "entry=\"%s\"\n",
+ (long) pid, maxloop, j, active, msgid, entry );
+#endif
+ break;
+ }
+ }
+ break;
- if ( rc ) {
- int first = tester_ignore_err( rc );
- char buf[ BUFSIZ ];
+ default:
+ /* other messages unexpected */
+ fprintf( stderr,
+ "### PID=%ld - Read(%d): "
+ "entry=\"%s\" attrs=%s%s. unexpected response tag=%d\n",
+ (long) pid, maxloop,
+ entry, attrs[0], attrs[1] ? " (more...)" : "", rc );
+ break;
+ }
- snprintf( buf, sizeof( buf ), "ldap_search_ext_s(%s)", entry );
+ if ( res != NULL ) {
+ ldap_msgfree( res );
+ }
+ } while ( i < maxloop || active > 0 );
- /* if ignore.. */
- if ( first ) {
- /* only log if first occurrence */
- if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
- tester_ldap_error( ld, buf, NULL );
- }
- continue;
+ } else {
+ for ( ; i < maxloop; i++ ) {
+ LDAPMessage *res = NULL;
+
+ if (swamp) {
+ int msgid;
+ rc = ldap_search_ext( ld, entry, LDAP_SCOPE_BASE,
+ NULL, attrs, noattrs, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, &msgid );
+ if ( rc == LDAP_SUCCESS ) continue;
+ else break;
+ }
+
+ rc = ldap_search_ext_s( ld, entry, LDAP_SCOPE_BASE,
+ NULL, attrs, noattrs, NULL, NULL, NULL,
+ LDAP_NO_LIMIT, &res );
+ if ( res != NULL ) {
+ ldap_msgfree( res );
}
- /* busy needs special handling */
- tester_ldap_error( ld, buf, NULL );
- if ( rc == LDAP_BUSY && do_retry > 0 ) {
- ldap_unbind_ext( ld, NULL, NULL );
- ld = NULL;
- do_retry--;
- goto retry;
+ if ( rc ) {
+ int first = tester_ignore_err( rc );
+ char buf[ BUFSIZ ];
+
+ snprintf( buf, sizeof( buf ), "ldap_search_ext_s(%s)", entry );
+
+ /* if ignore.. */
+ if ( first ) {
+ /* only log if first occurrence */
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
+ tester_ldap_error( ld, buf, NULL );
+ }
+ continue;
+ }
+
+ /* busy needs special handling */
+ tester_ldap_error( ld, buf, NULL );
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
+ ldap_unbind_ext( ld, NULL, NULL );
+ ld = NULL;
+ do_retry--;
+ goto retry;
+ }
+ break;
}
- break;
}
}
+cleanup:;
+ if ( msgids != NULL ) {
+ free( msgids );
+ }
+
if ( ldp != NULL ) {
*ldp = ld;
"[-C] "
"[-F] "
"[-N] "
- "[-S] "
+ "[-S[S[S]]] "
"[-i <ignore>] "
"[-l <loops>] "
"[-L <outerloops>] "
exit( EXIT_FAILURE );
}
-/* Just send requests without reading responses */
+/* -S: just send requests without reading responses
+ * -SS: send all requests asynchronous and immediately start reading responses
+ * -SSS: send all requests asynchronous; then read responses
+ */
static int swamp;
int
int rc = LDAP_SUCCESS;
int version = LDAP_VERSION3;
char buf[ BUFSIZ ];
+ int *msgids = NULL, active = 0;
+ /* make room for msgid */
+ if ( swamp > 1 ) {
+ msgids = (int *)calloc( sizeof(int), innerloop );
+ }
retry:;
if ( ld == NULL ) {
}
}
- for ( ; i < innerloop; i++ ) {
- LDAPMessage *res = NULL;
-
- if (swamp) {
- int msgid;
- rc = ldap_search_ext( ld, sbase, scope,
- filter, NULL, noattrs, NULL, NULL,
- NULL, LDAP_NO_LIMIT, &msgid );
- if ( rc == LDAP_SUCCESS ) continue;
- else break;
- }
+ if ( swamp > 1 ) {
+ do {
+ LDAPMessage *res = NULL;
+ int j, msgid;
+
+ if ( i < innerloop ) {
+ rc = ldap_search_ext( ld, sbase, scope,
+ filter, NULL, noattrs, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, &msgids[i] );
+
+ active++;
+#if 0
+ fprintf( stderr,
+ ">>> PID=%ld - Search maxloop=%d cnt=%d active=%d msgid=%d: "
+ "base=\"%s\" scope=%s filter=\"%s\"\n",
+ (long) pid, innerloop, i, active, msgids[i],
+ sbase, ldap_pvt_scope2str( scope ), filter );
+#endif
+ i++;
+
+ if ( rc ) {
+ int first = tester_ignore_err( rc );
+ /* if ignore.. */
+ if ( first ) {
+ /* only log if first occurrence */
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
+ tester_ldap_error( ld, "ldap_search_ext", NULL );
+ }
+ continue;
+ }
+
+ /* busy needs special handling */
+ snprintf( buf, sizeof( buf ),
+ "base=\"%s\" filter=\"%s\"\n",
+ sbase, filter );
+ tester_ldap_error( ld, "ldap_search_ext", buf );
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
+ ldap_unbind_ext( ld, NULL, NULL );
+ ld = NULL;
+ do_retry--;
+ goto retry;
+ }
+ break;
+ }
- rc = ldap_search_ext_s( ld, sbase, scope,
- filter, attrs, noattrs, NULL, NULL,
- NULL, LDAP_NO_LIMIT, &res );
- if ( res != NULL ) {
- ldap_msgfree( res );
- }
+ if ( swamp > 2 ) {
+ continue;
+ }
+ }
- if ( rc ) {
- int first = tester_ignore_err( rc );
- /* if ignore.. */
- if ( first ) {
- /* only log if first occurrence */
- if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
- tester_ldap_error( ld, "ldap_search_ext_s", NULL );
+ rc = ldap_result( ld, LDAP_RES_ANY, 0, NULL, &res );
+ switch ( rc ) {
+ case -1:
+ /* gone really bad */
+ goto cleanup;
+
+ case 0:
+ /* timeout (impossible) */
+ break;
+
+ case LDAP_RES_SEARCH_ENTRY:
+ case LDAP_RES_SEARCH_REFERENCE:
+ /* ignore */
+ break;
+
+ case LDAP_RES_SEARCH_RESULT:
+ /* just remove, no error checking (TODO?) */
+ msgid = ldap_msgid( res );
+ ldap_parse_result( ld, res, &rc, NULL, NULL, NULL, NULL, 1 );
+ res = NULL;
+
+ /* linear search, bah */
+ for ( j = 0; j < i; j++ ) {
+ if ( msgids[ j ] == msgid ) {
+ msgids[ j ] = -1;
+ active--;
+#if 0
+ fprintf( stderr,
+ "<<< PID=%ld - SearchDone maxloop=%d cnt=%d active=%d msgid=%d: "
+ "base=\"%s\" scope=%s filter=\"%s\"\n",
+ (long) pid, innerloop, j, active, msgid,
+ sbase, ldap_pvt_scope2str( scope ), filter );
+#endif
+ break;
+ }
}
- continue;
+ break;
+
+ default:
+ /* other messages unexpected */
+ fprintf( stderr,
+ "### PID=%ld - Search(%d): "
+ "base=\"%s\" scope=%s filter=\"%s\" "
+ "attrs=%s%s. unexpected response tag=%d\n",
+ (long) pid, innerloop,
+ sbase, ldap_pvt_scope2str( scope ), filter,
+ attrs[0], attrs[1] ? " (more...)" : "", rc );
+ break;
}
- /* busy needs special handling */
- snprintf( buf, sizeof( buf ),
- "base=\"%s\" filter=\"%s\"\n",
- sbase, filter );
- tester_ldap_error( ld, "ldap_search_ext_s", buf );
- if ( rc == LDAP_BUSY && do_retry > 0 ) {
- ldap_unbind_ext( ld, NULL, NULL );
- ld = NULL;
- do_retry--;
- goto retry;
+ if ( res != NULL ) {
+ ldap_msgfree( res );
+ }
+ } while ( i < innerloop || active > 0 );
+
+ } else {
+ for ( ; i < innerloop; i++ ) {
+ LDAPMessage *res = NULL;
+
+ if (swamp) {
+ int msgid;
+ rc = ldap_search_ext( ld, sbase, scope,
+ filter, NULL, noattrs, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, &msgid );
+ if ( rc == LDAP_SUCCESS ) continue;
+ else break;
+ }
+
+ rc = ldap_search_ext_s( ld, sbase, scope,
+ filter, attrs, noattrs, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, &res );
+ if ( res != NULL ) {
+ ldap_msgfree( res );
+ }
+
+ if ( rc ) {
+ int first = tester_ignore_err( rc );
+ /* if ignore.. */
+ if ( first ) {
+ /* only log if first occurrence */
+ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) {
+ tester_ldap_error( ld, "ldap_search_ext_s", NULL );
+ }
+ continue;
+ }
+
+ /* busy needs special handling */
+ snprintf( buf, sizeof( buf ),
+ "base=\"%s\" filter=\"%s\"\n",
+ sbase, filter );
+ tester_ldap_error( ld, "ldap_search_ext_s", buf );
+ if ( rc == LDAP_BUSY && do_retry > 0 ) {
+ ldap_unbind_ext( ld, NULL, NULL );
+ ld = NULL;
+ do_retry--;
+ goto retry;
+ }
+ break;
}
- break;
}
}
+cleanup:;
+ if ( msgids != NULL ) {
+ free( msgids );
+ }
+
if ( ldp != NULL ) {
*ldp = ld;
int sanum;
int sextra_args = 0;
char scmd[MAXPATHLEN];
+ int swamp = 0;
+ char swampopt[sizeof("-SSS")];
/* static so that its address can be used in initializer below. */
static char sloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)];
/* read */
mloops[0] = '\0';
bloops[0] = '\0';
- while ( ( i = getopt( argc, argv, "AB:CD:d:FH:h:Ii:j:L:l:NP:p:r:t:Ww:y:" ) ) != EOF )
+ while ( ( i = getopt( argc, argv, "AB:CD:d:FH:h:Ii:j:L:l:NP:p:r:St:Ww:y:" ) ) != EOF )
{
switch ( i ) {
case 'A':
retries = strdup( optarg );
break;
+ case 'S':
+ swamp++;
+ break;
+
case 't': /* the delay in seconds between each retry */
delay = strdup( optarg );
break;
}
/* setup friendly option */
-
switch ( friendly ) {
case 0:
break;
break;
}
+ /* setup swamp option */
+ if ( swamp ) {
+ swampopt[0] = '-';
+ if ( swamp > 3 ) swamp = 3;
+ swampopt[swamp + 1] = '\0';
+ for ( ; swamp-- > 0; ) swampopt[swamp + 1] = 'S';
+ }
+
+ /* setup loop options */
if ( sloops[0] == '\0' ) snprintf( sloops, sizeof( sloops ), "%d", 10 * loops );
if ( rloops[0] == '\0' ) snprintf( rloops, sizeof( rloops ), "%d", 20 * loops );
if ( aloops[0] == '\0' ) snprintf( aloops, sizeof( aloops ), "%d", loops );
sargs[sanum++] = "-i";
sargs[sanum++] = ignore;
}
+ if ( swamp ) {
+ sargs[sanum++] = swampopt;
+ }
sargs[sanum++] = "-b";
sargs[sanum++] = NULL; /* will hold the search base */
sargs[sanum++] = "-s";
rargs[ranum++] = "-i";
rargs[ranum++] = ignore;
}
+ if ( swamp ) {
+ rargs[ranum++] = swampopt;
+ }
rargs[ranum++] = "-e";
rargs[ranum++] = NULL; /* will hold the read entry */
} else {
bases[filter] = ArgDup( line );
}
- fgets( line, BUFSIZ, fp );
+ if ( fgets( line, BUFSIZ, fp ) == NULL )
+ *line = '\0';
if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
*nl = '\0';
ldap_free_urldesc( lud );
} else {
+ if ( filters != NULL )
+ filters[entry] = NULL;
+
entries[entry] = ArgDup( line );
}
int status;
while ( nkids >= nkidval ) {
- wait( &status );
+ pid_t pid = wait( &status );
if ( WIFSTOPPED(status) ) {
fprintf( stderr,
- "stopping: child stopped with signal %d\n",
- (int) WSTOPSIG(status) );
+ "stopping: child PID=%ld stopped with signal %d\n",
+ (long) pid, (int) WSTOPSIG(status) );
} else if ( WIFSIGNALED(status) ) {
fprintf( stderr,
- "stopping: child terminated with signal %d%s\n",
- (int) WTERMSIG(status),
+ "stopping: child PID=%ld terminated with signal %d%s\n",
+ (long) pid, (int) WTERMSIG(status),
#ifdef WCOREDUMP
WCOREDUMP(status) ? ", core dumped" : ""
#else
} else if ( WEXITSTATUS(status) != 0 ) {
fprintf( stderr,
- "stopping: child exited with status %d\n",
- (int) WEXITSTATUS(status) );
+ "stopping: child PID=%ld exited with status %d\n",
+ (long) pid, (int) WEXITSTATUS(status) );
exit( WEXITSTATUS(status) );
} else {