osaf/libs/core/common/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 +
 4 files changed, 420 insertions(+), 0 deletions(-)


These library functions are primarily intended to be used in agent libraries,
to handle the old SAF APIs that still are using 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/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)

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.  Get 
unparalleled scalability from the best Selenium testing platform available.
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to