From 2d39f617b84d586a097684a025647aeef3dadc6e Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Tue, 22 Dec 1998 03:17:25 +0000
Subject: [PATCH] Add LDAP_OPT_API_FEATURE_INFO to obtain feature info (ie:
 version) at runtime.

---
 include/ldap.h              | 10 +++++++
 libraries/libldap/apitest.c | 11 ++++++++
 libraries/libldap/options.c | 52 +++++++++++++++++++++++++++----------
 3 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/include/ldap.h b/include/ldap.h
index b84ece8613..f541337c93 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -51,6 +51,13 @@ LDAP_BEGIN_DECL
 /* #define LDAP_API_OPERATION_SESSION_SAFE	1	*/
 #endif
 
+#define LDAP_API_FEATURE_INFO 1
+
+typedef struct ldap_apifeature_info {
+	char*	ldapaif_name;    /* matches LDAP_API_FEATURE_... less the prefix */
+	int		ldapaif_version; /* matches the value LDAP_API_FEATURE_... */
+} LDAPAPIFeatureInfo;
+
 #define LDAP_PORT		389
 
 #define LDAP_ROOT_DSE				""
@@ -81,6 +88,9 @@ LDAP_BEGIN_DECL
 #define	LDAP_OPT_ERROR_NUMBER		0x0031
 #define LDAP_OPT_ERROR_STRING		0x0032
 
+/* LDAP_OPTions under IETF discussion */
+#define LDAP_OPT_API_FEATURE_INFO	0x0100
+
 /* not defined by current draft */
 /*	for LDAPv2 compatibility */
 #define LDAP_OPT_DNS				0x1001	/* use DN & DNS */
diff --git a/libraries/libldap/apitest.c b/libraries/libldap/apitest.c
index 0364b1e378..8438753ec2 100644
--- a/libraries/libldap/apitest.c
+++ b/libraries/libldap/apitest.c
@@ -80,8 +80,19 @@ main(int argc, char **argv)
 		for(i=0; api.ldapai_extensions[i] != NULL; i++) /* empty */;
 		printf("  Extensions:        %d\n", i);
 		for(i=0; api.ldapai_extensions[i] != NULL; i++) {
+#ifndef LDAP_API_FEATURE_INFO
 			printf("                     %s\n",
 				api.ldapai_extensions[i]);
+#else
+			LDAPAPIFeatureInfo fi;
+			fi.ldapaif_name = api.ldapai_extensions[i];
+			fi.ldapaif_version = 0;
+
+			ldap_get_option(NULL, LDAP_OPT_API_FEATURE_INFO, &fi);
+
+			printf("                     %s (%d)\n",
+				api.ldapai_extensions[i], fi.ldapaif_version);
+#endif
 		}
 	}
 
diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c
index c047f5a814..6468f9166c 100644
--- a/libraries/libldap/options.c
+++ b/libraries/libldap/options.c
@@ -8,30 +8,33 @@
 
 #include "ldap-int.h"
 
-static const char* features[] = {
+static const LDAPAPIFeatureInfo features[] = {
+#ifdef LDAP_API_FEATURE_INFO
+	{"INFO", LDAP_API_FEATURE_INFO},
+#endif
 #ifdef LDAP_API_FEATURE_THREAD_SAFE
-	"THREAD_SAFE",
+	{"THREAD_SAFE", LDAP_API_FEATURE_THREAD_SAFE},
 #endif
 #ifdef LDAP_API_FEATURE_SESSION_THREAD_SAFE
-	"SESSION_THREAD_SAFE",
+	{"SESSION_THREAD_SAFE", LDAP_API_FEATURE_SESSION_THREAD_SAFE},
 #endif
 #ifdef LDAP_API_FEATURE_OPERATION_THREAD_SAFE
-	"OPERATION_THREAD_SAFE",
+	{"OPERATION_THREAD_SAFE", LDAP_API_FEATURE_OPERATION_THREAD_SAFE},
 #endif
 #ifdef LDAP_API_FEATURE_X_OPENLDAP_REEENTRANT
-	"X_OPENLDAP_REENTRANT",
+	{"X_OPENLDAP_REENTRANT", LDAP_API_FEATURE_X_OPENLDAP_REENTRANT},
 #endif
 #if defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) && \
 	defined( LDAP_THREAD_SAFE )
-	"X_OPENLDAP_THREAD_SAFE",
+	{"X_OPENLDAP_THREAD_SAFE", LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE},
 #endif
 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-	"X_OPENLDAP_V2_DNS",
+	{"X_OPENLDAP_V2_DNS", LDAP_API_FEATURE_X_OPENLDAP_V2_DNS},
 #endif
 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
-	"X_OPENLDAP_V2_REFERRALS",
+	{"X_OPENLDAP_V2_REFERRALS", LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS},
 #endif
-	NULL
+	{NULL, 0}
 };
 
 int
@@ -75,15 +78,17 @@ ldap_get_option(
 			info->ldapai_api_version = LDAP_API_VERSION;
 			info->ldapai_api_version = LDAP_API_VERSION;
 			info->ldapai_protocol_version = LDAP_VERSION_MAX;
-			if(features[0] == NULL) {
+
+			if(features[0].ldapaif_name == NULL) {
 				info->ldapai_extensions = NULL;
 			} else {
 				int i;
-				info->ldapai_extensions = malloc(sizeof(features));
+				info->ldapai_extensions = malloc(sizeof(char *) *
+					sizeof(features)/sizeof(LDAPAPIFeatureInfo));
 
-				for(i=0; features[i] != NULL; i++) {
+				for(i=0; features[i].ldapaif_name != NULL; i++) {
 					info->ldapai_extensions[i] =
-						ldap_strdup(features[i]);
+						ldap_strdup(features[i].ldapaif_name);
 				}
 
 				info->ldapai_extensions[i] = NULL;
@@ -178,6 +183,23 @@ ldap_get_option(
 		}
 		break;
 
+	case LDAP_OPT_API_FEATURE_INFO: {
+			LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
+			int i;
+
+			if(info == NULL) return -1;
+			if(info->ldapaif_name == NULL) return -1;
+
+			for(i=0; features[i].ldapaif_name != NULL; i++) {
+				if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
+					info->ldapaif_version =
+						features[i].ldapaif_version;
+					return 0;
+				}
+			}
+		}
+		break;
+
 	case LDAP_OPT_DEBUG_LEVEL:
 		* (int *) outvalue = lo->ldo_debug;
 		break;
@@ -325,6 +347,10 @@ ldap_set_option(
 			ld->ld_error = err;
 		} return 0;
 
+	case LDAP_OPT_API_FEATURE_INFO:
+		/* read-only */
+		break;
+
 	case LDAP_OPT_DEBUG_LEVEL:
 		lo->ldo_debug = * (int *) invalue;
 		return 0;
-- 
GitLab