osaf/libs/core/common/Makefile.am                  |    1 +
 osaf/libs/core/common/include/Makefile.am          |    1 +
 osaf/libs/core/common/include/osaf_extended_name.h |  232 +++++++++++++++++++++
 osaf/libs/core/common/osaf_extended_name.c         |  184 ++++++++++++++++
 osaf/libs/core/leap/sysf_def.c                     |    3 +
 5 files changed, 421 insertions(+), 0 deletions(-)


Add support library functions that make it easier for agent libraries to handle
the extended SaNameT format in old SAF APIs that use the SaNameT type.

diff --git a/osaf/libs/core/common/Makefile.am 
b/osaf/libs/core/common/Makefile.am
--- a/osaf/libs/core/common/Makefile.am
+++ b/osaf/libs/core/common/Makefile.am
@@ -34,6 +34,7 @@ libopensaf_common_la_SOURCES = \
        osaf_utility.c \
        osaf_poll.c \
        osaf_time.c \
+       osaf_extended_name.c \
        nid_start_util.c \
        saf_edu.c \
        daemon.c \
diff --git a/osaf/libs/core/common/include/Makefile.am 
b/osaf/libs/core/common/include/Makefile.am
--- a/osaf/libs/core/common/include/Makefile.am
+++ b/osaf/libs/core/common/include/Makefile.am
@@ -30,6 +30,7 @@ noinst_HEADERS = \
        sprr_dl_api.h \
        nid_start_util.h \
        daemon.h \
+       osaf_extended_name.h \
        osaf_unicode.h \
        osaf_poll.h \
        osaf_time.h \
diff --git a/osaf/libs/core/common/include/osaf_extended_name.h 
b/osaf/libs/core/common/include/osaf_extended_name.h
new file mode 100644
--- /dev/null
+++ b/osaf/libs/core/common/include/osaf_extended_name.h
@@ -0,0 +1,232 @@
+/*      -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2014 The OpenSAF Foundation
+ *
+ * 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. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+/** @file
+ *
+ * This file contains functions to support tunneling strings through the legacy
+ * SaNameT structure. The definitions in this file are for internal use within
+ * OpenSAF only, and are intended to be used by the agent libraries to support
+ * legacy SAF API functions that have SaNameT parameters.
+ */
+
+#ifndef OPENSAF_OSAF_LIBS_CORE_COMMON_INCLUDE_OSAF_EXTENDED_NAME_H_
+#define OPENSAF_OSAF_LIBS_CORE_COMMON_INCLUDE_OSAF_EXTENDED_NAME_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include "saAis.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+enum {
+  /**
+   *  Magic number stored in the .length field (the first 16-bit word) of the
+   *  legacy SaNameT type, to indicate that it contains a string longer than or
+   *  equal to SA_MAX_UNEXTENDED_NAME_LENGTH bytes. A pointer to the string is
+   *  stored immediately after the first 16-bit word (typically in the first
+   *  four or eight bytes of the .value field of the legacy SaNameT type.
+   */
+  kExtendedNameMagic = 0xcd2b,
+
+  /**
+   *  Maximum length of a distinguished name, not counting the terminating NUL
+   *  character.
+   */
+  kMaxDnLength = 2048
+};
+
+/**
+ *  @brief Initialize the extended SaNameT functionality.
+ *
+ *  This function reads the environment variable SA_ENABLE_EXTENDED_NAMES to
+ *  determine whether extended SaNameT shall be enabled or not. It shall be
+ *  called by all top-level saXxxInitialize() functions, so that it is
+ *  guaranteed to have been called before any other SAF API function.
+ */
+void osaf_extended_name_init(void);
+
+/**
+ *  @brief Check whether extended SaNameT is enabled.
+ *
+ *  This function returns true if extended SaNameT is enabled, and false
+ *  otherwise. The function osaf_extended_name_init() must have been called
+ *  prior to calling this function.
+ */
+static inline bool osaf_is_extended_names_enabled(void);
+
+/**
+ *  @brief Set the string pointer in the legacy SaNameT type.
+ *
+ *  This function sets the legacy SaNameT @a name to the NUL-terminated string
+ *  @a value. If length of the string @a value is strictly less than
+ *  SA_MAX_UNEXTENDED_NAME_LENGTH bytes, the contents of the string is copied
+ *  into the legacy SaNameT type and can be read in a backwards compatible way
+ *  by legacy applications. If length of the string @a value is greater than or
+ *  equal to SA_MAX_UNEXTENDED_NAME_LENGTH, no copying is performed. Instead, a
+ *  reference to the original string @a value is stored in @a name. In this
+ *  case, it is important that @a value is not modified or freed until @a name
+ *  is either overwritten or freed.
+ */
+void osaf_extended_name_lend(SaConstStringT value, SaNameT* name);
+
+/**
+ *  @brief Get a pointer to the string in the legacy SaNameT type.
+ *
+ *  This function returns a pointer to the string value in the legacy SaNameT 
@a
+ *  name. If the .length field of the legacy SaNameT structure is not equal to
+ *  the magic number @a kExtendedNameMagic, the returned pointer points to a
+ *  copy of the string stored inside @a name. Otherwise, the returned pointer
+ *  points to memory outside @a name.
+ *
+ *  NOTE: This function is intended to be used in agent libraries to read
+ *  SaNameT structures that may have been set by legacy application
+ *  code. Therefore, the returned string pointer is not guaranteed to be NUL
+ *  terminated. To get NUL-terminated string, you can do the following: use
+ *  osaf_extended_name_length() to calculate the length of the string, call
+ *  malloc() to allocate a memory area that is one byte larger than the string
+ *  length, then use memcpy() to copy the string to the allocated memory, and
+ *  finally add a NUL character at the end of the copied string.
+ */
+SaConstStringT osaf_extended_name_borrow(const SaNameT* name);
+
+/**
+ *  @brief Check if an SaNameT is in using the extended (long) format.
+ *
+ *  This function returns true if the SaNameT @a name is using the new extended
+ *  (long) format where the SaNameT structure contains a pointer to the string,
+ *  and false if @a name is using the legacy format where a copy of the string
+ *  is stored inside the SaNameT structure.
+ */
+bool osaf_is_an_extended_name(const SaNameT* name);
+
+/**
+ *  @brief Check if an SaNameT passes some sanity checks.
+ *
+ *  This function returns true if the SaNameT @a name passes some sanity 
checks,
+ *  e.g. that the length field is either equal to the magic number @a
+ *  kExtendedNameMagic, or strictly less than SA_MAX_UNEXTENDED_NAME_LENGTH. It
+ *  returns false if @a name failed some of the sanity checks. It may of course
+ *  also crash the process if @a name is severly corrupted, e.g. if the pointer
+ *  stored inside @a name points to inaccessible memory.
+ *
+ *  NOTE: This function is intended to be used in agent libraries to read
+ *  SaNameT structures that may have been set by legacy application
+ *  code. Therefore, it does not require the string to be NUL terminated if it
+ *  is stored in the legacy (short) format.
+ */
+bool osaf_is_extended_name_valid(const SaNameT* name);
+
+/**
+ *  @brief Check if an SaNameT contains the empty string.
+ *
+ *  This function works also with legacy SaNameT structures containing a string
+ *  that is not NUL-terminated, and strings where there is a mismatch between
+ *  the string length as indicated by the .length field an any NUL character
+ *  contained in the string. It is equivalent to checking if the result of
+ *  osaf_extended_name_length() is equal to zero, but may execute faster.
+ */
+bool osaf_is_extended_name_empty(const SaNameT* name);
+
+/**
+ *  @brief Calculate the length of an SaNameT.
+ *
+ *  This function returns the length of the SaNameT @a name. It may abort the
+ *  process if @a name is not valid, but the sanity checks in this function are
+ *  guaranteed to be no stricter than the checks in the
+ *  osaf_is_extended_name_valid() function.
+ *
+ *  This function works also with legacy SaNameT structures containing a string
+ *  that is not NUL-terminated, and strings where there is a mismatch between
+ *  the string length as indicated by the .length field an any NUL character
+ *  contained in the string (in which case the shortest of the two string
+ *  lengths is returned).
+ */
+size_t osaf_extended_name_length(const SaNameT* name);
+
+/**
+ *  @brief Set an SaNameT to the empty string.
+ *
+ *  This function sets @a name to the empty string, i.e. a string of length
+ *  zero.
+ */
+void osaf_extended_name_clear(SaNameT* name);
+
+/**
+ *  @brief Move a dynamically allocated string into an SaNameT structure.
+ *
+ *  This function sets the SaNameT structure @a name to point to the 
dynamically
+ *  allocated string @a value. The string @a value must have been dynamically
+ *  allocated using malloc(), calloc(), strdup() or a similar function. When
+ *  this function returns, the original string pointer @a value is no longer
+ *  valid and must not be used. When the SaNameT structure @a name is no longer
+ *  needed, the dynamically allocated memory must be freed by a call to
+ *  osaf_extended_name_free().
+ *
+ *  This function works also in the case when @a value is a NULL pointer, in
+ *  which case it simply calls osaf_extended_name_clear().
+ */
+void osaf_extended_name_steal(SaStringT value, SaNameT* name);
+
+/**
+ *  @brief Make a copy of a string and store it in an SaNameT structure.
+ *
+ *  This function sets @a name to point to a newly allocated copy of the string
+ *  @a value. When the SaNameT structure @a name is no longer needed, the
+ *  dynamically allocated memory must be freed by a call to
+ *  osaf_extended_name_free().
+ *
+ *  When the length of the string is strictly less than
+ *  SA_MAX_UNEXTENDED_NAME_LENGTH, the SaNameT structure can be used in a
+ *  backwards compatible way by legacy applications that do not understand the
+ *  new extended SaNameT format.
+ *
+ *  This function works also in the case when @a value is a NULL pointer, in
+ *  which case it simply calls osaf_extended_name_clear().
+ */
+void osaf_extended_name_alloc(SaConstStringT value, SaNameT* name);
+
+/**
+ *  @brief Free dynamically allocated memory pointed to by an SaNameT.
+ *
+ *  This function checks if the SaNameT @a name contains a pointer (i.e. is
+ *  using the new extended format), and if so, it will call free() to release
+ *  the dynamically allocated memory referenced by this SaNameT. When this
+ *  function returns, @a name is no longer valid and must not be used (until it
+ *  is re-initialized).
+ *
+ *  When the length of the string is strictly less than
+ *  SA_MAX_UNEXTENDED_NAME_LENGTH, the SaNameT structure can be used in a
+ *  backwards compatible way by legacy applications that do not understand the
+ *  new extended SaNameT format.
+ *
+ *  This function works also in the case when @a name is a NULL pointer, in
+ *  which case it does nothing.
+ */
+void osaf_extended_name_free(SaNameT* name);
+
+static inline bool osaf_is_extended_names_enabled(void) {
+  extern bool osaf_extended_names_enabled;
+  return osaf_extended_names_enabled;
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif  /* OPENSAF_OSAF_LIBS_CORE_COMMON_INCLUDE_OSAF_EXTENDED_NAME_H_ */
diff --git a/osaf/libs/core/common/osaf_extended_name.c 
b/osaf/libs/core/common/osaf_extended_name.c
new file mode 100644
--- /dev/null
+++ b/osaf/libs/core/common/osaf_extended_name.c
@@ -0,0 +1,184 @@
+/*     -*- OpenSAF  -*-
+ *
+ * (C) Copyright 2014 The OpenSAF Foundation
+ *
+ * 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. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Ericsson AB
+ *
+ */
+
+#ifndef SA_EXTENDED_NAME_SOURCE
+#define SA_EXTENDED_NAME_SOURCE
+#endif
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include "osaf_extended_name.h"
+#include "ncsgl_defs.h"
+
+static inline SaConstStringT get_ptr(const SaNameT* name);
+static inline void set_ptr(SaConstStringT value, SaNameT* name);
+
+bool osaf_extended_names_enabled = false;
+static bool extended_names_initialized = false;
+
+static inline SaConstStringT get_ptr(const SaNameT* name)
+{
+       union {
+               SaConstStringT pointer;
+               SaUint8T bytes[sizeof(SaConstStringT)];
+       } tmp;
+       memcpy(tmp.bytes, name->_opaque + 1, sizeof(SaConstStringT));
+       return tmp.pointer;
+}
+
+static inline void set_ptr(SaConstStringT value, SaNameT* name)
+{
+       union {
+               SaConstStringT pointer;
+               SaUint8T bytes[sizeof(SaConstStringT)];
+       } tmp;
+       tmp.pointer = value;
+       name->_opaque[0] = kExtendedNameMagic;
+       memcpy(name->_opaque + 1, tmp.bytes, sizeof(SaConstStringT));
+}
+
+void osaf_extended_name_init(void)
+{
+       if (!extended_names_initialized) {
+               char* enable = getenv("SA_ENABLE_EXTENDED_NAMES");
+               if (enable != NULL && enable[0] == '1' && enable[1] == '\0') {
+                       osaf_extended_names_enabled = true;
+               } else {
+                       osaf_extended_names_enabled = false;
+               }
+               extended_names_initialized = true;
+       }
+}
+
+void osaf_extended_name_lend(SaConstStringT value, SaNameT* name)
+{
+       size_t length = strlen(value);
+       if (length < SA_MAX_UNEXTENDED_NAME_LENGTH) {
+               name->_opaque[0] = length;
+               memcpy(name->_opaque + 1, value, length + 1);
+       } else {
+               set_ptr(value, name);
+       }
+}
+
+SaConstStringT osaf_extended_name_borrow(const SaNameT* name)
+{
+       size_t length = name->_opaque[0];
+       SaConstStringT value;
+       if (length != kExtendedNameMagic) {
+               value = (SaConstStringT) (name->_opaque + 1);
+       } else {
+               value = get_ptr(name);
+       }
+       return value;
+}
+
+bool osaf_is_an_extended_name(const SaNameT* name)
+{
+       return name->_opaque[0] == kExtendedNameMagic;
+}
+
+bool osaf_is_extended_name_valid(const SaNameT* name)
+{
+       size_t length = name->_opaque[0];
+       bool is_valid;
+       if (length != kExtendedNameMagic) {
+               is_valid = length < SA_MAX_UNEXTENDED_NAME_LENGTH;
+       } else {
+               is_valid = osaf_extended_names_enabled &&
+                       strnlen(get_ptr(name), SA_MAX_UNEXTENDED_NAME_LENGTH) >=
+                       SA_MAX_UNEXTENDED_NAME_LENGTH;
+       }
+       return is_valid;
+}
+
+bool osaf_is_extended_name_empty(const SaNameT* name)
+{
+       size_t length = name->_opaque[0];
+       bool is_empty;
+       if (length != kExtendedNameMagic) {
+               is_empty = length == 0;
+       } else {
+               is_empty = *get_ptr(name) == '\0';
+       }
+       return is_empty;
+}
+
+size_t osaf_extended_name_length(const SaNameT* name)
+{
+       size_t length = name->_opaque[0];
+       if (length != kExtendedNameMagic) {
+               osafassert(length < SA_MAX_UNEXTENDED_NAME_LENGTH);
+               length = strnlen((const char*) (name->_opaque + 1), length);
+       } else {
+               length = strlen(get_ptr(name));
+               osafassert(osaf_extended_names_enabled &&
+                          length >= SA_MAX_UNEXTENDED_NAME_LENGTH);
+       }
+       return length;
+}
+
+void osaf_extended_name_clear(SaNameT* name)
+{
+       name->_opaque[0] = 0;
+       memset(name->_opaque + 1, 0, sizeof(SaConstStringT));
+}
+
+void osaf_extended_name_steal(SaStringT value, SaNameT* name)
+{
+       if (value != NULL) {
+               size_t length = strlen(value);
+               if (length < SA_MAX_UNEXTENDED_NAME_LENGTH) {
+                       name->_opaque[0] = length;
+                       memcpy(name->_opaque + 1, value, length + 1);
+                       free(value);
+               } else {
+                       set_ptr(value, name);
+               }
+       } else {
+               osaf_extended_name_clear(name);
+       }
+}
+
+void osaf_extended_name_alloc(SaConstStringT value, SaNameT* name)
+{
+       if (value != NULL) {
+               size_t length = strlen(value);
+               void* pointer;
+               if (length < SA_MAX_UNEXTENDED_NAME_LENGTH) {
+                       name->_opaque[0] = length;
+                       pointer = name->_opaque + 1;
+               } else {
+                       pointer = malloc(length + 1);
+                       set_ptr(pointer, name);
+               }
+               memcpy(pointer, value, length + 1);
+       } else {
+               osaf_extended_name_clear(name);
+       }
+}
+
+void osaf_extended_name_free(SaNameT* name)
+{
+       if (name != NULL) {
+               if (name->_opaque[0] == kExtendedNameMagic) {
+                       free((SaStringT*) get_ptr(name));
+               }
+               name->_opaque[0] = 0xffff;
+               memset(name->_opaque + 1, 0, sizeof(SaConstStringT));
+       }
+}
diff --git a/osaf/libs/core/leap/sysf_def.c b/osaf/libs/core/leap/sysf_def.c
--- a/osaf/libs/core/leap/sysf_def.c
+++ b/osaf/libs/core/leap/sysf_def.c
@@ -46,6 +46,7 @@
 #include "ncssysfpool.h"
 #include "sysf_exc_scr.h"
 #include "usrbuf.h"
+#include "osaf_extended_name.h"
 
 /**
  *  File descriptor pointing to /proc/sysrq-trigger. If a process wants to be
@@ -88,6 +89,8 @@ uint32_t leap_env_init(void)
 
        TRACE("INITIALIZING LEAP ENVIRONMENT");
 
+       osaf_extended_name_init();
+
        ncs_os_atomic_init();
 
 #if (NCSL_ENV_INIT_TMR == 1)

------------------------------------------------------------------------------
HPCC Systems Open Source Big Data Platform from LexisNexis Risk Solutions
Find What Matters Most in Your Big Data with HPCC Systems
Open Source. Fast. Scalable. Simple. Ideal for Dirty Data.
Leverages Graph Analysis for Fast Processing & Easy Data Exploration
http://www.hpccsystems.com
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to