[Fedora-directory-commits] ldapserver/ldap/servers/slapd proto-slap.h, 1.14, 1.15 util.c, 1.8, 1.9
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv22527
Modified Files:
proto-slap.h util.c
Log Message:
[174774] Backup does not clear the backup directory prior to performing backup; Restore tries to restore all the fles from the backupdir
1) if the specified backup directory exists, rename it to <dir>.bak
2) support relative dir for the backup/restore dir, e.g., "bak2db bak/mybak"
Index: proto-slap.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/proto-slap.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- proto-slap.h 10 Jan 2006 23:53:02 -0000 1.14
+++ proto-slap.h 12 Jan 2006 00:28:57 -0000 1.15
@@ -390,6 +390,7 @@
int config_get_csnlogging();
int is_abspath(const char *);
char* rel2abspath( char * );
+char* rel2abspath_ext( char *, char * );
/*
* configdse.c
Index: util.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/util.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- util.c 10 Jan 2006 23:53:02 -0000 1.8
+++ util.c 12 Jan 2006 00:28:57 -0000 1.9
@@ -455,6 +455,12 @@
char *
rel2abspath( char *relpath )
{
+ return rel2abspath_ext( relpath, NULL );
+}
+
+char *
+rel2abspath_ext( char *relpath, char *cwd )
+{
char abspath[ MAXPATHLEN + 1 ];
#if defined( _WIN32 )
@@ -480,11 +486,15 @@
if ( relpath[ 0 ] == _CSEP ) { /* absolute path */
PR_snprintf(abspath, sizeof(abspath), "%s", relpath);
} else { /* relative path */
- if ( getcwd( abspath, MAXPATHLEN ) == NULL ) {
- perror( "getcwd" );
- LDAPDebug( LDAP_DEBUG_ANY, "Cannot determine current directory\n",
- 0, 0, 0 );
- exit( 1 );
+ if ( NULL == cwd ) {
+ if ( getcwd( abspath, MAXPATHLEN ) == NULL ) {
+ perror( "getcwd" );
+ LDAPDebug( LDAP_DEBUG_ANY, "Cannot determine current directory\n",
+ 0, 0, 0 );
+ exit( 1 );
+ }
+ } else {
+ PR_snprintf(abspath, sizeof(abspath), "%s", cwd);
}
if ( strlen( relpath ) + strlen( abspath ) + 1 > MAXPATHLEN ) {
17 years, 2 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/tools/rsearch Makefile, 1.1, 1.2 addthread.c, 1.1, 1.2 addthread.h, 1.1, 1.2 infadd.c, 1.1, 1.2 infadd.h, 1.1, 1.2 main.c, 1.1, 1.2 nametable.c, 1.1, 1.2 nametable.h, 1.1, 1.2 rsearch.c, 1.1, 1.2 rsearch.h, 1.1, 1.2 sdattable.c, 1.1, 1.2 sdattable.h, 1.1, 1.2 searchthread.c, 1.1, 1.2 searchthread.h, 1.1, 1.2
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv8808/rsearch
Modified Files:
Makefile addthread.c addthread.h infadd.c infadd.h main.c
nametable.c nametable.h rsearch.c rsearch.h sdattable.c
sdattable.h searchthread.c searchthread.h
Log Message:
Added copyrights.
Index: Makefile
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile 6 Jan 2006 00:53:24 -0000 1.1
+++ Makefile 11 Jan 2006 02:00:32 -0000 1.2
@@ -33,7 +33,7 @@
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
-# Copyright (C) 2005 Red Hat, Inc.
+# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
#
@@ -52,14 +52,9 @@
BINDIR = $(RELDIR)/shared/bin
DATDIR = $(RELDIR)/shared/data
-SLAPD_OBJDIR = $(LDAP_OBJDIR)
-
include $(BUILD_ROOT)/nsdefs.mk
include $(BUILD_ROOT)/nsconfig.mk
include $(LDAP_SRC)/nsldap.mk
-INCLUDES+=-I$(DB_INCLUDE)
-
-SLAPDHDIR = ../
ifeq ($(ARCH), OSF1)
PLATFORM_SPECIFIC_EXTRA_LIBRARY = -lcxx
@@ -68,18 +63,6 @@
PLATFORM_SPECIFIC_EXTRA_LIBRARY =
endif # OSF1
-INCLUDES += $(SSLINCLUDE)
-DEFS += $(SSL)
-
-CFLAGS += $(ARCH_CFLAGS)
-
-INCLUDES += -I$(SLAPDHDIR) -I$(LDAP_ADMINCDIR)
-INCLUDES += -I$(ACLINC)
-INCLUDES += -I ../../plugins/rever
-LDFLAGS += $(EXLDFLAGS) $(SSLLIBFLAG)
-
-DEPLIBS=
-
EXTRA_LIBS_DEP = $(LDAPSDK_DEP) $(DB_LIB_DEP) $(LDAP_COMMON_LIBS_DEP)
EXTRA_LIBS += $(LDAPLINK) $(DB_LIB) \
@@ -91,9 +74,6 @@
EXTRA_LIBS += -lcrypt
endif
-KEYUPG_LIBS_DEP=
-KEYUPG_LIBS=$(LDAP_LIBLITEKEY)
-
# It looks like all of the latest versions of Unix that we ship on
# have a good enough heap implementations that they don't need
# SmartHeap. We still need it on NT.
Index: addthread.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/addthread.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- addthread.c 6 Jan 2006 00:53:24 -0000 1.1
+++ addthread.c 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: addthread.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/addthread.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- addthread.h 6 Jan 2006 00:53:24 -0000 1.1
+++ addthread.h 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: infadd.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/infadd.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- infadd.c 6 Jan 2006 00:53:24 -0000 1.1
+++ infadd.c 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: infadd.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/infadd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- infadd.h 6 Jan 2006 00:53:24 -0000 1.1
+++ infadd.h 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: main.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/main.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- main.c 6 Jan 2006 00:53:24 -0000 1.1
+++ main.c 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: nametable.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/nametable.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- nametable.c 6 Jan 2006 00:53:24 -0000 1.1
+++ nametable.c 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: nametable.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/nametable.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- nametable.h 6 Jan 2006 00:53:24 -0000 1.1
+++ nametable.h 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: rsearch.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/rsearch.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- rsearch.c 6 Jan 2006 00:53:24 -0000 1.1
+++ rsearch.c 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: rsearch.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/rsearch.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- rsearch.h 6 Jan 2006 00:53:24 -0000 1.1
+++ rsearch.h 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: sdattable.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/sdattable.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- sdattable.c 6 Jan 2006 00:53:24 -0000 1.1
+++ sdattable.c 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: sdattable.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/sdattable.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- sdattable.h 6 Jan 2006 00:53:24 -0000 1.1
+++ sdattable.h 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: searchthread.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/searchthread.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- searchthread.c 6 Jan 2006 00:53:24 -0000 1.1
+++ searchthread.c 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
Index: searchthread.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/rsearch/searchthread.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- searchthread.h 6 Jan 2006 00:53:24 -0000 1.1
+++ searchthread.h 11 Jan 2006 02:00:32 -0000 1.2
@@ -1,6 +1,38 @@
/** BEGIN COPYRIGHT BLOCK
- * Copyright 2001 Sun Microsystems, Inc.
- * Portions copyright 1999, 2001 Netscape Communications Corporation.
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
17 years, 2 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/tools/ldclt/examples/002 add.ksh, NONE, 1.1 config.ksh, NONE, 1.1 env.ksh, NONE, 1.1 ldif01.ksh, NONE, 1.1 ldif02.ksh, NONE, 1.1 ldif03.ksh, NONE, 1.1 ofile, NONE, 1.1
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/ldclt/examples/002
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv8602/ldclt/examples/002
Added Files:
add.ksh config.ksh env.ksh ldif01.ksh ldif02.ksh ldif03.ksh
ofile
Log Message:
[164596] LDCLT distributed with Directory Server
integrated ldclt from DSRK into the DS source tree.
--- NEW FILE add.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)add.ksh 1.1 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# Add 500 entries with strings randomly selected from Lastname.txt
#
. env.ksh
echo "dn: $BaseDN
objectclass: organization
" > /tmp/ldif01.ldif
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-q -v -n10 \
-e object=ofile \
-e add,commoncounter \
-e -e imagedir=../../../data/ldclt/images \
-b $BaseDN -e rdn='cn:blob [C=RNDFROMFILE(../../../data/ldclt/names/Lastname.txt)] [D=RNDN(3;11;5)] [E=INCRNNOLOOP(1;500;3)]'
--- NEW FILE config.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)config.ksh 1.1 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
. env.ksh
ldapmodify -D"$RootDN" -w"$RootPasswd" -h$Host -p$Port <<-EOD
dn: $UserDN
changetype: add
objectclass: person
sn: test user
userpassword: $UserPassword
dn: $BaseDN
changetype: modify
add : aci
aci: (targetattr = "*") (version 3.0;acl "test user";allow (all)(userdn = "ldap:///$UserDN");)
EOD
--- NEW FILE env.ksh ---
#ident "ldclt @(#)env.ksh 1.1 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
Host=localhost
Port=1389
BaseDN=o=test.com
RootDN="cn=directory manager"
RootPasswd=secret12
UserRDN="cn=test"
UserDN="$UserRDN,$BaseDN"
UserPassword=testpassword
--- NEW FILE ldif01.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)ldif01.ksh 1.1 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# Create ldif file with incremental strings from file.
# Will create one entry for each line in Lastname.txt
#
. env.ksh
echo "dn: $BaseDN
objectclass: organization
" > /tmp/ldif01.ldif
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-q -v -n1 \
-e object=ofile \
-e append,genldif=/tmp/ldif01.ldif \
-e imagedir=../../../data/ldclt/images \
-b $BaseDN -e rdn='cn:blob [C=INCRFROMFILENOLOOP(../../../data/ldclt/names/Lastname.txt)] [D=RNDN(3;11;5)] [E=INCRNNOLOOP(1;150000;6)]'
--- NEW FILE ldif02.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)ldif02.ksh 1.1 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# Create ldif file with incremental strings from file.
# Will create 150k entries
#
. env.ksh
echo "dn: $BaseDN
objectclass: organization
" > /tmp/ldif02.ldif
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-q -v -n1 \
-e object=ofile \
-e append,genldif=/tmp/ldif02.ldif \
-e imagedir=../../../data/ldclt/images \
-b $BaseDN -e rdn='cn:blob [C=INCRFROMFILE(../../../data/ldclt/names/Lastname.txt)] [D=RNDN(3;11;5)] [E=INCRNNOLOOP(1;150000;6)]'
--- NEW FILE ldif03.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)ldif03.ksh 1.1 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# Create ldif file with random strings from file.
# Will create 150k entries
#
. env.ksh
echo "dn: $BaseDN
objectclass: organization
" > /tmp/ldif03.ldif
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-q -v -n1 \
-e object=ofile \
-e append,genldif=/tmp/ldif03.ldif \
-e imagedir=../../../data/ldclt/images \
-b $BaseDN -e rdn='cn:blob [C=RNDFROMFILE(../../../data/ldclt/names/Lastname.txt)] [D=RNDN(3;11;5)] [E=INCRNNOLOOP(1;150000;6)]'
--- NEW FILE ofile ---
#ident "ldclt @(#)ofile 1.1 01/04/11"
#
objectclass: person
sn: mr [A=RNDS(12)] final [RNDN(1;5;6)]
description: blob [RNDN(1;5;6)] blib
description: [A]
description: [A=RNDFROMFILE(../../../data/ldclt/names/Firstname.txt)].[B=RNDFROMFILE(../../../data/ldclt/names/Lastname.txt)]
description: A = [A]
description: B = [B]
description: C = [C]
description: D = [D]
description: E = [E]
17 years, 2 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/tools/ldclt/examples/001 add.ksh, NONE, 1.1 add_incr.ksh, NONE, 1.1 config.ksh, NONE, 1.1 delete.ksh, NONE, 1.1 env.ksh, NONE, 1.1 search.ksh, NONE, 1.1
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/ldclt/examples/001
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv8602/ldclt/examples/001
Added Files:
add.ksh add_incr.ksh config.ksh delete.ksh env.ksh search.ksh
Log Message:
[164596] LDCLT distributed with Directory Server
integrated ldclt from DSRK into the DS source tree.
--- NEW FILE add.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)add.ksh 1.2 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# This script will add random entries in the database.
. env.ksh
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-e add,person,random \
-e imagedir=../../../data/ldclt/images \
-r0 -R1000000 \
-I68 \
-n50 \
-f cn=mrXXXXXXXXX -b o=data,$BaseDN \
-v -q
--- NEW FILE add_incr.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)add_incr.ksh 1.2 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# Sequential add of entries.
# This script will add entries from 0 to 1000000 and exit. All the
# threads will share the same counter, i.e. each entry will be added
# only one time.
. env.ksh
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-e add,person,incr,commoncounter,noloop \
-e imagedir=../../../data/ldclt/images \
-r0 -R1000000 \
-I68 \
-n5 \
-f cn=mrXXXXXXXXX -b o=data,$BaseDN \
-v -q
--- NEW FILE config.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)config.ksh 1.2 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
. env.ksh
ldapmodify -D"$RootDN" -w"$RootPasswd" -h$Host -p$Port <<-EOD
dn: $UserDN
changetype: add
objectclass: person
sn: test user
userpassword: $UserPassword
dn: $BaseDN
changetype: modify
add : aci
aci: (targetattr = "*") (version 3.0;acl "test user";allow (all)(userdn = "ldap:///$UserDN");)
EOD
--- NEW FILE delete.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)delete.ksh 1.2 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# This script will delete random entries in the database.
. env.ksh
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-e delete,random \
-e imagedir=../../../data/ldclt/images \
-r0 -R1000000 \
-I32 \
-n50 \
-f cn=mrXXXXXXXXX -b o=data,$BaseDN \
-v -q
--- NEW FILE env.ksh ---
#ident "ldclt @(#)env.ksh 1.2 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
Host=localhost
Port=1389
BaseDN=o=test.com
RootDN="cn=directory manager"
RootPasswd=secret12
UserRDN="cn=test"
UserDN="$UserRDN,$BaseDN"
UserPassword=testpassword
--- NEW FILE search.ksh ---
#!/bin/ksh -p
#ident "ldclt @(#)search.ksh 1.2 01/04/11"
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
# This script will search random entries in the database.
. env.ksh
ldclt \
-h $Host -p $Port \
-D "$UserDN" -w "$UserPassword" \
-e esearch,random \
-e imagedir=../../../data/ldclt/images \
-r0 -R1000000 \
-I32 \
-n200 \
-f cn=mrXXXXXXXXX -b o=data,$BaseDN \
-v -q
17 years, 2 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/tools/ldclt/examples README, NONE, 1.1
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/ldclt/examples
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv8602/ldclt/examples
Added Files:
README
Log Message:
[164596] LDCLT distributed with Directory Server
integrated ldclt from DSRK into the DS source tree.
--- NEW FILE README ---
#ident "ldclt @(#)README 1.1 01/04/11"
ldclt examples README
Introduction
The examples provided in this directory are delivered "as it" and
may not be 100% accurate from the last releases of ldclt. They have
been tested when added to the package, but are not meant to be
maintained.
Compatibility or stability of the examples from one version to another
is not a target : examples may be removed or changed in any way at any
time.
To know when they were introduced or updated, please read the release
notes in the file ../History
Please report any comment, suggestion, error, new example, whatever
to ldclt(a)france.sun.com.
001
This one is a very basic example of use of ldclt. It is based for
the configuration part, on iPlanet DS 5.0 but should work with any
kind of ldap server.
- env.ksh Environment and parameters.
- config.ksh Configure the server (create user and aci).
- add.ksh Add random entries.
- add_incr.ksh Add sequentialy numbered entries.
- delete.ksh Delete random entries.
- search.ksh Search random entries.
002
Using the advanced feature of ldclt allowing to specify very complex
objects, we will generate ldif files or add/search complex objects.
* Use the name files delivered with ldclt.
- env.ksh Environment and parameters.
- config.ksh Configure the server (create user and aci, modify
schema).
- ofile Description of the object that will be created.
- ldif01.ksh Create ldif file with incremental strings from file,
one entry per line in the file Lastname.txt
- ldif02.ksh Create ldif file with incremental strings from file,
150k entries in total.
- ldif03.ksh Create ldif file with random strings from file,
150k entries in total.
- add.ksh Add 500 entries with random strings from file.
# End of file
17 years, 2 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/tools/ldclt Makefile, NONE, 1.1 README, NONE, 1.1 data.c, NONE, 1.1 ldap-private.h, NONE, 1.1 ldapfct.c, NONE, 1.1 ldclt.c, NONE, 1.1 ldclt.h, NONE, 1.1 ldclt.man, NONE, 1.1 ldclt.use, NONE, 1.1 ldcltU.c, NONE, 1.1 opCheck.c, NONE, 1.1 parser.c, NONE, 1.1 port.c, NONE, 1.1 port.h, NONE, 1.1 remote.h, NONE, 1.1 repcheck.c, NONE, 1.1 repslave.c, NONE, 1.1 scalab01.c, NONE, 1.1 scalab01.h, NONE, 1.1 srv.c, NONE, 1.1 threadMain.c, NONE, 1.1 utils.c, NONE
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/ldclt
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv8602/ldclt
Added Files:
Makefile README data.c ldap-private.h ldapfct.c ldclt.c
ldclt.h ldclt.man ldclt.use ldcltU.c opCheck.c parser.c port.c
port.h remote.h repcheck.c repslave.c scalab01.c scalab01.h
srv.c threadMain.c utils.c utils.h version.c workarounds.c
Log Message:
[164596] LDCLT distributed with Directory Server
integrated ldclt from DSRK into the DS source tree.
--- NEW FILE Makefile ---
#
# BEGIN COPYRIGHT BLOCK
# This Program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 2 of the License.
#
# This Program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
#
# In addition, as a special exception, Red Hat, Inc. gives You the additional
# right to link the code of this Program with code not covered under the GNU
# General Public License ("Non-GPL Code") and to distribute linked combinations
# including the two, subject to the limitations in this paragraph. Non-GPL Code
# permitted under this exception must only link to the code of this Program
# through those well defined interfaces identified in the file named EXCEPTION
# found in the source code files (the "Approved Interfaces"). The files of
# Non-GPL Code may instantiate templates or use macros or inline functions from
# the Approved Interfaces without causing the resulting work to be covered by
# the GNU General Public License. Only Red Hat, Inc. may make changes or
# additions to the list of Approved Interfaces. You must obey the GNU General
# Public License in all respects for all of the Program code and other code used
# in conjunction with the Program except the Non-GPL Code covered by this
# exception. If you modify this file, you may extend this exception to your
# version of the file, but you are not obligated to do so. If you do not wish to
# provide this exception without modification, you must delete this exception
# statement from your version and license this file solely under the GPL without
# exception.
#
#
# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
# Copyright (C) 2006 Red Hat, Inc.
# All rights reserved.
# END COPYRIGHT BLOCK
#
#
# This Makefile is targetted to build the ldclt tool. This tool is a
# multithreaded ldap client, specially targetted to ensure good
# reliability of the product under test.
#
# -----------------------------------------------------------------------------
LDAP_SRC = ../../../..
BUILD_ROOT = ../../../../..
OBJDEST = $(OBJDIR)/servers/tools/obj
BINDIR = $(RELDIR)/shared/bin
DATDIR = $(RELDIR)/shared/data
include $(BUILD_ROOT)/nsdefs.mk
include $(BUILD_ROOT)/nsconfig.mk
include $(LDAP_SRC)/nsldap.mk
ifeq ($(OS_ARCH), WINNT)
OBJEXT =.obj
else
OBJEXT =.o
endif
EXTRA_LIBS_DEP = $(LDAPSDK_DEP) $(DB_LIB_DEP) $(LDAP_COMMON_LIBS_DEP)
EXTRA_LIBS += $(LDAPLINK) $(DB_LIB) \
$(PLATFORM_SPECIFIC_EXTRA_LIBRARY) \
$(ALIBS) $(NSPRLINK) $(SECURITYLINK) \
$(THREADSLIB) $(LDAP_COMMON_LIBS)
LDCLTSRC = \
data.c \
ldapfct.c \
ldclt.c \
ldcltU.c \
parser.c \
port.c \
scalab01.c \
threadMain.c \
utils.c \
version.c \
workarounds.c
#ifdef SUN_DS_3_X_SUPPORT
LDCLTSRC += opCheck.c
#endif
LDCLTOBJS = $(addprefix $(OBJDEST)/, $(LDCLTSRC:.c=$(OBJEXT)))
HDIR = $(LDAP_SRC)/include
LDCLTBIN = $(addsuffix $(EXE_SUFFIX), $(addprefix $(BINDIR)/, ldclt))
INC_FILES = \
ldclt.h \
port.h \
utils.h \
remote.h
INC_PLUGINS = \
scalab01.h
ADDLIBS = $(LDAPLIBS) $(SPEC_LIBS) $(SYSTEM_LIBS) $(END)
CFLAGS+=-DLDAP_DONT_USE_SMARTHEAP
EXTRA_LIBS_DEP = $(LDAPSDK_DEP) $(DB_LIB_DEP) $(LDAP_COMMON_LIBS_DEP)
EXTRA_LIBS += $(LDAPLINK) $(DB_LIB) \
$(PLATFORM_SPECIFIC_EXTRA_LIBRARY) \
$(ALIBS) $(NSPRLINK) $(SECURITYLINK) \
$(THREADSLIB) $(LDAP_COMMON_LIBS)
##########################################################################
all: $(OBJDEST) $(BINDIR) $(LDCLTBIN)
clean:
-$(RM) $(LDCLTOBJS) $(LDCLTBIN)
$(OBJDEST):
if [ ! -d $(OBJDEST) ]; then \
$(MKDIR) $(OBJDEST); \
fi
$(BINDIR):
if [ ! -d $(BINDIR) ]; then \
$(MKDIR) $(BINDIR); \
fi
$(LDCLTBIN): $(LDCLTOBJS)
$(LINK_EXE) $(LDCLTOBJS) $(EXTRA_LIBS)
-chmod 755 $(LDCLTBIN)
--- NEW FILE README ---
CVS snapshot in sync with ldclt 4.23
--- NEW FILE data.c ---
#ident "ldclt @(#)data.c 1.8 01/03/23"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : data.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 11 January 1999
DESCRIPTION :
This file implements the management of the data that
are manipulated by ldclt.
It is targetted to contain all the functions needed for
the images, etc...
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
11/01/99 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
06/03/00 | JL Schwing | 1.2 : Test malloc() return value.
---------+--------------+------------------------------------------------------
28/11/00 | JL Schwing | 1.3 : Port on NT 4.
---------+--------------+------------------------------------------------------
30/11/00 | JL Schwing | 1.4 : Implement loadImages for NT.
---------+--------------+------------------------------------------------------
30/11/00 | JL Schwing | 1.5 : Port on OSF1.
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.6 : Port on Linux.
---------+--------------+------------------------------------------------------
06/03/01 | JL Schwing | 1.7 : Better error messages if images not found.
---------+--------------+------------------------------------------------------
23/03/01 | JL Schwing | 1.8 : Implements data file list support in variants.
---------+--------------+------------------------------------------------------
*/
#include <stdio.h> /* printf(), etc... */
#include <stdlib.h> /* realloc(), etc... */
#include <string.h> /* strlen(), etc... */
#include <errno.h> /* errno, etc... */ /*JLS 06-03-00*/
#include <sys/types.h> /* Misc types... */
#include <sys/stat.h> /* stat(), etc... */
#include <fcntl.h> /* open(), etc... */
#include <lber.h> /* ldap C-API BER declarations */
#include <ldap.h> /* ldap C-API declarations */
#ifndef _WIN32 /*JLS 28-11-00*/
#include <unistd.h> /* close(), etc... */
#include <dirent.h> /* opendir(), etc... */
#include <pthread.h> /* pthreads(), etc... */
#include <sys/mman.h> /* mmap(), etc... */
#endif /*JLS 28-11-00*/
#include "port.h" /* Portability definitions */ /*JLS 28-11-00*/
#include "ldclt.h" /* This tool's include file */
/* ****************************************************************************
FUNCTION : getExtend
PURPOSE : Get the extension of the given string, i.e. the part
that is after the last '.'
INPUT : str = string to process
OUTPUT : None.
RETURN : The extension.
DESCRIPTION :
*****************************************************************************/
char *getExtend (
char *str)
{
int i;
for (i=strlen(str)-1; (i>=0) && (str[i]!='.') ; i--);
return (&(str[i+1]));
}
/* ****************************************************************************
FUNCTION : loadImages
PURPOSE : Load the images from the given directory.
INPUT : dirpath = directory where the images are located.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int loadImages (
char *dirpath)
{
#ifdef _WIN32
WIN32_FIND_DATA fileData; /* Current file */
HANDLE dirContext; /* Directory context */
char *findPath; /* To build the find path */
char *pt; /* To read the images */
#else /* _WIN32 */
DIR *dirp; /* Directory data */
struct dirent *direntp; /* Directory entry */
#endif /* _WIN32 */
char *fileName; /* As read from the system */
char name [1024]; /* To build the full path */
struct stat stat_buf; /* To read the image size */
int fd; /* To open the image */
int ret; /* Return value */
/*
* Initialization
*/
mctx.images = NULL;
mctx.imagesNb = 0;
mctx.imagesLast = -1;
if ((ret = ldclt_mutex_init(&(mctx.imagesLast_mutex))) != 0)
{
fprintf (stderr, "ldclt: %s\n", strerror (ret));
fprintf (stderr, "Error: cannot initiate imagesLast_mutex\n");
fflush (stderr);
return (-1);
}
/*
* Open the directory
*/
#ifdef _WIN32
findPath = (char *) malloc (strlen (dirpath) + 5);
strcpy (findPath, dirpath);
strcat (findPath, "/*.*");
dirContext = FindFirstFile (findPath, &fileData);
if (dirContext == INVALID_HANDLE_VALUE)
{
fprintf (stderr, "ldlct: cannot load images from %s\n", dirpath);
fprintf (stderr, "ldclt: try using -e imagesdir=path\n"); /*JLS 06-03-01*/
fflush (stderr);
free (findPath);
return (-1);
}
#else /* _WIN32 */
dirp = opendir (dirpath);
if (dirp == NULL)
{
perror (dirpath);
fprintf (stderr, "ldlct: cannot load images from %s\n", dirpath);
fprintf (stderr, "ldclt: try using -e imagesdir=path\n"); /*JLS 06-03-01*/
fflush (stderr);
return (-1);
}
#endif /* _WIN32 */
/*
* Process the directory.
* We will only accept the .jpg files, as stated by the RFC.
*/
#ifdef _WIN32
fileName = fileData.cFileName;
do
{
#else
while ((direntp = readdir (dirp)) != NULL)
{
fileName = direntp->d_name;
#endif
if (!strcmp (getExtend (fileName), "jpg"))
{
/*
* Allocate a new image, and initiates with its name.
*/
mctx.imagesNb++;
mctx.images =
(image *) realloc (mctx.images, mctx.imagesNb * sizeof (image));
if (mctx.images == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Error: cannot realloc(mctx.images), error=%d (%s)\n",
errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
mctx.images[mctx.imagesNb-1].name =
(char *) malloc (strlen(fileName) + 1);
if (mctx.images[mctx.imagesNb-1].name == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Error: cannot malloc(mctx.images[%d]).name, error=%d (%s)\n",
mctx.imagesNb-1, errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
strcpy (mctx.images[mctx.imagesNb-1].name, fileName);
/*
* Read the image size
*/
strcpy (name, dirpath);
strcat (name, "/");
strcat (name, fileName);
if (stat (name, &stat_buf) < 0)
{
perror (name);
fprintf (stderr, "Cannot stat(%s)\n", name);
fflush (stderr);
return (-1);
}
mctx.images[mctx.imagesNb-1].length = stat_buf.st_size;
/*
* Open the image
*/
fd = open (name, O_RDONLY);
if (fd < 0)
{
perror (name);
fprintf (stderr, "Cannot open(%s)\n", name);
fflush (stderr);
return (-1);
}
#ifdef _WIN32
/*
* Allocate buffer and read the data :-(
*/
mctx.images[mctx.imagesNb-1].data = (char *) malloc (stat_buf.st_size);
if (mctx.images[mctx.imagesNb-1].data == NULL)
{
fprintf (stderr, "Cannot malloc(%d) to load %s\n",
stat_buf.st_size, name);
fflush (stderr);
return (-1);
}
if (read (fd, mctx.images[mctx.imagesNb-1].data, stat_buf.st_size) < 0)
{
perror (name);
fprintf (stderr, "Cannot read(%s)\n", name);
fflush (stderr);
return (-1);
}
#else /* _WIN32 */
/*
* mmap() the image
*/
mctx.images[mctx.imagesNb-1].data = mmap (0, stat_buf.st_size,
PROT_READ, MAP_SHARED, fd, 0);
if (mctx.images[mctx.imagesNb-1].data == (char *)MAP_FAILED)
{
perror (name);
fprintf (stderr, "Cannot mmap(%s)\n", name);
fflush (stderr);
return (-1);
}
#endif /* _WIN32 */
/*
* Close the image. The mmap() will remain available, and this
* close() will save file descriptors.
*/
if (close (fd) < 0)
{
perror (name);
fprintf (stderr, "Cannot close(%s)\n", name);
fflush (stderr);
return (-1);
}
}
#ifdef _WIN32
} while (FindNextFile(dirContext, &fileData) == TRUE);
#else
} /* while ((direntp = readdir (dirp)) != NULL) */
#endif
/*
* Close the directory
*/
#ifndef _WIN32
if (closedir (dirp) < 0)
{
perror (dirpath);
fprintf (stderr, "Cannot closedir(%s)\n", dirpath);
fflush (stderr);
return (-1);
}
#endif
/*
* Normal end
*/
#ifdef _WIN32
free (findPath);
#endif
return (0);
}
/* ****************************************************************************
FUNCTION : getImage
PURPOSE : Add a random image to the given attribute.
INPUT : None.
OUTPUT : attribute = the attribute where the image should
be added.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int getImage (
LDAPMod *attribute)
{
int imageNumber; /* The image we will select */
int ret; /* Return value */
/*
* Select the next image
*/
if ((ret = ldclt_mutex_lock (&(mctx.imagesLast_mutex))) != 0) /*JLS 29-11-00*/
{
fprintf (stderr,
"Cannot mutex_lock(imagesLast_mutex), error=%d (%s)\n",
ret, strerror (ret));
fflush (stderr);
return (-1);
}
mctx.imagesLast++;
if (mctx.imagesLast == mctx.imagesNb)
mctx.imagesLast = 0;
imageNumber = mctx.imagesLast;
if ((ret = ldclt_mutex_unlock (&(mctx.imagesLast_mutex))) != 0)
{
fprintf (stderr,
"Cannot mutex_unlock(imagesLast_mutex), error=%d (%s)\n",
ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Create the data structure required
*/
attribute->mod_bvalues = (struct berval **)
malloc (2 * sizeof (struct berval *));
if (attribute->mod_bvalues == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Error: cannot malloc(attribute->mod_bvalues), error=%d (%s)\n",
errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
attribute->mod_bvalues[0] = (struct berval *) malloc (sizeof (struct berval));
if (attribute->mod_bvalues[0] == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Error: cannot malloc(attribute->mod_bvalues[0]), error=%d (%s)\n",
errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
attribute->mod_bvalues[1] = NULL;
/*
* Fill the bvalue with the image data
*/
attribute->mod_bvalues[0]->bv_len = mctx.images[imageNumber].length;
attribute->mod_bvalues[0]->bv_val = mctx.images[imageNumber].data;
/*
* Normal end
*/
return (0);
}
/* New */ /*JLS 23-03-01*/
/* ****************************************************************************
FUNCTION : loadDataListFile
PURPOSE : Load the data list file given in argument.
INPUT : dlf->fname = file to process
OUTPUT : dlf = file read
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
loadDataListFile (
data_list_file *dlf)
{
FILE *ifile; /* Input file */
char line[MAX_FILTER]; /* To read ifile */
/*
* Open the file
*/
ifile = fopen (dlf->fname, "r");
if (ifile == NULL)
{
perror (dlf->fname);
fprintf (stderr, "Error: cannot open file \"%s\"\n", dlf->fname);
return (-1);
}
/*
* Count the entries.
* Allocate the array.
* Rewind the file.
*/
for (dlf->strNb=0 ; fgets(line, MAX_FILTER, ifile) != NULL ; dlf->strNb++);
dlf->str = (char **) malloc (dlf->strNb * sizeof (char *));
if (fseek (ifile, 0, SEEK_SET) != 0)
{
perror (dlf->fname);
fprintf (stderr, "Error: cannot rewind file \"%s\"\n", dlf->fname);
return (-1);
}
/*
* Read all the entries from this file
*/
dlf->strNb=0;
while (fgets(line, MAX_FILTER, ifile) != NULL)
{
if ((strlen (line) > 0) && (line[strlen(line)-1]=='\n'))
line[strlen(line)-1] = '\0';
dlf->str[dlf->strNb] = strdup (line);
dlf->strNb++;
}
/*
* Close the file
*/
if (fclose (ifile) != 0)
{
perror (dlf->fname);
fprintf (stderr, "Error: cannot fclose file \"%s\"\n", dlf->fname);
return (-1);
}
return (0);
}
/* New */ /*JLS 23-03-01*/
/* ****************************************************************************
FUNCTION : dataListFile
PURPOSE : Find the given data_list_file either in the list of
files already loaded, either load it.
INPUT : fname = file name.
OUTPUT : None.
RETURN : NULL if error, else the requested file.
DESCRIPTION :
*****************************************************************************/
data_list_file *
dataListFile (
char *fname)
{
data_list_file *dlf; /* To process the request */
/*
* Maybe we already have loaded this file ?
*/
for (dlf=mctx.dlf ; dlf != NULL ; dlf=dlf->next)
if (!strcmp (fname, dlf->fname))
return (dlf);
/*
* Well, it looks like we should load a new file ;-)
* Allocate a new data structure, chain it in mctx and load the file.
*/
dlf = (data_list_file *) malloc (sizeof (data_list_file));
dlf->next = mctx.dlf;
mctx.dlf = dlf;
dlf->fname = strdup (fname);
if (loadDataListFile (dlf) < 0)
return (NULL);
/*
* Loaded...
*/
return (dlf);
}
/* End of file */
--- NEW FILE ldap-private.h ---
#ident "@(#)ldap-private.h 1.6 06/10/98 SMI"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
#ifndef _LDAP_PRIVATE_H
#define _LDAP_PRIVATE_H
#ifdef _REENTRANT
#ifndef MAX_THREAD_ID
#define MAX_THREAD_ID 500
#endif /* MAX_THREAD_ID */
#else /* _REENTRANT */
#ifndef MAX_THREAD_ID
#define MAX_THREAD_ID 1
#endif /* MAX_THREAD_ID */
#endif /* _REENTRANT */
#define COMPAT20
#define COMPAT30
#if defined(COMPAT20) || defined(COMPAT30)
#define COMPAT
#endif
#ifdef LDAP_DNS
#define LDAP_OPT_DNS 0x00000001 /* use DN & DNS */
#endif /* LDAP_DNS */
/*
#define DBG_LOCK1(st) printf("%d> %s %d:%s\n", _thr_self(), st, __LINE__, __FILE__);
#define DBG_LOCK2(ld,st) printf("%d> %s ld_lockcount=%d %d:%s\n", _thr_self(), st, (ld)->ld_lockcount, __LINE__, __FILE__);
*/
#define DBG_LOCK1(st)
#define DBG_LOCK2(ld,st)
#define LOCK_RESPONSE(ld) \
if ((ld)->ld_response_lockthread != _thr_self()) { \
DBG_LOCK1("waiting for response lock") \
pthread_mutex_lock( &((ld)->ld_response_mutex) ); \
DBG_LOCK1("got response lock") \
(ld)->ld_response_lockthread = _thr_self(); \
} else { \
(ld)->ld_response_lockcount++; \
DBG_LOCK2(ld, "fake ldap lock") \
}
#define UNLOCK_RESPONSE(ld) \
if ((ld)->ld_response_lockcount==0) { \
(ld)->ld_response_lockthread = 0; \
pthread_mutex_unlock( &((ld)->ld_response_mutex) ); \
DBG_LOCK1("freed response lock") \
} else { \
(ld)->ld_response_lockcount--; \
DBG_LOCK2(ld, "fake ldap unlock") \
}
#define LOCK_LDAP(ld) \
if ((ld)->ld_lockthread != _thr_self()) { \
DBG_LOCK1("waiting for ldap lock") \
pthread_mutex_lock( &((ld)->ld_ldap_mutex) ); \
DBG_LOCK1("got ldap lock") \
(ld)->ld_lockthread = _thr_self(); \
} else { \
(ld)->ld_lockcount++; \
DBG_LOCK2(ld, "fake ldap lock") \
}
#define UNLOCK_LDAP(ld) \
if ((ld)->ld_lockcount==0) { \
(ld)->ld_lockthread = 0; \
pthread_mutex_unlock( &((ld)->ld_ldap_mutex) ); \
DBG_LOCK1("freed ldap lock") \
} else { \
(ld)->ld_lockcount--; \
DBG_LOCK2(ld, "fake ldap unlock") \
}
#define LOCK_POLL(ld) pthread_mutex_lock( &ld->ld_poll_mutex )
#define UNLOCK_POLL(ld) pthread_mutex_unlock( &ld->ld_poll_mutex )
/*
* This structure represents both ldap messages and ldap responses.
* These are really the same, except in the case of search responses,
* where a response has multiple messages.
*/
typedef struct ldapmsg {
int lm_msgid; /* the message id */
int lm_msgtype; /* the message type */
BerElement *lm_ber; /* the ber encoded message contents */
struct ldapmsg *lm_chain; /* for search - next msg in the resp */
struct ldapmsg *lm_next; /* next response */
unsigned long lm_time; /* used to maintain cache */
} _struct_LDAPMessage;
typedef struct ldap_filt_list {
char *lfl_tag;
char *lfl_pattern;
char *lfl_delims;
LDAPFiltInfo *lfl_ilist;
struct ldap_filt_list *lfl_next;
} _struct_FiltList;
typedef struct ldap_filt_desc {
LDAPFiltList *lfd_filtlist;
LDAPFiltInfo *lfd_curfip;
LDAPFiltInfo lfd_retfi;
char lfd_filter[ LDAP_FILT_MAXSIZ ];
char *lfd_curval;
char *lfd_curvalcopy;
char **lfd_curvalwords;
char *lfd_filtprefix;
char *lfd_filtsuffix;
} _struct_FiltDesc;
/*
* structure for tracking LDAP server host, ports, DNs, etc.
*/
typedef struct ldap_server {
char *lsrv_host;
char *lsrv_dn; /* if NULL, use default */
int lsrv_port;
struct ldap_server *lsrv_next;
} LDAPServer;
/*
* structure for representing an LDAP server connection
*/
typedef struct ldap_conn {
Sockbuf *lconn_sb;
int lconn_refcnt;
unsigned long lconn_lastused; /* time */
int lconn_status;
#define LDAP_CONNST_NEEDSOCKET 1
#define LDAP_CONNST_CONNECTING 2
#define LDAP_CONNST_CONNECTED 3
LDAPServer *lconn_server;
char *lconn_krbinstance;
struct ldap_conn *lconn_next;
} LDAPConn;
/*
* Structure used to keep track of search references
*/
typedef struct ldap_reference {
char ** lref_refs;
struct ldap_reference *lref_next;
} LDAPRef;
/*
* structure used to track outstanding requests
*/
typedef struct ldapreq {
int lr_msgid; /* the message id */
int lr_status; /* status of request */
#define LDAP_REQST_INPROGRESS 1
#define LDAP_REQST_CHASINGREFS 2
#define LDAP_REQST_NOTCONNECTED 3
#define LDAP_REQST_WRITING 4
int lr_outrefcnt; /* count of outstanding referrals */
int lr_origid; /* original request's message id */
int lr_parentcnt; /* count of parent requests */
int lr_res_msgtype; /* result message type */
int lr_res_errno; /* result LDAP errno */
char *lr_res_error; /* result error string */
char *lr_res_matched;/* result matched DN string */
BerElement *lr_ber; /* ber encoded request contents */
LDAPConn *lr_conn; /* connection used to send request */
LDAPRef *lr_references;
char **lr_ref_followed; /* referral being followed */
char **lr_ref_unfollowed; /* Not being followed */
char **lr_ref_tofollow; /* referral to follow if the one being
followed fails. */
struct ldapreq *lr_parent; /* request that spawned this referral */
struct ldapreq *lr_refnext; /* next referral spawned */
struct ldapreq *lr_prev; /* previous request */
struct ldapreq *lr_next; /* next request */
} LDAPRequest;
/*
* structure for client cache
*/
#define LDAP_CACHE_BUCKETS 31 /* cache hash table size */
typedef struct ldapcache {
LDAPMessage *lc_buckets[LDAP_CACHE_BUCKETS];/* hash table */
LDAPMessage *lc_requests; /* unfulfilled reqs */
long lc_timeout; /* request timeout */
long lc_maxmem; /* memory to use */
long lc_memused; /* memory in use */
int lc_enabled; /* enabled? */
unsigned long lc_options; /* options */
#define LDAP_CACHE_OPT_CACHENOERRS 0x00000001
#define LDAP_CACHE_OPT_CACHEALLERRS 0x00000002
} LDAPCache;
#define NULLLDCACHE ((LDAPCache *)NULL)
/*
* structure representing an ldap connection
*/
typedef struct ldap {
Sockbuf ld_sb; /* socket descriptor & buffer */
char *ld_host;
int ld_version;
char ld_lberoptions;
int ld_deref;
int ld_timelimit;
int ld_sizelimit;
LDAPFiltDesc *ld_filtd; /* from getfilter for ufn searches */
char *ld_ufnprefix; /* for incomplete ufn's */
int ld_errno[MAX_THREAD_ID]; /* thread-specific */
#define ld_errno ld_errno[ldap_thr_index()]
char *ld_error[MAX_THREAD_ID]; /* thread-specific */
#define ld_error ld_error[ldap_thr_index()]
char *ld_matched[MAX_THREAD_ID]; /* thread-specific */
#define ld_matched ld_matched[ldap_thr_index()]
char **ld_referrals[MAX_THREAD_ID]; /* thread-specific */
#define ld_referrals ld_referrals[ldap_thr_index()]
LDAPControl **ld_ret_ctrls[MAX_THREAD_ID]; /* thread-specific */
#define ld_ret_ctrls ld_ret_ctrls[ldap_thr_index()]
int ld_msgid;
int ld_follow_referral; /* flag set to true if lib follow referrals */
LDAPRequest *ld_requests; /* list of outstanding requests -- referrals*/
LDAPMessage *ld_responses; /* list of outstanding responses */
int *ld_abandoned; /* array of abandoned requests */
pthread_mutex_t ld_response_mutex; /* mutex for responses part of structure */
pthread_t ld_response_lockthread; /* thread which currently holds the response lock */
int ld_response_lockcount; /* response lock depth */
char *ld_attrbuffer[MAX_THREAD_ID];
#define ld_attrbuffer ld_attrbuffer[ldap_thr_index()]
LDAPCache *ld_cache; /* non-null if cache is initialized */
char *ld_cldapdn; /* DN used in connectionless search */
/* it is OK to change these next four values directly */
int ld_cldaptries; /* connectionless search retry count */
int ld_cldaptimeout;/* time between retries */
int ld_refhoplimit; /* limit on referral nesting */
int ld_restart; /* Decide if continue after interruption */
#ifdef LDAP_SSL
int ld_use_ssl;
char *ld_ssl_key;
#endif
unsigned long ld_options; /* boolean options */
/* do not mess with the rest though */
char *ld_defhost; /* full name of default server */
int ld_defport; /* port of default server */
BERTranslateProc ld_lber_encode_translate_proc;
BERTranslateProc ld_lber_decode_translate_proc;
LDAPConn *ld_defconn; /* default connection */
LDAPConn *ld_conns; /* list of server connections */
void *ld_selectinfo; /* platform specifics for select */
LDAP_REBIND_FUNCTION *ld_rebindproc;
void *ld_rebind_extra_arg;
/* int (*ld_rebindproc)( struct ldap *ld, char **dnp, */
/* char **passwdp, int *authmethodp, int freeit ); */
/* routine to get info needed for re-bind */
pthread_mutex_t ld_ldap_mutex; /* mutex for thread dependent part of struct */
pthread_t ld_lockthread; /* thread which currently holds the lock */
int ld_lockcount; /* lock depth */
pthread_mutex_t ld_poll_mutex; /* a seperate lock for polling */
LDAPControl **ld_srvctrls; /* Controls used by ldap and server */
LDAPControl **ld_cltctrls; /* Client side controls */
/* KE: Lists of unsolicited notifications */
LDAPMessage *ld_notifs[MAX_THREAD_ID];
#define ld_notifs ld_notifs[ldap_thr_index()]
} _struct_LDAP;
/*
* handy macro to check whether LDAP struct is set up for CLDAP or not
*/
#define LDAP_IS_CLDAP( ld ) ( ld->ld_sb.sb_naddr > 0 )
#endif /* _LDAP_PRIVATE_H */
--- NEW FILE ldapfct.c ---
#ident "ldclt @(#)ldapfct.c 1.68 01/05/04"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : ldapfct.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 04 December 1998
DESCRIPTION :
This file contains the ldap part of this tool.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
04/12/98 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
09/12/98 | JL Schwing | 1.2 : Forget to free ldap returned data.
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.3 : Add nb of errors statistics.
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.4 : Implement asynchronous mode.
---------+--------------+------------------------------------------------------
11/12/98 | JL Schwing | 1.5 : fflush(stdout) after each printf.
---------+--------------+------------------------------------------------------
14/12/98 | JL Schwing | 1.6 : Implement "-e close".
| New function my_ldap_err2string() to prevent crashes.
---------+--------------+------------------------------------------------------
16/12/98 | JL Schwing | 1.7 : Implement "-e add" and "-e delete".
| Create separate functions for connection operations.
---------+--------------+------------------------------------------------------
23/12/98 | JL Schwing | 1.8 : Factorise the doXxxx() functions.
| Fix SIGSEGV in ldap_parse_result().
| Implement result decoding in doAddEntry().
---------+--------------+------------------------------------------------------
24/12/98 | JL Schwing | 1.9 : Bug fix - should support no message in async.
| Bug fix - forget to check mctx.asyncMax !!!
| Modify the getPending() algorythm to empty the queue
| (if possible).
---------+--------------+------------------------------------------------------
29/12/98 | JL Schwing | 1.10: Implement -Q.
| Bug fix mode -q when asynchronous.
---------+--------------+------------------------------------------------------
11/01/99 | JL Schwing | 1.11: Implement "-e emailPerson".
| Bug fix - bad building of rdn in buildNewEntry().
---------+--------------+------------------------------------------------------
13/01/99 | JL Schwing | 1.12: Implement "-e string".
---------+--------------+------------------------------------------------------
14/01/99 | JL Schwing | 1.13: Implement "-s <scope>".
---------+--------------+------------------------------------------------------
15/01/99 | JL Schwing | 1.14: Create automatically the missing nodes.
---------+--------------+------------------------------------------------------
18/01/99 | JL Schwing | 1.15: Implements "-e randombase".
---------+--------------+------------------------------------------------------
18/01/99 | JL Schwing | 1.16: Implements "-e v2".
---------+--------------+------------------------------------------------------
20/01/99 | JL Schwing | 1.17: Bug fix - should'nt fail in createMissingNodes()
| if error 68 (Already exists).
| Increment counter for intermediate node(s) too.
---------+--------------+------------------------------------------------------
23/01/99 | JL Schwing | 1.18: Improve traces.
| Bug fix - remove leading spaces from rdn.
---------+--------------+------------------------------------------------------
26/01/99 | JL Schwing | 1.19: Implement "-e noloop".
---------+--------------+------------------------------------------------------
01/02/99 | JL Schwing | 1.20: Create *all* the nodes in createMissingNodes()
---------+--------------+------------------------------------------------------
03/02/99 | JL Schwing | 1.21: Create the leaf entry after createMissingNodes()
---------+--------------+------------------------------------------------------
26/02/99 | JL Schwing | 1.22: Detect "\," in createMissingNodes().
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | 1.23: Add call to opAdd().
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | 1.24: Forget some calls to opAdd().
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | 1.25: Too many calls to opAdd() !!!
---------+--------------+------------------------------------------------------
19/05/99 | JL Schwing | 1.27: Implements doRename().
| Do not print messages about intermediate nodes created
| in quiet mode.
| MOdify getPending()to support rename operations.
---------+--------------+------------------------------------------------------
06/03/00 | JL Schwing | 1.28: Test malloc() return value.
---------+--------------+------------------------------------------------------
06/03/00 | A. Hornik | 1.29: Bug fix - SEGV if no passwd provided.
---------+--------------+------------------------------------------------------
03/08/00 | JL Schwing | 1.30: Improve errors decoding. This improvement
| is to retrieve the additional error string that
| is returned by the server. This is implemented for
| the asynchronous operations and for the synchronous
| search only, because for the other synchronous ops
| we should use ldap_get_lderrno() that is not
| implement in Solaris's libldap.
| Add new function printErrorFromLdap().
---------+--------------+------------------------------------------------------
03/08/00 | JL Schwing | 1.31: Fix SIGSEGV in printErrorFromLdap().
---------+--------------+------------------------------------------------------
11/08/00 | JL Schwing | 1.32: Improve error decoding.
---------+--------------+------------------------------------------------------
18/08/00 | JL Schwing | 1.33: Print begin and end dates.
---------+--------------+------------------------------------------------------
25/08/00 | JL Schwing | 1.34: Implement consistent exit status...
---------+--------------+------------------------------------------------------
11/10/00 | B Kolics | 1.35: Added SSL connection initialization to
| | connectToServer, createMissingNodes
---------+--------------+------------------------------------------------------
26/10/00 | B Kolics | 1.36: Moved SSL client initialization to basicInit
-------------------------------------------------------------------------------
07/11/00 | JL Schwing | 1.37: Implements dynamic load of ssl-related
| functions.
---------+--------------+------------------------------------------------------
07/11/00 | JL Schwing | 1.38: Implement "-e inetOrgPerson".
| Add new error message in createMissingNodes().
---------+--------------+------------------------------------------------------
13/11/00 | JL Schwing | 1.39: Add new options "-e randombaselow and ...high"
---------+--------------+------------------------------------------------------
14/11/00 | JL Schwing | 1.40: Will now use utils.c functions.
---------+--------------+------------------------------------------------------
14/11/00 | JL Schwing | 1.41 : Port on AIX.
---------+--------------+------------------------------------------------------
21/11/00 | JL Schwing | 1.42: Implement "-e attreplace=name:mask"
| Add new function buildNewModAttrib().
---------+--------------+------------------------------------------------------
24/11/00 | B Kolics | 1.43: Added SSL client authentication
---------+--------------+------------------------------------------------------
29/11/00 | JL Schwing | 1.44: Port on NT 4.
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.45: Port on Linux.
---------+--------------+------------------------------------------------------
14/12/00 | JL Schwing | 1.46: Add more trace in VERY_VERBOSE mode.
| Fix some trace messages.
| Add new function dnFromMessage().
---------+--------------+------------------------------------------------------
15/12/00 | JL Schwing | 1.47: Implement "-e counteach".
| Implement "-e withnewparent" - cf bug Scopus 526148
---------+--------------+------------------------------------------------------
18/12/00 | JL Schwing | 1.48: Add new exit status EXIT_RESSOURCE.
---------+--------------+------------------------------------------------------
18/12/00 | JL Schwing | 1.49: Bug fix when -e rename,counteach
---------+--------------+------------------------------------------------------
18/12/00 | JL Schwing | 1.50: Bug fix - support errors the user wants to
| ignore in connectToServer().
| Also a bug fix in tttctx->exitStatus management.
---------+--------------+------------------------------------------------------
03/01/01 | JL Schwing | 1.51: Implement "-e attrsonly=value".
---------+--------------+------------------------------------------------------
05/01/01 | JL Schwing | 1.52: Implement "-e randombinddn" and associated
| "-e randombinddnlow/high"
| Add new function buildNewBindDN().
---------+--------------+------------------------------------------------------
05/03/01 | JL Schwing | 1.53: Fix the "anonymous" mode.
---------+--------------+------------------------------------------------------
08/03/01 | JL Schwing | 1.54: Change referrals handling.
| Add new functions refRebindProc() and referralSetup().
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.55: Implement "-e commoncounter"
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.56: Lint cleanup.
| Port on _WIN32.
---------+--------------+------------------------------------------------------
15/03/01 | JL Schwing | 1.57: Implement "-e attrlist=name:name:name"
| Implement "-e randomattrlist=name:name:name"
[...3107 lines suppressed...]
* disconnection, bind/unbind/close etc... requested by the user.
* The cost is one more function call in this application, but the
* resulting source code will be much more easiest to maintain.
*/
if (connectToServer (tttctx) < 0) /*JLS 18-12-00*/
return (-1); /*JLS 18-12-00*/
if (!(tttctx->binded)) /*JLS 18-12-00*/
return (0); /*JLS 18-12-00*/
/*
* Build the filter
*/
if (buildRandomRdnOrFilter (tttctx) < 0)
return (-1);
/*
* Prepear the attribute list
*/
if (mctx.attrlistNb == 0) /*JLS 15-03-01*/
attrlist = NULL; /*JLS 15-03-01*/
else /*JLS 15-03-01*/
if (mctx.mode & RANDOM_ATTRLIST) /*JLS 15-03-01*/
attrlist = selectRandomAttrList (tttctx); /*JLS 15-03-01*/
else /*JLS 15-03-01*/
attrlist = mctx.attrlist; /*JLS 15-03-01*/
/*
* Do the search
* Maybe we are in synchronous mode ? I hope so, it is really
* much simple ;-)
*/
if (!(mctx.mode & ASYNC))
{
ret = ldap_search_s (tttctx->ldapCtx, tttctx->bufBaseDN, mctx.scope,
tttctx->bufFilter, attrlist, /*JLS 15-03-01*/
mctx.attrsonly, &res); /*JLS 03-01-01*/
if (ret != LDAP_SUCCESS)
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
(void) printErrorFromLdap (tttctx, res, ret, /*JLS 03-08-00*/
"Cannot ldap_search()"); /*JLS 03-08-00*/
if (addErrorStat (ret) < 0)
return (-1);
if ((ret == LDAP_NO_SUCH_OBJECT) && /*JLS 15-12-00*/
(mctx.mode & COUNT_EACH)) /*JLS 15-12-00*/
{ /*JLS 15-12-00*/
if (incrementNbOpers (tttctx) < 0) /*JLS 15-12-00*/
return (-1); /*JLS 15-12-00*/
} /*JLS 15-12-00*/
}
else
{
if (incrementNbOpers (tttctx) < 0)/* Memorize operation */
return (-1);
/*
* Don't forget to free the returned message !
*/
if ((ret = ldap_msgfree (res)) < 0)
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
{
printf ("ldclt[%d]: T%03d: Cannot ldap_msgfree(), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, my_ldap_err2string (ret));
fflush (stdout);
}
if (addErrorStat (ret) < 0)
return (-1);
}
}
/*
* End of synchronous operation
*/
return (0);
}
/*
* Here, we are in asynchronous mode...
* Too bad, lot of things to do here.
* First, let's see if we are above the reading threshold.
*/
if (tttctx->pendingNb >= mctx.asyncMin)
{
/*
* Retrieve the next pending request
*/
ret = ldap_result (tttctx->ldapCtx, LDAP_RES_ANY, 1, &(mctx.timeval), &res);
if (ret < 0)
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
(void) printErrorFromLdap (tttctx, res, ret, /*JLS 03-08-00*/
"Cannot ldap_result()"); /*JLS 03-08-00*/
if (addErrorStat (ret) < 0)
return (-1);
}
else
{
tttctx->pendingNb--;
/*
* Don't forget to free the returned message !
*/
if ((ret = ldap_msgfree (res)) < 0)
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
{
printf ("ldclt[%d]: T%03d: Cannot ldap_msgfree(), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, my_ldap_err2string (ret));
fflush (stdout);
}
if (addErrorStat (ret) < 0)
return (-1);
}
}
}
/*
* Maybe we may send another request ?
* Well... there is no proper way to retrieve the error number for
* this, so I guess I may use direct access to the ldap context
* to read the field ld_errno.
*/
if (tttctx->pendingNb > mctx.asyncMax)
{
if ((mctx.mode & VERBOSE) &&
(tttctx->asyncHit == 1) &&
(!(mctx.mode & SUPER_QUIET)))
{
tttctx->asyncHit = 1;
printf ("ldclt[%d]: T%03d: Max pending request hit.\n",
mctx.pid, tttctx->thrdNum);
fflush (stdout);
}
}
else
{
if ((mctx.mode & VERBOSE) &&
(tttctx->asyncHit == 1) &&
(!(mctx.mode & SUPER_QUIET)))
{
tttctx->asyncHit = 0;
printf ("ldclt[%d]: T%03d: Restart sending.\n",
mctx.pid, tttctx->thrdNum);
fflush (stdout);
}
ret = ldap_search (tttctx->ldapCtx, tttctx->bufBaseDN, mctx.scope,
tttctx->bufFilter, attrlist, /*JLS 15-03-01*/
mctx.attrsonly); /*JLS 03-01-01*/
if (ret < 0)
{
if (ldap_get_option (tttctx->ldapCtx, LDAP_OPT_ERROR_NUMBER, &ret) < 0)
{
printf ("ldclt[%d]: T%03d: Cannot ldap_get_option(LDAP_OPT_ERROR_NUMBER)\n",
mctx.pid, tttctx->thrdNum);
fflush (stdout);
return (-1);
}
else
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
{
printf ("ldclt[%d]: T%03d: Cannot ldap_search(), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, my_ldap_err2string (ret));
fflush (stdout);
}
if (addErrorStat (ret) < 0)
return (-1);
if ((ret == LDAP_NO_SUCH_OBJECT) && /*JLS 15-12-00*/
(mctx.mode & COUNT_EACH)) /*JLS 15-12-00*/
{ /*JLS 15-12-00*/
if (incrementNbOpers (tttctx) < 0) /*JLS 15-12-00*/
return (-1); /*JLS 15-12-00*/
} /*JLS 15-12-00*/
}
}
else
{
/*
* Memorize the operation
*/
if (incrementNbOpers (tttctx) < 0)
return (-1);
tttctx->pendingNb++;
}
}
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: pendingNb=%d\n",
mctx.pid, tttctx->thrdNum, tttctx->pendingNb);
/*
* End of asynchronous operation... and also end of function.
*/
return (0);
}
/* End of file */
--- NEW FILE ldclt.c ---
#ident "ldclt @(#)ldclt.c 1.89 01/06/19"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : ldclt.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 03 December 1998
DESCRIPTION :
This file is the main file of the ldclt tool. This tool
is targetted to be a multi-threaded ldap client,
specially designed to ensure good reliability of both
the basic ldap server purpose, and the replication
processes. It is *not* targetted against the
functionnality aspect of the product, but rather on the
stress and long-term operation.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
03/12/98 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.2 : Add statistics report when exiting.
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.3 : Trap SIGQUIL to issue statistics without exit.
| Bug fix - call ldap_err2string() to decode ldap errs.
---------+--------------+------------------------------------------------------
11/12/98 | JL Schwing | 1.4 : Implement max errors threshold.
| fflush(stdout) after each printf.
| Will exit(0) on SIGINT
---------+--------------+------------------------------------------------------
14/12/98 | JL Schwing | 1.5 : Implement "-e close".
| Ensure thread not dead prior to issue "no activity"
| Add statts for the number of dead threads.
---------+--------------+------------------------------------------------------
16/12/98 | JL Schwing | 1.6 : Implement "-e add" and "-e delete".
| Improve printout of options.
---------+--------------+------------------------------------------------------
24/12/98 | JL Schwing | 1.7 : Fix memory problem.
---------+--------------+------------------------------------------------------
28/12/98 | JL Schwing | 1.8 : Add more statistics.
---------+--------------+------------------------------------------------------
29/12/98 | JL Schwing | 1.9 : Implement -Q.
---------+--------------+------------------------------------------------------
29/12/98 | JL Schwing | 1.10: Don't print pending stats if not asynchronous.
---------+--------------+------------------------------------------------------
29/12/98 | JL Schwing | 1.11: Fix typo.
---------+--------------+------------------------------------------------------
30/12/98 | JL Schwing | 1.12: Protect messages "no activity for %d seconds"
| by SUPER_QUIET mode.
---------+--------------+------------------------------------------------------
11/01/99 | JL Schwing | 1.13: Implement "-e emailPerson".
---------+--------------+------------------------------------------------------
13/01/99 | JL Schwing | 1.14: Implement "-e string".
---------+--------------+------------------------------------------------------
14/01/99 | JL Schwing | 1.15: Implement "-s <scope>".
---------+--------------+------------------------------------------------------
18/01/99 | JL Schwing | 1.16: Implement "-e randombase".
---------+--------------+------------------------------------------------------
18/01/99 | JL Schwing | 1.17: Implement "-e v2".
---------+--------------+------------------------------------------------------
21/01/99 | JL Schwing | 1.18: Implement "-e ascii".
---------+--------------+------------------------------------------------------
26/01/99 | JL Schwing | 1.19: Implement "-e noloop".
---------+--------------+------------------------------------------------------
28/01/99 | JL Schwing | 1.20: Implement "-T <total>".
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | 1.21: Implement operations list.
---------+--------------+------------------------------------------------------
06/05/99 | JL Schwing | 1.25: Add proper shutdwon (wait for check threads).
| Implement "-P <master port>".
---------+--------------+------------------------------------------------------
06/05/99 | JL Schwing | 1.26: Implement "-e modrdn".
---------+--------------+------------------------------------------------------
06/05/99 | F. Pistolesi | 1.27: Some fixes.
---------+--------------+------------------------------------------------------
07/05/99 | JL Schwing | 1.28: Some fixes.
---------+--------------+------------------------------------------------------
19/05/99 | JL Schwing | 1.30: Implement "-e rename".
| Set the threads status to DEAD when nb of opers done.
| Lint-cleanup.
---------+--------------+------------------------------------------------------
21/05/99 | JL Schwing | 1.31: Fix Unitialized Memory Read for head's mutex.
---------+--------------+------------------------------------------------------
27/05/99 | JL Schwing | 1.32 : Add statistics to check threads.
---------+--------------+------------------------------------------------------
28/05/99 | JL Schwing | 1.33 : Add new option -W (wait).
---------+--------------+------------------------------------------------------
02/06/99 | JL Schwing | 1.34 : Add flag in main ctx to know if slave was
| connected or not.
| Add counter of operations received in check threads.
---------+--------------+------------------------------------------------------
06/03/00 | JL Schwing | 1.35: Test malloc() and strdup() return value.
---------+--------------+------------------------------------------------------
04/08/00 | JL Schwing | 1.36: Add stats on nb inactivity per thread.
---------+--------------+------------------------------------------------------
08/08/00 | JL Schwing | 1.37: Print global statistics every 1000 loops.
---------+--------------+------------------------------------------------------
18/08/00 | JL Schwing | 1.38: Print global statistics every 90 loops.
| Bug fix in this new feature.
| Print ldclt version.
| Print date of begin and of end.
| Add new function ldcltExit().
---------+--------------+------------------------------------------------------
25/08/00 | JL Schwing | 1.39: Implement consistent exit status...
---------+--------------+------------------------------------------------------
25/08/00 | JL Schwing | 1.40: Will only load images if -e emailPerson
---------+--------------+------------------------------------------------------
11/10/00 | B Kolics | 1.41: Implement "-Z certfile".
---------+--------------+------------------------------------------------------
26/10/00 | B Kolics | 1.42: Move SSL client initialization to basicInit()
-------------------------------------------------------------------------------
07/11/00 | JL Schwing | 1.43: Add handlers for dynamic load of ssl-related
| functions.
| Add new function sslDynLoadInit().
-----------------------------------------------------------------------------
07/11/00 | JL Schwing | 1.44: Implement "-e inetOrgPerson".
---------+--------------+------------------------------------------------------
08/11/00 | JL Schwing | 1.45: Improve error message when initiating ssl.
---------+--------------+------------------------------------------------------
13/11/00 | JL Schwing | 1.46: Add new options "-e randombaselow and ...high"
| Made use of exit (EXIT_PARAMS) in main().
---------+--------------+------------------------------------------------------
14/11/00 | JL Schwing | 1.47: Port on AIX.
---------+--------------+------------------------------------------------------
16/11/00 | JL Schwing | 1.48: Implement "-e imagesdir=path".
---------+--------------+------------------------------------------------------
17/11/00 | JL Schwing | 1.49: Implement "-e smoothshutdown".
| Forget to add mode decoding.
| Add new function shutdownThreads().
---------+--------------+------------------------------------------------------
21/11/00 | JL Schwing | 1.50: Implement "-e attreplace=name:mask"
| Add new function parseFilter().
---------+--------------+------------------------------------------------------
22/11/00 | JL Schwing | 1.51: Will now use LD_LIBRARY_PATH to load libssl.
---------+--------------+------------------------------------------------------
24/11/00 | B Kolics | 1.52: Added SSL client authentication
---------+--------------+------------------------------------------------------
29/11/00 | JL Schwing | 1.53: Port on NT 4.
---------+--------------+------------------------------------------------------
30/11/00 | JL Schwing | 1.54: Bug fix - bad error message if -eimagesdir=path
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.55: Port on Linux.
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.56: Port on HP-UX.
---------+--------------+------------------------------------------------------
07/12/00 | JL Schwing | 1.57: Bug fix - crash SIGBUS in main:1840 if no
| filter is provided to the tool.
| Build the argv list before parsing.
---------+--------------+------------------------------------------------------
15/12/00 | JL Schwing | 1.58: Implement "-e counteach".
| Implement "-e withnewparent".
---------+--------------+------------------------------------------------------
18/12/00 | JL Schwing | 1.59: Fix an exit status problem.
---------+--------------+------------------------------------------------------
18/12/00 | JL Schwing | 1.60: Minor fix/improvement in -I management.
---------+--------------+------------------------------------------------------
19/12/00 | JL Schwing | 1.61: Implement "-e noglobalstats".
---------+--------------+------------------------------------------------------
19/12/00 | JL Schwing | 1.62: Add comments.
---------+--------------+------------------------------------------------------
[...2667 lines suppressed...]
s1ctx.cnxduration); /*JLS 12-01-01*/
ldcltExit (EXIT_PARAMS); /*JLS 12-01-01*/
} /*JLS 12-01-01*/
if (s1ctx.maxcnxnb <= 0) /*JLS 12-01-01*/
{ /*JLS 12-01-01*/
fprintf (stderr, "Error : -e scalab01_maxcnxnb=%d <= 0\n",/*JLS 12-01-01*/
s1ctx.maxcnxnb); /*JLS 12-01-01*/
ldcltExit (EXIT_PARAMS); /*JLS 12-01-01*/
} /*JLS 12-01-01*/
if (s1ctx.wait <= 0) /*JLS 12-01-01*/
{ /*JLS 12-01-01*/
fprintf (stderr, "Error : -e scalab01_wait=%d <= 0\n", /*JLS 12-01-01*/
s1ctx.wait); /*JLS 12-01-01*/
ldcltExit (EXIT_PARAMS); /*JLS 12-01-01*/
} /*JLS 12-01-01*/
} /*JLS 12-01-01*/
if ((mctx.referral == REFERRAL_REBIND) && /*JLS 14-03-01*/
((mctx.bindDN == NULL) || (mctx.passwd == NULL))) /*JLS 14-03-01*/
{ /*JLS 14-03-01*/
fprintf (stderr, "Error: -e referral=rebind needs -D and -w\n");/*14-03-01*/
ldcltExit (EXIT_PARAMS); /*JLS 14-03-01*/
} /*JLS 14-03-01*/
if ((mctx.mode & COMMON_COUNTER) && /*JLS 14-03-01*/
(!((mctx.mode & INCREMENTAL) || (mctx.mod2 & M2_OBJECT))))/*JLS 28-03-01*/
{ /*JLS 14-03-01*/
fprintf (stderr, "Error: -e commoncounter needs -e incr or -e object\n");
ldcltExit (EXIT_PARAMS); /*JLS 14-03-01*/
} /*JLS 14-03-01*/
if ((mctx.attrlistNb != 0) && (!(mctx.mode & EXACT_SEARCH))) /*JLS 15-03-01*/
{ /*JLS 15-03-01*/
fprintf(stderr,"Error : -e attrlist requires -e esearch\n");/*JLS 15-03-01*/
ldcltExit (EXIT_PARAMS); /*JLS 15-03-01*/
} /*JLS 15-03-01*/
if ((mctx.mod2 & M2_GENLDIF) && (mctx.mode & VALID_OPERS)) /*JLS 19-03-01*/
{ /*JLS 19-03-01*/
fprintf(stderr,"Error : -e genldif is exclusive.\n"); /*JLS 19-03-01*/
ldcltExit (EXIT_PARAMS); /*JLS 19-03-01*/
} /*JLS 19-03-01*/
if ((mctx.mod2 & M2_RDN_VALUE) && (!(mctx.mod2 & M2_OBJECT))) /*JLS 23-03-01*/
{ /*JLS 23-03-01*/
fprintf(stderr,"Error : -e rdn needs -e object.\n"); /*JLS 23-03-01*/
ldcltExit (EXIT_PARAMS); /*JLS 23-03-01*/
} /*JLS 23-03-01*/
/*
* Maybe we should load ssl library ?
*/
if (mctx.mode & SSL) /*JLS 07-11-00*/
if (sslDynLoadInit() < 0) /*JLS 07-11-00*/
ldcltExit (EXIT_LOADSSL); /*JLS 07-11-00*/
/*
* Basic initialization from the user's parameters/options
*/
if (basicInit() < 0)
ldcltExit (EXIT_INIT); /*JLS 18-12-00*/
/*
* What are we doing now...
*/
if (mctx.mode & VERBOSE)
{
printf ("%s\n", argvList); /*JLS 07-12-00*/
printf ("Process ID = %d\n", mctx.pid);
printf ("Host to connect = %s\n", mctx.hostname);
printf ("Port number = %d\n", mctx.port);
if (mctx.bindDN == NULL)
printf ("Bind DN = NULL\n");
else
printf ("Bind DN = %s\n", mctx.bindDN);
if (mctx.passwd == NULL)
printf ("Passwd = NULL\n");
else
printf ("Passwd = %s\n", mctx.passwd);
switch (mctx.referral) /*JLS 08-03-01*/
{ /*JLS 08-03-01*/
case REFERRAL_OFF: /*JLS 08-03-01*/
printf ("Referral = off\n"); /*JLS 08-03-01*/
break; /*JLS 08-03-01*/
case REFERRAL_ON: /*JLS 08-03-01*/
printf ("Referral = on\n"); /*JLS 08-03-01*/
break; /*JLS 08-03-01*/
case REFERRAL_REBIND: /*JLS 08-03-01*/
printf ("Referral = rebind\n"); /*JLS 08-03-01*/
break; /*JLS 08-03-01*/
} /*JLS 08-03-01*/
printf ("Base DN = %s\n", mctx.baseDN);
if (mctx.filter == NULL)
printf ("Filter = NULL\n");
else
printf ("Filter = \"%s\"\n", mctx.filter);
if (mctx.attrlistNb > 0) /*JLS 15-03-01*/
{ /*JLS 15-03-01*/
printf ("Attributes list ="); /*JLS 15-03-01*/
for (i=0 ; i<mctx.attrlistNb ; i++) /*JLS 15-03-01*/
printf (" %s", mctx.attrlist[i]); /*JLS 15-03-01*/
printf ("\n"); /*JLS 15-03-01*/
} /*JLS 15-03-01*/
printf ("Max times inactive = %d\n", mctx.inactivMax);
printf ("Max allowed errors = %d\n", mctx.maxErrors);
printf ("Number of samples = %d\n", mctx.nbSamples);
printf ("Number of threads = %d\n", mctx.nbThreads);
printf ("Total op. req. = %d\n", mctx.totalReq);
printf ("Running mode = 0x%08x\n", mctx.mode);
printf ("Running mode =");
dumpModeValues (); /*JLS 19-03-01*/
printf ("\n");
if (mctx.mode & SCALAB01) /*JLS 12-01-01*/
{ /*JLS 12-01-01*/
printf("Scalab01 cnx dur. = %d sec\n",s1ctx.cnxduration);/*JLS 12-01-01*/
printf ("Scalab01 max nb cnx= %d\n", s1ctx.maxcnxnb); /*JLS 12-01-01*/
printf ("Scalab01 wait time = %d sec\n", s1ctx.wait); /*JLS 12-01-01*/
} /*JLS 12-01-01*/
printf ("LDAP oper. timeout = %d sec\n", mctx.timeout);
printf ("Sampling interval = %d sec\n", mctx.sampling);
if (mctx.mode & EXACT_SEARCH)
{ /*JLS 03-01-01*/
switch (mctx.scope)
{
case LDAP_SCOPE_BASE:
printf ("Scope = base\n");
break;
case LDAP_SCOPE_ONELEVEL:
printf ("Scope = one level\n");
break;
case LDAP_SCOPE_SUBTREE:
printf ("Scope = subtree\n");
break;
}
printf ("Attrsonly = %d\n", mctx.attrsonly); /*JLS 03-01-01*/
} /*JLS 03-01-01*/
if (mctx.images != NULL) /*JLS 17-11-00*/
printf ("Images directory = %s\n", mctx.imagesDir); /*JLS 17-11-00*/
if ((mctx.mode & NEED_RANGE) && (mctx.randomLow >= 0)) /*JLS 28-03-01*/
printf ("Values range = [%d , %d]\n",
mctx.randomLow, mctx.randomHigh);
if ((mctx.mode & (RANDOM | INCREMENTAL)) &&
(!(mctx.mod2 & M2_RDN_VALUE))) /*JLS 23-03-01*/
{
printf ("Filter's head = \"%s\"\n", mctx.randomHead);
printf ("Filter's tail = \"%s\"\n", mctx.randomTail);
}
if (mctx.mode & RANDOM_BASE)
{
printf ("Base DN's head = \"%s\"\n", mctx.baseDNHead);
printf ("Base DN's tail = \"%s\"\n", mctx.baseDNTail);
printf ("Base DN's range = [%d , %d]\n", /*JLS 13-11-00*/
mctx.baseDNLow, mctx.baseDNHigh); /*JLS 13-11-00*/
}
if (mctx.mode & RANDOM_BINDDN) /*JLS 05-01-01*/
{ /*JLS 05-01-01*/
printf ("Bind DN's head = \"%s\"\n", mctx.bindDNHead);/*JLS 05-01-01*/
printf ("Bind DN's tail = \"%s\"\n", mctx.bindDNTail);/*JLS 05-01-01*/
printf ("Bind DN's range = [%d , %d]\n", /*JLS 05-01-01*/
mctx.bindDNLow, mctx.bindDNHigh); /*JLS 05-01-01*/
printf ("Bind passwd's head = \"%s\"\n", mctx.passwdHead);/*JLS 05-01-01*/
printf ("Bind passwd's tail = \"%s\"\n", mctx.passwdTail);/*JLS 05-01-01*/
} /*JLS 05-01-01*/
if (mctx.mode & ATTR_REPLACE) /*JLS 21-11-00*/
{ /*JLS 21-11-00*/
printf ("Attribute's head = \"%s\"\n", mctx.attrplHead);/*JLS 21-11-00*/
printf ("Attribute's tail = \"%s\"\n", mctx.attrplTail);/*JLS 21-11-00*/
} /*JLS 21-11-00*/
if (mctx.mode & ASYNC)
{
printf ("Async max pending = %d\n", mctx.asyncMax);
printf ("Async min pending = %d\n", mctx.asyncMin);
}
for (i=0 ; i<mctx.ignErrNb ; i++)
printf ("Ignore error = %d (%s)\n",
mctx.ignErr[i], my_ldap_err2string (mctx.ignErr[i]));
fflush (stdout);
if (mctx.slavesNb > 0)
{
printf ("Slave(s) to check =");
for (i=0 ; i<mctx.slavesNb ; i++)
printf (" %s", mctx.slaves[i]);
printf ("\n");
}
}
/*
* Let's go!
*/
tim = time(NULL);
printf ("ldclt[%d]: Starting at %s\n", mctx.pid, ctime (&tim)); /*JLS 18-08-00*/
if (runThem() < 0)
ldcltExit (EXIT_OTHER); /*JLS 25-08-00*/
if (initMainThread() < 0)
ldcltExit (EXIT_OTHER); /*JLS 25-08-00*/
if (monitorThem() < 0)
ldcltExit (EXIT_OTHER); /*JLS 25-08-00*/
if (printGlobalStatistics() < 0)
ldcltExit (EXIT_OTHER); /*JLS 25-08-00*/
ldcltExit (mctx.exitStatus); /*JLS 25-08-00*/
}
/* End of file */
--- NEW FILE ldclt.h ---
#ident "ldclt @(#)ldclt.h 1.66 01/05/04"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : ldclt.h
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 03 December 1998
DESCRIPTION :
This file is the main include file of the tool named
"ldclt"
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
03/12/98 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.2 : Add stats numbers in main_context.
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.3 : Implement asynchronous mode.
---------+--------------+------------------------------------------------------
11/12/98 | JL Schwing | 1.4 : Implement max errors threshold.
---------+--------------+------------------------------------------------------
14/12/98 | JL Schwing | 1.5 : Implement "-e close".
---------+--------------+------------------------------------------------------
16/12/98 | JL Schwing | 1.6 : Implement "-e add" and "-e delete".
| Add counter nb timeouts (no activity).
---------+--------------+------------------------------------------------------
28/12/98 | JL Schwing | 1.7 : Add tag asyncHit.
---------+--------------+------------------------------------------------------
29/12/98 | JL Schwing | 1.8 : Implement -Q.
---------+--------------+------------------------------------------------------
11/01/99 | JL Schwing | 1.9 : Implement "-e emailPerson".
---------+--------------+------------------------------------------------------
13/01/99 | JL Schwing | 1.10: Implement "-e string".
---------+--------------+------------------------------------------------------
14/01/99 | JL Schwing | 1.11: Implement "-s <scope>".
---------+--------------+------------------------------------------------------
18/01/99 | JL Schwing | 1.12: Implement "-e randombase".
---------+--------------+------------------------------------------------------
18/01/99 | JL Schwing | 1.13: Implement "-e v2".
---------+--------------+------------------------------------------------------
21/01/99 | JL Schwing | 1.14: Implement "-e ascii".
---------+--------------+------------------------------------------------------
26/01/99 | JL Schwing | 1.15: Implement "-e noloop".
---------+--------------+------------------------------------------------------
28/01/99 | JL Schwing | 1.16: Implement "-T <total>".
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | 1.17: Implement operations list.
---------+--------------+------------------------------------------------------
06/05/99 | JL Schwing | 1.22: Implement "-e modrdn".
---------+--------------+------------------------------------------------------
19/05/99 | JL Schwing | 1.25: Implement "-e rename".
---------+--------------+------------------------------------------------------
27/05/99 | JL Schwing | 1.26 : Add statistics to check threads.
---------+--------------+------------------------------------------------------
28/05/99 | JL Schwing | 1.27 : Add new option -W (wait).
---------+--------------+------------------------------------------------------
02/06/99 | JL Schwing | 1.28 : Add flag in main ctx to know if slave was
| connected or not.
| Add counter of operations received in check threads.
---------+--------------+------------------------------------------------------
04/08/00 | JL Schwing | 1.29: Add stats on nb inactivity per thread.
---------+--------------+------------------------------------------------------
08/08/00 | JL Schwing | 1.30: Print global statistics every 1000 loops.
---------+--------------+------------------------------------------------------
18/08/00 | JL Schwing | 1.31: Print global statistics every 15'
| Print begin and end dates.
---------+--------------+------------------------------------------------------
25/08/00 | JL Schwing | 1.32: Implement consistent exit status...
---------+--------------+------------------------------------------------------
19/09/00 | JL Schwing | 1.33: Port on Netscape's libldap. This is realized in
| such a way that this library become the default
| way so a ifdef for Solaris will be used...
---------+--------------+----------------------------------------------------
11/10/00 | B Kolics | 1.34: Added 'SSL' to the list of running modes and
| | certfile to main_context structure
---------+--------------+------------------------------------------------------
07/11/00 | JL Schwing | 1.35: Add handlers for dynamic load of ssl-related
| functions.
-----------------------------------------------------------------------------
07/11/00 | JL Schwing | 1.36: Implement "-e inetOrgPerson".
---------+--------------+------------------------------------------------------
13/11/00 | JL Schwing | 1.37: Add new options "-e randombaselow and ...high"
---------+--------------+------------------------------------------------------
16/11/00 | JL Schwing | 1.38: Implement "-e imagesdir=path".
| lint-cleanup.
---------+--------------+------------------------------------------------------
17/11/00 | JL Schwing | 1.39: Implement "-e smoothshutdown".
---------+--------------+------------------------------------------------------
21/11/00 | JL Schwing | 1.40: Implement "-e attreplace=name:mask"
| Increase max number of threads from 512 to 1000.
---------+--------------+------------------------------------------------------
22/11/00 | JL Schwing | 1.41: Will now use LD_LIBRARY_PATH to load libssl.
---------+--------------+------------------------------------------------------
24/11/00 | JL Schwing | 1.41: Added SSL client authentication
---------+--------------+------------------------------------------------------
28/11/00 | JL Schwing | 1.43: Port on NT 4.
---------+--------------+------------------------------------------------------
15/12/00 | JL Schwing | 1.44: Add more trace in VERY_VERBOSE mode.
---------+--------------+------------------------------------------------------
15/12/00 | JL Schwing | 1.45: Implement "-e counteach".
| Implement "-e withnewparent".
---------+--------------+------------------------------------------------------
18/12/00 | JL Schwing | 1.46: Add exit status EXIT_INIT and EXIT_RESSOURCE.
---------+--------------+------------------------------------------------------
03/01/01 | JL Schwing | 1.47: Implement "-e attrsonly=value".
---------+--------------+------------------------------------------------------
05/01/01 | JL Schwing | 1.48: Implement "-e randombinddn" and associated
| "-e randombinddnlow/high"
---------+--------------+------------------------------------------------------
08/01/01 | JL Schwing | 1.49: Implement "-e scalab01".
---------+--------------+------------------------------------------------------
12/01/01 | JL Schwing | 1.50: Second set of options for -e scalab01
---------+--------------+------------------------------------------------------
06/03/01 | JL Schwing | 1.51: Change DEF_ATTRSONLY from 1 to 0
---------+--------------+------------------------------------------------------
08/03/01 | JL Schwing | 1.52: Change referrals handling.
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.53: Implement "-e commoncounter"
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.54: Implement "-e dontsleeponserverdown".
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.55: Lint cleanup.
---------+--------------+------------------------------------------------------
15/03/01 | JL Schwing | 1.56: Implement "-e attrlist=name:name:name"
| Implement "-e randomattrlist=name:name:name"
---------+--------------+------------------------------------------------------
19/03/01 | JL Schwing | 1.57: Implement "-e object=filename"
| Implement "-e genldif=filename"
---------+--------------+------------------------------------------------------
21/03/01 | JL Schwing | 1.58: Implements variables in "-e object=filename"
---------+--------------+------------------------------------------------------
23/03/01 | JL Schwing | 1.59: Implements data file list support in variants.
| Implements "-e rdn=value".
---------+--------------+------------------------------------------------------
28/03/01 | JL Schwing | 1.60: Update options checking for "-e rdn=value".
---------+--------------+------------------------------------------------------
28/03/01 | JL Schwing | 1.61: Support -e commoncounter with -e rdn/object
| Increase MAX_ATTRIBS from 20 to 40
| Remove MAX_ATTRLIST - use MAX_ATTRIBS.
---------+--------------+------------------------------------------------------
02/04/01 | JL Schwing | 1.62: Bug fix : large files support for -e genldif.
---------+--------------+------------------------------------------------------
05/04/01 | JL Schwing | 1.63: Implement -e append.
---------+--------------+------------------------------------------------------
11/04/01 | JL Schwing | 1.64: Implement [INCRFROMFILE<NOLOOP>(myfile)]
---------+--------------+------------------------------------------------------
03/05/01 | JL Schwing | 1.64: Implement -e randombinddnfromfile=filename.
---------+--------------+------------------------------------------------------
04/05/01 | JL Schwing | 1.65: Implement -e bindonly.
---------+--------------+------------------------------------------------------
*/
#ifndef LDCLT_H
#define LDCLT_H
/*
* Misc constant definitions
*/
#define DEF_ATTRSONLY 0 /* ldap_search() default */ /*JLS 06-03-01*/
#define DEF_GLOBAL_NB 90 /* Prt glob stats every 15' */ /*JLS 18-08-00*/
#define DEF_INACTIV_MAX 3 /* Inactivity max nb times */
#define DEF_MAX_ERRORS 1000 /* Max errors before exit */
#define DEF_NB_THREADS 10 /* Nb client threads */
#define DEF_PORT 389 /* Ldap server port */
#define DEF_SAMPLING 10 /* Default sampling rate */
#define DEF_TIMEOUT 30 /* Ldap operations timeout */
#define DEF_PORT_CHECK 16000 /* Port used for check processing */
#define MAX_ATTRIBS 40 /* Max number of attributes */ /*JLS 28-03-01*/
#define MAX_DN_LENGTH 1024 /* Max length for a DN */
#define MAX_ERROR_NB 0x62 /* Max ldap err number + 1 */
#define MAX_IGN_ERRORS 20 /* Max errors ignored */
#define MAX_FILTER 512 /* Max filters length */
#define MAX_THREADS 1000 /* Max number of threads */ /*JLS 21-11-00*/
#define MAX_SLAVES 20 /* Max number of slaves */
#define DEF_IMAGES_PATH "../../data/ldclt/images"
#define DEF_REFERRAL REFERRAL_ON /*JLS 08-03-01*/
#define DEF_SCOPE LDAP_SCOPE_SUBTREE /* Default for -s */
#ifndef SSL_LIB
#define SSL_LIB "libldapssl41.so"
#endif
#ifndef SSL_LIB_PATH
#define SSL_LIB_PATH "/qa/ldap/tools/ldclt/src/lib-sparc/ldapcsdk"
#endif
/*
* Referral choices...
*/
#define REFERRAL_OFF 0 /*JLS 08-03-01*/
#define REFERRAL_ON 1 /*JLS 08-03-01*/
#define REFERRAL_REBIND 2 /*JLS 08-03-01*/
/*
* Running modes
* Will be used as well for main_context and for thread_context
* Don't forget to update dumpModeValues().
*/
#define NOTHING 0x00000000 /* Nothing special */
#define VERBOSE 0x00000001 /* -v : verbose */
#define VERY_VERBOSE 0x00000002 /* -V : very verbose */
#define ASYNC 0x00000004 /* -a : asynchonous mode */
#define QUIET 0x00000008 /* -q : quiet */
#define SUPER_QUIET 0x00000010 /* -Q : super quiet */
#define SSL 0x00000020 /* -Z certfile :SSL enabled *//*BK 11-10-00*/
#define CLTAUTH 0x00000040 /* .... */ /* BK 23-11-00*/
/**/
#define RANDOM_ATTRLIST 0x00000080 /* -e randomattrlist*/ /*JLS 15-03-01*/
#define DONT_SLEEP_DOWN 0x00000100 /* -e dontsleeponserverdown*//*JLS 14-03-01*/
#define COMMON_COUNTER 0x00000200 /* -e commoncounter */ /*JLS 14-03-01*/
#define SCALAB01 0x00000400 /* -e scalab01 */ /*JLS 08-01-01*/
#define RANDOM_BINDDN 0x00000800 /* -e randombinddn */ /*JLS 05-01-01*/
#define WITH_NEWPARENT 0x00001000 /* -e withnewparent */ /*JLS 15-12-00*/
#define COUNT_EACH 0x00002000 /* -e counteach */ /*JLS 15-12-00*/
#define ATTR_REPLACE 0x00004000 /* -e attreplace */ /*JLS 21-11-00*/
#define SMOOTHSHUTDOWN 0x00008000 /* -e smoothshutdown */ /*JLS 17-11-00*/
#define OC_INETORGPRSON 0x00010000 /* -e inetOrgPerson : oc= */ /*JLS 07-11-00*/
#define RENAME_ENTRIES 0x00020000 /* -e rename : rename entries */
#define NOLOOP 0x00040000 /* -e noloop : don't loop nb */
#define ASCII_7BITS 0x00080000 /* -e ascii : ascii 7bits */
#define LDAP_V2 0x00100000 /* -e v2 : ldap v2 */
#define RANDOM_BASE 0x00200000 /* -e randombase : string mode */
#define STRING 0x00400000 /* -e string : string mode */
#define OC_EMAILPERSON 0x00800000 /* -e emailPerson : oc = person */
#define DELETE_ENTRIES 0x01000000 /* -e delete : delete */
#define OC_PERSON 0x02000000 /* -e person : oc = person */
#define ADD_ENTRIES 0x04000000 /* -e add : add entries */
#define INCREMENTAL 0x08000000 /* -e incr : incremental */
#define CLOSE_FD 0x10000000 /* -e close : close fd */
#define RANDOM 0x20000000 /* -e random : rnd values */
#define BIND_EACH_OPER 0x40000000 /* -e bindeach : bnd each op */
#define EXACT_SEARCH 0x80000000 /* -e esearch : exact srch */
#define M2_OBJECT 0x00000001 /* -e object */ /*JLS 19-03-01*/
#define M2_GENLDIF 0x00000002 /* -e genldif */ /*JLS 19-03-01*/
#define M2_RDN_VALUE 0x00000004 /* -e rdn */ /*JLS 23-03-01*/
#define M2_APPEND 0x00000008 /* -e append */ /*JLS 05-04-01*/
#define M2_RNDBINDFILE 0x00000010 /* -e randombinddnfromfile *//*JLS 03-05-01*/
#define M2_BINDONLY 0x00000020 /* -e bindonly */ /*JLS 04-05-01*/
/*
* Combinatory defines
* - NEED_FILTER : filter required
* - NEED_RANGE : -r and -R required
* - NEED_RND_INCR : need entry generator
* - VALID_OPERS : valid operations
*/
#define NEED_FILTER (ADD_ENTRIES|DELETE_ENTRIES|EXACT_SEARCH|RENAME_ENTRIES|ATTR_REPLACE|SCALAB01)
#define NEED_RANGE (INCREMENTAL|RANDOM)
#define NEED_RND_INCR (ADD_ENTRIES|DELETE_ENTRIES|RENAME_ENTRIES)
#define VALID_OPERS (ADD_ENTRIES|DELETE_ENTRIES|EXACT_SEARCH|RENAME_ENTRIES|ATTR_REPLACE|SCALAB01)
#define M2_VALID_OPERS (M2_GENLDIF|M2_BINDONLY)
#define NEED_CLASSES (ADD_ENTRIES)
#define THE_CLASSES (OC_PERSON|OC_EMAILPERSON|OC_INETORGPRSON)
/*
* The threads status - check thread_context.status
*/
#define FREE -1 /* Slot is free */
#define CREATED 0 /* Just created */
#define INITIATED 1 /* Initiated */
#define RUNNING 2 /* Doing it's job */
#define DEAD 9 /* Thread is dead */
#define MUST_SHUTDOWN 10 /* Monitor command this */ /*JLS 17-11-00*/
/*
* Exit status
* The biggest is the number, the higher priority is.
* Cf the end of monitorThem().
*/
#define EXIT_OK 0 /* No problem during execution */ /*JLS 25-08-00*/
#define EXIT_PARAMS 2 /* Error in parameters */ /*JLS 25-08-00*/
#define EXIT_MAX_ERRORS 3 /* Max errors reached */ /*JLS 25-08-00*/
#define EXIT_NOBIND 4 /* Cannot bind */ /*JLS 25-08-00*/
#define EXIT_LOADSSL 5 /* Cannot load libssl */ /*JLS 07-11-00*/
#define EXIT_MUTEX 6 /* Mutex error */ /*JLS 17-11-00*/
#define EXIT_INIT 7 /* Initialization error */ /*JLS 18-12-00*/
#define EXIT_RESSOURCE 8 /* Ressource limitation */ /*JLS 18-12-00*/
#define EXIT_OTHER 99 /* Other kind of error */ /*JLS 25-08-00*/
/*
* Some constants from Sun's ldap.h are not provided by
* Netscape implementation...
*/
#ifdef SOLARIS_LIBLDAP /*JLS 19-09-00*/
#define WORKAROUND_4197228 1 /*JLS 19-09-00*/
#else /*JLS 19-09-00*/
#define LDAP_REQ_BIND 0x60 /*JLS 19-09-00*/
#define LDAP_REQ_UNBIND 0x42 /*JLS 19-09-00*/
#define LDAP_REQ_SEARCH 0x63 /*JLS 19-09-00*/
#define LDAP_REQ_MODIFY 0x66 /*JLS 19-09-00*/
#define LDAP_REQ_ADD 0x68 /*JLS 19-09-00*/
#define LDAP_REQ_DELETE 0x4a /*JLS 19-09-00*/
#define LDAP_REQ_MODRDN 0x6c /*JLS 19-09-00*/
#define LDAP_REQ_COMPARE 0x6e /*JLS 19-09-00*/
#define LDAP_REQ_ABANDON 0x50 /*JLS 19-09-00*/
#define LDAP_REQ_EXTENDED 0x77 /*JLS 19-09-00*/
#define LDAP_REQ_UNBIND_30 0x62 /*JLS 19-09-00*/
#define LDAP_REQ_DELETE_30 0x6a /*JLS 19-09-00*/
#define LDAP_REQ_ABANDON_30 0x70 /*JLS 19-09-00*/
#endif /*JLS 19-09-00*/
/*
* This structure is the internal representation of an image
*/
typedef struct image {
char *name;
int length;
char *data;
} image;
/*
* Internal representation of a data list file
*/
typedef struct data_list_file { /*JLS 23-03-01*/
char *fname; /* File name */
char **str; /* Strings array */
int strNb; /* Nb of strings */
struct data_list_file *next; /* Next file */
} data_list_file;
/*
* This structure is the internal representation of an LDAP attribute
*/
typedef struct {
char *type; /* e.g. "objectclass" or "cn" */
int length; /* Length of the value */
char *value; /* The attribute value */
int dontFree; /* Don't free the value */
} attribute;
/*
* This structure is used to memorize an operation successfully
* performed by the tool in order to be checked later on.
* The operation type is a LDAP constant LDAP_REQ_ADD, etc...
* ATTENTION: don't forget to maintain in sync with the struct thoper below.
*/
typedef struct oper {
int type; /* Operation type */
char *dn; /* Target's DN */
attribute attribs[MAX_ATTRIBS]; /* Attributes to check */
/* attribs[i].type == NULL marks the */
/* end of the attributes */
char *newRdn; /* For rename operation */
char *newParent; /* For rename operation */
int skipped; /* Thread that skipped it */
ldclt_mutex_t skipped_mutex; /* Protect skipped */ /*JLS 28-11-00*/
struct oper *next; /* Next operation */
} oper;
/*
* Same as before, but this is a per thread "lost" operation list
*/
typedef struct _simpl_op {
int type;
int first; /* Keeps in order replies */
char *dn;
attribute attribs[MAX_ATTRIBS];
char *newRdn;
char *newParent;
struct _simpl_op *next;
} thoper;
/*
* This structure will allow to manage the handlers for ssl-related
* dynamic loaded functions.
*/
typedef struct ssl_context { /*JLS 07-11-00*/
#ifndef _WIN32
void *libssl; /* lib ssl handler */ /*JLS 07-11-00*/
LDAP *(*ldapssl_init)(const char *, int, int); /*JLS 07-11-00*/
int (*ldapssl_client_init)(const char*, void*); /*JLS 07-11-00*/
int (*ldapssl_clientauth_init)(char *, void *, int, char *, void*);
/* BK 23-11-00*/
int (*ldapssl_enable_clientauth)(LDAP *, char *, char *, char *);
/* BK 22-11-00*/
#else /* _WIN32 */
LDAP * (LDAP_CALL *ldapssl_init)(const char *, int, int);
int (LDAP_CALL *ldapssl_client_init)(const char*, void*);
int (LDAP_CALL *ldapssl_clientauth_init)(char *, void *, int, char *, void*);
int (LDAP_CALL *ldapssl_enable_clientauth)(LDAP *, char *, char *, char *);
#endif /* _WIN32 */
} ssl_context; /*JLS 07-11-00*/
/*
* Versatile object attribute's field
* - If ldclt should use a common counter, then this counter will
* be in the mctx structure and will be found by the commonField
* pointer.
*/
#define HOW_CONSTANT 0 /* Constant value */
#define HOW_INCR_FROM_FILE 1 /* Increment string from file *//*JLS 11-04-01*/
#define HOW_INCR_FROM_FILE_NL 2 /* Incr string file noloop*/ /*JLS 11-04-01*/
#define HOW_INCR_NB 3 /* Increment number */ /*JLS 23-03-01*/
#define HOW_INCR_NB_NOLOOP 4 /* Increment number no loop */ /*JLS 23-03-01*/
#define HOW_RND_FROM_FILE 5 /* Random string from file */ /*JLS 23-03-01*/
#define HOW_RND_NUMBER 6 /* Random number */
#define HOW_RND_STRING 7 /* Random string */
#define HOW_VARIABLE 8 /* Retrieve variable value */ /*JLS 21-03-01*/
typedef struct vers_field { /*JLS 21-03-01*/
int how; /* How to build this field */
int cnt; /* Counter */ /*JLS 23-03-01*/
ldclt_mutex_t cnt_mutex; /* Protect cnt */ /*JLS 28-03-01*/
struct vers_field *commonField; /* Common field */ /*JLS 28-03-01*/
char *cst; /* Constant field */
data_list_file *dlf; /* Data list file */ /*JLS 23-03-01*/
int high; /* High value */
int low; /* Low value */
int nb; /* Number of items */
int var; /* Variable number */
struct vers_field *next; /* Next field */
} vers_field;
/*
* Versatile object's attribute
*/
typedef struct vers_attribute { /*JLS 19-03-01*/
char *buf; /* Store the generated value */ /*JLS 21-03-01*/
char *name; /* Attribute name */
char *src; /* Source line */
vers_field *field; /* First field */ /*JLS 21-03-01*/
} vers_attribute;
/*
* This structure contains the definitions related to the versatile
* object classes managed by ldclt.
* The field 'rdn' of vers_object is a trick we will use to be
* able to support the same random mechanism for the entry's rdn
* generation than for the attributes themselves.
*/
#define VAR_MIN 'A' /*JLS 21-03-01*/
#define VAR_MAX 'H' /*JLS 21-03-01*/
typedef struct vers_object { /*JLS 19-03-01*/
vers_attribute attribs[MAX_ATTRIBS];
int attribsNb;
vers_attribute *rdn; /* Object's rdn */ /*JLS 23-03-01*/
char *rdnName; /* Attrib. name */ /*JLS 23-03-01*/
char *var[VAR_MAX-VAR_MIN]; /*JLS 21-03-01*/
char *fname; /* Object definition */
} vers_object;
/*
* This structure contain the *process* context, used only by the
* main thread(s).
* Another dedicated structure is used by each test thread.
*/
typedef struct main_context {
int asyncMin; /* Min pend for read */
int asyncMax; /* Max async pending */
char *attrlist[MAX_ATTRIBS]; /*JLS 15-03-01*/
int attrlistNb; /* Nb attrib in list */ /*JLS 15-03-01*/
char *attrpl; /* Attrib argument */ /*JLS 21-11-00*/
char *attrplHead; /* Attrib value head */ /*JLS 21-11-00*/
char *attrplName; /* Attrib name */ /*JLS 21-11-00*/
int attrplNbDigit; /* Attrib nb digits */ /*JLS 21-11-00*/
char *attrplTail; /* Attrib value tail */ /*JLS 21-11-00*/
int attrsonly; /* search() param. */ /*JLS 03-01-01*/
char *baseDN; /* Base DN to use */
int baseDNLow; /* Base DN's low val */ /*JLS 13-11-00*/
int baseDNHigh; /* Base DN's high val *//*JLS 13-11-00*/
int baseDNNbDigit; /* Base DN's nb of digits */
char *baseDNHead; /* Base DN's head string */
char *baseDNTail; /* Base DN's tail string */
char *bindDN; /* Bind DN */
int bindDNLow; /* Bind DN's low val */ /*JLS 05-01-01*/
int bindDNHigh; /* Bind DN's high val *//*JLS 05-01-01*/
int bindDNNbDigit; /* Bind DN's ndigits */ /*JLS 05-01-01*/
char *bindDNHead; /* Bind DN's head */ /*JLS 05-01-01*/
char *bindDNTail; /* Bind DN's tail */ /*JLS 05-01-01*/
char *certfile; /* certificate file */ /* BK 11-10-00 */
char *cltcertname; /* client cert name */ /* BK 23 11-00 */
data_list_file *dlf; /* Data list files */ /*JLS 23-03-01*/
int errors[MAX_ERROR_NB]; /* Err stats */
int errorsBad; /* Bad errors */
ldclt_mutex_t errors_mutex; /* Protect errors */ /*JLS 28-11-00*/
int exitStatus; /* Exit status */ /*JLS 25-08-00*/
char *filter; /* Filter for req. */
char *genldifName; /* Where to put ldif */ /*JLS 19-03-01*/
int genldifFile; /* Where to put ldif */ /*JLS 19-03-01*/
char *hostname; /* Host to connect */
int globStatsCnt; /* Global stats loop */ /*JLS 08-08-00*/
int ignErr[MAX_IGN_ERRORS]; /* Err ignor */
int ignErrNb; /* Nb err ignored */
image *images; /* The images */
char *imagesDir; /* Where are images */ /*JLS 16-11-00*/
int imagesNb; /* Nb of images */
int imagesLast; /* Last selected image */
ldclt_mutex_t imagesLast_mutex; /* Protect imagesLast */
int inactivMax; /* Allowed inactivity */
char *keydbfile; /* key DB file */ /* BK 23-11-00*/
char *keydbpin; /* key DB password */ /* BK 23-11-00*/
int lastVal; /* To build filters */ /*JLS 14-03-01*/
ldclt_mutex_t lastVal_mutex; /* Protect lastVal */ /*JLS 14-03-01*/
int maxErrors; /* Max allowed errors */
unsigned int mode; /* Running mode */
unsigned int mod2; /* Running mode - 2 */ /*JLS 19-03-01*/
int nbNoActivity; /* Nb times no activ. */
int nbSamples; /* Samples to get */
int nbThreads; /* Nb of client */
vers_object object; /* Object to generate *//*JLS 19-03-01*/
oper *opListTail; /* Tail of operation list */
ldclt_mutex_t opListTail_mutex; /* Protect opListTail */
char *passwd; /* Bind passwd */
int passwdNbDigit; /* Passwd's ndigits */ /*JLS 05-01-01*/
char *passwdHead; /* Passwd's head */ /*JLS 05-01-01*/
char *passwdTail; /* Passwd's tail */ /*JLS 05-01-01*/
int pid; /* Process ID */
int port; /* Port to use */
int randomLow; /* Rnd's low value */
int randomHigh; /* Rnd's high val */
int randomNbDigit; /* Rnd's nb of digits */
char *randomHead; /* Rnd's head string */
char *randomTail; /* Rnd's tail string */
data_list_file *rndBindDlf; /* Rnd bind file data *//*JLS 03-05-01*/
char *rndBindFname; /* Rnd bind file name *//*JLS 03-05-01*/
int referral; /* Referral followed */ /*JLS 08-03-01*/
int sampling; /* Sampling frequency */
int scope; /* Searches scope */
int slaveConn; /* Slave has connected */
char *slaves[MAX_SLAVES]; /* Slaves list */
int slavesNb; /* Number of slaves */
ssl_context sslctx; /* SSL dyn. load ctx */ /*JSL 07-11-00*/
int timeout; /* LDAP op. t.o. */
struct timeval timeval; /* Timeval structure */
struct timeval timevalZero; /* Timeout of zero */
int totalReq; /* Total requested */
int totNbOpers; /* Total opers number */
int totNbSamples; /* Total samples nb */
int waitSec; /* Wait between two operations */
} main_context;
/*
* This structure is aimed to ease the managing of asynchronous
* operations, keeping in memory the msgid returned by the library and
* a free string meaning something for the user.
* It is targetted that this string is something like a DN, and is
* locally managed by the list functions.
*/
typedef struct msgid_cell {
LDAPMod **attribs; /* Attributes */
char dn[MAX_DN_LENGTH]; /* entry's dn */
int msgid; /* msg id */
char str[MAX_DN_LENGTH]; /* free str */
struct msgid_cell *next; /* next cell */
} msgid_cell;
/*
* This structure contain the context associated with each thread.
* It is targetted to be initiated by the main thread, and maintained
* by each thread.
*/
typedef struct thread_context {
int active; /* thread is active */
int asyncHit; /* async max hit */
char *attrlist[MAX_ATTRIBS]; /*JLS 15-03-01*/
int binded; /* thread is binded */
int exitStatus; /* Exit status */ /*JLS 25-08-00*/
int fd; /* fd to the server */
int lastVal; /* To build filters */
LDAP *ldapCtx; /* LDAP context */
unsigned int mode; /* Running mode */
int nbInactRow; /* Nb inactive in row *//*JLS 04-08-00*/
int nbInactTot; /* Nb inactive total */ /*JLS 04-08-00*/
int nbOpers; /* Nb of operations */
ldclt_mutex_t nbOpers_mutex; /* Protect nbOpers */ /*JLS 28-11-00*/
vers_object *object; /* Template */ /*JLS 21-03-01*/
int pendingNb; /* Pending opers */
int status; /* Status */
ldclt_mutex_t status_mutex; /* Protect status */ /*JLS 28-11-00*/
ldclt_tid tid; /* Thread's id */ /*JLS 28-11-00*/
char thrdId[8]; /* This thread ident */ /*JLS 08-01-01*/
int thrdNum; /* This thread number */
int totOpers; /* Total nb operations */
int totalReq; /* Total nb operations requested */
/*
* Now some convenient buffers ;-)
*/
char buf2 [MAX_FILTER];
char *bufObject1; /*JLS 19-03-01*/
char *bufAttrpl; /* Attribute replace */ /*JLS 21-11-00*/
char *bufBaseDN; /* Base DN to use */
char *bufBindDN; /* Bind DN to use */ /*JLS 05-01-01*/
char *bufFilter; /* Filter to use */
char *bufPasswd; /* Bind passwd to use *//*JLS 05-01-01*/
/*
* Note about matcheddnp management. This pointer is managed by the
* function dnFromMessage() that need it to free or remember the string
* returned by the library. DO NOT manage this field another way.
*/
char *matcheddnp; /* See above */ /*JLS 15-12-00*/
int startAttrpl; /* Insert random here *//*JLS 21-11-00*/
int startBaseDN; /* Insert random here */
int startBindDN; /* Insert random here *//*JLS 05-01-01*/
int startPasswd; /* Insert random here *//*JLS 05-01-01*/
int startRandom; /* Insert random here */
msgid_cell *firstMsgId; /* pending messages */
msgid_cell *lastMsgId; /* last one */
} thread_context;
/*
* This structure gather the information used by a check thread
*/
typedef struct check_context {
oper *headListOp; /* Head list of operation */
thoper *dcOper; /* Double check operation list */
char *slaveName; /* Name of the slave */
int sockfd; /* Socket fd after accept() */
int status; /* Status */
int thrdNum; /* Thread number */
int calls; /* Number of timeouts */
ldclt_tid tid; /* Thread's id */ /*JLS 28-11-00*/
int nbEarly; /* err = Early */
int nbLate; /* err = Late replica */
int nbLostOp; /* err = Lost op */
int nbNotOnList; /* err = Not on list */
int nbOpRecv; /* Nb operations received */
int nbRepFail32; /* err = Replica failed err=32 */
int nbRepFail68; /* err = Replica failed err=68 */
int nbRepFailX; /* err = Replica failed err=X */
int nbStillOnQ; /* err = still on Queue */
} check_context;
/*
* Extern declarations of global variables.
*/
extern main_context mctx; /* Main context */
extern thread_context tctx[]; /* Thread contextes */
extern check_context cctx[]; /* Check thread contextes */
/*
* Extern functions prototypes (for exported functions)
*/
/* From ldclt.c */
extern void ldcltExit (int status); /*JLS 18-08-00*/
extern int printGlobalStatistics (void); /*JLS 16-11-00*/
/* From ldcltU.c */
extern void usage (void);
/* From threadMain.c */
extern int addErrorStat (int err);
extern int getThreadStatus (thread_context *tttctx, /*JLS 17-11-00*/
int *status); /*JLS 17-11-00*/
extern int ignoreError (int err);
extern int incrementCommonCounter (thread_context *tttctx); /*14-03-01*/
extern int incrementCommonCounterObject ( /*JLS 28-03-01*/
thread_context *tttctx, /*JLS 28-03-01*/
vers_field *field); /*JLS 28-03-01*/
extern int incrementNbOpers (thread_context *tttctx);
extern int msgIdAdd (thread_context *tttctx, int msgid, char *str,
char *dn, LDAPMod **attribs);
extern LDAPMod **msgIdAttribs (thread_context *tttctx, int msgid);
extern int msgIdDel (thread_context *tttctx, int msgid, int freeAttr);
extern char *msgIdDN (thread_context *tttctx, int msgid);
extern char *msgIdStr (thread_context *tttctx, int msgid);
extern int randomString (thread_context *tttctx, int nbDigits);
extern char **selectRandomAttrList (thread_context *tttctx); /*JLS 15-03-01*/
extern int setThreadStatus (thread_context *tttctx, /*JLS 17-11-00*/
int status); /*JLS 17-11-00*/
extern void *threadMain (void *);
/* From ldapfct.c */
extern int connectToServer (thread_context *tttctx); /*JLS 14-03-01*/
extern char *dnFromMessage (thread_context *tttctx, LDAPMessage *res);
extern int doAddEntry (thread_context *tttctx);
extern int doAttrReplace (thread_context *tttctx); /*JLS 21-11-00*/
extern int doBindOnly (thread_context *tttctx); /*JLS 04-05-01*/
extern int doDeleteEntry (thread_context *tttctx);
extern int doExactSearch (thread_context *tttctx);
extern int doGenldif (thread_context *tttctx); /*JLS 19-03-01*/
extern int doRename (thread_context *tttctx);
extern int freeAttrib (LDAPMod **attrs);
extern void ldclt_flush_genldif (void); /*JLS 02-04-01*/
extern char *my_ldap_err2string (int err);
extern char **strList1 (char *str1); /*JLS 08-01-01*/
/* From data.c */
extern data_list_file *dataListFile (char *fname); /*JLS 23-03-01*/
extern int getImage (LDAPMod *attribute);
extern int loadImages (char *dirpath);
/* From workarounds.c */
extern int getFdFromLdapSession (LDAP *ld, int *fd);
/* From opCheck.c */
extern int opAdd (thread_context *tttctx, int type, char *dn,
LDAPMod **attribs, char *newRdn, char *newParent);
extern void *opCheckMain (void *);
extern void *opCheckLoop (void *);
extern int opNext (check_context *ctctx, oper **op);
extern int opRead (check_context *ctctx, int num, oper **op);
/* From parser.c */
extern int parseAttribValue (char *fname, /*JLS 23-03-01*/
vers_object *obj, char *line, /*JLS 23-03-01*/
vers_attribute *attrib); /*JLS 23-03-01*/
extern int readObject (vers_object *obj); /*JLS 19-03-01*/
#endif /* LDCLT_H */
/* End of file */
--- NEW FILE ldclt.man ---
#ident "ldclt @(#)ldclt.man 1.56 01/05/04"
ldclt(1) SUNQAldap ldclt(1)
NAME
ldclt - ldap client for stress and reliability testing.
SYNOPSIS
ldclt [-qQvV] [-e <execParams>] [-t <timeout>]
[-b <base DN>] [-h <host>] [-p <port>]
[-D <bind DN>] [-w <passwd>]
[-n <nb threads>] [-i <nb times>] [-N <nb samples>]
[-r <low> -R <high>]
[-a <max pending>] [-E <max errors>]
[-I <ignored error>] [-T <total>]
[-f <filter>] [-s <scope>]
[-S <slave>] [-P<master port>]
[-W <waitsec>] [-Z <certfile>]
AVAILABILITY
SUNQAldap
DESCRIPTION
ldclt is a multi-threaded test tool targetted to stress a
ldap server with multiple simultaneous requests.
The tool automatically set its ulimit parameters to fit
with the options.
The tool uses a minimum of 16Mo of memory, and maybe more
depending on the operations requested.
A summary of global statistics regarding the operations
performed, and the errors that occurs, is printed at the
exit of the tool, as well as every 90 loops (15 minutes).
http://www-icnc.france/~jls/icnc_qa_lab_faq_05.html#ldclt
Mailing list : ldclt(a)france.sun.com
Referrals
By default, ldclt will let the ldap library try to follow
referrals as anonymous. The option "-e referral=value"
allows to change this behaviour :
on : (default) follow as anonymous.
off : do not follow.
rebind : try to rebind with the same binDN and passwd.
Search operation
The option -e attrsonly=value is used to request or not
the attributes values. It is recommanded to use ldclt
with the the default value (== 0) of this option.
Extract from the C-SDK documentation :
0 : both attribute types and attribute values are
returned.
1 : only attribute types are returned.
The options -e attrlist=name:name:name and similar option
-e randomattrlist=name:name:name allows to specify which
attributes are retrieved from the server.
Error decoding
The tool try to decode the error as much as possible, but
sometimes not enough information is send back to the
client. This happen if chaining the backend feature of
DS 5.0 or more is used, when one of the farm servers is
stopped. The error returned is "Operations error" without
any more information in synchronous mode (except for the
search).
This is a problem resides in the libldap implementation
of Solaris.
Implementation note : This improvement is to retrieve the
additional error string that is returned by the server.
This is implemented for the asynchronous operations and
for the synchronous search only, because for the other
synchronous ops we should use ldap_get_lderrno() that is
not implement in Solaris's libldap.
Missing nodes
The tool automatically create the missing nodes. These
nodes are created using the DN and passwd given in argu-
ments to ldclt, and thus it may be possible that the tool
cannot initiate an empty database if it is not cn=admin,
because only cn=admin may create the root entry.
Note that when it occurs, the tool doesn't retry to
create the original entry IF running *asynchronously*.
Special consideration about rename entries : from the
c-sdk function description, if the parent node of the new
dn doesn't exist, the error returned LDAP_PROTOCOL_ERROR
may report as well three other problems :
- BER problem, unlike to happen
- newrdn is invalid, also unlike to happen
- ldclt is not running ldap v3 - ok, we could leave with
this issue.
- the newparent is invalid. I thing that we could take
this for "doesn't exist"...
The current version of this tool recognize the following
naming attributes:
cn organizationalRole
o organization
ou organizationalUnit
Close(fd) vs ldap_unbind(ld)
The option "-e bindeach" made the tool to release the
connection to the server after each operation being
processed. This is intended to simulate many clients
doing quick operations.
Without any other option, the connection is properly
released with a ldap_unbind(ld), but if the additional
option "-e close" is used, the socket with the server is
close() simulating a suddent exit of the client process.
Random
This feature is activated by the option "-e random". When
used with filters, the tool will seek the given filters
for the first sequence of 'X' and will take this as the
place where the random numbers should be put. The span of
the random numbers generated is given by the options -r
and -R.
For example, if the tool is called with the options:
-f mail=a0000XXXXXX(a)sympatico.ca -e random -r0 \
-R 9000000
the following filters will be generated:
mail=a0000492027(a)sympatico.ca
mail=a0000001941(a)sympatico.ca
mail=a0000075117(a)sympatico.ca
mail=a0000589623(a)sympatico.ca
mail=a0000283543(a)sympatico.ca
mail=a0000051688(a)sympatico.ca
etc...
The same feature may be applied to the base DN, and is
activated by the options "-e randombase",
"-e randombaselow=value" and "-e randombasehigh=value".
The same feature may be applied to the bind DN, and is
activated by the options "-e randombinddn",
"-e randombinddnlow=value", "-e randombinddnhigh=value".
Incremental
This feature is activated by the option "-e incr", and is
similar to the "Random" feature described above. It will
replace the 'X' partern by incremental numbers starting
by the value of "-r" and ending with "-R". When the top
value is reached, return back to the lower value.
The option "-e noloop" will prevent ldclt from looping
the numbers: when the -R value is reached, the thread
dies.
The option "-e commoncounter" will made all the threads
use the same counter rather than each thread having its
own private counter. This may be used for example to have
many threads adding entries without "collisions".
String
This feature is activated by the option "-e string", and
will make this tool generates random strings for the 'X'
partern rather than random numbers.
This option is only valid with the mode "-e random", and
will be applied as well to the base DN if "-e randombase"
is set, and to the bind DN and bind password if the
option "-e randombinddn" is set.
The option "-e ascii" will produce characters less than
0x7f, otherwise UTF-8 will be produced.
Signals
The signal SIGINT (^C or kill -2) is trapped to perform a
smooth exit of the tool, with statistics report.
The signal SIGQUIT (^\ or kill -3) is trapped to issue
the current statistics numbers, but without exiting the
tool.
Entry generator
If you do not want to use the hard-coded object classes
person/emailPerson/inetOrgPerson (see below), you may use
the option "-e object=filename" to give ldclt a template
to build the entries.
The same syntax may be used for the option "-e rdn=value"
including variables. The RDN is build first and you may
retrieve the variables you defined in it for the object.
You could use the option -e commoncounter with the entry
generator. When used, all the variants INCRNNOLOOP or
INCRN will share the same counter (if you are using three
times one of these variants, three different counters
will be used).
The option -e commoncounter is also compatible with the
variants INCRFROMFILE and INCRFROMFILENOLOOP.
File grammar :
# Comment start with a '#'
#
LINE = ATTRIBUTE_NAME: FIELD+
ATTRIBUTE_NAME = constant_string
FIELD = constant_string | VARIANT
VARIANT = [VAR=VDEF] | [VAR] | [VDEF]
VAR = letter A to H
VDEF = see below
The keywords and associated args are listed below. Note
that the separator is ';' and not ','.
INCRFROMFILE(file_name)
Will select each entry of file_name in sequence.
After the last entry, will reset the index for
to process again the first entry.
INCRFROMFILENOLOOP(file_name)
Will select each entry of file_name in sequence.
After the last entry, the thread will exit.
INCRN(low;hign;nb)
Increment a counter that will go from low to
high, and will loop to restart with low. This
counter is VARIANT-specific.
Similar to "-e incr".
INCRNNOLOOP(low;high;nb)
Same as INCRN, except that the thread will exit
when reaching the value high (after processing
of this value).
Similar to "-e incr,noloop".
RNDFROMFILE(file_name)
Select a random string from the file. One entry
per line is expected.
RNDN(low;high;length)
Build a random number of length digits, value
selected from low to high.
RNDS(lenght)
Build a random string.
Here is an example of template file :
# Example.
#
objectclass: person
sn: mr [RNDS(12)] final
description: blob [RNDN(1,5,6)] blib
Resulting entries :
dn: cn=mr00000,ou=object,o=test.com
cn: mr00000
objectclass: person
sn: mr 2[kK-:9)_(qv final
description: blob 000005 blib
dn: cn=mr00001,ou=object,o=test.com
cn: mr00001
objectclass: person
sn: mr Jwf01XrZs.mt final
description: blob 000002 blib
Person
Activated by "-e person" and valid only for the "-e add"
feature, the new entries are of the objectclass=person
as described here:
EmailPerson
Activated by "-e emailPerson" and valid only for the "-e
add" feature, the new entries are of the objectclass=
emailPerson as described here. These entries contain a
jpegPhoto attribute, and thus are very big entries. The
jpeg image itself is randomly (in fact: sequencially)
selected from /opt/SUNQA/ldap/lib/images/*.jpg or in the
directory specified by -e imagesdir=path.
InetOrgPerson
Activated by "-e inetOrgPerson", it is the Netscape
version of emailPerson.
Scalab01 scenario
This scenario is activated by the "-e scalab01" and is
a special evolution of ldclt for the purpose of the
system tests "scalab01". This scenario simulates a modem
pool that uses LDAP to store information about users, as
well as to autheticate them by binding.
The associated options are :
-e scalab01
Activate this scenario.
-e scalab01_cnxduration
Specifies the maximum cnx duration in seconds.
Default value is 3600 seconds.
-e scalab01_maxcnxnb
Modem pool size. Default size if 5000.
-e scalab01_wait
Sleep() in seconds while to attempts to connect.
Default value is 10 seconds.
OPTIONS
The valid options are:
-a <number>
Asynchronous mode. When used, the tool will issue
asynchronous requests, with a maximum number of
pending requests (aka results non-read). There is
a threshold at "max pending / 2" giving the
minimum number of pending operations needed to
read the answers from the server.
Each thread will process with the same algorythm,
each having the same thresholds.
-b <DN> Specify the base DN to use. Default "o=sun,c=us".
-D <DN> Bind DN. See -w for the password. You could use
the option "-e randombinddn" to randomize the
bind DN. Read below in -e options for the
details.
-e <parm1,parm2,etc...>
Execution parameters. This option is used to
select the kind of tests that should be run. It
is possible to specify more than one value (see
example below). The valid values are:
add
Add entries.
append
Append new entries to genldif file.
See also -e genldif.
ascii
Ascii 7-bits strings.
attreplace=name:mask
Will replace the attribute "name" with a
random string value build using the mask
i.e. :
attreplace=sn:"mr XXXX Jr"
Note : You DO NOT need to use -e random
nor -e string with this option.
attrlist=name:name:name
Specify the list of attributes to
retrieve.
See also -e randomattrlist.
attrsonly=0|1
This ldap_search() parameter means : 0
specifies that both attribute types and
attribute values are returned and 1
specifies that only attribute types are
returned.
Default value : 0
bindeach
Bind for each operation.
bindonly
ldclt will only perform ldap_bind() and
ldap_unbind() or close() depending on
the options.
See also -e close.
close
Will disconnect from the server by a
close() on the fd, rather than by a
ldap_unbind().
cltcertname=certificate_name
Use certificate_name for SSL client
authentication. The certificate database
is specified with the -Z option.
SSL client authentication requires the
option -Z and cltcertname, keydbfile,
keydbpin execution parameters to be
specified.
commoncounter
Valid only with -e incr or -e object.
All the threads will use the same
counter, i.e. T000 will process entry n,
T001 entry n+1, etc...
When used with an object (-e object) or
within a rdn (-e rdn), a common counter
will be used for each variant field
INCRN or INCRNNOLOOP. Each field will
have its own common counter.
counteach
To count each operation, and not only
the ones that succeed. Without this
option, an add request with result
68==LDAP_ALREADY_EXISTS is not counted,
that may mislead the statistics about
the thread's activity.
The changes are that we will count as a
valid request :
- add ==> LDAP_ALREADY_EXISTS
- delete ==> LDAP_NO_SUCH_OBJECT
- rename ==> LDAP_ALREADY_EXISTS
LDAP_NO_SUCH_OBJECT
LDAP_PROTOCOL_ERROR
- search ==> LDAP_NO_SUCH_OBJECT
delete
ldap_delete() entries.
dontsleeponserverdown
By default, ldclt sleep 1 second when
occurs an error like 81 or 91 (i.e.
server down). This should avoid ldclt
looping when server is down, otherwise it
may take 100% of all 10 CPUs of a E6000.
Basically, the client machine is down if
this happen.
emailPerson
The new entries objectclass is
emailPerson. See details above in
DESCRIPTION.
esearch
Exact search. No wildcards expected in
the filter.
genldif=filename
Create a ldif file using ldclt entry
generator.
See also -e append.
imagesdir=<path>
The images are taken from the given path
rather than from the default directory :
/opt/SUNQA/ldap/lib/images
incr
Incremental values, from -r to -R values
When -R is reached, go back to -r.
See also -e commoncounter.
inetOrgPerson
The new entries objectclass is
inetOrgPerson. See details above in
DESCRIPTION.
keydbfile=key_DB_filename
The file name of the key database.
SSL client authentication requires the
option -Z and cltcertname, keydbfile,
keydbpin execution parameters to be
specified.
keydbpin=key_DB_password
Password required for accessing the key
database specified in keydbfile
execution parameter.
SSL client authentication requires the
option -Z and cltcertname, keydbfile,
keydbpin execution parameters to be
specified.
noglobalstats
Don't print the periodical global stats
(by default : every 90 loops).
noloop
Does not loop the numbers. Cf the option
"-e incr".
object=filename
Entries will be created using template
from the given file. See details above
in DESCRIPTION.
See "-e rdn=attrname:value".
person
The new entries objectclass is person.
See details in DESCRIPTION.
random
Random filters, etc... generation. See
details above in this tool description.
randomattrlist=name:name:name
Specify the list of attributes from
which ldclt will randomly select one to
be retrieved.
See also -e attrlist.
randombase
Random base DN generation.
randombaselow=<number>
Low value range for random base DN.
randombasehigh=<number>
High value range for random base DN.
randombinddn
Random bind DN and bind password
generation. When used, this option will
produce a random value that will be used
to randomize the bind DN and password
with the same random value. e.g. cn=m123
and passwd123 will be generated.
If you want to have fix password (the
same password) for each bind DN, just no
'X' in the password.
randombinddnfromfile=filename
A bind DN and its corresponding password
will be randomly selected from the given
file. Each line must contain the bind DN
and password, separated by one or more
tabs. Leading & trailing spaces are not
ignored.
Exclusive with -e randombinddn and with
-D / -w.
randombinddnlow=<number>
Low value range for random bind DN.
randombinddnhigh=<number>
High value range for random bind DN.
rdn=attrname:value
Similar to the option "-f filterspec",
this feature allow to use the full power
of the entry generator (see DESCRIPTION)
to build the rdn of the entry that will
be processed.
Requires "-e object=".
Exclusive with -f.
referral=value
Change referral behaviour. See details
above in the DESCRIPTION section.
rename
Rename entries (aka modrdn). See also
-e withnewparent.
scalab01
Activates the scalab01 scenario. Please
read the corresponding section above for
the other associated options and
behaviour.
string
Will generate random strings rather than
numbers. See details above in the string
sub-section.
v2
Ldap v2 mode.
withnewparent
The ldap_rename() will be called with a
newparent argument. By default, only the
new rdn is specified. This option is
valid only with -e rename.
-E <number>
Specify the maximum number of times one error
may occur. It is usefull to detect a big problem
on the server side, and to exit the tool. The
default value is 1000.
-f <filter>
Filter for searches. The syntax is the same as
specified in ldap's RFCs.
See option "-e rdn=attrname:value".
-h <hostname>
Host to connect. Default "localhost".
-i <number of 10 seconds>
Number of times inactivity allowed. The tool
ensure that no thread is starving, i.e. expect
that all the threads should perform at least one
operation every 10 seconds. This parameter gives
the number of times a thread may be starving
before releasing an alert message. The default
value is 3 (30 seconds).
-I <error number>
The tool will ignore the errors the same number
as the ones specified with -I. These errors may
be for example:
32 : No such object - when -e random,delete
68 : Already exists - when -e random,add
When used, this option will configure ldclt to
ignore/support these errors during the ldap_bind
to the server. Otherwise, any error that happen
during the connection is a fatal error for the
thread where it occurs.
Note that although ldclt support a certain level
of errors during connection, any error that
happen while creating missing nodes is a fatal
error.
-n <number>
Number of threads. Each thread is a ldap client
for the ldap server under test. The maximum
number of threads is system-dependand, and is of
1000 threads. The default number is 10 threads.
-N <number>
Number of samples (10 seconds each). It is the
time the tool should run. A value of 360 means
360 samples of 10 seconds, i.e. 3600 seconds of
testing (one hour). Default infinite.
-p <port number>
Server port. Default port 389.
-P <master port number>
This is the port used to communicate with the
slaves in order to check the replication.
-q Quiet mode. When used, the errors of the option
-I are not printed. The messages "Intermediate
nodes created for xxx" are not printed either.
-Q Super quiet mode. In addition to -q, the
following messages are not printed:
Max pending request hit.
No activity for %d seconds.
Restart sending.
-r <number>
Range's low value.
-R <number>
Range's high value.
-s <scope>
Valid only for searches. May be base, subtree
or one. The default value is subtree.
-S <slave>
The slave host given in argument will be under
monitoring to ensure that the operations
performed on the server are well realized on
the given slave. This option may be used more
than one time to indicate more than one slave.
-t <seconds>
LDAP operations timeout. Default 30 seconds.
-T <total>
Total number of operations requested per thread
before exit. When used, this parameter will
cause each thread to exit when this number of
operations is reached.
-v Verbose.
-V Very verbose.
-w <password>
Bind passwd. See option -D.
-W <wait seconds>
Wait between two operations. Default=0 seconds.
-Z <certfile>
Establish secure communication with the server
over SSL using certfile as the certificate
database.
EXIT STATUS
ldclt exit status may be :
0 : no problem during execution.
1 : please report this to me - shouldn't happen !!
2 : error in parameters.
3 : max errors reached.
4 : cannot bind.
5 : cannot load libssl.
6 : mutex error.
7 : initialization problem.
8 : ressource limitation (malloc, etc...).
99 : other kind of error - please report to me.
EXAMPLES
jls@chronos$ ldclt -v \
-h aegir -e esearch,random \
-r0 -R900000 \
-bo=Sympatico,c=CA \
-fmail=a0000XXXXXX(a)sympatico.ca \
-ebindeach -n230 -i6
Host to connect = aegir
Port number = 389
Bind DN = NULL
Passwd = NULL
Base DN = o=Sympatico,c=CA
Filter = mail=a0000XXXXXX(a)sympatico.ca
Max times inactive = 6
Number of samples = 20
Number of threads = 5
Running mode = 0x0000001d
Sampling interval = 10 sec
Random range = [0 , 900000]
Filter's head = mail=a0000
Filter's tail = @sympatico.ca
Average rate: 9.98/thr (229.50/sec), total: 2295
Average rate: 10.13/thr (233.00/sec), total: 2330
Average rate: 10.05/thr (231.10/sec), total: 2311
Average rate: 10.17/thr (233.80/sec), total: 2338
Average rate: 9.99/thr (229.80/sec), total: 2298
^CCatch SIGINT - exit...
jls@chronos$
NOTES
This tool doesn't retry to create the original entry when
the creation of the missing nodes is activated. This is a
known missing feature of the asynchronous mode.
Please read the file "History" delivered with this tool
for more information about new features, todo list, etc.
IMPORTANT NOTE : you may specify a filter that return lot
of entries (e.g. : -f "cn=*") but you should then know
that such filters leads to retrieve a lot of data from
the server. These data are malloc() and free() by ldclt
and the ldap C library, but as you may have many threads
running at the same time in ldclt, you will have many
times these data allocated, leading to a *very) big ldclt
process, even more than 1Gb. It is not a memory leak but
rather allocation of lot of data. If you want the server
to retrieve a lot of data from its database and however
limit the ressources required by ldclt, use the option
"-e attrsonly=1".
AUTHORS
Jean-Luc Schwing
Fabio Pistolesi : replication check.
Bertold Kolics : SSL.
--- NEW FILE ldclt.use ---
usage: ldclt [-qQvV] [-E <max errors>]
[-b <base DN>] [-h <host>] [-p <port>] [-t <timeout>]
[-D <bind DN>] [-w <passwd>]
[-e <execParams>] [-a <max pending>]
[-n <nb threads>] [-i <nb times>] [-N <nb samples>]
[-I <err number>] [-T <total>]
[-r <low> -R <high>]
[-f <filter>] [-s <scope>]
[-S <slave>] [-P<master port>]
[-W <waitsec>] [-Z <certfile>]
This tool is a ldap client targetted to validate the reliability of
the product under test under hard use.
The valid options are:
-a Asynchronous mode, with max pending operations.
-b Give the base DN to use. Default "o=sun,c=us".
-D Bind DN. See -w
-E Max errors allowed. Default 1000.
-e Execution parameters:
add : ldap_add() entries.
append : append entries to the genldif file.
ascii : ascii 7-bits strings.
attreplace=name:mask : replace attribute of existing entry.
attrlist=name:name:name : specify list of attribs to retrieve
attrsonly=0|1 : ldap_search() parameter. Set 0 to read values.
bindeach : ldap_bind() for each operation.
bindonly : only bind/unbind, no other operation is performed.
close : will close() the fd, rather than ldap_unbind().
cltcertname=name : name of the SSL client certificate
commoncounter : all threads share the same counter.
counteach : count each operation not only successful ones.
delete : ldap_delete() entries.
dontsleeponserverdown : will loop very fast if server down.
emailPerson : objectclass=emailPerson (-e add only).
esearch : exact search.
genldif=filename : generates a ldif file
imagesdir=path : specify where are the images.
incr : incremental values.
inetOrgPerson : objectclass=inetOrgPerson (-e add only).
keydbfile=file : filename of the key database
keydbpin=password : password for accessing the key database
noglobalstats : don't print periodical global statistics
noloop : does not loop the incremental numbers.
object=filename : build object from input file
person : objectclass=person (-e add only).
random : random filters, etc...
randomattrlist=name:name:name : random select attrib in the list
randombase : random base DN.
randombaselow=value : low value for random generator.
randombasehigh=value : high value for random generator.
randombinddn : random bind DN.
randombinddnfromfile=fine : retrieve bind DN & passwd from file
randombinddnlow=value : low value for random generator.
randombinddnhigh=value : high value for random generator.
rdn=attrname:value : alternate for -f.
referral=on|off|rebind : change referral behaviour.
scalab01 : activates scalab01 scenario.
scalab01_cnxduration : maximum connection duration.
scalab01_maxcnxnb : modem pool size.
scalab01_wait : sleep() between 2 attempts to connect.
string : create random strings rather than random numbers.
v2 : ldap v2.
withnewparent : rename with newparent specified as argument.
-f Filter for searches.
-h Host to connect. Default "localhost".
-i Number of times inactivity allowed. Default 3 (30 seconds)
-I Ignore errors (cf. -E). Default none.
-n Number of threads. Default 10.
-N Number of samples (10 seconds each). Default infinite.
-p Server port. Default 389.
-P Master port (to check replication). Default 16000.
-q Quiet mode. See option -I.
-Q Super quiet mode.
-r Range's low value.
-R Range's high value.
-s Scope. May be base, subtree or one. Default subtree.
-S Slave to check.
-t LDAP operations timeout. Default 30 seconds.
-T Total number of operations per thread. Default infinite.
-v Verbose.
-V Very verbose.
-w Bind passwd. See -D.
-W Wait between two operations. Default 0 seconds.
-Z certfile. Turn on SSL and use certfile as the certificate DB
--- NEW FILE ldcltU.c ---
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
#include <stdio.h>
/*
* usage: ldclt [-qQvV] [-E <max errors>]
* [-b <base DN>] [-h <host>] [-p <port>] [-t <timeout>]
* [-D <bind DN>] [-w <passwd>]
* [-e <execParams>] [-a <max pending>]
* [-n <nb threads>] [-i <nb times>] [-N <nb samples>]
* [-I <err number>] [-T <total>]
* [-r <low> -R <high>]
* [-f <filter>] [-s <scope>]
* [-S <slave>] [-P<master port>]
* [-W <waitsec>] [-Z <certfile>]
*
* This tool is a ldap client targetted to validate the reliability of
* the product under test under hard use.
*
* The valid options are:
* -a Asynchronous mode, with max pending operations.
* -b Give the base DN to use. Default "o=sun,c=us".
* -D Bind DN. See -w
* -E Max errors allowed. Default 1000.
* -e Execution parameters:
* add : ldap_add() entries.
* append : append entries to the genldif file.
* ascii : ascii 7-bits strings.
* attreplace=name:mask : replace attribute of existing entry.
* attrlist=name:name:name : specify list of attribs to retrieve
* attrsonly=0|1 : ldap_search() parameter. Set 0 to read values.
* bindeach : ldap_bind() for each operation.
* bindonly : only bind/unbind, no other operation is performed.
* close : will close() the fd, rather than ldap_unbind().
* cltcertname=name : name of the SSL client certificate
* commoncounter : all threads share the same counter.
* counteach : count each operation not only successful ones.
* delete : ldap_delete() entries.
* dontsleeponserverdown : will loop very fast if server down.
* emailPerson : objectclass=emailPerson (-e add only).
* esearch : exact search.
* genldif=filename : generates a ldif file
* imagesdir=path : specify where are the images.
* incr : incremental values.
* inetOrgPerson : objectclass=inetOrgPerson (-e add only).
* keydbfile=file : filename of the key database
* keydbpin=password : password for accessing the key database
* noglobalstats : don't print periodical global statistics
* noloop : does not loop the incremental numbers.
* object=filename : build object from input file
* person : objectclass=person (-e add only).
* random : random filters, etc...
* randomattrlist=name:name:name : random select attrib in the list
* randombase : random base DN.
* randombaselow=value : low value for random generator.
* randombasehigh=value : high value for random generator.
* randombinddn : random bind DN.
* randombinddnfromfile=fine : retrieve bind DN & passwd from file
* randombinddnlow=value : low value for random generator.
* randombinddnhigh=value : high value for random generator.
* rdn=attrname:value : alternate for -f.
* referral=on|off|rebind : change referral behaviour.
* scalab01 : activates scalab01 scenario.
* scalab01_cnxduration : maximum connection duration.
* scalab01_maxcnxnb : modem pool size.
* scalab01_wait : sleep() between 2 attempts to connect.
* smoothshutdown : main thread waits till the worker threads exit.
* string : create random strings rather than random numbers.
* v2 : ldap v2.
* withnewparent : rename with newparent specified as argument.
* -f Filter for searches.
* -h Host to connect. Default "localhost".
* -i Number of times inactivity allowed. Default 3 (30 seconds)
* -I Ignore errors (cf. -E). Default none.
* -n Number of threads. Default 10.
* -N Number of samples (10 seconds each). Default infinite.
* -p Server port. Default 389.
* -P Master port (to check replication). Default 16000.
* -q Quiet mode. See option -I.
* -Q Super quiet mode.
* -r Range's low value.
* -R Range's high value.
* -s Scope. May be base, subtree or one. Default subtree.
* -S Slave to check.
* -t LDAP operations timeout. Default 30 seconds.
* -T Total number of operations per thread. Default infinite.
* -v Verbose.
* -V Very verbose.
* -w Bind passwd. See -D.
* -W Wait between two operations. Default 0 seconds.
* -Z certfile. Turn on SSL and use certfile as the certificate DB
*/
void usage ()
{
(void) printf ("\n");
(void) printf ("usage: ldclt [-qQvV] [-E <max errors>]\n");
(void) printf (" [-b <base DN>] [-h <host>] [-p <port>] [-t <timeout>]\n");
(void) printf (" [-D <bind DN>] [-w <passwd>]\n");
(void) printf (" [-e <execParams>] [-a <max pending>]\n");
(void) printf (" [-n <nb threads>] [-i <nb times>] [-N <nb samples>]\n");
(void) printf (" [-I <err number>] [-T <total>]\n");
(void) printf (" [-r <low> -R <high>]\n");
(void) printf (" [-f <filter>] [-s <scope>]\n");
(void) printf (" [-S <slave>] [-P<master port>]\n");
(void) printf (" [-W <waitsec>] [-Z <certfile>]\n");
(void) printf ("\n");
(void) printf (" This tool is a ldap client targetted to validate the reliability of\n");
(void) printf (" the product under test under hard use.\n");
(void) printf ("\n");
(void) printf (" The valid options are:\n");
(void) printf (" -a Asynchronous mode, with max pending operations.\n");
(void) printf (" -b Give the base DN to use. Default \"o=sun,c=us\".\n");
(void) printf (" -D Bind DN. See -w\n");
(void) printf (" -E Max errors allowed. Default 1000.\n");
(void) printf (" -e Execution parameters:\n");
(void) printf (" add : ldap_add() entries.\n");
(void) printf (" append : append entries to the genldif file.\n");
(void) printf (" ascii : ascii 7-bits strings.\n");
(void) printf (" attreplace=name:mask : replace attribute of existing entry.\n");
(void) printf (" attrlist=name:name:name : specify list of attribs to retrieve\n");
(void) printf (" attrsonly=0|1 : ldap_search() parameter. Set 0 to read values.\n");
(void) printf (" bindeach : ldap_bind() for each operation.\n");
(void) printf (" bindonly : only bind/unbind, no other operation is performed.\n");
(void) printf (" close : will close() the fd, rather than ldap_unbind().\n");
(void) printf (" cltcertname=name : name of the SSL client certificate\n");
(void) printf (" commoncounter : all threads share the same counter.\n");
(void) printf (" counteach : count each operation not only successful ones.\n");
(void) printf (" delete : ldap_delete() entries.\n");
(void) printf (" dontsleeponserverdown : will loop very fast if server down.\n");
(void) printf (" emailPerson : objectclass=emailPerson (-e add only).\n");
(void) printf (" esearch : exact search.\n");
(void) printf (" genldif=filename : generates a ldif file\n");
(void) printf (" imagesdir=path : specify where are the images.\n");
(void) printf (" incr : incremental values.\n");
(void) printf (" inetOrgPerson : objectclass=inetOrgPerson (-e add only).\n");
(void) printf (" keydbfile=file : filename of the key database\n");
(void) printf (" keydbpin=password : password for accessing the key database\n");
(void) printf (" noglobalstats : don't print periodical global statistics\n");
(void) printf (" noloop : does not loop the incremental numbers.\n");
(void) printf (" object=filename : build object from input file\n");
(void) printf (" person : objectclass=person (-e add only).\n");
(void) printf (" random : random filters, etc...\n");
(void) printf (" randomattrlist=name:name:name : random select attrib in the list\n");
(void) printf (" randombase : random base DN.\n");
(void) printf (" randombaselow=value : low value for random generator.\n");
(void) printf (" randombasehigh=value : high value for random generator.\n");
(void) printf (" randombinddn : random bind DN.\n");
(void) printf (" randombinddnfromfile=fine : retrieve bind DN & passwd from file\n");
(void) printf (" randombinddnlow=value : low value for random generator.\n");
(void) printf (" randombinddnhigh=value : high value for random generator.\n");
(void) printf (" rdn=attrname:value : alternate for -f.\n");
(void) printf (" referral=on|off|rebind : change referral behaviour.\n");
(void) printf (" scalab01 : activates scalab01 scenario.\n");
(void) printf (" scalab01_cnxduration : maximum connection duration.\n");
(void) printf (" scalab01_maxcnxnb : modem pool size.\n");
(void) printf (" scalab01_wait : sleep() between 2 attempts to connect.\n");
(void) printf (" smoothshutdown : main thread waits till the worker threads exit.\n");
(void) printf (" string : create random strings rather than random numbers.\n");
(void) printf (" v2 : ldap v2.\n");
(void) printf (" withnewparent : rename with newparent specified as argument.\n");
(void) printf (" -f Filter for searches.\n");
(void) printf (" -h Host to connect. Default \"localhost\".\n");
(void) printf (" -i Number of times inactivity allowed. Default 3 (30 seconds)\n");
(void) printf (" -I Ignore errors (cf. -E). Default none.\n");
(void) printf (" -n Number of threads. Default 10.\n");
(void) printf (" -N Number of samples (10 seconds each). Default infinite.\n");
(void) printf (" -p Server port. Default 389.\n");
(void) printf (" -P Master port (to check replication). Default 16000.\n");
(void) printf (" -q Quiet mode. See option -I.\n");
(void) printf (" -Q Super quiet mode.\n");
(void) printf (" -r Range's low value.\n");
(void) printf (" -R Range's high value.\n");
(void) printf (" -s Scope. May be base, subtree or one. Default subtree.\n");
(void) printf (" -S Slave to check.\n");
(void) printf (" -t LDAP operations timeout. Default 30 seconds.\n");
(void) printf (" -T Total number of operations per thread. Default infinite.\n");
(void) printf (" -v Verbose.\n");
(void) printf (" -V Very verbose.\n");
(void) printf (" -w Bind passwd. See -D.\n");
(void) printf (" -W Wait between two operations. Default 0 seconds.\n");
(void) printf (" -Z certfile. Turn on SSL and use certfile as the certificate DB\n");
(void) printf ("\n");
} /* usage() */
/* End of file */
--- NEW FILE opCheck.c ---
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : opCheck.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 04 May 1999
DESCRIPTION :
This file contains the functions used to manage and
check the operations performed by the tool.
These functions manages the operation list
"mctx.opListTail", match an entry retrieved from the
server to the attributes memorized for one operation,
etc...
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
05/05/99 | F. Pistolesi | 1.8 : Add communication with remote host.
| Implement operations check.
---------+--------------+------------------------------------------------------
06/05/99 | JL Schwing | 1.10: Implements opDecOper().
| Add more traces in VERY_VERBOSE
---------+--------------+------------------------------------------------------
20/05/99 | JL Schwing | 1.18: Add params (newRdn and newParent) to opAdd()
| Decode operations in Cnnn messages.
| No more exit on EINTR in accept()
| Fix memory leak in thOperFree()
---------+--------------+------------------------------------------------------
21/05/99 | JL Schwing | 1.19: Minor fixes in messages.
| Purify cleanup - Free memory read in opCheckLoop()
| Fix thOperFree() - pb when head of list to delete
| Fix memory leak in opNext().
---------+--------------+------------------------------------------------------
26/05/99 | JL Schwing | 1.21: Bug fix - return(-1) bad place in opNext().
| Minor fixes in messages.
---------+--------------+------------------------------------------------------
27/05/99 | JL Schwing | 1.22 : Add statistics to check threads.
---------+--------------+------------------------------------------------------
27/05/99 | F. Pistolesi | 1.23 : Fix statistics and other algorythms.
---------+--------------+------------------------------------------------------
31/05/99 | JL Schwing | 1.25 : Bug fix - should test opRead() returned pointer
---------+--------------+------------------------------------------------------
02/06/99 | JL Schwing | 1.26 : Add flag in main ctx to know if slave was
| connected or not.
| Add counter of operations received in check threads.
---------+--------------+------------------------------------------------------
06/03/00 | JL Schwing | 1.27: Test malloc() return value.
---------+--------------+------------------------------------------------------
18/08/00 | JL Schwing | 1.28: Print begin and end dates.
---------+--------------+------------------------------------------------------
17/11/00 | JL Schwing | 1.29: Implement "-e smoothshutdown".
---------+--------------+------------------------------------------------------
29/11/00 | JL Schwing | 1.30: Port on NT 4.
---------+--------------+------------------------------------------------------
*/
#include <pthread.h> /* Posix threads */
#include <errno.h> /* errno, etc... */
#include <stdlib.h> /* exit(), etc... */
#include <unistd.h> /* sleep(), etc... */
#include <stdio.h> /* printf(), etc... */
#include <signal.h> /* sigset(), etc... */
#include <string.h> /* strerror(), etc... */
#include <sys/resource.h> /* setrlimit(), etc... */
#include <lber.h> /* ldap C-API BER decl. */
#include <ldap.h> /* ldap C-API decl. */
#include <sys/poll.h> /* djani : while porting */
#include <sys/socket.h> /* djani : while porting */
#include <sys/types.h> /* djani : while porting */
#include <netdb.h> /* djani : while porting */
#include <netinet/in.h> /* djani : while porting */
#ifdef LDAP_H_FROM_QA_WKA
#include <proto-ldap.h> /* ldap C-API prototypes */
#endif
#include "port.h" /* Portability definitions */ /*JLS 29-11-00*/
#include "ldclt.h" /* This tool's include file */
#include "remote.h" /* Definitions common with the slave */
enum {SINGLE=0,FIRST,MIDDLE,LAST};
/* ****************************************************************************
FUNCTION : opDecOper
PURPOSE : This function decodes an LDAP operation and return a
printable string.
INPUT : op = operation to decode
OUTPUT : None.
RETURN : The decoded string.
DESCRIPTION :
*****************************************************************************/
char *
opDecOper (
int op)
{
switch (op)
{
case LDAP_REQ_MODIFY: return ("modify"); break;
case LDAP_REQ_ADD: return ("add"); break;
case LDAP_REQ_DELETE: return ("delete"); break;
case LDAP_REQ_MODRDN: return ("modrdn"); break;
default: return ("??unknown??"); break;
}
}
/* ****************************************************************************
FUNCTION : LDAPMod2attributes
PURPOSE : Convert a LDAPMod-like array of attributes to the
internal attributes array.
INPUT : mods = LDAPMod array. If NULL, attribs[] is
initiated as an empty array.
OUTPUT : attribs = struct attribute array. This array is of
MAX_ATTRIBS length.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
LDAPMod2attributes (
LDAPMod **mods,
attribute *attribs)
{
int i; /* For the loop */
/*
* Maybe there is no mods ?? This occurs for rename operation, for example.
*/
if (mods == NULL)
{
attribs[0].type = NULL;
return (0);
}
/*
* Process each entry
*/
for (i=0 ; i< MAX_ATTRIBS && mods[i] != NULL ; i++)
{
attribs[i].type = strdup (mods[i]->mod_type);
if (attribs[i].type == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Error: cannot strdup(attribs[%d].type), error=%d (%s)\n",
i, errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
/*
* Well, if it is a binary value, it is most likely an image
* that is read by mmap and always available. Thus there is no reason
* to copy it, just modify the pointers.
*/
if (mods[i]->mod_op & LDAP_MOD_BVALUES)
{
attribs[i].dontFree = 1;
attribs[i].length = mods[i]->mod_bvalues[0]->bv_len;
attribs[i].value = mods[i]->mod_bvalues[0]->bv_val;
}
else
{
attribs[i].dontFree = 0;
attribs[i].length = strlen (mods[i]->mod_values[0]);
attribs[i].value = strdup (mods[i]->mod_values[0]);
if (attribs[i].value == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Error: cannot strdup(attribs[%d].value), error=%d (%s)\n",
i, errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
}
}
/*
* Don't forget to mark the end !
*/
if (i<MAX_ATTRIBS)
attribs[i].type = NULL;
return (0);
}
/* ****************************************************************************
FUNCTION : freeAttributesArray
PURPOSE : This function is targetted to free an array of
struct attribute. It does not free the array itself,
but only the types and values memorized in it.
INPUT : attribs = array to free.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
freeAttributesArray (
attribute *attribs)
{
int i; /* For the loop */
for (i=0;i<MAX_ATTRIBS&&attribs[i].type != NULL;i++)
{
free (attribs[i].type);
if (!(attribs[i].dontFree))
free (attribs[i].value);
}
return (0);
}
/* ****************************************************************************
FUNCTION : opAdd
PURPOSE : Add a new operation to the list.
INPUT : tttctx = thread context
type = operation type
dn = target's DN
attribs = operation attributes
newRdn = new rdn (valid for rename only)
newParent = new parent (valid for rename only)
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION : Note that the attributes given in argument are
directly memorized (i.e. no copy), hence they should
*not* be freed by the calling function.
*****************************************************************************/
int
opAdd (
thread_context *tttctx,
int type,
char *dn,
LDAPMod **attribs,
char *newRdn,
char *newParent)
{
int ret; /* Return value */
oper *newOper; /* New operation to memorize */
if (mctx.mode & VERY_VERBOSE)
printf ("T%03d: opAdd (%s, %s)\n", tttctx->thrdNum, opDecOper(type), dn);
/*
* Go to protected section. This will enforce the correct sequencing
* of the operations performed because the whole function is lock
* for the threads.
* Note: Maybe reduce the size of this section ? To be checked.
*/
if ((ret = pthread_mutex_lock (&(mctx.opListTail_mutex))) != 0)
{
fprintf (stderr,
"T%03d: cannot pthread_mutex_lock(opListTail), error=%d (%s)\n",
tttctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Create the new cell
*/
newOper = (oper *) malloc (sizeof (oper));
if (newOper == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("T%03d: cannot malloc(newOper), error=%d (%s)\n", /*JLS 06-03-00*/
tttctx->thrdNum, errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
newOper->next = NULL;
newOper->type = type;
newOper->skipped = mctx.slavesNb;
newOper->dn = strdup (dn);
if (newOper->dn == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf("T%03d: cannot strdup(newOper->dn), error=%d (%s)\n",/*JLS 06-03-00*/
tttctx->thrdNum, errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
newOper->newRdn = (newRdn == NULL ? NULL : strdup (newRdn));
if (newOper->newRdn == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("T%03d: cannot strdup(newOper->newRdn), error=%d (%s)\n",
tttctx->thrdNum, errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
newOper->newParent = (newParent == NULL ? NULL : strdup (newParent));
if (newOper->newParent == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("T%03d: cannot strdup(newOper->newParent), error=%d (%s)\n",
tttctx->thrdNum, errno, strerror (errno)); /*JLS 06-03-00*/
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
if (LDAPMod2attributes (attribs, newOper->attribs) < 0)
return (-1);
/*
* Don't forget to initiate this cell's mutex !
*/
if ((ret = pthread_mutex_init(&(newOper->skipped_mutex), NULL)) != 0)
{
fprintf (stderr,
"T%03d: cannot initiate skipped_mutex error=%d (%s)\n",
tttctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Link the cell
*/
mctx.opListTail->next = newOper;
mctx.opListTail = newOper;
/*
* Release the mutex
*/
if ((ret = pthread_mutex_unlock (&(mctx.opListTail_mutex))) != 0)
{
fprintf (stderr,
"T%03d: cannot pthread_mutex_unlock(opListTail), error=%d (%s)\n",
tttctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
return (0);
}
/* ****************************************************************************
FUNCTION : opNext
PURPOSE : Return the next available operation. May return NULL
if no operation available.
INPUT : ctctx = thread context
OUTPUT : op = next operation. May be NULL.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
opNext (
check_context *ctctx,
oper **op)
{
int ret; /* Return value */
oper *newHead; /* The new head operation */
/*
* Maybe there is no new operation ?
*/
if (ctctx->headListOp->next == NULL)
{
*op = NULL;
if (mctx.mode & VERY_VERBOSE)
printf ("C%03d: opNext --> NULL\n", ctctx->thrdNum);
return (0);
}
/*
* Ok, there is one new operation. Let's skip the head and
* go to the new operation...
*/
if ((ret = pthread_mutex_lock (&(ctctx->headListOp->skipped_mutex))) != 0)
{
fprintf (stderr,
"C%03d: cannot pthread_mutex_lock(skipped_mutex), error=%d (%s)\n",
ctctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
newHead = ctctx->headListOp->next;
ctctx->headListOp->skipped--;
/*
* If there is another thread that has not skipped, let's move to the
* next operation and unlock the counter.
*/
if (ctctx->headListOp->skipped != 0)
{
if ((ret = pthread_mutex_unlock (&(ctctx->headListOp->skipped_mutex))) != 0)
{
fprintf (stderr,
"C%03d: cannot pthread_mutex_unlock(skipped_mutex), error=%d (%s)\n",
ctctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
}
else
{
/*
* Well, looks like we are the last thread to skip.... Let's free this
* operation. BTW, there is no reason to unlock/release the mutex because
* it will be destroyed !
* Note: may be NULL when LDAP_REQ_DELETE for example.
*/
if (ctctx->headListOp->attribs != NULL)
if (freeAttributesArray (ctctx->headListOp->attribs) < 0)
return (-1);
if (ctctx->headListOp->dn != NULL)
free (ctctx->headListOp->dn);
if (ctctx->headListOp->newRdn != NULL)
free (ctctx->headListOp->newRdn);
if (ctctx->headListOp->newParent != NULL)
free (ctctx->headListOp->newParent);
free (ctctx->headListOp);
}
/*
* End of function
*/
*op = ctctx->headListOp = newHead;
if (mctx.mode & VERY_VERBOSE)
printf ("C%03d: opNext --> (%s, %s)\n",
ctctx->thrdNum, opDecOper ((*op)->type), (*op)->dn);
return (0);
}
/* ****************************************************************************
FUNCTION : opRead
PURPOSE : Read the n'th operation from the head.
INPUT : ctctx = thread context
num = number of the operation to retrieve
OUTPUT : op = returned operation. May be NULL.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
opRead (
check_context *ctctx,
int num,
oper **op)
{
*op = ctctx->headListOp;
while (num != 0)
{
/*
* Maybe not enough entries in the list ?
*/
if (*op == NULL)
return (0);
*op = (*op)->next;
num--;
}
/*
* If there, we got it :-)
*/
return (0);
}
/* ****************************************************************************
FUNCTION : thOperAdd
PURPOSE : This function copies an operation to the late
operation list
INPUT : head list and operation to copy
OUTPUT : None.
RETURN : New head
DESCRIPTION :
*****************************************************************************/
thoper *
thOperAdd ( thoper *head, oper *elem, int f)
{
thoper *new,*t=head;
int i;
new=malloc(sizeof(thoper));
if (new == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Txxx: cannot malloc(new), error=%d (%s)\n", /*JLS 06-03-00*/
errno, strerror (errno)); /*JLS 06-03-00*/
ldcltExit (1); /*JLS 18-08-00*/
} /*JLS 06-03-00*/
new->next=NULL;
new->first=f;
new->type=elem->type;
new->dn=strdup(elem->dn);
if (elem->newRdn != NULL)
new->newRdn=strdup(elem->newRdn);
if (elem->newParent != NULL)
new->newParent=strdup(elem->newParent);
for(i=0;i<MAX_ATTRIBS&&elem->attribs[i].type;i++)
{
new->attribs[i].type=strdup(elem->attribs[i].type);
if (new->attribs[i].type == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Txxx: cannot strdup(new->attribs[%d].type), error=%d (%s)\n",
errno, i, strerror (errno)); /*JLS 06-03-00*/
ldcltExit (1); /*JLS 18-08-00*/
} /*JLS 06-03-00*/
new->attribs[i].length = elem->attribs[i].length;
if((new->attribs[i].dontFree=elem->attribs[i].dontFree))
new->attribs[i].value = elem->attribs[i].value;
else
{
new->attribs[i].value = strdup(elem->attribs[i].value);
if (new->attribs[i].value == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("Txxx: cannot strdup(new->attribs[%d].value), error=%d (%s)\n",
errno, i, strerror (errno)); /*JLS 06-03-00*/
ldcltExit (1); /*JLS 18-08-00*/
} /*JLS 06-03-00*/
}
}
if(i<MAX_ATTRIBS)
new->attribs[i].type=NULL;
if(head==NULL)
return new;
for(t=head;t->next;)
t=t->next;
t->next=new;
return head;
}
/* ****************************************************************************
FUNCTION : thOperFree
PURPOSE : This function frees memory for a late operation
INPUT : Head of list and operation to delete
OUTPUT : None.
RETURN : new head
DESCRIPTION :
*****************************************************************************/
thoper *
thOperFree (thoper *head, thoper *elem)
{
thoper *t;
freeAttributesArray(elem->attribs);
free (elem->dn);
if (elem->newRdn != NULL)
free (elem->newRdn);
if (elem->newParent != NULL)
free (elem->newParent);
if(head!=elem)
{
for(t=head;t->next!=elem;)
t=t->next;
t->next=t->next->next;
}
else
head = head->next;
free(elem);
return head;
}
/* ****************************************************************************
FUNCTION : opCheckLoop
PURPOSE : This function is the per slave check function
INPUT : arg = this check thread's check_context
OUTPUT : None.
RETURN : None.
DESCRIPTION :
*****************************************************************************/
void *
opCheckLoop ( void* arg)
{
struct check_context *cctx=(struct check_context *)arg;
struct pollfd pfd;
repconfirm *recOper;
oper *myop;
thoper *t;
unsigned char recbuf[1500];
int ret,i,timeout;
int cnt; /* To count loops for timeout purpose */
int fndlt; /* Found late operation */
int nbRead; /* Nb char read() */
int status; /* Thread status */ /*JLS 17-11-00*/
recOper=(repconfirm*)recbuf;
pfd.fd=cctx->sockfd;
pfd.events=(POLLIN|POLLPRI);
pfd.revents=0;
cctx->status=INITIATED;
if((timeout=mctx.timeout)<30)
timeout=30;
/*
* First time in here?
*/
if(cctx->calls==1)
cctx->dcOper=NULL;
while((ret=poll(&pfd,1,500))>=0)
{
if(ret)
{
/*
* Exit if read error on the net
*/
if ((nbRead = read (pfd.fd,recOper,sizeof(repconfirm)))<0)
break;
if (nbRead != sizeof(repconfirm))
printf ("C%03d(%s): Partial header read %d - expected %d\n",cctx->thrdNum, cctx->slaveName, nbRead, sizeof(repconfirm));
recOper->type=ntohl(recOper->type);
recOper->res=ntohl(recOper->res);
recOper->dnSize=ntohl(recOper->dnSize);
/*
* Beware of structure alignment
*/
if((nbRead=read(pfd.fd,recOper->dn+sizeof(recOper->dn),recOper->dnSize))<0)
break;
if (nbRead != recOper->dnSize)
printf ("C%03d(%s): Partial dn read %d - expected %d\n",cctx->thrdNum, cctx->slaveName, nbRead, recOper->dnSize);
if (nbRead > (1500 - sizeof(repconfirm)))
printf ("C%03d(%s): Read too much %d - expected %d\n",cctx->thrdNum, cctx->slaveName, nbRead, 1500 - sizeof(repconfirm));
cnt=0;
cctx->nbOpRecv++;
if(mctx.mode&VERY_VERBOSE)
{
printf("C%03d(%s): Rec %s\n",cctx->thrdNum,cctx->slaveName,recOper->dn);
for(myop=cctx->headListOp->next;myop;myop=myop->next)
printf("C%03d(%s): IN : %s\n",cctx->thrdNum,cctx->slaveName,myop->dn);
for(t=cctx->dcOper;t;t=t->next)
printf("C%03d(%s): LATE : %s\n",cctx->thrdNum,cctx->slaveName,t->dn);
}
/*
* Do not tell me there was an error during replica...
*/
if(recOper->res)
{
printf("C%03d(%s): Replica failed, op:%d(%s), dn=\"%s\" res=%d\n",
cctx->thrdNum, cctx->slaveName,
recOper->type, opDecOper(recOper->type),
recOper->dn, recOper->res );
switch (recOper->res)
{
case 32: cctx->nbRepFail32++ ; break;
case 68: cctx->nbRepFail68++ ; break;
default: cctx->nbRepFailX++ ; break;
}
}
/*
* Is this a late operation?
*/
fndlt=0;
if(cctx->dcOper)
{
for (i=1,t = cctx->dcOper;t;i++)
if ((recOper->type!=t->type) || strcmp(recOper->dn,t->dn))
t = t->next;
else
{
/*
* if this is a single operation: 132456
*/
if(t->first==SINGLE)
{
/*
* error.
*/
printf("C%03d(%s): Late replica: op:%d(%s), dn=\"%s\"\n",
cctx->thrdNum, cctx->slaveName,
t->type, opDecOper(t->type), t->dn );
cctx->nbLate++;
} else if (t->first==MIDDLE)
{
/*
* Middle of a series : 23546
*/
printf("C%03d(%s): Early (%3d) op:%d(%s), dn=\"%s\"\n",
cctx->thrdNum, cctx->slaveName,i,
t->type, opDecOper(t->type), t->dn );
cctx->nbEarly++;
} else if(t->next)
{
/*
* else maybe we are in a re-corrected situation.
* we should receive the next one, now.
*/
if(t->next->first!=LAST)
t->next->first=FIRST;
}
cctx->dcOper = thOperFree (cctx->dcOper, t);
fndlt=1;
break;
}
}
if(!fndlt)
{
/*
* See if the operation we received is the same as the head
*/
opRead(cctx,1,&myop);
if (myop != NULL &&
recOper->type==myop->type &&
strcmp(recOper->dn,myop->dn) == 0)
opNext(cctx,&myop);
else
{
/*
* Nope, look for it
*/
for(i=2;opRead(cctx,i,&myop)==0;i++)
if(myop)
{
if(recOper->type==myop->type &&
strcmp(recOper->dn,myop->dn) == 0)
{
/*
* Skip all between current head and this one
*/
printf("C%03d(%s): Early (%3d) op:%d(%s), dn=\"%s\"\n", cctx->thrdNum,cctx->slaveName, i-1, recOper->type, opDecOper(recOper->type), recOper->dn );
cctx->nbEarly++;
opNext(cctx,&myop);
/*
* mark the first of the series as leader
*/
cctx->dcOper=thOperAdd(cctx->dcOper,myop,
i==2?SINGLE:FIRST);
for(;i>2;i--)
{
opNext(cctx,&myop);
/*
* copy up until one before last
*/
if(myop)
thOperAdd(cctx->dcOper,myop,
i==3?LAST:MIDDLE);
}
opNext(cctx,&myop);
break;
}
} else break;
if(!myop)
{
printf("C%03d(%s): Not on list op:%d(%s), dn=\"%s\"\n", cctx->thrdNum,cctx->slaveName, recOper->type, opDecOper(recOper->type), recOper->dn );
cctx->nbNotOnList++;
}
}
}
}
pfd.events=(POLLIN|POLLPRI);
pfd.revents=0;
/*
* operations threads still running?
*/
for(i=0;i<mctx.nbThreads;i++)
{ /*JLS 17-11-00*/
if (getThreadStatus (&(tctx[i]), &status) < 0) /*JLS 17-11-00*/
break; /*JLS 17-11-00*/
if(status != DEAD) /*JLS 17-11-00*/
{
cnt=0;
break;
}
} /*JLS 17-11-00*/
/*
* twice half a second...
*/
if(++cnt>timeout*2)
break;
}
if(mctx.mode&VERY_VERBOSE)
printf("C%03d(%s): Exiting\n",cctx->thrdNum,cctx->slaveName);
/*
* Any operation left?
*/
for(opNext(cctx,&myop);myop;opNext(cctx,&myop))
{
printf("Operation %d(%s) still on Queue for %s (%s)\n",myop->type,opDecOper(myop->type),cctx->slaveName,myop->dn);
cctx->nbStillOnQ++;
}
for(t=cctx->dcOper;t;t=t->next)
{
printf("Lost op %d(%s) on %s (%s)\n",t->type,opDecOper(t->type),cctx->slaveName,t->dn);
cctx->nbLostOp++;
}
close(cctx->sockfd);
cctx->status=DEAD;
pthread_exit(NULL);
}
/* ****************************************************************************
FUNCTION : opCheckMain
PURPOSE : This function is the main function of the check
operation threads,
INPUT : arg = NULL
OUTPUT : None.
RETURN : None.
DESCRIPTION :
*****************************************************************************/
void *
opCheckMain (
void *arg)
{
struct sockaddr_in srvsaddr,claddr;
struct hostent cltaddr;
#ifdef LINUX
struct hostent *stupidlinux=NULL;
#endif
#ifdef AIX
struct hostent_data stupidaix;
#endif
struct linger lopt;
uint32_t ipaddr;
int newfd,sockfd,ncctx,i,err;
char buffer[128];
int retry; /* To retry on EINTR */
/*
* Initialization
*/
srvsaddr.sin_addr.s_addr=htonl(INADDR_ANY);
srvsaddr.sin_family=AF_INET;
srvsaddr.sin_port=htons(masterPort);
/*
* Let's go !!!
*/
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("Socket");
ldcltExit(1); /*JLS 18-08-00*/
}
i=1;
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(void *)&i,sizeof(int))!=0)
perror("Sockopt");
if(bind(sockfd,(struct sockaddr*)&srvsaddr,sizeof(struct sockaddr))!=0)
{
perror("Bind");
ldcltExit(1); /*JLS 18-08-00*/
}
if(listen(sockfd,1)!=0)
perror("listen");
for(ncctx=0;;)
{
i=sizeof(claddr);
retry = 1;
while (retry)
{
#ifdef AIX
if ((newfd=accept(sockfd,(struct sockaddr *)&claddr,(unsigned long *)&i))>=0)
#else
if ((newfd=accept(sockfd,(struct sockaddr *)&claddr,&i))>=0)
#endif
retry = 0;
else
if (errno != EINTR)
{
perror("Accept");
ldcltExit(1); /*JLS 18-08-00*/
}
}
/*
* get client's name
*/
ipaddr=ntohl(claddr.sin_addr.s_addr);
#ifdef AIX
gethostbyaddr_r((char*)&ipaddr,sizeof(ipaddr),AF_INET,&cltaddr,
&stupidaix);
#else
#ifdef LINUX
gethostbyaddr_r((char*)&ipaddr,sizeof(ipaddr),AF_INET,&cltaddr,
buffer,128, &stupidlinux, &err);
#else
#if defined(HPUX) && defined(__LP64__)
gethostbyaddr((char*)&ipaddr,sizeof(ipaddr),AF_INET);
#else
gethostbyaddr_r((char*)&ipaddr,sizeof(ipaddr),AF_INET,&cltaddr,
buffer,128,&err);
#endif
#endif
#endif
i=1;
if(setsockopt(newfd,IPPROTO_TCP, TCP_NODELAY,(void *)&i,sizeof(int))!=0)
perror("Nagle");
/*
* Linger: when connection ends, send an RST instead of a FIN
* This way the client will have a fail on the first write instead of
* the second
*/
lopt.l_onoff=1;
lopt.l_linger=0;
if(setsockopt(newfd,SOL_SOCKET,SO_LINGER,(void*)&lopt,sizeof(struct linger))<0)
perror("Linger");
/*
* Search for an empty client slot. If a client reconnects, use the
* same slot
*/
for(i=0;i<mctx.slavesNb;i++)
{
if(cctx[i].calls==0)
{
i=ncctx++;
break;
}
if(cctx[i].slaveName&&cctx[i].status==DEAD)
if(strcmp(cctx[i].slaveName,cltaddr.h_name)==0)
break;
}
if(i>=mctx.slavesNb)
{
fprintf (stderr, "ldclt: Too many slaves %s\n",cltaddr.h_name);
close(newfd);
continue;
}
cctx[i].sockfd=newfd;
cctx[i].calls++;
cctx[i].slaveName=strdup(cltaddr.h_name);
if ((err = pthread_create (&(cctx[i].tid), NULL,
opCheckLoop, (void *)&(cctx[i]))) != 0)
{
fprintf (stderr, "ldclt: %s\n", strerror (err));
fprintf (stderr, "Error: cannot create thread opCheck for %s\n",
cltaddr.h_name);
fflush (stderr);
}
else
mctx.slaveConn = 1;
}
close(sockfd);
}
/* End of file */
--- NEW FILE parser.c ---
#ident "@(#)parser.c 1.5 01/04/11"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : parser.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 19 March 2001
DESCRIPTION :
This file contains the parser functions of ldclt
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
19/03/01 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
21/03/01 | JL Schwing | 1.2 : Implements variables in "-e object=filename"
---------+--------------+------------------------------------------------------
23/03/01 | JL Schwing | 1.3 : Implements data file list support in variants.
| Bug fix : close the file !
| Implements "-e rdn=value".
---------+--------------+------------------------------------------------------
28/03/01 | JL Schwing | 1.4 : Support -e commoncounter with -e rdn/object
---------+--------------+------------------------------------------------------
11/04/01 | JL Schwing | 1.5 : Implement [INCRFROMFILE<NOLOOP>(myfile)]
| Improved error message.
---------+--------------+------------------------------------------------------
*/
#include <stdio.h> /* printf(), etc... */
#include <string.h> /* strcpy(), etc... */
#include <errno.h> /* errno, etc... */
#include <stdlib.h> /* malloc(), etc... */
#include <lber.h> /* ldap C-API BER declarations */
#include <ldap.h> /* ldap C-API declarations */
#ifdef LDAP_H_FROM_QA_WKA
#include <proto-ldap.h> /* ldap C-API prototypes */
#endif
#ifndef _WIN32
#include <unistd.h> /* close(), etc... */
#include <pthread.h> /* pthreads(), etc... */
#endif
#include "port.h" /* Portability definitions */
#include "ldclt.h" /* This tool's include file */
#include "utils.h" /* Utilities functions */
/* ****************************************************************************
FUNCTION : decodeHow
PURPOSE : Decode the how field
INPUT : how = field to decode
OUTPUT : None.
RETURN : -1 if error, how value else.
DESCRIPTION :
*****************************************************************************/
int
decodeHow (
char *how)
{
if (mctx.mode & VERY_VERBOSE)
printf ("decodeHow: how=\"%s\"\n", how);
if (!strcmp (how, "INCRFROMFILE")) return (HOW_INCR_FROM_FILE);
if (!strcmp (how, "INCRFROMFILENOLOOP")) return (HOW_INCR_FROM_FILE_NL);
if (!strcmp (how, "INCRN")) return (HOW_INCR_NB);
if (!strcmp (how, "INCRNNOLOOP")) return (HOW_INCR_NB_NOLOOP);
if (!strcmp (how, "RNDFROMFILE")) return (HOW_RND_FROM_FILE);
if (!strcmp (how, "RNDN")) return (HOW_RND_NUMBER);
if (!strcmp (how, "RNDS")) return (HOW_RND_STRING);
return (-1);
}
/* ****************************************************************************
FUNCTION : parseVariant
PURPOSE : Parse a variant definition.
INPUT : variant = string to parse
fname = file name
line = source line
obj = object we are parsing and building
OUTPUT : field = field parsed
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
parseVariant (
char *variant,
char *fname,
char *line,
vers_object *obj,
vers_field *field)
{
int start, end; /* For the loops */
char how[MAX_FILTER]; /* To parse the variant : */
char first[MAX_FILTER]; /* how(first) */
char second[MAX_FILTER]; /* how(first,second) */
char third[MAX_FILTER]; /* how(first,second,third) */
int ret; /* ldclt_mutex_init() return value */
if (mctx.mode & VERY_VERBOSE)
printf ("parseVariant: variant=\"%s\"\n", variant);
/*
* Maybe a variable ?
*/
if (variant[1] == '\0')
{
if ((variant[0] < VAR_MIN) || (variant[0] > VAR_MAX))
{
fprintf (stderr, "Error: bad variable in %s : \"%s\"\n", fname, line);
fprintf (stderr, "Error: must be in [%c-%c]\n", VAR_MIN, VAR_MAX);
return (-1);
}
field->how = HOW_VARIABLE;
field->var = variant[0] - VAR_MIN;
return (0);
}
/*
* Maybe a variable definition ?
*/
if (variant[1] != '=')
field->var = -1;
else
{
if ((variant[0] < VAR_MIN) || (variant[0] > VAR_MAX))
{
fprintf (stderr, "Error: bad variable in %s : \"%s\"\n", fname, line);
fprintf (stderr, "Error: must be in [%c-%c]\n", VAR_MIN, VAR_MAX);
return (-1);
}
field->var = variant[0] - VAR_MIN;
variant++; /* Skip variable name */
variant++; /* Skip '=' */
/*
* We need a variable !
*/
if (obj->var[field->var] == NULL)
obj->var[field->var] = (char *) malloc (MAX_FILTER);
}
/*
* Find how definition
*/
for (end=0 ; (variant[end]!='\0') && (variant[end]!='(') ; end++);
if (variant[end]=='\0')
{
fprintf (stderr, "Error: bad variant in %s : \"%s\"\n", fname, line);
fprintf (stderr, "Error: missing '('\n");
return (-1);
}
strncpy (how, variant, end);
how[end] = '\0';
/*
* Parse the first parameter
*/
end++; /* Skip '(' */
for (start=end ; (variant[end]!='\0') && (variant[end]!=';')
&& (variant[end]!=')') ; end++);
if (variant[end]=='\0')
{
fprintf (stderr, "Error: bad variant in %s : \"%s\"\n", fname, line);
fprintf (stderr, "Error: missing ')'\n");
return (-1);
}
strncpy (first, variant+start, end-start);
first[end-start] = '\0';
/*
* Parse the second parameter
*/
if (variant[end] == ')')
second[0] = '\0';
else
{
end++; /* Skip ';' */
for (start=end ; (variant[end]!='\0') && (variant[end]!=';')
&& (variant[end]!=')') ; end++);
if (variant[end]=='\0')
{
fprintf (stderr, "Error: bad variant in %s : \"%s\"\n", fname, line);
fprintf (stderr, "Error: missing ')'\n");
return (-1);
}
strncpy (second, variant+start, end-start);
second[end-start] = '\0';
}
/*
* Parse the third parameter
*/
if (variant[end]==')')
third[0]='\0';
else
{
end++; /* Skip ';' */
for (start=end ; (variant[end]!='\0') && (variant[end]!=')') ; end++);
if (variant[end]=='\0')
{
fprintf (stderr, "Error: bad variant in %s : \"%s\"\n", fname, line);
fprintf (stderr, "Error: missing ')'\n");
return (-1);
}
strncpy (third, variant+start, end-start);
third[end-start] = '\0';
}
/*
* Analyse it
* Note : first parameter always exist (detected when parsing) while
* second and third may not have been provided by the user.
*/
switch (field->how = decodeHow (how))
{
case HOW_INCR_FROM_FILE:
case HOW_INCR_FROM_FILE_NL:
case HOW_RND_FROM_FILE:
if ((field->dlf = dataListFile (first)) == NULL)
{
fprintf (stderr, "Error : bad file in %s : \"%s\"\n", fname, line);
return (-1);
}
/*
* Useless for HOW_RND_FROM_FILE
*/
field->cnt = 0;
field->low = 0;
field->high = field->dlf->strNb - 1;
/*
* Maybe common counter ?
*/
if ((mctx.mode & COMMON_COUNTER) &&
((field->how == HOW_INCR_FROM_FILE) ||
(field->how == HOW_INCR_FROM_FILE_NL)))
{
if ((ret = ldclt_mutex_init (&(field->cnt_mutex))) != 0)
{
fprintf (stderr, "ldclt: %s\n", strerror (ret));
fprintf (stderr, "Error: cannot initiate cnt_mutex in %s for %s\n",
fname, line);
fflush (stderr);
return (-1);
}
}
break;
case HOW_INCR_NB:
case HOW_INCR_NB_NOLOOP:
case HOW_RND_NUMBER:
if (third[0] == '\0')
{
fprintf (stderr, "Error : missing parameters in %s : \"%s\"\n",
fname, line);
return (-1);
}
field->cnt = atoi (first);
field->low = atoi (first);
field->high = atoi (second);
field->nb = atoi (third);
/*
* Maybe common counter ?
*/
if ((mctx.mode & COMMON_COUNTER) &&
((field->how == HOW_INCR_NB) || (field->how == HOW_INCR_NB_NOLOOP)))
{
if ((ret = ldclt_mutex_init (&(field->cnt_mutex))) != 0)
{
fprintf (stderr, "ldclt: %s\n", strerror (ret));
fprintf (stderr, "Error: cannot initiate cnt_mutex in %s for %s\n",
fname, line);
fflush (stderr);
return (-1);
}
}
break;
case HOW_RND_STRING:
field->nb = atoi (first);
break;
case -1:
fprintf (stderr, "Error: illegal keyword \"%s\" in %s : \"%s\"\n",
how, fname, line);
return (-1);
break;
}
return (0);
}
/* ****************************************************************************
FUNCTION : parseAttribValue
PURPOSE : Parse the right part of attribname: attribvalue.
INPUT : fname = file name
obj = object where variables are.
line = value to parse.
OUTPUT : attrib = attribute where the value should be stored
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
parseAttribValue (
char *fname,
vers_object *obj,
char *line,
vers_attribute *attrib)
{
char variant[MAX_FILTER]; /* To process the variant */
int start, end; /* For the loops */
vers_field *field; /* To build the fields */
if (mctx.mode & VERY_VERBOSE)
printf ("parseAttribValue: line=\"%s\"\n", line);
/*
* We will now parse this line for the different fields.
*/
field = NULL;
end = start = 0;
while (line[end]!='\0')
{
/*
* Allocate a new field
*/
if (field == NULL)
{
field = (vers_field *) malloc (sizeof (vers_field));
field->next = NULL;
attrib->field = field;
}
else
{
field->next = (vers_field *) malloc (sizeof (vers_field));
field = field->next;
field->next = NULL;
}
/*
* Is it a variant field ?
*/
if (line[end] == '[')
{
/*
* Extract the variant definition
*/
end++; /* Skip '[' */
for (start=end ; (line[end]!='\0') && (line[end]!=']') ; end++);
strncpy (variant, line+start, end-start);
variant[end-start] = '\0';
if (line[end]=='\0')
{
fprintf (stderr, "Error: missing ']' in %s : \"%s\"\n", fname, line);
return (-1);
}
if (parseVariant (variant, fname, line, obj, field) < 0)
return (-1);
end++; /* Skip ']' */
/*
* We need to allocate a buffer in this attribute !
*/
if (attrib->buf == NULL)
{
attrib->buf = (char *) malloc (MAX_FILTER);
if (mctx.mode & VERY_VERBOSE)
printf ("parseAttribValue: buffer allocated\n");
}
}
else
{
/*
* It is a constant field. Find the end : [ or \0
*/
for (start=end ; (line[end]!='\0') && (line[end]!='[') ; end++);
field->how = HOW_CONSTANT;
field->cst = (char *) malloc (1+end-start);
strncpy (field->cst, line+start, end-start);
field->cst[end-start] = '\0';
}
}
/*
* Attribute value is parsed !
*/
return (0);
}
/* ****************************************************************************
FUNCTION : parseLine
PURPOSE : Parse the given line to find an attribute definition.
INPUT : line = line to parse
fname = file name
OUTPUT : obj = object where the attribute should be added
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
parseLine (
char *line,
char *fname,
vers_object *obj)
{
int end; /* For the loops */
if (mctx.mode & VERY_VERBOSE)
printf ("parseLine: line=\"%s\"\n", line);
/*
* Empty line ? Comment ?
* No more place for new attributes ?
*/
if ((line[0]=='\0') || (line[0]=='#'))
return (0);
if (obj->attribsNb == MAX_ATTRIBS)
{
fprintf (stderr, "Error: too many attributes in %s, max is %d\n",
fname, MAX_ATTRIBS);
return (-1);
}
/*
* Find the attribute name
* name:
*/
for (end=0 ; (line[end]!='\0') && (line[end]!=':') ; end++);
if (line[end]!=':')
{
fprintf (stderr, "Error: can't find attribute name in %s : \"%s\"\n",
fname, line);
return (-1);
}
/*
* Initiate the attribute
*/
obj->attribs[obj->attribsNb].buf = NULL;
obj->attribs[obj->attribsNb].src = strdup (line);
obj->attribs[obj->attribsNb].name = (char *) malloc (1+end);
strncpy (obj->attribs[obj->attribsNb].name, line, end);
obj->attribs[obj->attribsNb].name[end] = '\0';
for (end++ ; line[end]==' ' ; end++); /* Skip the leading ' ' */
/*
* We will now parse the value of this attribute
*/
if (parseAttribValue(fname,obj, line+end, &(obj->attribs[obj->attribsNb]))<0)
return (-1);
/*
* Do not forget to increment attributes number !
*/
obj->attribsNb++;
return (0);
}
/* ****************************************************************************
FUNCTION : readObject
PURPOSE : This function will read an object description from the
file given in argument.
The object should be already initiated !!!
INPUT : None.
OUTPUT : obj = parsed object.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
readObject (
vers_object *obj)
{
FILE *ifile; /* The file that contains the object to read */
char line[MAX_FILTER]; /* To read ifile */
/*
* Open the file
*/
ifile = fopen (obj->fname, "r");
if (ifile == NULL)
{
perror (obj->fname);
fprintf (stderr, "Error: cannot open file \"%s\"\n", obj->fname);
return (-1);
}
/*
* Process each line of the input file.
* Reminder : the object is initiated by the calling function !
*/
while (fgets (line, MAX_FILTER, ifile) != NULL)
{
if ((strlen (line) > 0) && (line[strlen(line)-1]=='\n'))
line[strlen(line)-1] = '\0';
if (parseLine (line, obj->fname, obj) < 0)
return (-1);
}
/*
* Do not forget to close the file !
*/
if (fclose (ifile) != 0)
{
perror (obj->fname);
fprintf (stderr, "Error: cannot fclose file \"%s\"\n", obj->fname);
return (-1);
}
/*
* End of function
*/
if (obj->attribsNb == 0)
{
fprintf (stderr, "Error: no object found in \"%s\"\n", obj->fname);
return (-1);
}
return (0);
}
/* End of file */
--- NEW FILE port.c ---
#ident "ldclt @(#)port.c 1.2 01/03/14"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : port.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 28 November 2000
DESCRIPTION :
This file contains platform-independant version of
common (unix) functions in order to have portable
source code for either unix and windows platforms.
It is greatly inspired from iPlanet DS 5.0 workspace.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
28/11/00 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.2 : Lint cleanup.
---------+--------------+------------------------------------------------------
*/
#include <stdio.h> /* EOF, etc... */
#ifdef _WIN32
#include <windows.h>
#include <winbase.h>
#else
#include <unistd.h> /* sleep(), etc... */ /*JLS 14-03-01*/
#include <pthread.h> /* pthreads(), etc... */
#endif
#include "port.h"
/************************************************************************/
/************************************************************************/
/**************** NT section ***********************/
/************************************************************************/
/************************************************************************/
#ifdef _WIN32
int
ldclt_mutex_init (
ldclt_mutex_t *mutex)
{
InitializeCriticalSection (mutex);
return (0);
}
int
ldclt_mutex_lock (
ldclt_mutex_t *mutex)
{
EnterCriticalSection(mutex);
return (0);
}
int
ldclt_mutex_unlock (
ldclt_mutex_t *mutex)
{
LeaveCriticalSection (mutex);
return (0);
}
void
ldclt_sleep (
int nseconds)
{
Sleep (1000 * nseconds);
}
int
ldclt_thread_create (
ldclt_tid *tid,
void *fct,
void *param)
{
CreateThread (NULL, 0, fct, param, 0, tid);
return (0);
}
long
lrand48 (void)
{
return ((rand()<<8)+rand());
}
/*
* Implements the Unix getopt function for NT systems
*/
char *optarg;
int optind;
int
getopt (
int argc,
char **argv,
char *optstring)
{
static char **prevArgv = NULL; /* Memorize argv to parse */
static int inOption; /* In option parsing ? */
static int cNum; /* Current char num */
int c; /* Current char */
int i; /* Loops */
/*
* Initialization - maybe the first time this function is called ?
*/
if (prevArgv != argv)
{
prevArgv = argv;
optind = 0;
inOption = 0;
}
/*
* Maybe we processed the last chars of the option in the previous call
*/
if (inOption)
{
if (argv[optind][cNum] == '\0')
inOption = 0;
}
/*
* Maybe we should look for '-'
*/
if (!inOption)
{
optind++; /* Next option */
if (optind == argc) /* No more option */
return (EOF);
if (argv[optind][0] != '-') /* Not an option */
return (EOF);
if (argv[optind][1] == '\0') /* Only '-' */
return (EOF);
cNum = 1; /* Next char to process */
inOption = 0; /* We are in an option */
}
/*
* See if this is a valid option
*/
c = argv[optind][cNum];
for (i=0 ; (i<strlen(optstring)) && (c!=optstring[i]) ; i++);
if (c != optstring[i]) /* Not an option */
return ('?');
cNum++; /* Next char */
/*
* Check if this option requires an argument
* Note that for the last char of optstring, it is a valid '\0' != ':'
*/
if (optstring[i+1] != ':') /* No argument */
return (c);
/*
* Need an argument...
* The argument is either the end of argv[optind] or argv[++optind]
*/
if (argv[optind][cNum] == '\0') /* Must return next argument */
{
optind++; /* Next argument */
if (optind == argc) /* There is no next argument */
{
printf ("%s: option requires an argument -- %c\n", argv[0], c);
return ('?');
}
optarg = argv[optind]; /* Set optarg to teh argument argv[] */
inOption = 0; /* No more in option... */
return (c);
}
/*
* Return the end of the current argv[optind]
*/
optarg = &(argv[optind][cNum]); /* End of argv[optind] */
inOption = 0; /* No more in option */
return (c);
}
/*
* Implement the Unix getsubopt function for NT systems
*/
int
getsubopt(
char **optionp,
char **tokens,
char **valuep)
{
int i; /* Loops */
char *curOpt; /* Current optionp */
curOpt = *optionp; /* Begin of current option */
/*
* Find the end of the current option
*/
for (i=0 ; (curOpt[i]!='\0') && (curOpt[i]!=',') ; i++);
if (curOpt[i] == '\0')
*optionp = &(curOpt[i]);
else
*optionp = &(curOpt[i+1]);
curOpt[i] = '\0'; /* Do not forget to end this string */
/*
* Find if there is a subvalue for this option
*/
for (i=0 ; (curOpt[i]!='\0') && (curOpt[i]!='=') ; i++);
if (curOpt[i] == '\0')
*valuep = &(curOpt[i]);
else
*valuep = &(curOpt[i+1]);
curOpt[i] = '\0'; /* Do not forget to end this string */
/*
* Find if this option is valid...
*/
for (i=0 ; tokens[i] != NULL ; i++)
if (!strcmp (curOpt, tokens[i]))
return (i);
/*
* Not found...
*/
return (-1);
}
#else /* NT 4 */
/************************************************************************/
/************************************************************************/
/**************** Unix section ***********************/
/************************************************************************/
/************************************************************************/
int
ldclt_mutex_init (
ldclt_mutex_t *mutex)
{
return (pthread_mutex_init (mutex, NULL));
}
int
ldclt_mutex_lock (
ldclt_mutex_t *mutex)
{
return (pthread_mutex_lock (mutex));
}
int
ldclt_mutex_unlock (
ldclt_mutex_t *mutex)
{
return (pthread_mutex_unlock (mutex));
}
void
ldclt_sleep (
int nseconds)
{
sleep (nseconds);
}
int
ldclt_thread_create (
ldclt_tid *tid,
void *(*fct)(void *),
void *param)
{
return (pthread_create (tid, NULL, fct, param));
}
#endif /* _WIN32 */
/* End of file */
--- NEW FILE port.h ---
#ident "ldclt @(#)port.h 1.4 01/04/03"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : port.h
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 28 November 2000
DESCRIPTION :
This file contains the include (interface) definitions
of port.c
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
28/11/00 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.2 : Port on Linux.
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.3 : Port on HP-UX.
---------+--------------+------------------------------------------------------
03/04/01 | JL Schwing | 1.4 : Linux large file issue...
---------+--------------+------------------------------------------------------
*/
/*
* Tuning of the code
*/
#ifdef AIX /*JLS 01-12-00*/
#define LDCLT_CAST_SIGACTION 1 /*JLS 01-12-00*/
#endif /*JLS 01-12-00*/
#ifdef HPUX /*JLS 01-12-00*/
#define LDCLT_CAST_SIGACTION 1 /*JLS 01-12-00*/
#define LDCLT_NO_DLOPEN 1 /*JLS 01-12-00*/
#endif /*JLS 01-12-00*/
#ifdef LINUX /*JLS 01-12-00*/
#define LDCLT_CAST_SIGACTION 1 /*JLS 01-12-00*/
#ifndef O_LARGEFILE /*JLS 03-04-01*/
# define O_LARGEFILE 0100000 /*JLS 03-04-01*/
#endif /*JLS 03-04-01*/
#endif /*JLS 01-12-00*/
#ifdef _WIN32 /*JLS 01-12-00*/
#define LDCLT_NO_DLOPEN 1 /*JLS 01-12-00*/
#endif /*JLS 01-12-00*/
/************************************************************************/
/************************************************************************/
/**************** NT section ***********************/
/************************************************************************/
/************************************************************************/
#ifdef _WIN32
typedef CRITICAL_SECTION ldclt_mutex_t;
typedef DWORD ldclt_tid;
extern int getopt (int argc, char **argv, char *optstring);
extern int getsubopt(char **optionp, char **tokens, char **valuep);
extern long lrand48 (void);
extern char *optarg;
extern int optind;
#else /* _WIN32 */
extern int getsubopt(char **optionp, char **tokens, char **valuep);
/************************************************************************/
/************************************************************************/
/**************** Unix section ***********************/
/************************************************************************/
/************************************************************************/
typedef pthread_mutex_t ldclt_mutex_t;
typedef pthread_t ldclt_tid;
#endif /* _WIN32 */
/*
* Portability functions common to all platforms
*/
extern int ldclt_mutex_init (ldclt_mutex_t *mutex);
extern int ldclt_mutex_lock (ldclt_mutex_t *mutex);
extern int ldclt_mutex_unlock (ldclt_mutex_t *mutex);
extern void ldclt_sleep (int nseconds);
extern int ldclt_thread_create (ldclt_tid *tid, void *(*fct)(void *), void *param);
/* End of file */
--- NEW FILE remote.h ---
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : remote.h
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 04 May 1999
DESCRIPTION :
This file contains the definitions used by the remote
control module of ldclt.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
05/05/99 | F. Pistolesi | 1.3 : Implements communication with remote part.
---------+--------------+------------------------------------------------------
06/05/99 | JL Schwing | 1.4 : Port on Solaris 2.5.1
---------+--------------+------------------------------------------------------
*/
/*
* Network includes
*/
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef OSF1
#ifndef _UINT32_T
#define _UINT32_T
typedef unsigned long uint32_t;
#endif /* _UINT32_T */
#else /* OS_RELEASE */
#include <inttypes.h>
#endif /* OS_RELEASE */
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
typedef struct {
uint32_t type,res,dnSize;
char dn[sizeof(uint32_t)];
} repconfirm;
extern int masterPort;
/* End of file */
--- NEW FILE repcheck.c ---
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <signal.h>
#include "remote.h"
#include "lber.h"
#include "ldap.h"
enum {ADD,DELETE,MODRDN,MODIFY,RESULT};
typedef struct {
int conn,op,type;
char *dn;
} Optype;
Optype *pendops;
int npend,maxop,connected;
char *ldap_ops[]={"ADD","DEL","MODRDN","MOD ","RESULT",NULL};
int ldap_val[]={LDAP_REQ_ADD,LDAP_REQ_DELETE,LDAP_REQ_MODRDN,LDAP_REQ_MODIFY};
get_op_par(char *s,Optype *op)
{
char *t;
int i;
t=strstr(s,"conn=");
for(t+=5,op->conn=0;isdigit(*t);t++)
op->conn=op->conn*10+*t-'0';
t=strstr(s,"op=");
for(t+=3,op->op=0;isdigit(*t);t++)
op->op=op->op*10+*t-'0';
if(t=strstr(s,"dn="))
op->dn=strdup(t+3);
}
send_op(char* s,int sfd)
{
int sz,i;
Optype tmp;
repconfirm *result;
char *t;
get_op_par(s,&tmp);
for(i=0;i<maxop;i++)
if(pendops[i].op==tmp.op && pendops[i].conn==tmp.conn){
t=strstr(s,"err=");
sz=strlen(pendops[i].dn);
result=(repconfirm*)malloc(sizeof(repconfirm)+sz);
for(t+=4,result->res=0;isdigit(*t);t++)
result->res=result->res*10+*t-'0';
result->type=htonl(ldap_val[pendops[i].type]);
strcpy(result->dn,pendops[i].dn);
result->dnSize=htonl(sz);
result->res=htonl(result->res);
if(write(sfd,result,sizeof(repconfirm)+sz)<=0){
close(sfd);
memset(pendops,0,maxop*sizeof(Optype));
maxop=npend=connected=0;
return;
}
if(i!=maxop)
pendops[i]=pendops[maxop];
else memset(pendops+i,0,sizeof(Optype));
return;
}
}
main(int argc, char**argv)
{
int i,port=16000;
int sockfd;
static char logline[512];
char **tmp;
struct hostent *serveraddr;
struct sockaddr_in srvsaddr;
while((i=getopt(argc,argv,"p:"))!=EOF){
switch(i){
case 'p': port=atoi(optarg);
break;
}
}
serveraddr=gethostbyname(argv[optind]);
srvsaddr.sin_addr.s_addr=htonl(*((u_long*)(serveraddr->h_addr_list[0])));
srvsaddr.sin_family=AF_INET;
srvsaddr.sin_port=htons(port);
maxop=npend=0;
pendops=(Optype*)malloc(sizeof(Optype)*20);
sigset(SIGPIPE,SIG_IGN);
while(gets(logline)){
if(!connected){
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror(argv[0]);
exit(1);
}
i=1;
if(setsockopt(sockfd,IPPROTO_TCP, TCP_NODELAY,&i,sizeof(int))!=0)
perror("Nagle");
if(connect(sockfd,(struct sockaddr*)&srvsaddr,sizeof(struct sockaddr))!=-1)
connected=1;
else {
close(sockfd);
continue;
}
}
for(tmp=ldap_ops,i=0;tmp[i];i++)
if(strstr(logline,tmp[i]))
break;
if(i<RESULT){
get_op_par(logline,&pendops[maxop]);
pendops[maxop].type=i;
if(++maxop>npend)
npend=maxop;
if(!(npend%20)){
pendops=(Optype*)realloc(pendops,sizeof(Optype)*(npend+20));
memset(pendops+npend,0,sizeof(Optype)*20);
}
}
if(i==RESULT)
send_op(logline,sockfd);
}
close(sockfd);
}
--- NEW FILE repslave.c ---
#ident "@(#)repslave.c 1.15 99/06/09"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : repslave.c
AUTHOR : Fabio Pistolesi
VERSION : 1.0
DATE : 05 May 1999
DESCRIPTION :
This file contains the implementation of the slave part
of ldclt tool. This slave is intended to scan the logs
of the ldap server and to communicate the operations
logged to the master ldclt, to be checked against the
memorized operations performed on the master ldap
server.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
05/05/99 | F. Pistolesi | Creation
---------+--------------+------------------------------------------------------
06/05/99 | JL Schwing | 1.2 : Port on Solaris 2.5.1
---------+--------------+------------------------------------------------------
10/05/99 | F. Pistolesi | Added multiple filtered servers to send results to.
---------+--------------+------------------------------------------------------
18/05/99 | JL Schwing | 1.8 : Port on 2.5.1
---------+--------------+------------------------------------------------------
26/05/99 | F. Pistolesi | 1.10: Bug fix - missing free()
---------+--------------+------------------------------------------------------
27/05/99 | F. Pistolesi | 1.11: Add new option -d (debug)
---------+--------------+------------------------------------------------------
29/05/99 | F. Pistolesi | 1.12: Add new option -t (log)
---------+--------------+------------------------------------------------------
09/06/99 | JL Schwing | 1.14: Bug fix - crash in send_op() if tmp.dn==NULL
---------+--------------+------------------------------------------------------
09/06/99 | F. Pistolesi | 1.15: Fix the fix above.
---------+--------------+------------------------------------------------------
*/
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <signal.h>
#include <libgen.h>
#if OS_RELEASE == 551
#include <re_comp.h>
#endif
#include "remote.h"
#include "lber.h"
#include "ldap.h"
/*
* Enumeration for internal list
*/
enum {ADD,DELETE,MODRDN,MODIFY,RESULT,LAST};
/*
* internal list
*/
typedef struct {
int conn,op,type;
char *dn;
} Optype;
typedef struct {
int fd;
char *filter,*hname;
struct sockaddr_in addr;
} Towho;
Optype *pendops;
Towho *srvlist;
int npend,maxop,connected,nsrv,debug;
char *ldap_ops[]={"ADD","DEL","MODRDN","MOD ","RESULT","NONE",NULL};
/*
* To map internal values to LDAP_REQ
*/
int ldap_val[]={LDAP_REQ_ADD,LDAP_REQ_DELETE,LDAP_REQ_MODRDN,LDAP_REQ_MODIFY};
get_op_par(char *s,Optype *op)
{
char *t;
int i;
/*
* Provided they do not change dsservd's log format, this should work
* Magic numbers are the length of the lookup string
*/
t=strstr(s,"conn=");
for(t+=5,op->conn=0;isdigit(*t);t++)
op->conn=op->conn*10+*t-'0';
t=strstr(s,"op=");
for(t+=3,op->op=0;isdigit(*t);t++)
op->op=op->op*10+*t-'0';
if(t=strstr(s,"dn="))
op->dn=strdup(t+3);
}
open_cnx(struct sockaddr *srv)
{
int i,sockfd;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("Slave");
exit(1);
}
i=1;
/*
* Disable TCP's Nagle algorithm
*/
if(setsockopt(sockfd,IPPROTO_TCP, TCP_NODELAY,(void *)&i,sizeof(int))!=0)
perror("Nagle");
if(connect(sockfd,srv,sizeof(struct sockaddr))!=-1)
return sockfd;
else close(sockfd);
return -1;
}
send_op(char* s)
{
int sz,i,j,ret;
Optype tmp;
repconfirm *result;
char *t;
struct pollfd pfd;
get_op_par(s,&tmp);
for(i=0;i<maxop;i++)
/*
* got a RESULT string. Try to match with known operations.
*/
if(pendops[i].op==tmp.op && pendops[i].conn==tmp.conn)
{
sz=strlen(pendops[i].dn);
result=(repconfirm*)malloc(sizeof(repconfirm)+sz);
t=strstr(s,"err=");
for(t+=4,result->res=0;isdigit(*t);t++)
result->res=result->res*10+*t-'0';
/*
* Build packet
*/
result->type=htonl(ldap_val[pendops[i].type]);
strcpy(result->dn,pendops[i].dn+1);
sz-=2;
result->dn[sz]='\0';
result->dnSize=htonl(sz);
if(debug)
printf("Sending %d %d %s\n",ntohl(result->type),result->res,result->dn);
result->res=htonl(result->res);
/*
* find which filter applies. Note that if no filter applies, no
* packets are sent
*/
for(j=0;j<nsrv;j++)
{
/*
* Suppose a NULL filter means everything
*/
if(srvlist[j].filter)
if(regex(srvlist[j].filter,result->dn)==NULL)
continue;
/*
* try to write. This works if server set SO_LINGER option
* with parameters l_onoff=1,l_linger=0. This means terminate
* the connection sending an RST instead of FIN, so that
* write() will fail on first attempt instead of second.
*/
if(write(srvlist[j].fd,result,sizeof(repconfirm)+sz)<=0)
{
/*
* socket was closed by peer. try again
*/
close(srvlist[j].fd);
if((srvlist[j].fd=connected=open_cnx((struct sockaddr*)&srvlist[j].addr))==-1)
/*
* OK, server disconnected for good
*/
continue;
if((ret=write(srvlist[j].fd,result,sizeof(repconfirm)+sz))<=0)
puts("Porc!");
}
}
/*
* Copy over the operation at the end
*/
free(pendops[i].dn);
maxop--;
pendops[i]=pendops[maxop];
free(result);
break;
}
if (tmp.dn != NULL)
free(tmp.dn);
}
main(int argc, char**argv)
{
int i,port=16000;
int sockfd,log=0;
static char logline[512];
char **tmp,*hn,*hp,*hf;
struct hostent *serveraddr;
while((i=getopt(argc,argv,"tdP:s:"))!=EOF)
{
switch(i)
{
case 't': log=1;
break;
case 'd': debug=1;
break;
case 'P':
port=atoi(optarg);
break;
case 's':
/*
* pointers to hostname, host port, filter
*/
hn=strtok(optarg,",");
hp=strtok(NULL,",");
hf=strtok(NULL,",");
if(hf==NULL&&hp)
if(*hp<'0' || *hp >'9')
hf=hp;
if(hn==NULL||hf==NULL)
{
puts("Missing parameter\n");
break;
}
/*
* Get master address, just the first.
*/
if((serveraddr=gethostbyname(hn))==NULL)
{
printf("Unknown host %s\n",hn);
break;
}
srvlist=(Towho*)realloc(srvlist,(nsrv+1)*sizeof(Towho));
srvlist[nsrv].addr.sin_addr.s_addr=htonl(*((u_long*)(serveraddr->h_addr_list[0])));
srvlist[nsrv].addr.sin_family=AF_INET;
srvlist[nsrv].addr.sin_port=htonl((hp==hf?port:atoi(hp)));
if((srvlist[nsrv].filter=regcmp(hf,NULL))==NULL)
printf("Wrong REX: %s\n",hf);
srvlist[nsrv].fd=open_cnx((struct sockaddr*)&srvlist[nsrv].addr);
srvlist[nsrv].hname=strdup(hn);
nsrv++;
break;
}
}
if(!nsrv)
{
if(!argv[optind])
{
printf("Usage: %s [-td] -P port <hostname>\n\tor %s [-td] -s <host>,[<port>,]<REGEX>\n",argv[0],argv[0]);
printf("\t-t\tprints input on stdout.\n\t-d\tdebug mode.\n");
exit(1);
}
srvlist=(Towho*)malloc(sizeof(Towho));
if((serveraddr=gethostbyname(argv[optind]))==NULL)
{
printf("Unknown host %s\n",argv[optind]);
exit(1);
}
srvlist[nsrv].addr.sin_addr.s_addr=htonl(*((u_long*)(serveraddr->h_addr_list[0])));
srvlist[nsrv].addr.sin_family=AF_INET;
srvlist[nsrv].addr.sin_port=htons(port);
srvlist[nsrv].filter=NULL;
srvlist[nsrv].fd=open_cnx((struct sockaddr*)&srvlist[nsrv].addr);
srvlist[nsrv].hname=strdup(argv[optind]);
nsrv++;
}
maxop=npend=0;
pendops=(Optype*)malloc(sizeof(Optype)*20);
/*
* Ignore SIGPIPE during write()
*/
sigset(SIGPIPE,SIG_IGN);
while(gets(logline))
{
if(log)
puts(logline);
for(tmp=ldap_ops,i=0;tmp[i];i++)
if(strstr(logline,tmp[i]))
break;
if(i<RESULT)
{
get_op_par(logline,&pendops[maxop]);
pendops[maxop].type=i;
if(++maxop>npend)
npend=maxop;
if(!(npend%20))
{
pendops=(Optype*)realloc(pendops,sizeof(Optype)*(npend+20));
memset(pendops+npend,0,sizeof(Optype)*20);
}
}
if(i==RESULT)
send_op(logline);
}
}
/* End of file */
--- NEW FILE scalab01.c ---
#ident "ldclt @(#)scalab01.c 1.8 01/05/03"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : scalab01.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 08 January 2001
DESCRIPTION :
This file contains the implmentation of the specific
scenario scalab01 of ldclt.
I implement this set of functions in a separate file to
reduce the interconnection(s) between the main ldclt
and the add-ons, keeping in mind the possibility to use
a dynamic load of plugins for a future release.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
08/01/01 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
12/01/01 | JL Schwing | 1.2 : Second set of options for -e scalab01
---------+--------------+------------------------------------------------------
29/01/01 | B Kolics | 1.3 : readAttrValue() uses filter of requested attr
---------+--------------+------------------------------------------------------
01/02/01 | JL Schwing | 1.4 : Protect against multiple choice of same user.
---------+--------------+------------------------------------------------------
26/02/01 | JL Schwing | 1.5 : Port on non-solaris platforms...
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.6 : Lint cleanup.
| Bug fix : forget to set ldap protocol version.
---------+--------------+------------------------------------------------------
26/04/01 | B Kolics | 1.7 : in case of lock failure, thread is not aborted
---------+--------------+------------------------------------------------------
03/05/01 | B Kolics | 1.8 : bug fix - forget to release more line.
---------+--------------+------------------------------------------------------
*/
#include <stdio.h> /* printf(), etc... */
#include <stdlib.h> /* malloc(), etc... */
#include <string.h> /* strcpy(), etc... */
#include <errno.h> /* perror(), etc... */
#ifndef _WIN32
#include <pthread.h> /* pthreads(), etc... */
#endif
#include <lber.h> /* ldap C-API BER declarations */
#include <ldap.h> /* ldap C-API declarations */
#include "port.h" /* Portability definitions */
#include "ldclt.h" /* This tool's include file */
#include "utils.h" /* Utilities functions */
#include "scalab01.h" /* Scalab01 specific definitions */
/*
* Private data structures.
*/
scalab01_context s1ctx;
/* ****************************************************************************
FUNCTION : scalab01_init
PURPOSE : Initiates the scalab01 scenario.
INPUT : None.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
scalab01_init (void)
{
int ret; /* Return value */
s1ctx.nbcnx = 0; /* No connection yet */
s1ctx.list = NULL; /* No record yet */
s1ctx.lockingMax = 0; /* No locking yet */
/*
* Initiates mutexes
*/
if ((ret = ldclt_mutex_init (&(s1ctx.list_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s\n", mctx.pid, strerror (ret));
fprintf (stderr, "ldclt[%d]: Error: cannot initiate s1ctx.list_mutex\n", mctx.pid);
fflush (stderr);
return (-1);
}
if ((ret = ldclt_mutex_init (&(s1ctx.locking_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s\n", mctx.pid, strerror (ret));
fprintf (stderr, "ldclt[%d]: Error: cannot initiate s1ctx.locking_mutex\n", mctx.pid);
fflush (stderr);
return (-1);
}
if ((ret = ldclt_mutex_init (&(s1ctx.nbcnx_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s\n", mctx.pid, strerror (ret));
fprintf (stderr, "ldclt[%d]: Error: cannot initiate s1ctx.nbcnx_mutex\n", mctx.pid);
fflush (stderr);
return (-1);
}
/*
* No error
*/
return (0);
}
/* ****************************************************************************
FUNCTION : scalab01Lock
PURPOSE : Lock for single user trying to connect.
INPUT : tttctx = thread context.
OUTPUT : None.
RETURN : -1 if error, 0 cannot lock, 1 if could lock.
DESCRIPTION :
*****************************************************************************/
int
scalab01Lock (
thread_context *tttctx)
{
int i; /* For the loop */
int ret; /* Return code */
int res; /* Result of this function */
/*
* Get secure access to the common data structure.
*/
if ((ret = ldclt_mutex_lock (&(s1ctx.locking_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_lock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Is it locked ?
*/
res = 1;
for (i=0 ; i<s1ctx.lockingMax ; i++)
if ((s1ctx.locking[i] != NULL) &&
(!strcmp (s1ctx.locking[i], tttctx->bufBindDN)))
{
res = 0;
break;
}
if (res == 1)
{
for (i=0 ; (i<s1ctx.lockingMax) && (s1ctx.locking[i] != NULL) ; i++);
if (i == s1ctx.lockingMax)
{
if (s1ctx.lockingMax == SCALAB01_MAX_LOCKING)
res = 0;
else
s1ctx.lockingMax++;
}
if (res != 0)
s1ctx.locking[i] = tttctx->bufBindDN;
}
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(s1ctx.locking_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_unlock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
return (res);
}
/* ****************************************************************************
FUNCTION : scalab01Unlock
PURPOSE : Unlock for single user trying to connect.
INPUT : tttctx = thread context.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
scalab01Unlock (
thread_context *tttctx)
{
int i; /* For the loop */
int ret; /* Return code */
/*
* Get secure access to the common data structure.
*/
if ((ret = ldclt_mutex_lock (&(s1ctx.locking_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_lock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Find the entry and unlock it.
*/
for (i=0 ; i<s1ctx.lockingMax ; i++)
if ((s1ctx.locking[i] != NULL) &&
(!strcmp (s1ctx.locking[i], tttctx->bufBindDN)))
{
s1ctx.locking[i] = NULL;
break;
}
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(s1ctx.locking_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_unlock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
return (0);
}
/* ****************************************************************************
FUNCTION : scalab01_modemIncr
PURPOSE : Increments the modem nb of cnx
INPUT : ident = thread identifier
OUTPUT : None.
RETURN : -1 if error
0 if no modem available
1 if modem available
DESCRIPTION :
*****************************************************************************/
int
scalab01_modemIncr (
char *ident)
{
int ret; /* Return value */
int res; /* Result of this function */
/*
* Get secure access to the common data structure.
*/
if ((ret = ldclt_mutex_lock (&(s1ctx.nbcnx_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_lock(), error=%d (%s)\n",
mctx.pid, ident, ret, strerror (ret));
fflush (stderr);
return (-1);
}
if (s1ctx.nbcnx >= s1ctx.maxcnxnb)
res = 0;
else
{
res = 1;
s1ctx.nbcnx++;
}
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(s1ctx.nbcnx_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_unlock(), error=%d (%s)\n",
mctx.pid, ident, ret, strerror (ret));
fflush (stderr);
return (-1);
}
return (res);
}
/* ****************************************************************************
FUNCTION : scalab01_modemDecr
PURPOSE : Decrements the modem nb of cnx
INPUT : ident = thread identifier
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
scalab01_modemDecr (
char *ident)
{
int ret; /* Return value */
/*
* Get secure access to the common data structure.
*/
if ((ret = ldclt_mutex_lock (&(s1ctx.nbcnx_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_lock(), error=%d (%s)\n",
mctx.pid, ident, ret, strerror (ret));
fflush (stderr);
return (-1);
}
s1ctx.nbcnx--;
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(s1ctx.nbcnx_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_unlock(), error=%d (%s)\n",
mctx.pid, ident, ret, strerror (ret));
fflush (stderr);
return (-1);
}
return (0);
}
/* ****************************************************************************
FUNCTION : scalab01_addLogin
PURPOSE : Add a new user login to the s1ctx structure.
INPUT : tttctx = thread context.
dn = user's dn.
duration = duration of the connection.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
scalab01_addLogin (
thread_context *tttctx,
char *dn,
int duration)
{
int ret; /* Return value */
isp_user *new; /* New entry */
isp_user *cur; /* Current entry */
/*
* Create the new record.
*/
new = (isp_user *) malloc (sizeof (isp_user));
strcpy (new->dn, dn);
new->cost = new->counter = duration;
new->next = NULL;
/*
* Get secure access to the common data structure.
* Note : it should be possible to reduce the "size" of this critical
* section but I am not 100% certain this won't mess up all things.
*/
if ((ret = ldclt_mutex_lock (&(s1ctx.list_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_lock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Maybe this is the first entry of the list ?
*/
if (s1ctx.list == NULL)
s1ctx.list = new;
else
{
/*
* Check with the list's head
*/
if (s1ctx.list->counter >= duration)
{
new->next = s1ctx.list;
s1ctx.list = new;
}
else
{
cur = s1ctx.list;
while (cur != NULL)
{
if (cur->next == NULL)
{
cur->next = new;
cur = NULL; /* Exit loop */
}
else
if (cur->next->counter >= duration)
{
new->next = cur->next;
cur->next = new;
cur = NULL; /* Exit loop */
}
else
cur = cur->next;
}
}
}
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(s1ctx.list_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_unlock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
return (0);
}
/* ****************************************************************************
FUNCTION : scalab01_connectSuperuser
PURPOSE : Purpose of the fct
INPUT : None.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
scalab01_connectSuperuser (void)
{
int ret; /* Return value */
int v2v3; /* LDAP version used */
char bindDN [MAX_DN_LENGTH]; /* To bind */
/*
* Create the LDAP context
*/
#ifdef LDCLTSSL
/*
* SSL is enabled ?
*/
if (mctx.mode & SSL)
{
/*
* LDAP session initialization in SSL mode
*/
s1ctx.ldapCtx = (LDAP *)(*(mctx.sslctx.ldapssl_init))
(mctx.hostname, mctx.port, 1);
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: ctrl: ldapssl_init (%s, %d), ldapCtx=0x%08x\n",
mctx.pid, mctx.hostname, mctx.port, (unsigned int)s1ctx.ldapCtx);
if (s1ctx.ldapCtx == NULL)
{
printf ("ldclt[%d]: ctrl: Cannot ldapssl_init (%s, %d), errno=%d\n",
mctx.pid, mctx.hostname, mctx.port, errno);
fflush (stdout);
return (-1);
}
/*
* Client authentication is used ?
*/
if (mctx.mode & CLTAUTH)
{
ret = (int)(*(mctx.sslctx.ldapssl_enable_clientauth))
(s1ctx.ldapCtx, "", mctx.keydbpin, mctx.cltcertname);
if (mctx.mode & VERY_VERBOSE)
printf
("ldclt[%d]: ctrl: After ldapssl_enable_clientauth (ldapCtx=0x%08x, %s, %s)",
mctx.pid, (unsigned int)s1ctx.ldapCtx, mctx.keydbpin, mctx.cltcertname);
if (ret < 0)
{
printf
("ldclt[%d]: ctrl: Cannot ldapssl_enable_clientauth (ldapCtx=0x%08x, %s, %s)",
mctx.pid, (unsigned int)s1ctx.ldapCtx, mctx.keydbpin, mctx.cltcertname);
ldap_perror(s1ctx.ldapCtx, "ldapssl_enable_clientauth");
fflush (stdout);
return (-1);
}
}
}
else
{
#endif
/*
* Connection initialization in normal, unencrypted mode
*/
s1ctx.ldapCtx = ldap_init (mctx.hostname, mctx.port);
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: ctrl: After ldap_init (%s, %d), ldapCtx=0x%08x\n",
mctx.pid, mctx.hostname, mctx.port, (unsigned int)s1ctx.ldapCtx);
if (s1ctx.ldapCtx == NULL)
{
printf ("ldclt[%d]: ctrl: Cannot ldap_init (%s, %d), errno=%d\n",
mctx.pid, mctx.hostname, mctx.port, errno);
fflush (stdout);
return (-1);
}
#ifdef LDCLTSSL
}
#endif
/*
* Set the LDAP version and other options...
*/
if (mctx.mode & LDAP_V2)
v2v3 = LDAP_VERSION2;
else
v2v3 = LDAP_VERSION3;
ret = ldap_set_option (s1ctx.ldapCtx, LDAP_OPT_PROTOCOL_VERSION, &v2v3);
if (ret < 0) /*JLS 14-03-01*/
{ /*JLS 14-03-01*/
printf ("ldclt[%d]: ctrl: Cannot ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)\n",
mctx.pid);
fflush (stdout); /*JLS 14-03-01*/
return (-1); /*JLS 14-03-01*/
} /*JLS 14-03-01*/
/*
* Now we could bind
*/
#ifdef LDCLTSSL
/*
* for SSL client authentication, SASL BIND is used
*/
if (mctx.mode & CLTAUTH)
{
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: ctrl: Before ldap_sasl_bind_s\n", mctx.pid);
ret = ldap_sasl_bind_s (s1ctx.ldapCtx, "", "EXTERNAL", NULL, NULL, NULL,
NULL);
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: ctrl: After ldap_sasl_bind_s\n", mctx.pid);
if (ret != LDAP_SUCCESS)
{
printf ("ldclt[%d]: ctrl: Cannot ldap_sasl_bind_s, error=%d (%s)\n",
mctx.pid, ret, my_ldap_err2string (ret));
fflush (stdout);
return (-1);
}
}
else
{
#endif /* LDCLTSSL */
strcpy (bindDN, SCALAB01_SUPER_USER_RDN);
strcat (bindDN, ",");
strcat (bindDN, mctx.baseDN);
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: ctrl: Before ldap_simple_bind_s (%s , %s)\n",
mctx.pid, bindDN, SCALAB01_SUPER_USER_PASSWORD);
ret = ldap_simple_bind_s (s1ctx.ldapCtx,
bindDN, SCALAB01_SUPER_USER_PASSWORD);
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: ctrl: After ldap_simple_bind_s (%s, %s)\n",
mctx.pid, bindDN, SCALAB01_SUPER_USER_PASSWORD);
if (ret != LDAP_SUCCESS)
{
printf("ldclt[%d]: ctrl: Cannot ldap_simple_bind_s (%s, %s), error=%d (%s)\n",
mctx.pid, bindDN, SCALAB01_SUPER_USER_PASSWORD,
ret, my_ldap_err2string (ret));
fflush (stdout);
return (-1);
}
#ifdef LDCLTSSL
}
#endif
/*
* Normal end...
*/
return (0);
}
/* ****************************************************************************
FUNCTION : readAttrValue
PURPOSE : This function will ldap_search the given entry for the
value of the given attribute.
INPUT : ident = thread identifier
ldapCtx = LDAP context
dn = dn of the entry to process
attname = attribute name
OUTPUT : value = attribute value. This buffer must be
initiated with enough memory.
value[0] == '\0' if not find.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
readAttrValue (
LDAP *ldapCtx,
char *ident,
char *dn,
char *attname,
char *value)
{
int ret; /* Return value */
char *attrs[2]; /* Attribute to retrieve */
LDAPMessage *res; /* LDAP responses */
LDAPMessage *cur; /* Current message */
BerElement *ber; /* To decode the response */
char *aname; /* Current attribute name */
char **vals; /* Attribute value returned */
char *filter; /* Filter used for searching */
/*
* First, ldap_search() the entry.
*/
attrs[0] = attname;
attrs[1] = NULL;
filter = (char *)malloc((4+strlen(attname))*sizeof(char));
sprintf(filter, "(%s=*)", attname);
ret = ldap_search_s (ldapCtx, dn, LDAP_SCOPE_BASE,
filter, attrs, 0, &res);
if (filter != NULL) free(filter);
if (ret != LDAP_SUCCESS)
{
printf ("ldclt[%d]: %s: Cannot ldap_search (%s in %s), error=%d (%s)\n",
mctx.pid, ident, attname, dn, ret, my_ldap_err2string (ret));
fflush (stdout);
return (-1);
}
/*
* Decode the response
*/
value[0] = '\0'; /* Not find yet */
cur = ldap_first_entry (ldapCtx, res);
while ((!value[0]) && (cur != NULL))
{
aname = ldap_first_attribute (ldapCtx, cur, &ber);
while ((!value[0]) && (aname != NULL))
{
/*
* We expect this attribute to be single-valued.
*/
if (!strcmp (aname, attname))
{
vals = ldap_get_values (ldapCtx, cur, aname);
if (vals == NULL)
{
printf ("ldclt[%d]: %s: no value for %s in %s\n",
mctx.pid, ident, dn, attname);
fflush (stdout);
return (-1);
}
strcpy (value, vals[0]);
ldap_value_free (vals);
}
/*
* Next attribute
*/
ldap_memfree (aname);
if (!value[0])
aname = ldap_next_attribute (ldapCtx, cur, ber);
}
/*
* Next entry - shouldn't happen in theory
*/
if (ber != NULL)
ldap_ber_free (ber, 0);
cur = ldap_next_entry (ldapCtx, cur);
}
ldap_msgfree (res); /* Free the response */
return (0);
}
/* ****************************************************************************
FUNCTION : writeAttrValue
PURPOSE : This function will ldap_modify the given entry to
replace the value of the given attribute.
INPUT : ident = thread identifier
ldapCtx = LDAP context
dn = dn of the entry to process
attname = attribute name
value = attribute value
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
writeAttrValue (
LDAP *ldapCtx,
char *ident,
char *dn,
char *attname,
char *value)
{
int ret; /* Return value */
LDAPMod attribute; /* To build the attributes */
LDAPMod *attrsmod[2]; /* Modify attributes */
char *pvalues[2]; /* To build the values list */
/*
* Prepear the data to be written
*/
pvalues[0] = value;
pvalues[1] = NULL;
attribute.mod_op = LDAP_MOD_REPLACE;
attribute.mod_type = attname;
attribute.mod_values = pvalues;
attrsmod[0] = &attribute;
attrsmod[1] = NULL;
/*
* Store the data in the directory.
*/
ret = ldap_modify_ext_s (ldapCtx, dn, attrsmod, NULL, NULL);
if (ret != LDAP_SUCCESS)
{
printf ("ldclt[%d]: %s: Cannot ldap_modify_ext_s (%s in %s), error=%d (%s)\n",
mctx.pid, ident, attname, dn, ret, my_ldap_err2string (ret));
fflush (stdout);
return (-1);
}
return (0);
}
/* ****************************************************************************
FUNCTION : scalab01_unlock
PURPOSE : Unlock the user given in argument.
INPUT : entry = entry to unlock.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
scalab01_unlock (
isp_user *user)
{
int account; /* Accounting value */
char buf[20]; /* To read/write attribute */
/*
* Increment accounting counters
* First, read the current value.
*/
if (readAttrValue (s1ctx.ldapCtx,"ctrl",user->dn,SCALAB01_ACC_ATTRIB,buf) < 0)
{
printf ("ldclt[%d]: ctrl: Cannot read accounting attribute of %s\n",
mctx.pid, user->dn);
fflush (stdout);
return (-1);
}
/*
* If this attribute has no value (doesn't exist) we assume it is 0.
*/
if (buf[0] != '\0')
account = atoi (buf);
else
{
printf ("ldclt[%d]: ctrl: No accounting attribute for %s - assume it is 0\n",
mctx.pid, user->dn);
fflush (stdout);
account = 0;
}
/*
* Compute the new value and store it in the directory.
*/
sprintf (buf, "%d", account + user->cost);
if (writeAttrValue (s1ctx.ldapCtx,"ctrl",user->dn,SCALAB01_ACC_ATTRIB,buf) <0)
{
printf ("ldclt[%d]: ctrl: Cannot write accounting attribute of %s\n",
mctx.pid, user->dn);
fflush (stdout);
return (-1);
}
/*
* Unlock the user
*/
if (writeAttrValue (s1ctx.ldapCtx, "ctrl", user->dn,
SCALAB01_LOCK_ATTRIB, SCALAB01_VAL_UNLOCKED) < 0)
{
printf ("ldclt[%d]: ctrl: Cannot write lock (unlock) attribute of %s\n",
mctx.pid, user->dn);
fflush (stdout);
return (-1);
}
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: ctrl: entry %s unlocked\n",
mctx.pid, user->dn);
/*
* Decrement modem pool usage...
*/
if (scalab01_modemDecr ("ctrl") < 0)
return (-1);
/*
* Normal end
*/
return (0);
}
/* ****************************************************************************
FUNCTION : scalab01_control
PURPOSE : This function implements the control loop/thread of
the scalab01 scenario. Its main target is to manage
the counters of each "connection" and to unlock the
entry when time is reached.
INPUT : None.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
void *
scalab01_control (
void *arg)
{
isp_user *cur; /* Current entry */
isp_user *head; /* Head of entries to process */
int ret; /* Return value */
int nbTot; /* Total nb entries locked */
int nbU; /* Number unlocked */
/*
* Initialization
* Failure to connect is a critical error...
*/
if (scalab01_connectSuperuser () < 0)
ldcltExit (EXIT_NOBIND);
/*
* Main loop
*/
while (1 /*CONSTCOND*/) /*JLS 14-03-01*/
{
ldclt_sleep (1); /* Poll the connections every second */
nbTot = nbU = 0; /* No entries processed yet */
/*
* Get protected access to the entries
*/
if ((ret = ldclt_mutex_lock (&(s1ctx.list_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: ctrl: cannot mutex_lock(), error=%d (%s)\n",
mctx.pid, ret, strerror (ret));
fflush (stderr);
ldcltExit (EXIT_OTHER);
}
/*
* Decrement all counters
*/
for (cur=s1ctx.list ; cur!=NULL ; cur=cur->next)
{
cur->counter--;
nbTot++;
}
/*
* Find the entries to process.
*/
if ((s1ctx.list == NULL) || (s1ctx.list->counter > 0))
head = NULL;
else
{
head = cur = s1ctx.list;
while ((cur != NULL) && (cur->counter == 0))
cur = cur->next;
s1ctx.list = cur;
}
/*
* Release mutex
*/
if ((ret = ldclt_mutex_unlock (&(s1ctx.list_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: ctrl: cannot mutex_unlock(), error=%d (%s)\n",
mctx.pid, ret, strerror (ret));
fflush (stderr);
ldcltExit (EXIT_OTHER);
}
/*
* Now, we have "head" that points either to NULL or to a list of
* entries to process.
* Attention, this list of entries is not terminated by NULL, but
* we must rather check the field head->next->counter" for the last
* entry...
*
* NOTE : implements this section as a separate thread to keep the
* general timer working...
*/
while (head != NULL)
{
if (scalab01_unlock (head) < 0)
{
printf ("ldclt[%d]: ctrl: cannot unlock %s\n", mctx.pid, head->dn);
ldcltExit (EXIT_OTHER);
}
nbU++; /* One more entry unlocked */
/*
* Next entry...
*/
cur = head;
if (head->next == NULL)
head = NULL;
else
if (head->next->counter != 0)
head = NULL;
else
head = head->next;
free (cur);
} /* while (head =! NULL) */
/*
* Print some stats...
*/
if (mctx.mode & VERBOSE)
printf ("ldclt[%d]: ctrl: nb entries unlocked / total : %3d / %5d\n",
mctx.pid, nbU, nbTot);
} /* Main loop */
/*
* End of thread
*/
return (arg);
}
/* ****************************************************************************
FUNCTION : doScalab01
PURPOSE : Implements the client part of the scalab01 scenario.
INPUT : tttctx = this thread context
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
doScalab01 (
thread_context *tttctx)
{
char buf[32]; /* To read attributes value */
int duration; /* Use a variable for trace purpose */
int res; /* Result of cnx to modem pool */
int doloop; /* To know if we should loop */
/*
* Simulate connection to the modem pool.
*/
while ((res = scalab01_modemIncr(tttctx->thrdId)) != 1)
switch (res)
{
case 0:
ldclt_sleep (s1ctx.wait==0?SCALAB01_DEF_WAIT_TIME:rndlim(0,s1ctx.wait));
break;
case -1:
return (-1);
break;
}
/*
* Connection to the server
* The function connectToServer() will take care of the various connection/
* disconnection, bind/unbind/close etc... requested by the user.
* The cost is one more function call in this application, but the
* resulting source code will be much more easiest to maintain.
*/
if (connectToServer (tttctx) < 0)
return (-1);
if (!(tttctx->binded))
return (0);
/*
* Check that no other thread is using the same identity...
*/
doloop = 1;
while (doloop)
{
switch (scalab01Lock (tttctx))
{
case 0:
ldclt_sleep (1);
break;
case 1:
doloop = 0;
break;
case -1:
return (-1);
break;
}
}
/*
* Ok, we are now binded. Great ;-)
* The DN we used to bind is available in tttctx->bufBindDN
* Read lock attribute
*/
if (readAttrValue (tttctx->ldapCtx, tttctx->thrdId, tttctx->bufBindDN,
SCALAB01_LOCK_ATTRIB, buf) < 0)
{
printf ("ldclt[%d]: %s: Cannot read lock attribute of %s\n",
mctx.pid, tttctx->thrdId, tttctx->bufBindDN);
fflush (stdout);
(void) scalab01_modemDecr (tttctx->thrdId);
return (-1);
}
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: %s: entry %s lock read\n",
mctx.pid, tttctx->thrdId, tttctx->bufBindDN);
/*
* If locked, then we cannot login now...
*/
if (!strcmp (buf, SCALAB01_VAL_LOCKED))
{
if (scalab01_modemDecr (tttctx->thrdId) < 0)
return (-1);
return (0);
}
/*
* If not locked :
* - lock the user
* - decide how many times will be connected
* - add information to the list of connected
*/
if (writeAttrValue (tttctx->ldapCtx, tttctx->thrdId, tttctx->bufBindDN,
SCALAB01_LOCK_ATTRIB, SCALAB01_VAL_LOCKED) < 0)
{
printf ("ldclt[%d]: %s: Cannot write lock attribute of %s\n",
mctx.pid, tttctx->thrdId, tttctx->bufBindDN);
fflush (stdout);
/*
* It can still happen that two threads write this attribute at the same
* time, so there can be failure in one of the threads
* in this case just return
*/
if (scalab01_modemDecr (tttctx->thrdId) < 0) /*JLS 03-05-01*/
return (-1); /*JLS 03-05-01*/
return (0); /*BK 26-04-01*/
}
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: %s: entry %s lock written\n",
mctx.pid, tttctx->thrdId, tttctx->bufBindDN);
if (scalab01Unlock (tttctx) < 0)
return (-1);
duration = rndlim (1, s1ctx.cnxduration);
if (scalab01_addLogin (tttctx, tttctx->bufBindDN, duration) < 0)
{
printf ("ldclt[%d]: %s: Cannot memorize new login of %s\n",
mctx.pid, tttctx->thrdId, tttctx->bufBindDN);
fflush (stdout);
return (-1);
}
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: %s: entry %s login added duration %6d\n",
mctx.pid, tttctx->thrdId, tttctx->bufBindDN, duration);
/*
* Memorize the operation
*/
if (incrementNbOpers (tttctx) < 0)
return (-1);
/*
* Wait before next operation...
*/
if (s1ctx.wait > 0)
ldclt_sleep (rndlim (0,s1ctx.wait));
/*
* Unbind
*/
/*
TBC - this is done in the next loop... - cf connectToServer()
*/
return (0);
}
/* End of file */
--- NEW FILE scalab01.h ---
#ident "ldclt @(#)scalab01.h 1.3 01/03/14"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : scalab01.h
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 12 January 2001
DESCRIPTION :
This file contains the definitions related to the
scenario scalab01 of ldclt.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
12/01/01 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
01/02/01 | JL Schwing | 1.2 : Protect against multiple choice of same user.
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.3 : Lint cleanup.
---------+--------------+------------------------------------------------------
*/
#ifndef SCALAB01_H
#define SCALAB01_H
/*
* Default values for scalab01
*/
#define SCALAB01_ACC_ATTRIB "ntUserUnitsPerWeek"
#define SCALAB01_DEF_MAX_CNX 5000
#define SCALAB01_DEF_CNX_DURATION 3600
#define SCALAB01_DEF_WAIT_TIME 10
#define SCALAB01_LOCK_ATTRIB "ntUserFlags"
#define SCALAB01_SUPER_USER_RDN "cn=super user"
#define SCALAB01_SUPER_USER_PASSWORD "super user password"
#define SCALAB01_VAL_LOCKED "1"
#define SCALAB01_VAL_UNLOCKED "0"
#define SCALAB01_MAX_LOCKING 4096
/*
* This structure is intended to memorize the information about
* the "ISP" users connected.
* Uses mainly static size data to save malloc()/free() calls.
*/
typedef struct isp_user {
char dn[MAX_DN_LENGTH]; /* User's DN */
int cost; /* Cnx cost */
int counter; /* To free it */
struct isp_user *next; /* Next entry */
} isp_user;
/*
* This is the scalab01 context structure.
*/
typedef struct scalab01_context {
int cnxduration; /* Max cnx duration */
LDAP *ldapCtx; /* LDAP context */
isp_user *list; /* ISP users list */
ldclt_mutex_t list_mutex; /* Protect list */
char *locking[SCALAB01_MAX_LOCKING];
ldclt_mutex_t locking_mutex;
int lockingMax;
int maxcnxnb; /* Modem pool size */
int nbcnx; /* Nb cnx to the modem */
ldclt_mutex_t nbcnx_mutex; /* Protect nbcnx */
int wait; /* Retry every this time */
} scalab01_context;
/*
* Exported functions and structures
*/
extern int doScalab01 (thread_context *tttctx);
extern scalab01_context s1ctx;
extern void *scalab01_control (void *);
extern int scalab01_init (void); /*JLS 14-03-01*/
#endif /* SCALAB01_H */
/* End of file */
--- NEW FILE srv.c ---
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <sys/inttypes.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include "remote.h"
#include "lber.h"
#include "ldap.h"
enum {ADD,DELETE,MODRDN,MODIFY,RESULT};
typedef struct {
int conn,op,type;
char *dn;
} Optype;
Optype *pendops;
int npend=-1,maxop;
char *ldap_ops[]={"ADD","DEL","MODRDN","MOD ","RESULT",NULL};
int ldap_val[]={LDAP_REQ_ADD,LDAP_REQ_DELETE,LDAP_REQ_MODRDN,LDAP_REQ_MODIFY};
print_packet(repconfirm *op)
{
int i;
printf("type=%d, res=%d, dnlen=%d, dN: %s\n",op->type,op->res,op->dnSize,op->dn);
}
main(int argc, char**argv)
{
int i,port=16000;
int sockfd,newfd;
static char buff[512];
char **tmp;
struct sockaddr_in srvsaddr,claddr;
struct hostent *cltaddr;
uint32_t ipaddr;
while((i=getopt(argc,argv,"p:"))!=EOF){
switch(i){
case 'p': port=atoi(optarg);
break;
}
}
srvsaddr.sin_addr.s_addr=htonl(INADDR_ANY);
srvsaddr.sin_family=AF_INET;
srvsaddr.sin_port=htons(port);
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("Socket");
exit(1);
}
i=1;
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int))!=0)
perror("Sockopt");
if(bind(sockfd,(struct sockaddr*)&srvsaddr,sizeof(struct sockaddr))!=0){
perror("Bind");
exit(1);
}
if(listen(sockfd,1)!=0)
perror("listen");
for(;;){
i=sizeof(claddr);
if((newfd=accept(sockfd,(struct sockaddr *)&claddr,&i))<0){
perror("Accept");
exit(1);
}
ipaddr=ntohl(claddr.sin_addr.s_addr);
cltaddr=gethostbyaddr((char*)&ipaddr,sizeof(ipaddr),AF_INET);
printf("Accepting from %s\n",cltaddr->h_name);
while(read(newfd,buff,512)>0){
print_packet((repconfirm*) buff);
memset(buff,0,512);
}
close(newfd);
}
close(sockfd);
}
--- NEW FILE threadMain.c ---
#ident "ldclt @(#)threadMain.c 1.40 01/05/04"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : threadMain.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 04 December 1998
DESCRIPTION :
This file implements the main/core part of the
threads. The ldap part is in another source file.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
04/12/98 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.2 : Add nb of errors statistics.
---------+--------------+------------------------------------------------------
10/12/98 | JL Schwing | 1.3 : Implement asynchronous mode.
---------+--------------+------------------------------------------------------
11/12/98 | JL Schwing | 1.4 : Implement max errors threshold.
| fflush(stdout) after each printf.
---------+--------------+------------------------------------------------------
14/12/98 | JL Schwing | 1.5 : Implement "-e close".
| Add "thread is dead" message.
---------+--------------+------------------------------------------------------
16/12/98 | JL Schwing | 1.6 : Implement "-e add" and "-e delete".
---------+--------------+------------------------------------------------------
23/12/98 | JL Schwing | 1.7 : bug fix - crash in msgIdDel().
---------+--------------+------------------------------------------------------
28/12/98 | JL Schwing | 1.8 : Add tag asyncHit.
---------+--------------+------------------------------------------------------
13/01/99 | JL Schwing | 1.9 : Implement "-e string".
---------+--------------+------------------------------------------------------
18/01/99 | JL Schwing | 1.10: Implement "-e randombase".
---------+--------------+------------------------------------------------------
21/01/99 | JL Schwing | 1.11: Implement "-e ascii".
---------+--------------+------------------------------------------------------
26/02/99 | JL Schwing | 1.12: Improve strict ascii: reject more characters.
---------+--------------+------------------------------------------------------
26/02/99 | JL Schwing | 1.13: Quote (aka \) characters rather than reject.
---------+--------------+------------------------------------------------------
04/05/99 | JL Schwing | 1.14: Modify msgId*() to memorize attribs as well.
---------+--------------+------------------------------------------------------
19/05/99 | JL Schwing | 1.15: Implement "-e rename".
| Exit the thread if status==DEAD
---------+--------------+------------------------------------------------------
28/05/99 | JL Schwing | 1.16: Add new option -W (wait).
---------+--------------+------------------------------------------------------
06/03/00 | JL Schwing | 1.17: Test malloc() return value.
---------+--------------+------------------------------------------------------
18/08/00 | JL Schwing | 1.18: Print begin and end dates.
---------+--------------+------------------------------------------------------
25/08/00 | JL Schwing | 1.19: Implement consistent exit status...
| Fix some old legacy code.
---------+--------------+------------------------------------------------------
14/11/00 | JL Schwing | 1.20: Will now use utils.c functions.
---------+--------------+------------------------------------------------------
17/11/00 | JL Schwing | 1.21: Implement "-e smoothshutdown".
| Add new functions setThreadStatus() getThreadStatus().
---------+--------------+------------------------------------------------------
21/11/00 | JL Schwing | 1.22: Implement "-e attreplace=name:mask"
---------+--------------+------------------------------------------------------
29/11/00 | JL Schwing | 1.23: Port on NT 4.
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.24: Port on Linux.
---------+--------------+------------------------------------------------------
15/12/00 | JL Schwing | 1.25: Add more trace in VERY_VERBOSE mode.
---------+--------------+------------------------------------------------------
18/12/00 | JL Schwing | 1.26: Add new exit status EXIT_INIT.
---------+--------------+------------------------------------------------------
05/01/01 | JL Schwing | 1.27: Implement "-e randombinddn" and associated
| "-e randombinddnlow/high"
---------+--------------+------------------------------------------------------
08/01/01 | JL Schwing | 1.28: Implement "-e scalab01".
---------+--------------+------------------------------------------------------
12/01/01 | JL Schwing | 1.29: Include scalab01.h
---------+--------------+------------------------------------------------------
05/03/01 | JL Schwing | 1.30: Bug fix - crash SIGSEGV if no binDN provided.
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.31: Implement "-e commoncounter"
| Add new function incrementCommonCounter().
---------+--------------+------------------------------------------------------
14/03/01 | JL Schwing | 1.32: Implement "-e dontsleeponserverdown".
---------+--------------+------------------------------------------------------
15/03/01 | JL Schwing | 1.33: Implement "-e randomattrlist=name:name:name"
| Add new function selectRandomAttrList().
---------+--------------+------------------------------------------------------
19/03/01 | JL Schwing | 1.34: Implement "-e genldif=filename"
---------+--------------+------------------------------------------------------
23/03/01 | JL Schwing | 1.35: Implements "-e rdn=value".
---------+--------------+------------------------------------------------------
28/03/01 | JL Schwing | 1.36: Support -e commoncounter with -e rdn/object
| Add new function incrementCommonCounterObject().
---------+--------------+------------------------------------------------------
02/04/01 | JL Schwing | 1.37: Bug fix : large files support for -e genldif.
---------+--------------+------------------------------------------------------
11/04/01 | JL Schwing | 1.38: Implement [INCRFROMFILE<NOLOOP>(myfile)]
---------+--------------+------------------------------------------------------
03/05/01 | JL Schwing | 1.39: Implement -e randombinddnfromfile=filename.
---------+--------------+------------------------------------------------------
04/05/01 | JL Schwing | 1.40: Implement -e bindonly.
---------+--------------+------------------------------------------------------
*/
#include <stdio.h> /* printf(), etc... */
#include <string.h> /* strerror(), etc... */
#include <stdlib.h> /* exit(), etc... */
#include <ctype.h> /* isascii(), etc... */
#include <errno.h> /* errno, etc... */ /*JLS 06-03-00*/
#include <lber.h> /* ldap C-API BER declarations */
#include <ldap.h> /* ldap C-API declarations */
#ifndef _WIN32 /*JLS 29-11-00*/
#include <unistd.h> /* close(), etc... */
#include <pthread.h> /* pthreads(), etc... */
#include <signal.h> /* sigfillset(), etc... */
#endif /*JLS 29-11-00*/
#include "port.h" /* Portability definitions */ /*JLS 29-11-00*/
#include "ldclt.h" /* This tool's include file */
#include "utils.h" /* Utilities functions */ /*JLS 14-11-00*/
#include "scalab01.h" /* Scalab01 specific */ /*JLS 12-01-01*/
/* New */ /*JLS 15-03-01*/
/* ****************************************************************************
FUNCTION : selectRandomAttrList
PURPOSE : Select a random attr list.
INPUT : tttctx = this thread context
OUTPUT : None.
RETURN : The random list.
DESCRIPTION :
*****************************************************************************/
char **
selectRandomAttrList (
thread_context *tttctx)
{
tttctx->attrlist[0] = mctx.attrlist[rndlim(0,mctx.attrlistNb-1)];
return (tttctx->attrlist);
}
/* ****************************************************************************
FUNCTION : randomString
PURPOSE : Return a random string, of length nbDigits.
The string is returned in tttctx->buf2.
INPUT : tttctx = thread context.
nbDigits = number of digits required.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
randomString (
thread_context *tttctx,
int nbDigits)
{
rndstr (tttctx->buf2, nbDigits); /*JLS 14-11-00*/
return (0);
}
/* New */ /*JLS 28-03-01*/
/* ****************************************************************************
FUNCTION : incrementCommonCounterObject
PURPOSE : Purpose of the fct
INPUT : tttctx = thread context
field = field to process
OUTPUT : None.
RETURN : -1 if error or end of loop (no_loop), new value else.
DESCRIPTION :
*****************************************************************************/
int
incrementCommonCounterObject (
thread_context *tttctx,
vers_field *field)
{
int ret; /* Return value */
int val; /* New value */
/*
* Get mutex
*/
if ((ret = ldclt_mutex_lock (&(field->cnt_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: %s: cannot mutex_lock(field->cnt_mutex), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Compute next value
*/
switch (field->how)
{
case HOW_INCR_FROM_FILE:
case HOW_INCR_NB:
if (field->cnt <= field->high) /* Limit not reached */
{
val = field->cnt;
field->cnt++;
}
else
{
val = field->low;
field->cnt = field->low + 1;
}
break;
case HOW_INCR_FROM_FILE_NL:
case HOW_INCR_NB_NOLOOP:
if (field->cnt <= field->high) /* Limit not reached */
{
val = field->cnt;
field->cnt++;
}
else
val = -1; /* Exit thread */
break;
default:
printf ("ldclt[%d]: %s: Illegal how=%d in incrementCommonCounterObject()\n",
mctx.pid, tttctx->thrdId, field->how);
val = -1;
break;
}
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(field->cnt_mutex))) != 0)
{
fprintf(stderr,"ldclt[%d]: %s: cannot mutex_unlock(field->cnt_mutex), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Maybe a message to print ?
*/
if (val < 0)
printf ("ldclt[%d]: %s: Hit top incrementeal value\n", mctx.pid, tttctx->thrdId);
return (val);
}
/* New */ /*JLS 14-03-01*/
/* ****************************************************************************
FUNCTION : incrementCommonCounter
PURPOSE : Purpose of the fct
INPUT : tttctx = thread context
OUTPUT : None.
RETURN : -1 if error or end of loop (no_loop), new value else.
DESCRIPTION :
*****************************************************************************/
int
incrementCommonCounter (
thread_context *tttctx)
{
int ret; /* Return value */
int val; /* New value */
/*
* Get mutex
*/
if ((ret = ldclt_mutex_lock (&(mctx.lastVal_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: T%03d: cannot mutex_lock(lastVal_mutex), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Compute next value
*/
if ((mctx.mode & NOLOOP) && (mctx.lastVal == mctx.randomHigh))
val = -1;
else
{
mctx.lastVal++;
if (mctx.lastVal > mctx.randomHigh)
{
if (mctx.mode & NOLOOP)
val = -1;
else
mctx.lastVal = mctx.randomLow;
}
val = mctx.lastVal;
}
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(mctx.lastVal_mutex))) != 0)
{
fprintf(stderr,"ldclt[%d]: T%03d: cannot mutex_unlock(lastVal_mutex), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Maybe a message to print ?
*/
if (val < 0)
printf ("ldclt[%d]: T%03d: Hit top incrementeal value\n", mctx.pid, tttctx->thrdNum);
return (val);
}
/* ****************************************************************************
FUNCTION : incrementNbOpers
PURPOSE : Increment the counters tttctx->nbOpers and
tttctx->totOpers of the given thread.
INPUT : tttctx = thread context.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
incrementNbOpers (
thread_context *tttctx)
{
int ret; /* Return value */
/*
* Get mutex
*/
if ((ret = ldclt_mutex_lock (&(tttctx->nbOpers_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: T%03d: cannot mutex_lock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Increment counter
*/
tttctx->nbOpers++;
/*
* Free mutex
*/
if ((ret = ldclt_mutex_unlock (&(tttctx->nbOpers_mutex))) != 0)
{
fprintf (stderr, "ldclt[%d]: T%03d: cannot mutex_unlock(), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Increment total and check if max value reached
*/
tttctx->totOpers++;
if(tttctx->totalReq > -1) {
if (tttctx->totOpers >= tttctx->totalReq) {
if (setThreadStatus(tttctx, MUST_SHUTDOWN) < 0) {
tttctx->status = DEAD; /* Force thread to die! */
}
}
}
return (0);
}
/* ****************************************************************************
FUNCTION : ignoreError
PURPOSE : Returns true or false depending on the given error
should be ignored or not (option -I).
We will sleep() if an error about server down is to be
ignored.
INPUT : err = error number
OUTPUT : None.
RETURN : 1 if should be ignored, 0 else.
DESCRIPTION :
*****************************************************************************/
int
ignoreError (
int err)
{
int i;
for (i=0 ; i<mctx.ignErrNb ; i++)
if (mctx.ignErr[i] == err)
{ /*JLS 14-03-01*/
if ((!(mctx.mode & DONT_SLEEP_DOWN)) && /*JLS 14-03-01*/
((err == LDAP_SERVER_DOWN) || /*JLS 14-03-01*/
(err == LDAP_CONNECT_ERROR))) /*JLS 14-03-01*/
ldclt_sleep (1); /*JLS 14-03-01*/
return (1);
} /*JLS 14-03-01*/
return (0);
}
/* ****************************************************************************
FUNCTION : addErrorStat
PURPOSE : Add the given error number to the statistics.
INPUT : err = error number
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
addErrorStat (
int err)
{
int ret; /* Return value */
/*
* Get mutex
*/
if ((ret = ldclt_mutex_lock (&(mctx.errors_mutex))) != 0)
{
fprintf (stderr,
"ldclt[%d]: Cannot mutex_lock(errors_mutex), error=%d (%s)\n",
mctx.pid, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Update the counters
*/
if ((err <= 0) || (err >= MAX_ERROR_NB))
{
fprintf (stderr, "ldclt[%d]: Illegal error number %d\n", mctx.pid, err);
fflush (stderr);
mctx.errorsBad++;
}
else
mctx.errors[err]++;
/*
* Release the mutex
*/
if ((ret = ldclt_mutex_unlock (&(mctx.errors_mutex))) != 0)
{
fprintf (stderr,
"ldclt[%d]: Cannot mutex_unlock(errors_mutex), error=%d (%s)\n",
mctx.pid, ret, strerror (ret));
fflush (stderr);
return (-1);
}
/*
* Maybe we should ignore this error ?
*/
if (!(ignoreError (err)))
{
/*
* Ok, we should not ignore this error...
* Maybe the limit is reached ?
*/
if ((err <= 0) || (err >= MAX_ERROR_NB))
{
if (mctx.errorsBad > mctx.maxErrors)
{
printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid);
(void) printGlobalStatistics(); /*JLS 25-08-00*/
fflush (stdout);
ldclt_sleep (5);
ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/
}
}
else
if (mctx.errors[err] > mctx.maxErrors)
{
printf ("ldclt[%d]: Max error limit reached - exiting.\n", mctx.pid);
(void) printGlobalStatistics(); /*JLS 25-08-00*/
fflush (stdout);
ldclt_sleep (5);
ldcltExit (EXIT_MAX_ERRORS); /*JLS 25-08-00*/
}
}
/*
* Normal end
*/
return (0);
}
/* ****************************************************************************
FUNCTION : msgIdAdd
PURPOSE : Add a new message id to the pending ones.
INPUT : tttctx = thread's context.
msgid = message id.
str = free string.
dn = dn of the entry
attribs = attributes
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
msgIdAdd (
thread_context *tttctx,
int msgid,
char *str,
char *dn,
LDAPMod **attribs)
{
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: msgIdAdd (%d, %s)\n", mctx.pid, tttctx->thrdNum, msgid, str);
/*
* Add the new cell
*/
if (tttctx->firstMsgId == NULL)
{
tttctx->firstMsgId = (msgid_cell *) malloc (sizeof (msgid_cell));
if (tttctx->firstMsgId == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->firstMsgId), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, errno, strerror (errno));
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
tttctx->lastMsgId = tttctx->firstMsgId;
}
else
{
tttctx->lastMsgId->next = (msgid_cell *) malloc (sizeof (msgid_cell));
if (tttctx->lastMsgId->next == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->lastMsgId->next), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, errno, strerror (errno));
return (-1); /*JLS 06-03-00*/
} /*JLS 06-03-00*/
tttctx->lastMsgId = tttctx->lastMsgId->next;
}
/*
* Memorize the information
*/
tttctx->lastMsgId->next = NULL;
tttctx->lastMsgId->msgid = msgid;
strcpy (tttctx->lastMsgId->str, str);
strcpy (tttctx->lastMsgId->dn, dn);
tttctx->lastMsgId->attribs = attribs;
return (0);
}
/* ****************************************************************************
FUNCTION : msgIdAttribs
PURPOSE : Found the requested message id in the pending list.
INPUT : tttctx = thread's context
msgid = message id
OUTPUT : None
RETURN : The associated attributes, or NULL.
DESCRIPTION :
*****************************************************************************/
LDAPMod **
msgIdAttribs (
thread_context *tttctx,
int msgid)
{
msgid_cell *pt;
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: msgIdAttribs (%d)\n", mctx.pid, tttctx->thrdNum, msgid);
for (pt = tttctx->firstMsgId ; pt != NULL ; pt = pt->next)
if (pt->msgid == msgid)
return (pt->attribs);
return (NULL);
}
/* ****************************************************************************
FUNCTION : msgIdDN
PURPOSE : Found the requested message id in the pending list.
INPUT : tttctx = thread's context
msgid = message id
OUTPUT : None
RETURN : The associated DN, or NULL.
DESCRIPTION :
*****************************************************************************/
char *
msgIdDN (
thread_context *tttctx,
int msgid)
{
msgid_cell *pt;
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: msgIdDN (%d)\n", mctx.pid, tttctx->thrdNum, msgid);
for (pt = tttctx->firstMsgId ; pt != NULL ; pt = pt->next)
if (pt->msgid == msgid)
return (pt->dn);
return (NULL);
}
/* ****************************************************************************
FUNCTION : msgIdStr
PURPOSE : Found the requested message id in the pending list.
INPUT : tttctx = thread's context
msgid = message id
OUTPUT : None
RETURN : The associated str, or an error message string.
DESCRIPTION :
*****************************************************************************/
char *
msgIdStr (
thread_context *tttctx,
int msgid)
{
msgid_cell *pt;
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: msgIdStr (%d)\n", mctx.pid, tttctx->thrdNum, msgid);
for (pt = tttctx->firstMsgId ; pt != NULL ; pt = pt->next)
if (pt->msgid == msgid)
return (pt->str);
return ("Error: msgid not found");
}
/* ****************************************************************************
FUNCTION : msgIdDel
PURPOSE : Delete a message id from the pending ones.
INPUT : tttctx = thread's context
msgid = message id.
freeAttr= true or false depending on freing the attribs
OUTPUT : None.
RETURN : -1 if not found, 0 else.
DESCRIPTION :
*****************************************************************************/
int
msgIdDel (
thread_context *tttctx,
int msgid,
int freeAttr)
{
msgid_cell *pt; /* For the loop */
msgid_cell *ptToFree; /* The cell to free */
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: msgIdDel (%d)\n", mctx.pid, tttctx->thrdNum, msgid);
/*
* Make sure there is a list !
*/
if (tttctx->firstMsgId != NULL)
{
/*
* Maybe it is the first one ?
*/
if (tttctx->firstMsgId->msgid == msgid)
{
ptToFree = tttctx->firstMsgId;
tttctx->firstMsgId = tttctx->firstMsgId->next;
if (tttctx->firstMsgId == NULL)
tttctx->lastMsgId = NULL;
free (ptToFree);
return (0);
}
/*
* Let's go through the whole list
*/
for (pt = tttctx->firstMsgId ; pt->next != NULL ; pt = pt->next)
if (pt->next->msgid == msgid)
{
/*
* Be carrefull if it is the last element of the list
*/
if (pt->next->next == NULL)
tttctx->lastMsgId = pt;
ptToFree = pt->next;
pt->next = ptToFree->next;
if (freeAttr)
if (freeAttrib (ptToFree->attribs) < 0)
return (-1);
/*
* Free the pointer itself
*/
free (ptToFree);
return (0);
}
}
/*
* Not found
*/
printf ("ldclt[%d]: T%03d: message %d not found.\n", mctx.pid, tttctx->thrdNum, msgid);
fflush (stdout);
return (-1);
}
/* New function */ /*JLS 17-11-00*/
/* ****************************************************************************
FUNCTION : getThreadStatus
PURPOSE : Get the value of a given thread's status.
INPUT : tttctx = thread context
OUTPUT : status = the thread's status
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
getThreadStatus (
thread_context *tttctx,
int *status)
{
int ret; /* Return code */
if ((ret = ldclt_mutex_lock (&(tttctx->status_mutex))) != 0)
{
fprintf (stderr,
"ldclt[%d]: Cannot mutex_lock(T%03d), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fprintf (stderr, "ldclt[%d]: Problem in getThreadStatus()\n", mctx.pid);
fflush (stderr);
return (-1);
}
*status = tttctx->status;
if ((ret = ldclt_mutex_unlock (&(tttctx->status_mutex))) != 0)
{
fprintf (stderr,
"ldclt[%d]: Cannot mutex_unlock(T%03d), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fprintf (stderr, "ldclt[%d]: Problem in getThreadStatus()\n", mctx.pid);
fflush (stderr);
return (-1);
}
return (0);
}
/* New function */ /*JLS 17-11-00*/
/* ****************************************************************************
FUNCTION : setThreadStatus
PURPOSE : Set the value of a given thread's status.
INPUT : tttctx = thread context
status = new status
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
setThreadStatus (
thread_context *tttctx,
int status)
{
int ret; /* Return code */
if ((ret = ldclt_mutex_lock (&(tttctx->status_mutex))) != 0)
{
fprintf (stderr,
"ldclt[%d]: Cannot mutex_lock(T%03d), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fprintf (stderr, "ldclt[%d]: Problem in setThreadStatus()\n", mctx.pid);
fflush (stderr);
return (-1);
}
tttctx->status = status;
if ((ret = ldclt_mutex_unlock (&(tttctx->status_mutex))) != 0)
{
fprintf (stderr,
"ldclt[%d]: Cannot mutex_unlock(T%03d), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, ret, strerror (ret));
fprintf (stderr, "ldclt[%d]: Problem in setThreadStatus()\n", mctx.pid);
fflush (stderr);
return (-1);
}
return (0);
}
/* ****************************************************************************
FUNCTION : threadMain
PURPOSE : This function is the main function of the client threads
part of this tool.
INPUT : arg = this thread's thread_context
OUTPUT : None.
RETURN : None.
DESCRIPTION :
*****************************************************************************/
void *
threadMain (
void *arg)
{
thread_context *tttctx; /* This thread's context */
int go = 1; /* Thread must continue */
int status; /* Thread's status */ /*JLS 17-11-00*/
/*
* Initialization
*/
tttctx = (thread_context *) arg;
if (setThreadStatus (tttctx, CREATED) < 0) /*JLS 17-11-00*/
{ /*JLS 17-11-00*/
tttctx->status = DEAD; /*JLS 17-11-00*/
return NULL; /*JLS 17-11-00*/
} /*JLS 17-11-00*/
tttctx->asyncHit = 0;
tttctx->binded = 0;
tttctx->fd = -1;
tttctx->lastVal = mctx.randomLow-1;
tttctx->ldapCtx = NULL;
tttctx->matcheddnp = NULL; /*JLS 15-12-00*/
tttctx->nbOpers = 0;
tttctx->totOpers = 0;
tttctx->pendingNb = 0;
tttctx->firstMsgId = NULL;
tttctx->lastMsgId = NULL;
/*
* Don't forget the buffers !!
* This should save time while redoing random values
*/
if ((mctx.mode & NEED_FILTER) || (mctx.mod2 & M2_GENLDIF)) /*JLS 19-03-01*/
{
if (mctx.mod2 & M2_RDN_VALUE) /*JLS 23-03-01*/
tttctx->bufFilter = (char *) malloc (MAX_FILTER); /*JLS 23-03-01*/
else /*JLS 23-03-01*/
{ /*JLS 23-03-01*/
/*
* Variable filter ?
*/
tttctx->bufFilter = (char *) malloc (strlen (mctx.filter) + 1);
if (tttctx->bufFilter == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("ldclt[%d]: %s: cannot malloc(tttctx->bufFilter), error=%d (%s)\n",
mctx.pid, tttctx->thrdId, errno, strerror (errno));
ldcltExit (EXIT_INIT); /*JLS 18-12-00*/
} /*JLS 06-03-00*/
if (!(mctx.mode & (RANDOM | INCREMENTAL)))
strcpy (tttctx->bufFilter, mctx.filter);
else
{
tttctx->startRandom = strlen (mctx.randomHead);
strcpy (tttctx->bufFilter, mctx.randomHead);
strcpy (&(tttctx->bufFilter[tttctx->startRandom+mctx.randomNbDigit]),
mctx.randomTail);
if (mctx.mode & VERY_VERBOSE)
{
printf ("ldclt[%d]: %s: startRandom = %d\n",
mctx.pid, tttctx->thrdId, tttctx->startRandom);
printf ("ldclt[%d]: %s: randomHead = \"%s\", randomTail = \"%s\"\n",
mctx.pid, tttctx->thrdId, mctx.randomHead, mctx.randomTail);
}
}
} /*JLS 23-03-01*/
/*
* Variable base DN ?
*/
tttctx->bufBaseDN = (char *) malloc (strlen (mctx.baseDN) + 1);
if (tttctx->bufBaseDN == NULL) /*JLS 06-03-00*/
{ /*JLS 06-03-00*/
printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufBaseDN), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, errno, strerror (errno));
ldcltExit (EXIT_INIT); /*JLS 18-12-00*/
} /*JLS 06-03-00*/
if (!(mctx.mode & RANDOM_BASE))
strcpy (tttctx->bufBaseDN, mctx.baseDN);
else
{
tttctx->startBaseDN = strlen (mctx.baseDNHead);
strcpy (tttctx->bufBaseDN, mctx.baseDNHead);
strcpy (&(tttctx->bufBaseDN[tttctx->startBaseDN+mctx.baseDNNbDigit]),
mctx.baseDNTail);
}
/*
* Variable bind DN ?
* Do not forget the random bind password below that is activated
* at the same time as the random bind DN.
*/
if (mctx.bindDN != NULL) /*JLS 05-03-01*/
{ /*JLS 05-03-01*/
tttctx->bufBindDN = (char *) malloc (strlen (mctx.bindDN) + 1);
if (tttctx->bufBindDN == NULL)
{
printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufBindDN), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, errno, strerror (errno));
ldcltExit (EXIT_INIT);
}
if (!(mctx.mode & RANDOM_BINDDN))
strcpy (tttctx->bufBindDN, mctx.bindDN);
else
{
tttctx->startBindDN = strlen (mctx.bindDNHead);
strcpy (tttctx->bufBindDN, mctx.bindDNHead);
strcpy (&(tttctx->bufBindDN[tttctx->startBindDN+mctx.bindDNNbDigit]),
mctx.bindDNTail);
}
} /*JLS 05-03-01*/
/*
* Variable bind password ?
* Remember that the random bind password feature is activated
* by the same option as the random bind DN, but has here its own
* code section for the ease of coding.
*/
if (mctx.passwd != NULL) /*JLS 05-03-01*/
{ /*JLS 05-03-01*/
tttctx->bufPasswd = (char *) malloc (strlen (mctx.passwd) + 1);
if (tttctx->bufPasswd == NULL)
{
printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufPasswd), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, errno, strerror (errno));
ldcltExit (EXIT_INIT);
}
if (!(mctx.mode & RANDOM_BINDDN))
strcpy (tttctx->bufPasswd, mctx.passwd);
else
{
tttctx->startPasswd = strlen (mctx.passwdHead);
strcpy (tttctx->bufPasswd, mctx.passwdHead);
strcpy (&(tttctx->bufPasswd[tttctx->startPasswd+mctx.passwdNbDigit]),
mctx.passwdTail);
}
}
} /*JLS 05-03-01*/
/*
* Bind DN from a file ?
* The trick (mctx.passwd = "foo bar"; ) is needed to
* simplify the code, because in many places we check
* if mctx.passwd exist before sending password.
*/
if (mctx.mod2 & M2_RNDBINDFILE) /*JLS 03-05-01*/
{ /*JLS 03-05-01*/
tttctx->bufBindDN = (char *) malloc (MAX_DN_LENGTH); /*JLS 03-05-01*/
tttctx->bufPasswd = (char *) malloc (MAX_DN_LENGTH); /*JLS 03-05-01*/
mctx.passwd = "foo bar"; /* trick... */ /*JLS 03-05-01*/
} /*JLS 03-05-01*/
/*
* Initiates the attribute replace buffers
*/
if (mctx.mode & ATTR_REPLACE) /* New */ /*JLS 21-11-00*/
{
tttctx->bufAttrpl = (char *) malloc (strlen (mctx.attrpl) + 1);
if (tttctx->bufAttrpl == NULL)
{
printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufAttrpl), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, errno, strerror (errno));
ldcltExit (EXIT_INIT); /*JLS 18-12-00*/
}
tttctx->startAttrpl = strlen (mctx.attrplHead);
strcpy (tttctx->bufAttrpl, mctx.attrplHead);
strcpy (&(tttctx->bufAttrpl[tttctx->startAttrpl+mctx.attrplNbDigit]),
mctx.attrplTail);
}
/*
* We are ready to go !
*/
status = RUNNING; /*JLS 17-11-00*/
if (setThreadStatus (tttctx, RUNNING) < 0) /*JLS 17-11-00*/
status = DEAD; /*JLS 17-11-00*/
/*
* Let's go !
*/
while (go && (status != DEAD) && (status != MUST_SHUTDOWN)) /*JLS 17-11-00*/
{
if (mctx.waitSec > 0)
{ /*JLS 17-11-00*/
ldclt_sleep (mctx.waitSec);
/*
* Maybe we should shutdown ?
*/
if (getThreadStatus (tttctx, &status) < 0) /*JLS 17-11-00*/
break; /*JLS 17-11-00*/
if (status == MUST_SHUTDOWN) /*JLS 17-11-00*/
break; /*JLS 17-11-00*/
} /*JLS 17-11-00*/
/*
* Do a LDAP request
*/
if (tttctx->mode & ADD_ENTRIES)
if (doAddEntry (tttctx) < 0)
{
go = 0;
continue;
}
if (tttctx->mode & ATTR_REPLACE) /*JLS 21-11-00*/
if (doAttrReplace (tttctx) < 0) /*JLS 21-11-00*/
{ /*JLS 21-11-00*/
go = 0; /*JLS 21-11-00*/
continue; /*JLS 21-11-00*/
} /*JLS 21-11-00*/
if (tttctx->mode & DELETE_ENTRIES)
if (doDeleteEntry (tttctx) < 0)
{
go = 0;
continue;
}
if (mctx.mod2 & M2_BINDONLY) /*JLS 04-05-01*/
if (doBindOnly (tttctx) < 0) /*JLS 04-05-01*/
{ /*JLS 04-05-01*/
go = 0; /*JLS 04-05-01*/
continue; /*JLS 04-05-01*/
} /*JLS 04-05-01*/
if (tttctx->mode & EXACT_SEARCH)
if (doExactSearch (tttctx) < 0)
{
go = 0;
continue;
}
if (tttctx->mode & RENAME_ENTRIES)
if (doRename (tttctx) < 0)
{
go = 0;
continue;
}
/*
* Maybe a specific scenario ?
*/
if (tttctx->mode & SCALAB01) /*JLS 08-01-01*/
if (doScalab01 (tttctx) < 0) /*JLS 08-01-01*/
{ /*JLS 08-01-01*/
go = 0; /*JLS 08-01-01*/
continue; /*JLS 08-01-01*/
} /*JLS 08-01-01*/
/*
* Maybe genldif mode ?
*/
if (mctx.mod2 & M2_GENLDIF) /*JLS 19-03-01*/
if (doGenldif (tttctx) < 0) /*JLS 19-03-01*/
{ /*JLS 19-03-01*/
ldclt_flush_genldif(); /*JLS 02-04-01*/
go = 0; /*JLS 19-03-01*/
continue; /*JLS 19-03-01*/
} /*JLS 19-03-01*/
/*
* Check the thread's status
*/
if (getThreadStatus (tttctx, &status) < 0) /*JLS 17-11-00*/
break; /*JLS 17-11-00*/
}
/*
* End of thread
*/
/* [156984] once setting "DEAD", nothing should be done in the context */
/* moved the dead message above setThreadStatus(DEAD) */
printf ("ldclt[%d]: T%03d: thread is dead.\n", mctx.pid, tttctx->thrdNum);
fflush (stdout);
if (setThreadStatus (tttctx, DEAD) < 0) /*JLS 17-11-00*/
{ /*JLS 17-11-00*/
ldclt_sleep (1); /*JLS 17-11-00*/
tttctx->status = DEAD; /* Force it !!! */ /*JLS 17-11-00*/
} /*JLS 17-11-00*/
return (arg);
}
/* End of file */
--- NEW FILE utils.c ---
#ident "ldclt @(#)utils.c 1.4 01/01/11"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : utils.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 14 November 2000
DESCRIPTION :
This file contains the utilities functions that will be
used as well by ldclt and by the genldif command, e.g.
the random generator functions, etc...
The main target/reason for creating this file is to be
able to easely separate these functions from ldclt's
framework and data structures, and thus to provide a
kind of library suitable for any command.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
14/11/00 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
14/11/00 | JL Schwing | 1.2 : Port on AIX.
---------+--------------+------------------------------------------------------
16/11/00 | JL Schwing | 1.3 : lint cleanup.
---------+--------------+------------------------------------------------------
11/01/01 | JL Schwing | 1.4 : Add new function rndlim().
---------+--------------+------------------------------------------------------
*/
#include "utils.h" /* Basic definitions for this file */
#include <stdio.h> /* sprintf(), etc... */
#include <stdlib.h> /* lrand48(), etc... */
#include <ctype.h> /* isascii(), etc... */ /*JLS 16-11-00*/
#include <string.h> /* strerror(), etc... */ /*JLS 14-11-00*/
/*
* Some global variables...
*/
#ifdef AIX
pthread_mutex_t ldcltrand48_mutex; /* ldcltrand48() */ /*JLS 14-11-00*/
#endif
#ifdef AIX /* New */ /*JLS 14-11-00*/
/* ****************************************************************************
FUNCTION : ldcltrand48
PURPOSE : Implement a thread-save version of lrand48()
INPUT : None.
OUTPUT : None.
RETURN : A random value.
DESCRIPTION :
*****************************************************************************/
long int
ldcltrand48 (void)
{
long int val;
int ret;
if ((ret = pthread_mutex_lock (&ldcltrand48_mutex)) != 0)
{
fprintf (stderr,
"Cannot pthread_mutex_lock(ldcltrand48_mutex), error=%d (%s)\n",
ret, strerror (ret));
fflush (stderr);
ldcltExit (99);
}
val = lrand48();
if ((ret = pthread_mutex_unlock (&ldcltrand48_mutex)) != 0)
{
fprintf (stderr,
"Cannot pthread_mutex_unlock(ldcltrand48_mutex), error=%d (%s)\n",
ret, strerror (ret));
fflush (stderr);
ldcltExit (99);
}
return (val);
}
#else /* AIX */
#define ldcltrand48() lrand48()
#endif /* AIX */
/* ****************************************************************************
FUNCTION : utilsInit
PURPOSE : Initiates the utilities functions.
INPUT : None.
OUTPUT : None.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int
utilsInit (void)
{
#ifdef AIX /*JLS 14-11-00*/
int ret; /*JLS 14-11-00*/
/*
* Initiate the mutex that protect ldcltrand48()
*/
if ((ret = pthread_mutex_init(&ldcltrand48_mutex, NULL)) != 0)/*JLS 14-11-00*/
{ /*JLS 14-11-00*/
fprintf (stderr, "ldclt: %s\n", strerror (ret)); /*JLS 14-11-00*/
fprintf (stderr, /*JLS 14-11-00*/
"Error: cannot initiate ldcltrand48_mutex\n"); /*JLS 14-11-00*/
fflush (stderr); /*JLS 14-11-00*/
return (-1); /*JLS 14-11-00*/
} /*JLS 14-11-00*/
#endif /*JLS 14-11-00*/
/*
* No error
*/
return (0);
}
/* ****************************************************************************
FUNCTION : rndlim
PURPOSE : Returns a random number between the given limits.
INPUT : low = low limit
high = high limit
OUTPUT : None.
RETURN : The random value.
DESCRIPTION :
*****************************************************************************/
int
rndlim (
int low,
int high)
{
return (low + ldcltrand48() % (high-low+1));
}
/* ****************************************************************************
FUNCTION : rnd
PURPOSE : Creates a random number string between the given
arguments. The string is returned in the buffer.
INPUT : low = low limit
high = high limit
ndigits = number of digits
OUTPUT : buf = buffer to write the random string. Note that
it is generated with fixed number of digits,
completed with leading '0'.
RETURN : None.
DESCRIPTION :
*****************************************************************************/
void
rnd (
char *buf,
int low,
int high,
int ndigits)
{
sprintf (buf, "%0*d", ndigits,
(int)(low + (ldcltrand48() % (high-low+1)))); /*JLS 14-11-00*/
}
/* ****************************************************************************
FUNCTION : rndstr
PURPOSE : Return a random string, of length ndigits. The string
is returned in the buf.
INPUT : ndigits = number of digits required.
OUTPUT : buf = the buf must be long enough to contain the
requested string.
RETURN : None.
DESCRIPTION :
*****************************************************************************/
void
rndstr (
char *buf,
int ndigits)
{
unsigned int rndNum; /* The random value */
int charNum; /* Random char in buf */
int byteNum; /* Byte in rndNum */
char newChar; /* The new byte as a char */
char *rndArray; /* To cast the rndNum into chars */
charNum = 0;
byteNum = 4;
rndArray = (char *)(&rndNum);
while (charNum < ndigits)
{
/*
* Maybe we should generate a new random number ?
*/
if (byteNum == 4)
{
rndNum = ldcltrand48(); /*JLS 14-11-00*/
byteNum = 0;
}
/*
* Is it a valid char ?
*/
newChar = rndArray[byteNum];
/*
* The last char must not be a '\' nor a space.
*/
if (!(((charNum+1) == ndigits) &&
((newChar == '\\') || (newChar == ' '))))
{
/*
* First, there are some special characters that have a meaning for
* LDAP, and thus that must be quoted. What LDAP's rfc1779 means by
* "to quote" may be translated by "to antislash"
* Note: we do not check the \ because in this way, it leads to randomly
* quote some valid characters.
*/
if ((newChar == '=') || (newChar == ';') || (newChar == ',') ||
(newChar == '+') || (newChar == '"') || (newChar == '<') ||
(newChar == '>') || (newChar == '#'))
{
/*
* Ensure that the previous char is *not* a \ otherwise
* it will result in a \\, rather than a \,
* If it is the case, add one more \ to have \\\,
*/
if ((charNum > 0) && (buf[charNum-1] == '\\'))
{
if ((charNum+3) < ndigits)
{
buf[charNum++] = '\\';
buf[charNum++] = '\\';
buf[charNum++] = newChar;
}
}
else
{
if ((charNum+2) < ndigits)
{
buf[charNum++] = '\\';
buf[charNum++] = newChar;
}
}
}
else
{
/*
* Maybe strict ascii required ?
*/
if (1)
{
if (isascii (newChar) && !iscntrl(newChar))
buf[charNum++] = newChar;
}
else
{
if (((newChar >= 0x30) && (newChar <= 0x7a)) ||
((newChar >= 0xc0) && (newChar <= 0xf6)))
buf[charNum++] = newChar;
}
}
}
/*
* Next byte of the random value.
*/
byteNum++;
}
/*
* End of function
*/
buf[charNum] = '\0';
}
/* End of file */
--- NEW FILE utils.h ---
#ident "ldclt @(#)utils.h 1.3 01/01/11"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : utils.h
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 14 November 2000
DESCRIPTION :
This files contians the prototypes and other
definitions related to utils.c, utilities functions
that will be used as well by ldclt and by the genldif
command.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
14/11/00 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
16/11/00 | JL Schwing | 1.2 : Fix typo.
---------+--------------+------------------------------------------------------
11/01/01 | JL Schwing | 1.3 : Add new function rndlim().
---------+--------------+------------------------------------------------------
*/
/*
* Functions exported by utils.c
*/
extern void rnd (char *buf, int low, int high, int ndigits);
extern int rndlim (int low, int high);
extern void rndstr (char *buf, int ndigits);
extern int utilsInit (void);
/* End of file */
--- NEW FILE version.c ---
char *ldcltVersion="4.23";
--- NEW FILE workarounds.c ---
#ident "ldclt @(#)workarounds.c 1.5 00/12/01"
/** BEGIN COPYRIGHT BLOCK
* This Program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; version 2 of the License.
*
* This Program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA.
*
* In addition, as a special exception, Red Hat, Inc. gives You the additional
* right to link the code of this Program with code not covered under the GNU
* General Public License ("Non-GPL Code") and to distribute linked combinations
* including the two, subject to the limitations in this paragraph. Non-GPL Code
* permitted under this exception must only link to the code of this Program
* through those well defined interfaces identified in the file named EXCEPTION
* found in the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline functions from
* the Approved Interfaces without causing the resulting work to be covered by
* the GNU General Public License. Only Red Hat, Inc. may make changes or
* additions to the list of Approved Interfaces. You must obey the GNU General
* Public License in all respects for all of the Program code and other code used
* in conjunction with the Program except the Non-GPL Code covered by this
* exception. If you modify this file, you may extend this exception to your
* version of the file, but you are not obligated to do so. If you do not wish to
* provide this exception without modification, you must delete this exception
* statement from your version and license this file solely under the GPL without
* exception.
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
* Copyright (C) 2006 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
/*
FILE : workarounds.c
AUTHOR : Jean-Luc SCHWING
VERSION : 1.0
DATE : 15 December 1998
DESCRIPTION :
This file contains special work-arounds targetted to
fix, or work-around, the various bugs that may appear
in Solaris 2.7 libldap.
LOCAL : None.
HISTORY :
---------+--------------+------------------------------------------------------
dd/mm/yy | Author | Comments
---------+--------------+------------------------------------------------------
15/12/98 | JL Schwing | Creation
---------+--------------+------------------------------------------------------
19/09/00 | JL Schwing | 1.2: Port on Netscape's libldap. This is realized in
| such a way that this library become the default
| way so a ifdef for Solaris will be used...
---------+--------------+------------------------------------------------------
16/11/00 | JL Schwing | 1.3 : lint cleanup.
-----------------------------------------------------------------------------
29/11/00 | JL Schwing | 1.4 : Port on NT 4.
---------+--------------+------------------------------------------------------
01/12/00 | JL Schwing | 1.5 : Port on Linux.
---------+--------------+------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* exit(), ... */ /*JLS 16-11-00*/
#include "lber.h"
#include "ldap.h"
#ifdef SOLARIS_LIBLDAP /*JLS 19-09-00*/
#include "ldap-private.h"
#else /*JLS 19-09-00*/
#ifndef _WIN32 /*JLS 01-12-00*/
#include <pthread.h> /*JLS 01-12-00*/
#endif /*JLS 01-12-00*/
#include "port.h" /* Portability definitions */ /*JLS 29-11-00*/
#include "ldclt.h" /*JLS 19-09-00*/
#endif /*JLS 19-09-00*/
/* ****************************************************************************
FUNCTION : getFdFromLdapSession
PURPOSE : This function is a work-around for the bug 4197228
that is not expected to be fixed soon...
INPUT : ld = ldap session to process.
OUTPUT : fd = the corresponding fd.
RETURN : -1 if error, 0 else.
DESCRIPTION :
*****************************************************************************/
int getFdFromLdapSession (
LDAP *ld,
int *fd)
{
#ifdef SOLARIS_LIBLDAP /*JLS 19-09-00*/
*fd = ld->ld_sb.sb_sd;
return (0);
#else /*JLS 19-09-00*/
printf("Error : getFdFromLdapSession() not implemented...\n");/*JLS 19-09-00*/
exit (EXIT_OTHER); /*JLS 19-09-00*/
#endif /*JLS 19-09-00*/
}
/* End of file */
17 years, 2 months
[Fedora-directory-commits] ldapserver/ldap/servers/slapd/tools Makefile, 1.9, 1.10
by Doctor Conrad
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/tools
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv8602
Modified Files:
Makefile
Log Message:
[164596] LDCLT distributed with Directory Server
integrated ldclt from DSRK into the DS source tree.
Index: Makefile
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/tools/Makefile,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Makefile 6 Jan 2006 00:53:18 -0000 1.9
+++ Makefile 11 Jan 2006 01:54:24 -0000 1.10
@@ -171,7 +171,7 @@
BINS= $(LDIF) $(PWDHASH) $(KEYUPG) $(MMLDIF) $(MIGRATECRED) $(DBSCAN)
EXTRABINS= $(EGGENCODE)
-all: $(OBJDEST) $(BINDIR) $(LDAP_ADMIN_BIN_RELDIR) $(BINS) buildRsearch
+all: $(OBJDEST) $(BINDIR) $(LDAP_ADMIN_BIN_RELDIR) $(BINS) buildRsearch buildLdclt
extras: $(OBJDEST) $(BINDIR) $(EGGENCODE)
@@ -202,6 +202,9 @@
buildRsearch:
cd rsearch; $(MAKE)
+buildLdclt:
+ cd ldclt; $(MAKE)
+
clean:
-$(RM) $(ALL_OBJS)
-$(RM) $(BINS) $(EXTRABINS)
17 years, 2 months