summaryrefslogtreecommitdiffstats
path: root/util/src/platforms/os400
diff options
context:
space:
mode:
authorGravatar nadiramra2010-05-30 20:43:13 +0000
committerGravatar nadiramra2010-05-30 20:43:13 +0000
commitcddcc5e6b3d63e42ded5bca4a3e5e7972cb2e216 (patch)
treed619453afb5f99ca02634b8305a0787af69d4de8 /util/src/platforms/os400
parent4952078f0c24283ce57a6d316ef9470caf5a8fb2 (diff)
downloadaxis2c-cddcc5e6b3d63e42ded5bca4a3e5e7972cb2e216.tar.gz
axis2c-cddcc5e6b3d63e42ded5bca4a3e5e7972cb2e216.tar.bz2
AXIS2C-1478 Changes due to port to IBM i (aka OS/400).
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@949568 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'util/src/platforms/os400')
-rw-r--r--util/src/platforms/os400/date_time_util_os400.c31
-rw-r--r--util/src/platforms/os400/platformSpecificOS400.c482
-rw-r--r--util/src/platforms/os400/thread_os400.c358
-rw-r--r--util/src/platforms/os400/uuid_gen_os400.c244
4 files changed, 1115 insertions, 0 deletions
diff --git a/util/src/platforms/os400/date_time_util_os400.c b/util/src/platforms/os400/date_time_util_os400.c
new file mode 100644
index 0000000..c593246
--- /dev/null
+++ b/util/src/platforms/os400/date_time_util_os400.c
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <platforms/os400/axutil_date_time_util_os400.h>
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_platform_get_milliseconds()
+{
+ struct timeb t_current;
+ int milliseconds;
+
+ ftime(&t_current);
+ milliseconds = t_current.millitm;
+
+ return milliseconds;
+
+}
diff --git a/util/src/platforms/os400/platformSpecificOS400.c b/util/src/platforms/os400/platformSpecificOS400.c
new file mode 100644
index 0000000..be60e8c
--- /dev/null
+++ b/util/src/platforms/os400/platformSpecificOS400.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright 2004-2004 The Apache Software Foundation.
+// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "platforms/axutil_platform_auto_sense.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <qusec.h> // Qus_EC_t
+#include <mih/rslvsp.h> // rslvsp()
+#include <mih/micommon.h> // _AUTH_EXECUTE
+#include <qleawi.h> // QleActBndPgm(), QleGetExp()
+#include <qp0lstdi.h> // Qp0lCvtPathToQSYSObjName()
+#include <unistd.h> // readlink()
+#include <except.h>
+#include <errno.h>
+#include <qwcrtvca.h> // Retrieve job's ccsid API prototype
+
+
+
+/**********************************************************************/
+/* Function: */
+/* retrieveJobCcsid */
+/* Description: */
+/* Retrieves the ccsid of the current job. */
+/* If the current job's ccsid is 65535, the job's default ccsid is */
+/* returned. */
+/* If the ccsid cannot be retrieved (error occurs), -1 is returned. */
+/* Return: */
+/* int status of call. if 0, success; -1 failure. */
+/**********************************************************************/
+
+#define RTV_CCSID_ATTR_LEN 512
+
+static int retrieveJobCcsid(int *ccsid, char *langID)
+{
+ char receiverVariable[RTV_CCSID_ATTR_LEN];
+ char format[8] = {'R', 'T', 'V', 'C', '0', '1', '0', '0'};
+ int numberOfAttributes = 3;
+ int attributeKeys[3] = {QWCA_KEY_CCSID, QWCA_KEY_DEFAULTCCSID, QWCA_KEY_LANGID};
+ Qwc_RTVC_Attribute_Data_t *attribute;
+ int defaultCcsid;
+ char errorCode[8];
+ int i;
+ memset(errorCode, 0x00, sizeof(errorCode));
+
+#pragma exception_handler(RetrieveJobCcsidError,0,_C1_ALL,_C2_ALL,_CTLA_HANDLE)
+ QWCRTVCA(receiverVariable,RTV_CCSID_ATTR_LEN,format,numberOfAttributes,attributeKeys,&errorCode);
+#pragma disable_handler
+ if (((Qwc_RTVC0100_t *)receiverVariable)->Number_Fields_Rtnd != 3)
+ {
+ /* Unable to retrieve the ccsid information */
+ return -1;
+ }
+ /* Retrieved ccsid, default CCSID and language ID */
+ attribute = (Qwc_RTVC_Attribute_Data_t *)(receiverVariable + sizeof(int));
+ for (i=0; i < 3; i++)
+ {
+ if (attribute->Key_Field == QWCA_KEY_CCSID)
+ *ccsid = *(int *)((char *)attribute + sizeof(Qwc_RTVC_Attribute_Data_t));
+ else if (attribute->Key_Field == QWCA_KEY_DEFAULTCCSID)
+ defaultCcsid = *(int *)((char *)attribute + sizeof(Qwc_RTVC_Attribute_Data_t));
+ else
+ strncpy(langID, ((char *)attribute + sizeof(Qwc_RTVC_Attribute_Data_t)), 3);
+ attribute = (Qwc_RTVC_Attribute_Data_t *)((char *)attribute + attribute->Length_Field_Info_Rtnd);
+ }
+ if (*ccsid == 65535)
+ *ccsid = defaultCcsid;
+
+ return 0;
+
+ RetrieveJobCcsidError:
+ return -1;
+}
+
+
+typedef int HMODULE;
+
+static char *dlErrorMessage = NULL;
+
+/*
+ * ==========================================
+ * dlopen()
+ * Gain access to an executable object file.
+ * ==========================================
+ */
+void * os400_dlopen(const char *file)
+{
+ Qus_EC_t err = { sizeof(err), 0};
+ int rc;
+ char dllPath[4*1024+1];
+ char *fp;
+ char pathNameBuffer[8*1024];
+ Qlg_Path_Name_T *pathName;
+ Qp0l_QSYS_Info_t qsys_info;
+ char objectName[11];
+ char objectLibrary[11];
+ _SYSPTR sysP;
+ _OBJ_TYPE_T objectType;
+ HMODULE handle;
+ int actInfoLen;
+ Qle_ABP_Info_t activationInfo;
+ void *returnHandle;
+
+ dlErrorMessage = NULL;
+
+ // Assume symbolic link, if error, assume actual path
+
+ memset(dllPath, 0x00, 4*1024+1);
+ rc = readlink ( file , dllPath, 4*1024);
+ if (rc == -1)
+ strcpy(dllPath, file);
+
+ // Uppercase file
+ fp = dllPath;
+ while (*fp++) *fp = toupper(*fp);
+
+ // Parse the path to its QSYS.LIB file system name: library and service program.
+
+ pathName = (Qlg_Path_Name_T *)pathNameBuffer;
+
+ memset(pathNameBuffer, 0x00, sizeof (pathNameBuffer));
+ pathName->Path_Length = strlen(dllPath);
+ memcpy( &(((char *) pathName)[sizeof(Qlg_Path_Name_T)]), dllPath, pathName->Path_Length);
+ pathName->Path_Name_Delimiter[0] = '/';
+
+ Qp0lCvtPathToQSYSObjName(pathName,&qsys_info,"QSYS0100",sizeof(Qp0l_QSYS_Info_t), 0, &err);
+
+ if (err.Bytes_Available)
+ {
+ dlErrorMessage = "Path to shared library not valid.";
+ return NULL;
+ }
+
+ // blank pad object name and library in order to use on rslvsp().
+
+ sprintf(objectName, "%-10.10s", qsys_info.Obj_Name);
+ sprintf(objectLibrary,"%-10.10s", qsys_info.Lib_Name);
+
+#pragma exception_handler (LBL_RSLV_EH, 0,_C1_ALL,_C2_MH_ESCAPE |_C2_MH_FUNCTION_CHECK, _CTLA_HANDLE)
+
+ // Resolve pointer to DLL.
+ objectType = WLI_SRVPGM;
+ sysP = rslvsp(objectType,objectName, objectLibrary,_AUTH_EXECUTE);
+
+#pragma disable_handler
+
+ // We got a pointer to the DLL. Activate it (i.e. load it).
+ actInfoLen = sizeof(activationInfo);
+ QleActBndPgm (&sysP,&handle,&activationInfo,&actInfoLen,&err);
+ if (err.Bytes_Available)
+ {
+ dlErrorMessage = "Unable to activate shared library.";
+ return NULL;
+ }
+
+ // Return the dlopen object.
+ returnHandle = malloc(sizeof(HMODULE));
+ memcpy(returnHandle, &handle, sizeof(HMODULE));
+ return returnHandle;
+
+ LBL_RSLV_EH:
+ dlErrorMessage = "Unable to resolve to shared library.";
+ return NULL;
+}
+
+/*
+ * dlsym()
+ * Obtain the address to symbol from a dlopen() object.
+ */
+void * os400_dlsym(void *handle, const char * name)
+{
+ void *symbolAddress = NULL;
+ int exportType;
+
+ Qus_EC_t err = {sizeof(err),0 };
+ dlErrorMessage = NULL;
+
+#pragma exception_handler (LBL_RSLV_EH, 0,_C1_ALL,_C2_MH_ESCAPE |_C2_MH_FUNCTION_CHECK, _CTLA_HANDLE)
+
+ // Get the function pointer.
+ // Export type of 1 means that that the pointer is to a procedure.
+
+ QleGetExp ((int *)handle,0,0,(char *)name,&symbolAddress,&exportType,&err);
+ if (err.Bytes_Available)
+ {
+ dlErrorMessage = "Unable to resolve to procedure in shared library.";
+ return NULL;
+ }
+
+ return symbolAddress;
+
+#pragma disable_handler
+
+ LBL_RSLV_EH:
+ dlErrorMessage = "Unable to resolve to procedure in shared library.";
+ return NULL;
+}
+
+
+/*
+ * ==========================================
+ * dlclose()
+ * Close a dlopen() object.
+ * ==========================================
+ */
+int os400_dlclose(void *handle)
+{
+ dlErrorMessage = NULL;
+ *(int *)handle = -1;
+ free(handle);
+ return 0;
+}
+
+/*
+ * ==========================================
+ * dlclose()
+ * Close a dlopen() object.
+ * ==========================================
+ */
+char * os400_dlerror()
+{
+ char *retError = dlErrorMessage;
+ dlErrorMessage = NULL;
+ return retError;
+}
+
+/* ---------------------------------------------------------------------------------*/
+/* ---------------------------------------------------------------------------------*/
+/* Below are routines to handle conversion between ascii and ebcdic */
+/* */
+/* The tables below are used to translate single byte data, and should never */
+/* be used to translate data that is not single byte. */
+/* ---------------------------------------------------------------------------------*/
+/* ---------------------------------------------------------------------------------*/
+
+
+/* constToAsc conversion table generated by ebcdic 37 -> ascii 819 */
+const char EBCDICtoASCII[256] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
+ 128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
+ 144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26,
+ 32, 160, 226, 228, 224, 225, 227, 229, 231, 241, 162, 46, 60, 40, 43, 124,
+ 38, 233, 234, 235, 232, 237, 238, 239, 236, 223, 33, 36, 42, 41, 59, 172,
+ 45, 47, 194, 196, 192, 193, 195, 197, 199, 209, 166, 44, 37, 95, 62, 63,
+ 248, 201, 202, 203, 200, 205, 206, 207, 204, 96, 58, 35, 64, 39, 61, 34,
+ 216, 97, 98, 99, 100, 101, 102, 103, 104, 105, 171, 187, 240, 253, 254, 177,
+ 176, 106, 107, 108, 109, 110, 111, 112, 113, 114, 170, 186, 230, 184, 198, 164,
+ 181, 126, 115, 116, 117, 118, 119, 120, 121, 122, 161, 191, 208, 221, 222, 174,
+ 94, 163, 165, 183, 169, 167, 182, 188, 189, 190, 91, 93, 175, 168, 180, 215,
+ 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 173, 244, 246, 242, 243, 245,
+ 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 185, 251, 252, 249, 250, 255,
+ 92, 247, 83, 84, 85, 86, 87, 88, 89, 90, 178, 212, 214, 210, 211, 213,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 179, 219, 220, 217, 218, 159
+};
+
+/* ascToString conversion table generated by ascii 819 -> ebcdic 37 */
+const char ASCIItoEBCDIC[256] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
+ 64, 90, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75, 97,
+ 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110, 111,
+ 124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 186, 224, 187, 176, 109,
+ 121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 79, 208, 161, 7,
+ 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27,
+ 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62, 255,
+ 65, 170, 74, 177, 159, 178, 106, 181, 189, 180, 154, 138, 95, 202, 175, 188,
+ 144, 143, 234, 250, 190, 160, 182, 179, 157, 218, 155, 139, 183, 184, 185, 171,
+ 100, 101, 98, 102, 99, 103, 158, 104, 116, 113, 114, 115, 120, 117, 118, 119,
+ 172, 105, 237, 238, 235, 239, 236, 191, 128, 253, 254, 251, 252, 173, 174, 89,
+ 68, 69, 66, 70, 67, 71, 156, 72, 84, 81, 82, 83, 88, 85, 86, 87,
+ 140, 73, 205, 206, 203, 207, 204, 225, 112, 221, 222, 219, 220, 141, 142, 223
+};
+
+
+/* converts an existing non constant character buffer from Ebcdic ( 37 ) */
+/* to Ascii ( 819 ). */
+char* strtoasc( char *string )
+{
+ char* pch = string;
+ if( string == NULL ) return NULL;
+
+ /* while not EOL... */
+ while( *pch != (char)0 )
+ {
+ *pch = EBCDICtoASCII[*pch];
+ pch++;
+ }
+ return string;
+}
+char* buftoasc( char *b, int len )
+{
+ char* pch = b;
+ if( b == NULL ) return NULL;
+
+ /* while not EOL... */
+ while( len > 0 )
+ {
+ *pch = EBCDICtoASCII[*pch];
+ pch++;len--;
+ }
+ return b;
+}
+
+/* converts an existing non-constant character buffer from ASCII ( 819 ) */
+/* to EBCDIC ( 37 ). */
+char* asctostr( char *string )
+{
+ char* pch = string;
+ if( string == NULL ) return NULL;
+
+ /* while not EOL... */
+ while( *pch != (char)0 )
+ {
+ *pch = ASCIItoEBCDIC[*pch];
+ pch++;
+ }
+ return string;
+}
+char* asctobuf( char *b, int len )
+{
+ char* pch = b;
+ if( b == NULL ) return NULL;
+
+ /* while not EOL... */
+ while( len > 0 )
+ {
+ *pch = ASCIItoEBCDIC[*pch];
+ pch++;len--;
+ }
+ return b;
+}
+
+
+char PLATFORM_DOUBLE_QUOTE_S[] = "\"";
+char PLATFORM_DOUBLE_QUOTE_C = '\"';
+char PLATFORM_XML_ENTITY_REFERENCE_CHARS_S[] = "<>&\"\'";
+
+static int initializePlatform(void)
+{
+ char *language= "En_US";
+ char langID[3] = {'E' , 'N' , 'U'};
+ int jobCCSID = 37;
+
+ int rc = retrieveJobCcsid(&jobCCSID, langID);
+ if (rc == 0)
+ {
+ // double quote character is not invariant when running
+ // turkish ccsid (1026). That is, the hexadecimal value
+ // of double quote is different than when running in
+ // any other language. So use correct double quote character.
+ if (jobCCSID == 1026)
+ {
+ strcpy(PLATFORM_DOUBLE_QUOTE_S, "\xFC");
+ PLATFORM_DOUBLE_QUOTE_C = '\xFC';
+ strcpy(PLATFORM_XML_ENTITY_REFERENCE_CHARS_S, "<>&\xFC\'");
+ }
+ }
+
+ return rc;
+}
+
+// TODO-AMRA static int platformRc = initializePlatform();
+
+
+int
+os400_alphasort(
+ const struct dirent **__d1,
+ const struct dirent **__d2)
+{
+ return strcoll((*__d1)->d_name, (*__d2)->d_name);
+}
+
+int
+os400_scandir(
+ const char *_dirname,
+ struct dirent **__namelist[],
+ int (*selector) (const struct dirent * entry),
+ int (*compare) (const struct dirent ** __d1,
+ const struct dirent ** __d2))
+{
+ DIR *dirp = NULL;
+ struct dirent **vector = NULL;
+ struct dirent *dp = NULL;
+ int vector_size = 0;
+ int nfiles = 0;
+
+ if (__namelist == NULL)
+ {
+ return -1;
+ }
+ dirp = opendir(_dirname);
+ if (!dirp)
+ {
+ return -1;
+ }
+ dp = readdir(dirp);
+ while (dp)
+ {
+ int dsize = 0;
+ struct dirent *newdp = NULL;
+
+ if (selector && (*selector) (dp) == 0)
+ {
+ dp = readdir(dirp);
+ continue;
+ }
+
+ if (nfiles == vector_size)
+ {
+ struct dirent **newv;
+ if (vector_size == 0)
+ {
+ vector_size = 10;
+ }
+ else
+ {
+ vector_size *= 2;
+ }
+
+ newv =
+ (struct dirent **) realloc(vector,
+ vector_size *
+ sizeof(struct dirent *));
+ if (!newv)
+ {
+ return -1;
+ }
+ vector = newv;
+ }
+
+ /*dsize =
+ (int) sizeof(struct dirent) +
+ (int) ((strlen(dp->d_name) + 1) * sizeof(char));*/
+ dsize = (int) sizeof(struct dirent);
+ newdp = (struct dirent *) malloc(dsize);
+
+ if (newdp == NULL)
+ {
+ while (nfiles-- > 0)
+ {
+ free(vector[nfiles]);
+ }
+ free(vector);
+ return -1;
+ }
+
+ vector[nfiles++] = (struct dirent *) memcpy(newdp, dp, dsize);
+ dp = readdir(dirp);
+ }
+
+ closedir(dirp);
+
+ *__namelist = vector;
+
+ if (compare)
+ {
+ // TODO-AMRA qsort(*__namelist, nfiles, sizeof(struct dirent *), compare);
+ }
+
+ return nfiles;
+}
diff --git a/util/src/platforms/os400/thread_os400.c b/util/src/platforms/os400/thread_os400.c
new file mode 100644
index 0000000..0269f9e
--- /dev/null
+++ b/util/src/platforms/os400/thread_os400.c
@@ -0,0 +1,358 @@
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "axutil_thread_os400.h"
+
+AXIS2_EXTERN axutil_threadattr_t *AXIS2_CALL
+axutil_threadattr_create(
+ axutil_allocator_t * allocator)
+{
+ int stat = 0;
+ axutil_threadattr_t *new = NULL;
+
+ new = AXIS2_MALLOC(allocator, sizeof(axutil_threadattr_t));
+ if (!new)
+ {
+ return NULL;
+ }
+ stat = pthread_attr_init(&(new->attr));
+
+ if (stat != 0)
+ {
+ AXIS2_FREE(allocator, new);
+ return NULL;
+ }
+ return new;
+}
+
+/* Destroy the threadattr object */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+threadattr_cleanup(
+ void *data)
+{
+ axutil_threadattr_t *attr = data;
+ int rv;
+
+ rv = pthread_attr_destroy(&(attr->attr));
+
+ if (0 != rv)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+#define DETACH_ARG(v) ((v) ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE)
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_threadattr_detach_set(
+ axutil_threadattr_t * attr,
+ axis2_bool_t detached)
+{
+ if (0 == pthread_attr_setdetachstate(&(attr->attr), DETACH_ARG(detached)))
+ {
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_threadattr_detach_get(
+ axutil_threadattr_t * attr)
+{
+ int state = 0;
+ pthread_attr_getdetachstate(&(attr->attr), &state);
+ if (state == 1)
+ {
+ return AXIS2_TRUE;
+ }
+ return AXIS2_FALSE;
+}
+
+static void *
+dummy_worker(
+ void *opaque)
+{
+ axutil_thread_t *thread = (axutil_thread_t *) opaque;
+ return thread->func(thread, thread->data);
+}
+
+AXIS2_EXTERN axutil_thread_t *AXIS2_CALL
+axutil_thread_create(
+ axutil_allocator_t * allocator,
+ axutil_threadattr_t * attr,
+ axutil_thread_start_t func,
+ void *data)
+{
+ axis2_status_t stat;
+ pthread_attr_t *temp = NULL;
+ axutil_thread_t *new = NULL;
+
+ new = (axutil_thread_t *) AXIS2_MALLOC(allocator, sizeof(axutil_thread_t));
+
+ if (!new)
+ {
+ return NULL;
+ }
+ new->td = (pthread_t *) AXIS2_MALLOC(allocator, sizeof(pthread_t));
+ if (!new->td)
+ {
+ return NULL;
+ }
+
+ new->data = data;
+ new->func = func;
+ new->try_exit = AXIS2_FALSE;
+
+ if (attr)
+ {
+ temp = &(attr->attr);
+ }
+ else
+ {
+ temp = NULL;
+ }
+
+ if ((stat = pthread_create(new->td, temp, dummy_worker, new)) == 0)
+ {
+ return new;
+ }
+ return NULL;
+}
+
+AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL
+axis2_os_thread_current(
+ void)
+{
+ return pthread_self();
+}
+
+AXIS2_EXTERN int AXIS2_CALL
+axis2_os_thread_equal(
+ axis2_os_thread_t tid1,
+ axis2_os_thread_t tid2)
+{
+ return pthread_equal(tid1, tid2);
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_exit(
+ axutil_thread_t * thd,
+ axutil_allocator_t * allocator)
+{
+ axis2_bool_t same_thread = AXIS2_TRUE;
+ if (thd)
+ {
+ while (!thd->try_exit)
+ {
+ sleep(1);
+ }
+
+ if (thd->td)
+ {
+ same_thread = pthread_equal(pthread_self(), *thd->td);
+ if(!same_thread)
+ {
+ pthread_kill(*(thd->td), 0);
+ axutil_thread_join(thd);
+ }
+ AXIS2_FREE(allocator, thd->td);
+ }
+ AXIS2_FREE(allocator, thd);
+ }
+ if(same_thread)
+ {
+ pthread_exit(NULL);
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_join(
+ axutil_thread_t * thd)
+{
+ void *thread_stat;
+ if (0 == pthread_join(*(thd->td), (void *) (&thread_stat)))
+ {
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_detach(
+ axutil_thread_t * thd)
+{
+ if (0 == pthread_detach(*(thd->td)))
+ {
+ thd->try_exit = AXIS2_TRUE;
+ return AXIS2_SUCCESS;
+ }
+ return AXIS2_FAILURE;
+}
+
+void
+axutil_thread_yield(
+ void)
+{
+ return;
+}
+
+/**
+ * function is used to allocate a new key. This key now becomes valid for all threads in our process.
+ * When a key is created, the value it points to defaults to NULL. Later on each thread may change
+ * its copy of the value as it wishes.
+ */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_key_create(
+ axutil_threadkey_t * axis2_key)
+{
+ int rc = -1;
+ pthread_key_t key = axis2_key->key;
+ rc = pthread_key_create(&key, NULL);
+ if (0 == rc)
+ return AXIS2_SUCCESS;
+ else
+ return AXIS2_FAILURE;
+}
+
+/**
+ * This function is used to get the value of a given key
+ * @return void*. A key's value is simply a void pointer (void*)
+ */
+AXIS2_EXTERN void *AXIS2_CALL
+axutil_thread_getspecific(
+ axutil_threadkey_t * axis2_key)
+{
+ void *value = NULL;
+ pthread_key_t key = axis2_key->key;
+ value = pthread_getspecific(key);
+ return value;
+}
+
+/**
+ * This function is used to get the value of a given key
+ * @param keys value. A key's value is simply a void pointer (void*), so we can
+ * store in it anything that we want
+ */
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_setspecific(
+ axutil_threadkey_t * axis2_key,
+ void *value)
+{
+ int rc = -1;
+ pthread_key_t key = axis2_key->key;
+ rc = pthread_setspecific(key, value);
+ if (0 == rc)
+ return AXIS2_SUCCESS;
+ else
+ return AXIS2_FAILURE;
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axutil_thread_key_free(
+ axutil_threadkey_t * axis2_key)
+{
+ pthread_key_t key = axis2_key->key;
+ pthread_key_delete(key);
+}
+
+AXIS2_EXTERN axis2_os_thread_t *AXIS2_CALL
+axis2_os_thread_get(
+ axutil_thread_t * thd)
+{
+ if (!thd)
+ {
+ return NULL;
+ }
+ return thd->td;
+}
+
+AXIS2_EXTERN axutil_thread_once_t *AXIS2_CALL
+axutil_thread_once_init(
+ axutil_allocator_t * allocator)
+{
+ static const pthread_once_t once_init = PTHREAD_ONCE_INIT;
+ axutil_thread_once_t *control = AXIS2_MALLOC(allocator, sizeof(axutil_thread_once_t));
+ if (!control)
+ {
+ return NULL;
+ }
+ (control)->once = once_init;
+ return control;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_once(
+ axutil_thread_once_t * control,
+ void
+ (*func)(
+ void))
+{
+ return pthread_once(&(control->once), func);
+}
+
+/*************************Thread locking functions*****************************/
+AXIS2_EXTERN axutil_thread_mutex_t *AXIS2_CALL
+axutil_thread_mutex_create(
+ axutil_allocator_t * allocator,
+ unsigned int flags)
+{
+ axutil_thread_mutex_t *new_mutex = NULL;
+
+ new_mutex = AXIS2_MALLOC(allocator, sizeof(axutil_thread_mutex_t));
+ new_mutex->allocator = allocator;
+
+ if (pthread_mutex_init(&(new_mutex->mutex), NULL) != 0)
+ {
+ AXIS2_FREE(allocator, new_mutex);
+ return NULL;
+ }
+ return new_mutex;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_mutex_lock(
+ axutil_thread_mutex_t * mutex)
+{
+ return pthread_mutex_lock(&(mutex->mutex));
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_mutex_unlock(
+ axutil_thread_mutex_t * mutex)
+{
+ if (pthread_mutex_unlock(&(mutex->mutex)) != 0)
+ {
+ return AXIS2_FAILURE;
+ }
+ return AXIS2_SUCCESS;
+}
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+axutil_thread_mutex_destroy(
+ axutil_thread_mutex_t * mutex)
+{
+ if (0 != pthread_mutex_destroy(&(mutex->mutex)))
+ {
+ return AXIS2_FAILURE;
+ }
+ AXIS2_FREE(mutex->allocator, mutex);
+ return AXIS2_SUCCESS;
+}
diff --git a/util/src/platforms/os400/uuid_gen_os400.c b/util/src/platforms/os400/uuid_gen_os400.c
new file mode 100644
index 0000000..6c40a82
--- /dev/null
+++ b/util/src/platforms/os400/uuid_gen_os400.c
@@ -0,0 +1,244 @@
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <sys/ioctl.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+# include <net/if.h>
+
+#include "platforms/os400/axutil_uuid_gen_os400.h"
+#include "platforms/axutil_platform_auto_sense.h"
+
+/* We need these static variables to track throughout the program execution */
+static axis2_bool_t axutil_uuid_gen_is_first = AXIS2_TRUE;
+static struct axutil_uuid_st axutil_uuid_static;
+
+axutil_uuid_t *AXIS2_CALL
+axutil_uuid_gen_v1()
+{
+ struct timeval time_now;
+ struct timeval tv;
+ unsigned long long time_val;
+ unsigned long long time_val2;
+ unsigned short int clck = 0;
+ axutil_uuid_t *ret_uuid = NULL;
+ unsigned short int time_high_version = 0;
+
+ if (AXIS2_TRUE == axutil_uuid_gen_is_first)
+ {
+ char *mac_addr = axutil_uuid_get_mac_addr();
+ memcpy(axutil_uuid_static.mac, mac_addr, 6);
+ axutil_uuid_static.time_seq = 0;
+ axutil_uuid_static.clock = 0;
+ free(mac_addr);
+ axutil_uuid_gen_is_first = AXIS2_FALSE;
+ }
+ /*
+ * GENERATE TIME
+ */
+
+ /* determine current system time and sequence counter */
+ if (gettimeofday(&time_now, NULL) == -1)
+ return NULL;
+
+ /* check whether system time changed since last retrieve */
+ if(!(time_now.tv_sec == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec
+ == axutil_uuid_static.time_last.tv_usec))
+ {
+ /* reset time sequence counter and continue */
+ axutil_uuid_static.time_seq = 0;
+ }
+
+ /* until we are out of UUIDs per tick, increment
+ the time/tick sequence counter and continue */
+ while (axutil_uuid_static.time_seq < UUIDS_PER_TICK)
+ {
+ axutil_uuid_static.time_seq++;
+ }
+ /* sleep for 1000ns (1us) */
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+ /*
+ The following select causes severe performance problems.
+ Hence commenting out. I am not sure why this is required. - Samisa.
+ select(0, NULL, NULL, NULL, &tv); */
+
+ time_val = (unsigned long long) time_now.tv_sec * 10000000ull;
+ time_val += (unsigned long long) time_now.tv_usec * 10ull;
+
+ ret_uuid = malloc(sizeof(axutil_uuid_t));
+
+ time_val += UUID_TIMEOFFSET;
+ /* compensate for low resolution system clock by adding
+ the time/tick sequence counter */
+ if (axutil_uuid_static.time_seq > 0)
+ time_val += (unsigned long long) axutil_uuid_static.time_seq;
+
+ time_val2 = time_val;
+ ret_uuid->time_low = (unsigned long) time_val2;
+ time_val2 >>= 32;
+ ret_uuid->time_mid = (unsigned short int) time_val2;
+ time_val2 >>= 16;
+ time_high_version = (unsigned short int) time_val2;
+
+ /* store the 60 LSB of the time in the UUID and make version 1 */
+ time_high_version <<= 4;
+ time_high_version &= 0xFFF0;
+ time_high_version |= 0x0001;
+ ret_uuid->time_high_version = time_high_version;
+
+ /*
+ * GENERATE CLOCK
+ */
+
+ /* retrieve current clock sequence */
+ clck = axutil_uuid_static.clock;
+
+ /* generate new random clock sequence (initially or if the
+ time has stepped backwards) or else just increase it */
+ if(clck == 0 || (time_now.tv_sec < axutil_uuid_static.time_last.tv_sec || (time_now.tv_sec
+ == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec
+ < axutil_uuid_static.time_last.tv_usec)))
+ {
+ srand(time_now.tv_usec);
+ clck = rand();
+ }
+ else
+ {
+ clck++;
+ }
+ clck %= (2 << 14);
+
+ /* store back new clock sequence */
+ axutil_uuid_static.clock = clck;
+
+ clck &= 0x1FFF;
+ clck |= 0x2000;
+
+ /*
+ * FINISH
+ */
+ /* remember current system time for next iteration */
+ axutil_uuid_static.time_last.tv_sec = time_now.tv_sec;
+ axutil_uuid_static.time_last.tv_usec = time_now.tv_usec;
+
+ if (!ret_uuid)
+ {
+ return NULL;
+ }
+ ret_uuid->clock_variant = clck;
+ memcpy(ret_uuid->mac_addr, axutil_uuid_static.mac, 6);
+ return ret_uuid;
+}
+
+axis2_char_t *AXIS2_CALL
+axutil_platform_uuid_gen(
+ char *s)
+{
+ axutil_uuid_t *uuid_struct = NULL;
+ axis2_char_t *uuid_str = NULL;
+ unsigned char mac[7];
+ char mac_hex[13];
+
+ if (!s)
+ {
+ return NULL;
+ }
+ uuid_struct = axutil_uuid_gen_v1();
+ if (!uuid_struct)
+ {
+ return NULL;
+ }
+ uuid_str = s;
+ if (!uuid_str)
+ {
+ return NULL;
+ }
+ memcpy(mac, uuid_struct->mac_addr, 6);
+ sprintf(mac_hex, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ sprintf(uuid_str, "%08x-%04x-%04x-%04x-%s", uuid_struct->time_low, uuid_struct->time_mid,
+ uuid_struct->time_high_version, uuid_struct->clock_variant, mac_hex);
+ free(uuid_struct);
+ uuid_struct = NULL;
+ return uuid_str;
+}
+
+char *AXIS2_CALL
+axutil_uuid_get_mac_addr(
+ )
+{
+ struct ifreq ifr;
+ struct ifreq *IFR;
+ struct ifconf ifc;
+ struct sockaddr *sa;
+ int s = 0;
+ int i = 0;
+ char *buffer = NULL;
+ char buf[1024];
+ int ok = AXIS2_FALSE;
+
+ if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+ return NULL;
+
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+ ioctl(s, SIOCGIFCONF, &ifc);
+ IFR = ifc.ifc_req;
+
+ for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++)
+ {
+ strcpy(ifr.ifr_name, IFR->ifr_name);
+ /*sprintf(ifr.ifr_name, "eth0"); */
+ if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0)
+ {
+ if (!(ifr.ifr_flags & IFF_LOOPBACK))
+ {
+
+// TODO-AMRA if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0)
+ {
+ ok = AXIS2_TRUE;
+ break;
+ }
+ }
+ }
+ }
+ buffer = (char *) malloc(6 * sizeof(char));
+ if (ok)
+ {
+ sa = (struct sockaddr *) &ifr.ifr_addr;
+ for (i = 0; i < 6; i++)
+ buffer[i] = (unsigned char) (sa->sa_data[i] & 0xff);
+ }
+ else
+ {
+ for (i = 0; i < 6; i++)
+ buffer[i] = (unsigned char) ((AXIS2_LOCAL_MAC_ADDR[i]) - '0');
+ }
+ close(s);
+ return buffer;
+}
+