Revert "Move dpm-common codes to klay git" 35/82435/1
authorSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 3 Aug 2016 09:55:25 +0000 (02:55 -0700)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 3 Aug 2016 09:55:25 +0000 (02:55 -0700)
This reverts commit 4d9d56100691b99eebd6836ef80d6a75b8db844f.

Change-Id: I2a4f722901a36879dfdb3a05651dd89bf7b093fd

172 files changed:
CMakeLists.txt
common/CMakeLists.txt [new file with mode: 0755]
common/array.h [moved from zone/libs/zone/array.h with 100% similarity]
common/audit/console-sink.cpp [new file with mode: 0644]
common/audit/console-sink.h [new file with mode: 0644]
common/audit/logger.cpp [new file with mode: 0644]
common/audit/logger.h [new file with mode: 0644]
common/audit/logsink.h [new file with mode: 0644]
common/audit/null-sink.cpp [new file with mode: 0644]
common/audit/null-sink.h [new file with mode: 0644]
common/auth/group.cpp [new file with mode: 0644]
common/auth/group.h [new file with mode: 0644]
common/auth/user.cpp [new file with mode: 0644]
common/auth/user.h [new file with mode: 0644]
common/data-type.h [new file with mode: 0644]
common/db/column.cpp [new file with mode: 0644]
common/db/column.h [new file with mode: 0644]
common/db/connection.cpp [new file with mode: 0644]
common/db/connection.h [new file with mode: 0644]
common/db/statement.cpp [new file with mode: 0644]
common/db/statement.h [new file with mode: 0644]
common/dbus/connection.cpp [new file with mode: 0644]
common/dbus/connection.h [new file with mode: 0644]
common/dbus/error.cpp [new file with mode: 0644]
common/dbus/error.h [new file with mode: 0644]
common/dbus/variant.cpp [new file with mode: 0644]
common/dbus/variant.h [new file with mode: 0644]
common/error.cpp [new file with mode: 0644]
common/error.h [new file with mode: 0644]
common/eventfd.cpp [new file with mode: 0644]
common/eventfd.h [new file with mode: 0644]
common/exception.h [new file with mode: 0644]
common/file-descriptor.h [new file with mode: 0644]
common/filesystem.cpp [new file with mode: 0755]
common/filesystem.h [new file with mode: 0644]
common/mainloop.cpp [new file with mode: 0644]
common/mainloop.h [new file with mode: 0644]
common/pam.cpp [new file with mode: 0644]
common/pam.h [new file with mode: 0644]
common/preprocessor.h [new file with mode: 0644]
common/process.cpp [new file with mode: 0644]
common/process.h [new file with mode: 0644]
common/reflection.h [new file with mode: 0644]
common/rmi/callback-holder.h [new file with mode: 0644]
common/rmi/client.cpp [new file with mode: 0644]
common/rmi/client.h [new file with mode: 0644]
common/rmi/connection.cpp [new file with mode: 0644]
common/rmi/connection.h [new file with mode: 0644]
common/rmi/message-composer.cpp [new file with mode: 0644]
common/rmi/message-composer.h [new file with mode: 0644]
common/rmi/message.cpp [new file with mode: 0644]
common/rmi/message.h [new file with mode: 0644]
common/rmi/notification.cpp [new file with mode: 0644]
common/rmi/notification.h [new file with mode: 0644]
common/rmi/service.cpp [new file with mode: 0644]
common/rmi/service.h [new file with mode: 0644]
common/rmi/socket.cpp [new file with mode: 0644]
common/rmi/socket.h [new file with mode: 0644]
common/serialize.h [new file with mode: 0644]
common/thread-pool.cpp [new file with mode: 0644]
common/thread-pool.h [moved from libs/dpm/array.h with 58% similarity]
common/xml/document.cpp [new file with mode: 0644]
common/xml/document.h [new file with mode: 0644]
common/xml/keepblanks.cpp [new file with mode: 0644]
common/xml/keepblanks.h [new file with mode: 0644]
common/xml/node.cpp [new file with mode: 0644]
common/xml/node.h [new file with mode: 0644]
common/xml/parser.cpp [new file with mode: 0644]
common/xml/parser.h [new file with mode: 0644]
libs/CMakeLists.txt
libs/bluetooth.cpp
libs/dpm/client-handle.cpp
libs/location.cpp
libs/password.cpp
libs/policy-client.cpp
libs/policy-client.h
libs/restriction.cpp
libs/security.cpp
libs/storage.cpp
libs/wifi.cpp
libs/zone.cpp
measure.sh
packaging/device-policy-manager.spec
policy/administration.hxx
policy/application.hxx
policy/bluetooth.hxx
policy/location.hxx
policy/password.hxx
policy/restriction.hxx
policy/security.hxx
policy/storage.hxx
policy/wifi.hxx
policy/zone.hxx
policy/zone/app-proxy.hxx
policy/zone/package-proxy.hxx
policy/zone/zone.hxx
server/CMakeLists.txt
server/administration.cpp
server/app-bundle.cpp
server/app-bundle.h
server/application.cpp
server/bluetooth.cpp
server/client-manager.cpp
server/client-manager.h
server/launchpad.cpp
server/launchpad.h
server/location.cpp
server/main.cpp
server/packman.cpp
server/packman.h
server/password.cpp
server/policy-storage.cpp
server/policy-storage.h
server/policy.h
server/restriction.cpp
server/security.cpp
server/server.cpp
server/server.h
server/storage.cpp
server/wifi.cpp
server/zone.cpp
server/zone/app-proxy.cpp
server/zone/package-proxy.cpp
server/zone/zone.cpp
tests/CMakeLists.txt
tests/api/CMakeLists.txt [new file with mode: 0644]
tests/api/admin.c [moved from tests/admin.c with 100% similarity]
tests/api/application.c [moved from tests/application.c with 100% similarity]
tests/api/bluetooth.c [moved from tests/bluetooth.c with 100% similarity]
tests/api/common.cmake [moved from tests/common.cmake with 100% similarity]
tests/api/context.c [moved from tests/context.c with 100% similarity]
tests/api/ivi.cmake [moved from tests/ivi.cmake with 100% similarity]
tests/api/main.c [moved from tests/main.c with 100% similarity]
tests/api/manager.c [moved from tests/manager.c with 100% similarity]
tests/api/mobile.cmake [moved from tests/mobile.cmake with 100% similarity]
tests/api/password.c [moved from tests/password.c with 100% similarity]
tests/api/restriction.c [moved from tests/restriction.c with 100% similarity]
tests/api/security.c [moved from tests/security.c with 100% similarity]
tests/api/testbench.c [moved from tests/testbench.c with 100% similarity]
tests/api/testbench.h [moved from tests/testbench.h with 100% similarity]
tests/api/tv.cmake [moved from tests/tv.cmake with 100% similarity]
tests/api/wearable.cmake [moved from tests/wearable.cmake with 100% similarity]
tests/api/wifi.c [moved from tests/wifi.c with 100% similarity]
tests/api/zone.c [moved from tests/zone.c with 100% similarity]
tests/testbench/testbench.cpp [new file with mode: 0644]
tests/testbench/testbench.h [new file with mode: 0644]
tests/unit/CMakeLists.txt [new file with mode: 0755]
tests/unit/data/sample-policy.xml [new file with mode: 0755]
tests/unit/data/unittest-proc.sh [new file with mode: 0755]
tests/unit/database.cpp [new file with mode: 0644]
tests/unit/dbus.cpp [new file with mode: 0644]
tests/unit/eventfd.cpp [new file with mode: 0644]
tests/unit/filesystem.cpp [new file with mode: 0644]
tests/unit/logger.cpp [new file with mode: 0644]
tests/unit/main.cpp [new file with mode: 0644]
tests/unit/misc.cpp [new file with mode: 0644]
tests/unit/proc.cpp [new file with mode: 0644]
tests/unit/rmi.cpp [new file with mode: 0644]
tests/unit/shadow.cpp [new file with mode: 0644]
tests/unit/xml.cpp [new file with mode: 0644]
tools/syspopup/CMakeLists.txt
zone/cli/CMakeLists.txt
zone/cli/zone-admin-cli.cpp
zone/libs/CMakeLists.txt
zone/libs/zone/app-proxy.cpp
zone/libs/zone/package-proxy.cpp
zone/libs/zone/zone.cpp
zone/module/CMakeLists.txt
zone/volume/CMakeLists.txt
zone/volume/key-generator.cpp
zone/volume/key-manager.cpp
zone/volume/main.cpp

index 8969033..d82ebbe 100755 (executable)
@@ -28,6 +28,7 @@ IF(NOT CMAKE_BUILD_TYPE)
        SET(CMAKE_BUILD_TYPE "DEBUG")
 ENDIF(NOT CMAKE_BUILD_TYPE)
 
+SET(DPM_COMMON ${PROJECT_SOURCE_DIR}/common)
 SET(DPM_POLICY ${PROJECT_SOURCE_DIR}/policy)
 SET(DPM_LIBS   ${PROJECT_SOURCE_DIR}/libs)
 SET(DPM_SERVER ${PROJECT_SOURCE_DIR}/server)
@@ -85,6 +86,7 @@ ENDIF(NOT DEFINED SYSTEMD_UNIT_INSTALL_DIR)
 
 ADD_DEFINITIONS(-DUG_WAYLAND)
 
+ADD_SUBDIRECTORY(${DPM_COMMON})
 ADD_SUBDIRECTORY(${DPM_SERVER})
 ADD_SUBDIRECTORY(${DPM_LIBS})
 ADD_SUBDIRECTORY(${DPM_TOOLS})
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..364441f
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd 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.
+#
+
+PROJECT(dpm-common)
+
+SET (COMMON_SOURCES     ${DPM_COMMON}/error.cpp
+                                               ${DPM_COMMON}/process.cpp
+                                               ${DPM_COMMON}/eventfd.cpp
+                                               ${DPM_COMMON}/mainloop.cpp
+                                               ${DPM_COMMON}/filesystem.cpp
+                                               ${DPM_COMMON}/thread-pool.cpp
+                                               ${DPM_COMMON}/rmi/socket.cpp
+                                               ${DPM_COMMON}/rmi/client.cpp
+                                               ${DPM_COMMON}/rmi/message.cpp
+                                               ${DPM_COMMON}/rmi/message-composer.cpp
+                                               ${DPM_COMMON}/rmi/service.cpp
+                                               ${DPM_COMMON}/rmi/connection.cpp
+                                               ${DPM_COMMON}/rmi/notification.cpp
+                                               ${DPM_COMMON}/audit/logger.cpp
+                                               ${DPM_COMMON}/audit/null-sink.cpp
+                                               ${DPM_COMMON}/audit/console-sink.cpp
+                                               ${DPM_COMMON}/xml/node.cpp
+                                               ${DPM_COMMON}/xml/parser.cpp
+                                               ${DPM_COMMON}/xml/document.cpp
+                                               ${DPM_COMMON}/xml/keepblanks.cpp
+                                               ${DPM_COMMON}/db/column.cpp
+                                               ${DPM_COMMON}/db/statement.cpp
+                                               ${DPM_COMMON}/db/connection.cpp
+                                               ${DPM_COMMON}/auth/user.cpp
+                                               ${DPM_COMMON}/auth/group.cpp
+                                               ${DPM_COMMON}/dbus/error.cpp
+                                               ${DPM_COMMON}/dbus/variant.cpp
+                                               ${DPM_COMMON}/dbus/connection.cpp
+)
+
+SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
+
+ADD_LIBRARY(${PROJECT_NAME} STATIC ${COMMON_SOURCES})
+
+PKG_CHECK_MODULES(COMMON_DEPS REQUIRED  libxml-2.0
+                                                                               sqlite3
+                                                                               gio-2.0
+)
+
+INCLUDE_DIRECTORIES(SYSTEM  ${DPM_COMMON}
+                                                       ${COMMON_DEPS_INCLUDE_DIRS}
+)
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${COMMON_DEPS_LIBRARIES})
similarity index 100%
rename from zone/libs/zone/array.h
rename to common/array.h
diff --git a/common/audit/console-sink.cpp b/common/audit/console-sink.cpp
new file mode 100644 (file)
index 0000000..747fe51
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <iostream>
+
+#include "console-sink.h"
+
+namespace audit {
+
+void ConsoleLogSink::sink(const std::string& message)
+{
+       std::cout << message << std::flush;
+}
+
+} // namespace audit
diff --git a/common/audit/console-sink.h b/common/audit/console-sink.h
new file mode 100644 (file)
index 0000000..85dbe27
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __AUDIT_CONSOLE_LOGSINK_H__
+#define __AUDIT_CONSOLE_LOGSINK_H__
+
+#include <string>
+
+#include "logsink.h"
+
+namespace audit {
+
+class ConsoleLogSink : public LogSink {
+public:
+       void sink(const std::string& message) override;
+};
+
+} // namespace audit
+#endif //__AUDIT_CONSOLE_LOGSINK_H__
diff --git a/common/audit/logger.cpp b/common/audit/logger.cpp
new file mode 100644 (file)
index 0000000..d9c9fb6
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <unistd.h>
+
+#include <stdexcept>
+
+#include "logger.h"
+#include "console-sink.h"
+
+#include "exception.h"
+
+namespace audit {
+
+LogLevel Logger::logLevel = LogLevel::Trace;
+std::unique_ptr<LogSink> Logger::backend(new ConsoleLogSink());
+
+std::string LogLevelToString(const LogLevel level)
+{
+       switch (level) {
+       case LogLevel::Error:
+               return "ERROR";
+       case LogLevel::Warning:
+               return "WARN";
+       case LogLevel::Debug:
+               return "DEBUG";
+       case LogLevel::Info:
+               return "INFO";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+void Logger::setLogLevel(const LogLevel level)
+{
+       Logger::logLevel = level;
+}
+
+LogLevel Logger::getLogLevel(void)
+{
+       return Logger::logLevel;
+}
+
+void Logger::log(LogLevel severity,
+                                const std::string& file,
+                                const unsigned int line,
+                                const std::string& func,
+                                const std::string& message)
+{
+       std::ostringstream buffer;
+
+       buffer << LogLevelToString(severity)
+                  << "<" << ::getpid() << ">:"
+                  << file << ":" << line
+                  << " " << func << " " << message
+                  << std::endl;
+
+       Logger::backend->sink(buffer.str());
+}
+
+} // namespace audit
diff --git a/common/audit/logger.h b/common/audit/logger.h
new file mode 100644 (file)
index 0000000..209aa69
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __AUDIT_LOGGER_H__
+#define __AUDIT_LOGGER_H__
+
+#include <cstring>
+#include <string>
+#include <memory>
+#include <sstream>
+#include <iostream>
+
+#include "logsink.h"
+
+namespace audit {
+
+enum class LogLevel : int {
+       Error,
+       Warning,
+       Debug,
+       Info,
+       Trace
+};
+
+class Logger {
+public:
+       static void setLogLevel(const LogLevel level);
+       static LogLevel getLogLevel(void);
+       static void log(LogLevel severity,
+                                       const std::string& file,
+                                       const unsigned int line,
+                                       const std::string& func,
+                                       const std::string& message);
+
+private:
+       static LogLevel logLevel;
+       static std::unique_ptr<LogSink> backend;
+};
+
+#ifndef __FILENAME__
+#define __FILENAME__                                                   \
+(::strrchr(__FILE__, '/') ? ::strrchr(__FILE__, '/') + 1 : __FILE__)
+#endif
+
+#define LOG(SEVERITY, MESSAGE)                                         \
+do {                                                                   \
+       if (audit::LogLevel::SEVERITY <= audit::Logger::getLogLevel()) {   \
+               audit::Logger::log(audit::LogLevel::SEVERITY,                  \
+                                                  __FILENAME__, __LINE__, __func__, MESSAGE); \
+       }                                                                  \
+} while (0)
+
+#define ERROR(MESSAGE) LOG(Error, MESSAGE)
+#define WARN(MESSAGE)  LOG(Warning, MESSAGE)
+
+#if !defined(NDEBUG)
+#define INFO(MESSAGE)  LOG(Info, MESSAGE)
+#define DEBUG(MESSAGE) LOG(Debug, MESSAGE)
+#define TRACE(MESSAGE) LOG(Trace, MESSAGE)
+#else
+#define INFO(MESSAGE)  do {} while (0)
+#define DEBUG(MESSAGE) do {} while (0)
+#define TRACE(MESSAGE) do {} while (0)
+#endif //NDEBUG
+
+std::string LogLevelToString(const LogLevel level);
+
+} // namespace audit
+#endif //__AUDIT_LOGGER_H__
diff --git a/common/audit/logsink.h b/common/audit/logsink.h
new file mode 100644 (file)
index 0000000..f1949df
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __AUDIT_LOGSINK_H__
+#define __AUDIT_LOGSINK_H__
+
+#include <string>
+
+namespace audit {
+
+class LogSink {
+public:
+       LogSink() {}
+       virtual ~LogSink() {}
+       virtual void sink(const std::string& message) = 0;
+};
+
+} // namespace audit
+#endif //__AUDIT_LOGSINK_H__
diff --git a/common/audit/null-sink.cpp b/common/audit/null-sink.cpp
new file mode 100644 (file)
index 0000000..ec335a0
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "null-sink.h"
+
+namespace audit {
+
+void NullLogSink::sink(const std::string& message)
+{
+};
+
+} // namespace audit
diff --git a/common/audit/null-sink.h b/common/audit/null-sink.h
new file mode 100644 (file)
index 0000000..cd5d9dc
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __AUDIT_NULL_LOGSINK_H__
+#define __AUDIT_NULL_LOGSINK_H__
+
+#include <string>
+
+#include "logsink.h"
+
+namespace audit {
+
+class NullLogSink : public LogSink {
+public:
+       void sink(const std::string& message) override;
+};
+
+} // namespace audit
+#endif //__AUDIT_NULL_LOGSINK_H__
diff --git a/common/auth/group.cpp b/common/auth/group.cpp
new file mode 100644 (file)
index 0000000..89e1ceb
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <grp.h>
+#include <gshadow.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <regex>
+#include <memory>
+
+#include "group.h"
+#include "shadow.h"
+#include "exception.h"
+
+namespace runtime {
+
+Group::Group(const Group& group) :
+       name(group.name), gid(group.gid)
+{
+}
+
+Group::Group(const std::string& group)
+{
+       struct group grp, *result;
+       int bufsize;
+
+       bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+       if (bufsize == -1)
+               bufsize = 16384;
+
+       std::unique_ptr<char[]> buf(new char[bufsize]);
+
+       ::getgrnam_r(group.c_str(), &grp, buf.get(), bufsize, &result);
+       if (result == NULL) {
+               throw runtime::Exception("Group doesn't exist");
+       }
+
+       name = result->gr_name;
+       gid = result->gr_gid;
+}
+
+Group::Group(const gid_t group)
+{
+       struct group grp, *result;
+       int bufsize;
+
+       bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+       if (bufsize == -1)
+               bufsize = 16384;
+
+       std::unique_ptr<char[]> buf(new char[bufsize]);
+
+       ::getgrgid_r(group, &grp, buf.get(), bufsize, &result);
+       if (result == NULL) {
+               throw runtime::Exception("Group doesn't exist");
+       }
+
+       name = result->gr_name;
+       gid = result->gr_gid;
+}
+
+Group::Group() :
+       Group(::getgid())
+{
+}
+
+} // namespace Shadow
diff --git a/common/auth/group.h b/common/auth/group.h
new file mode 100644 (file)
index 0000000..5c0b583
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_GROUP_H__
+#define __RUNTIME_GROUP_H__
+
+#include <limits.h>
+#include <sys/types.h>
+
+#include <string>
+
+#ifndef INVALID_GID
+#define INVALID_GID             UINT_MAX
+#endif
+
+namespace runtime {
+
+class Group final {
+public:
+       Group(const std::string& name);
+       Group(const gid_t group);
+       Group(const Group& group);
+       Group();
+
+       const std::string& getName() const
+       {
+               return name;
+       }
+
+       const gid_t getGid() const
+       {
+               return gid;
+       }
+
+private:
+       std::string name;
+       gid_t gid;
+};
+
+} // namespace runtime
+
+#endif //__RUNTIME_GROUP_H__
diff --git a/common/auth/user.cpp b/common/auth/user.cpp
new file mode 100644 (file)
index 0000000..0848a5e
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <pwd.h>
+#include <shadow.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <regex>
+#include <memory>
+
+#include "user.h"
+#include "group.h"
+#include "shadow.h"
+#include "filesystem.h"
+#include "exception.h"
+
+namespace runtime {
+
+User::User(const User& user) :
+       name(user.name), uid(user.uid), gid(user.gid)
+{
+}
+
+User::User(const std::string& user)
+{
+       struct passwd pwd, *result;
+       int bufsize;
+
+       bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+       if (bufsize == -1)
+               bufsize = 16384;
+
+       std::unique_ptr<char[]> buf(new char[bufsize]);
+
+       ::getpwnam_r(user.c_str(), &pwd, buf.get(), bufsize, &result);
+       if (result == NULL) {
+               throw runtime::Exception("User " + user + " doesn't exist");
+       }
+
+       name = result->pw_name;
+       uid = result->pw_uid;
+       gid = result->pw_gid;
+}
+
+User::User(const uid_t user)
+{
+       struct passwd pwd, *result;
+       int bufsize;
+
+       bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+       if (bufsize == -1)
+               bufsize = 16384;
+
+       std::unique_ptr<char[]> buf(new char[bufsize]);
+       ::getpwuid_r(user, &pwd, buf.get(), bufsize, &result);
+       if (result == NULL) {
+               throw runtime::Exception("User " + std::to_string(user) + "doesn't exist");
+       }
+
+       name = result->pw_name;
+       uid = result->pw_uid;
+       gid = result->pw_gid;
+}
+
+User::User() :
+       User(::getuid())
+{
+}
+
+} // namespace runtime
diff --git a/common/auth/user.h b/common/auth/user.h
new file mode 100644 (file)
index 0000000..88aa5b0
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_USER_H__
+#define __RUNTIME_USER_H__
+
+#include <limits.h>
+#include <sys/types.h>
+
+#include <string>
+
+#ifndef INVALID_UID
+#define INVALID_UID             UINT_MAX
+#endif
+
+namespace runtime  {
+
+class User final {
+public:
+       User(const std::string& name);
+       User(const uid_t user);
+       User(const User& user);
+       User();
+
+       const std::string& getName() const
+       {
+               return name;
+       }
+
+       uid_t getUid() const
+       {
+               return uid;
+       }
+
+       gid_t getGid() const
+       {
+               return gid;
+       }
+
+private:
+       std::string name;
+       uid_t uid;
+       gid_t gid;
+};
+
+} // namespace runtime
+
+#endif //__RUNTIME_USER_H__
diff --git a/common/data-type.h b/common/data-type.h
new file mode 100644 (file)
index 0000000..b5b232c
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_DATA_TYPE_H__
+#define __RUNTIME_DATA_TYPE_H__
+#include <string>
+#include <vector>
+#include <utility>
+
+#include "reflection.h"
+
+struct Void {
+       NO_REFLECTABLE_PROPERTY
+};
+
+struct String {
+       String() = default;
+       String(const String& str) : value(str.value) {}
+       String(String&& str) : value(std::move(str.value)) {}
+
+       String(const char* str) : value(str) {}
+       String(const std::string& str) : value(str) {}
+
+       String& operator=(const String& str)
+       {
+               if (this != &str) {
+                       value = str.value;
+               }
+
+               return *this;
+       }
+
+       String& operator=(String&& str)
+       {
+               if (this != &str) {
+                       value = std::move(str.value);
+               }
+               return *this;
+       }
+
+       std::string value;
+       REFLECTABLE(value)
+};
+
+struct StringPair {
+       std::string first;
+       std::string second;
+       REFLECTABLE(first, second)
+};
+
+struct Status {
+       Status() : code(0) {}
+       Status(int v) : code(v) {}
+
+       operator int() const
+       {
+               return code;
+       }
+
+       int code;
+       REFLECTABLE(code)
+};
+
+template<typename T>
+struct Vector {
+       std::vector<T> value;
+       REFLECTABLE(value)
+};
+
+#endif //!__RUNTIME_DATA_TYPE_H__
diff --git a/common/db/column.cpp b/common/db/column.cpp
new file mode 100644 (file)
index 0000000..3a57600
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+
+#include "column.h"
+
+namespace database {
+
+Column::Column(const Statement& stmt, int idx) :
+       statement(stmt.get()),
+       index(idx)
+{
+}
+
+Column::~Column() noexcept
+{
+}
+
+std::string Column::getName() const
+{
+       return sqlite3_column_name(statement, index);
+}
+
+int Column::getInt() const
+{
+       return sqlite3_column_int(statement, index);
+}
+
+sqlite3_int64 Column::getInt64() const
+{
+       return sqlite3_column_int64(statement, index);
+}
+
+double Column::getDouble() const
+{
+       return sqlite3_column_double(statement, index);
+}
+
+const char* Column::getText() const
+{
+       return reinterpret_cast<const char *>(sqlite3_column_text(statement, index));
+}
+
+const void* Column::getBlob() const
+{
+       return sqlite3_column_blob(statement, index);
+}
+
+int Column::getType() const
+{
+       return sqlite3_column_type(statement, index);
+}
+
+int Column::getBytes() const
+{
+       return sqlite3_column_bytes(statement, index);
+}
+
+} // namespace database
diff --git a/common/db/column.h b/common/db/column.h
new file mode 100644 (file)
index 0000000..1dc9965
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __DATABASE_COLUMN_H__
+#define __DATABASE_COLUMN_H__
+
+#include <string>
+
+#include <sqlite3.h>
+
+#include "statement.h"
+
+namespace database {
+
+class Column {
+public:
+       Column(const Statement& stmt, int idx);
+       virtual ~Column() noexcept;
+
+       std::string getName() const;
+       sqlite3_int64 getInt64() const;
+       const char* getText() const;
+       double getDouble() const;
+       const void* getBlob() const;
+       int getInt() const;
+       int getType() const;
+       int getBytes() const;
+
+       inline int size() const
+       {
+               return getBytes();
+       }
+
+       inline operator int() const
+       {
+               return getInt();
+       }
+
+       inline operator sqlite3_int64() const
+       {
+               return getInt64();
+       }
+
+       inline operator double() const
+       {
+               return getDouble();
+       }
+
+       inline operator const char*() const
+       {
+               return getText();
+       }
+
+       inline operator const void*() const
+       {
+               return getBlob();
+       }
+
+private:
+       sqlite3_stmt* statement;
+       int index;
+};
+
+} // namespace database
+
+#endif //__DATABASE_COLUMN_H__
diff --git a/common/db/connection.cpp b/common/db/connection.cpp
new file mode 100644 (file)
index 0000000..5ea016e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <iostream>
+
+#include "exception.h"
+
+#include "connection.h"
+
+namespace database {
+
+Connection::Connection(const std::string& name, const int flags) :
+       handle(nullptr), filename(name)
+{
+       if (::sqlite3_open_v2(filename.c_str(), &handle, flags, NULL)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+Connection::~Connection()
+{
+       ::sqlite3_close(handle);
+}
+
+int Connection::exec(const std::string& query)
+{
+       if (::sqlite3_exec(handle, query.c_str(), NULL, NULL, NULL) != SQLITE_OK) {
+               throw runtime::Exception(getErrorMessage());
+       }
+
+       return ::sqlite3_changes(handle);
+}
+
+} // namespace database
diff --git a/common/db/connection.h b/common/db/connection.h
new file mode 100644 (file)
index 0000000..1465533
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __DATABASE_CONNECTION_H__
+#define __DATABASE_CONNECTION_H__
+
+#include <string>
+
+#include <sqlite3.h>
+
+namespace database {
+
+class Connection {
+public:
+       enum Mode {
+               Create = SQLITE_OPEN_CREATE,
+               ReadWrite = SQLITE_OPEN_READWRITE
+       };
+
+       Connection(const std::string& name, const int flags);
+       ~Connection();
+
+       int exec(const std::string& query);
+       bool isTableExists(const std::string& tableName);
+
+       inline long long getLastInsertRowId() const noexcept
+       {
+               return sqlite3_last_insert_rowid(handle);
+       }
+
+       inline const std::string& getName() const noexcept
+       {
+               return filename;
+       }
+
+       inline int getErrorCode() const
+       {
+               return sqlite3_errcode(handle);
+       }
+
+       inline int getExtendedErrorCode() const
+       {
+               return sqlite3_extended_errcode(handle);
+       }
+
+       inline std::string getErrorMessage() const
+       {
+               return sqlite3_errmsg(handle);
+       }
+
+       inline sqlite3* get() const noexcept
+       {
+               return handle;
+       }
+
+private:
+       sqlite3* handle;
+       std::string filename;
+};
+
+} // namespace database
+#endif //__DATABASE_CONNECTION_H__
diff --git a/common/db/statement.cpp b/common/db/statement.cpp
new file mode 100644 (file)
index 0000000..22d2243
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <iostream>
+
+#include "connection.h"
+#include "statement.h"
+#include "column.h"
+
+#include "exception.h"
+
+namespace database {
+
+Statement::Statement(const Connection& db, const std::string& query) :
+       statement(nullptr),
+       columnCount(0),
+       validRow(false)
+{
+       if (SQLITE_OK != ::sqlite3_prepare_v2(db.get(),
+                                                                                 query.c_str(),
+                                                                                 query.size(),
+                                                                                 &statement,
+                                                                                 NULL)) {
+               throw runtime::Exception(db.getErrorMessage());
+       }
+
+       columnCount = sqlite3_column_count(statement);
+}
+
+Statement::~Statement()
+{
+       ::sqlite3_finalize(statement);
+}
+
+void Statement::reset()
+{
+       if (::sqlite3_reset(statement) != SQLITE_OK) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::clearBindings()
+{
+       if (::sqlite3_clear_bindings(statement) != SQLITE_OK) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+std::string Statement::getErrorMessage() const
+{
+       return ::sqlite3_errmsg(::sqlite3_db_handle(statement));
+}
+
+std::string Statement::getErrorMessage(int errorCode) const
+{
+       return ::sqlite3_errstr(errorCode);
+}
+
+bool Statement::step()
+{
+       if (SQLITE_ROW == ::sqlite3_step(statement)) {
+               return (validRow = true);
+       }
+
+       return (validRow = false);
+}
+
+int Statement::exec()
+{
+       if (SQLITE_DONE == ::sqlite3_step(statement)) {
+               validRow = false;
+       }
+
+       return sqlite3_changes(sqlite3_db_handle(statement));
+}
+
+Column Statement::getColumn(const int index)
+{
+       if (!validRow || (index >= columnCount)) {
+               throw runtime::Exception(getErrorMessage(SQLITE_RANGE));
+       }
+
+       return Column(*this, index);
+}
+
+bool Statement::isNullColumn(const int index) const
+{
+       if (!validRow || (index >= columnCount)) {
+               throw runtime::Exception(getErrorMessage(SQLITE_RANGE));
+       }
+
+       return (SQLITE_NULL == sqlite3_column_type(statement, index));
+}
+
+std::string Statement::getColumnName(const int index) const
+{
+       if (index >= columnCount) {
+               throw runtime::Exception(getErrorMessage(SQLITE_RANGE));
+       }
+
+       return sqlite3_column_name(statement, index);
+}
+
+
+void Statement::bind(const int index, const int& value)
+{
+       if (SQLITE_OK != ::sqlite3_bind_int(statement, index, value)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const int index, const sqlite3_int64& value)
+{
+       if (SQLITE_OK != ::sqlite3_bind_int64(statement, index, value)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const int index, const double& value)
+{
+       if (SQLITE_OK != ::sqlite3_bind_double(statement, index, value)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const int index, const char* value)
+{
+       if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value, -1, SQLITE_TRANSIENT)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const int index, const std::string& value)
+{
+       if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value.c_str(),
+                                                                                static_cast<int>(value.size()), SQLITE_TRANSIENT)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const int index, const void* value, const int size)
+{
+       if (SQLITE_OK != ::sqlite3_bind_blob(statement, index, value, size, SQLITE_TRANSIENT)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const int index)
+{
+       if (SQLITE_OK != ::sqlite3_bind_null(statement, index)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const std::string& name, const int& value)
+{
+       int index = sqlite3_bind_parameter_index(statement, name.c_str());
+       if (SQLITE_OK != sqlite3_bind_int(statement, index, value)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const std::string& name, const sqlite3_int64& value)
+{
+       int index = sqlite3_bind_parameter_index(statement, name.c_str());
+       if (SQLITE_OK != ::sqlite3_bind_int64(statement, index, value)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const std::string& name, const double& value)
+{
+       int index = sqlite3_bind_parameter_index(statement, name.c_str());
+       if (SQLITE_OK != ::sqlite3_bind_double(statement, index, value)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const std::string& name, const std::string& value)
+{
+       int index = sqlite3_bind_parameter_index(statement, name.c_str());
+       if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value.c_str(),
+                                                                                static_cast<int>(value.size()), SQLITE_TRANSIENT)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const std::string& name, const char* value)
+{
+       int index = sqlite3_bind_parameter_index(statement, name.c_str());
+       if (SQLITE_OK != ::sqlite3_bind_text(statement, index, value, -1, SQLITE_TRANSIENT)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const std::string& name, const void* value, const int size)
+{
+       int index = sqlite3_bind_parameter_index(statement, name.c_str());
+       if (SQLITE_OK != ::sqlite3_bind_blob(statement, index, value, size, SQLITE_TRANSIENT)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+void Statement::bind(const std::string& name)
+{
+       int index = sqlite3_bind_parameter_index(statement, name.c_str());
+       if (SQLITE_OK != ::sqlite3_bind_null(statement, index)) {
+               throw runtime::Exception(getErrorMessage());
+       }
+}
+
+} // namespace database
diff --git a/common/db/statement.h b/common/db/statement.h
new file mode 100644 (file)
index 0000000..c834303
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __DATABASE_STATEMENT_H__
+#define __DATABASE_STATEMENT_H__
+
+#include <string>
+#include <map>
+
+#include <sqlite3.h>
+
+namespace database {
+
+class Column;
+class Connection;
+
+class Statement {
+public:
+       Statement(const Connection& db, const std::string& query);
+       virtual ~Statement();
+
+       int exec();
+       bool step();
+
+       void reset();
+       void clearBindings();
+       std::string getErrorMessage() const;
+       std::string getErrorMessage(int errorCode) const;
+
+       Column getColumn(const int index);
+       std::string getColumnName(const int index) const;
+       bool isNullColumn(const int index) const;
+
+       void bind(const int index, const int& value);
+       void bind(const int index, const sqlite3_int64& value);
+       void bind(const int index, const double& value);
+       void bind(const int index, const std::string& value);
+       void bind(const int index, const char* value);
+       void bind(const int index, const void* value, const int size);
+       void bind(const int index);
+
+       void bind(const std::string& name, const int& value);
+       void bind(const std::string& name, const sqlite3_int64& value);
+       void bind(const std::string& name, const double& value);
+       void bind(const std::string& name, const std::string& value);
+       void bind(const std::string& name, const char* value);
+       void bind(const std::string& name, const void* value, const int size);
+       void bind(const std::string& name);
+
+       inline int getColumnCount() const
+       {
+               return columnCount;
+       }
+
+       inline sqlite3_stmt* get() const noexcept
+       {
+               return statement;
+       }
+
+private:
+       typedef std::map<std::string, int> ColumnMap;
+
+       sqlite3_stmt* statement;
+       int columnCount;
+       int validRow;
+       ColumnMap columnNames;
+};
+
+} // namespace database
+
+#endif //__DATABASE_STATEMENT_H__
diff --git a/common/dbus/connection.cpp b/common/dbus/connection.cpp
new file mode 100644 (file)
index 0000000..e85310d
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "connection.h"
+
+#include "exception.h"
+#include "dbus/error.h"
+#include "dbus/variant.h"
+#include "dbus/connection.h"
+#include "audit/logger.h"
+
+namespace dbus {
+
+namespace {
+
+const std::string DBUS_SYSTEM_BUS_ADDRESS = "kernel:path=/sys/fs/kdbus/0-system/bus;unix:path=/var/run/dbus/system_bus_socket";
+
+void defaultCallback(GDBusConnection* connection,
+                                        const gchar *sender_name,
+                                        const gchar *object_path,
+                                        const gchar *interface_name,
+                                        const gchar *signal_name,
+                                        GVariant *parameters,
+                                        gpointer user_data) {
+       Connection::signalCallback* func = reinterpret_cast<Connection::signalCallback*> (user_data);
+       (*func)(Variant(parameters));
+       delete func;
+}
+
+} // namespace
+
+Connection::Connection(const std::string& address) :
+        connection(nullptr)
+{
+       Error error;
+       const GDBusConnectionFlags flags = static_cast<GDBusConnectionFlags>
+               (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION);
+
+       connection = g_dbus_connection_new_for_address_sync(address.c_str(), flags, NULL, NULL, &error);
+       if (error) {
+               ERROR(error->message);
+               throw runtime::Exception(error->message);
+       }
+}
+
+Connection::~Connection()
+{
+       if (connection) {
+               g_dbus_connection_close_sync(connection, NULL, NULL);
+               g_object_unref(connection);
+       }
+}
+
+Connection& Connection::getSystem()
+{
+       static Connection __instance__(DBUS_SYSTEM_BUS_ADDRESS);
+       return __instance__;
+}
+
+Connection::subscriptionId Connection::subscribeSignal(const std::string& sender,
+                                                                                                          const std::string& interface,
+                                                                                                          const std::string& object,
+                                                                                                          const std::string& member,
+                                                                                                          const signalCallback callback)
+{
+       subscriptionId id;
+       id = g_dbus_connection_signal_subscribe(connection,
+                                                                                       sender.empty()    ? NULL : sender.c_str(),
+                                                                                       interface.empty() ? NULL : interface.c_str(),
+                                                                                       object.empty()    ? NULL : object.c_str(),
+                                                                                       member.empty()    ? NULL : member.c_str(),
+                                                                                       NULL,
+                                                                                       G_DBUS_SIGNAL_FLAGS_NONE,
+                                                                                       defaultCallback,
+                                                                                       new signalCallback(callback),
+                                                                                       NULL);
+       return id;
+}
+
+void Connection::unsubscribeSignal(Connection::subscriptionId id)
+{
+       g_dbus_connection_signal_unsubscribe(connection, id);
+}
+
+const Variant Connection::methodcall(const std::string& busName,
+                                                                        const std::string& object,
+                                                                        const std::string& interface,
+                                                                        const std::string& method,
+                                                                        int timeout,
+                                                                        const std::string& replyType,
+                                                                        const std::string& paramType,
+                                                                        ...)
+{
+       Variant result;
+       Error error;
+       va_list ap;
+
+       va_start(ap, paramType);
+       result = g_dbus_connection_call_sync(connection,
+                                                                                busName.empty() ? NULL :
+                                                                                busName.c_str(),
+                                                                                object.c_str(),
+                                                                                interface.c_str(),
+                                                                                method.c_str(),
+                                                                                paramType.empty() ? NULL :
+                                                                                g_variant_new_va(paramType.c_str(), NULL, &ap),
+                                                                                replyType.empty() ? NULL :
+                                                                                G_VARIANT_TYPE(replyType.c_str()),
+                                                                                G_DBUS_CALL_FLAGS_NONE,
+                                                                                timeout,
+                                                                                NULL,
+                                                                                &error);
+       va_end(ap);
+
+       if (error) {
+               ERROR(error->message);
+               throw runtime::Exception(error->message);
+       }
+
+       return result;
+}
+
+} // namespace dbus
diff --git a/common/dbus/connection.h b/common/dbus/connection.h
new file mode 100644 (file)
index 0000000..451b700
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+ #ifndef __RUNTIME_DBUS_CONNECTION_H__
+ #define __RUNTIME_DBUS_CONNECTION_H__
+
+#include <string>
+#include <functional>
+
+#include <gio/gio.h>
+
+#include "dbus/variant.h"
+
+namespace dbus {
+
+class Connection {
+public:
+       typedef unsigned int subscriptionId;
+       typedef std::function<void(Variant)> signalCallback;
+
+       Connection() = delete;
+       Connection(const Connection&) = delete;
+       ~Connection();
+
+       Connection& operator=(const Connection&) = delete;
+
+       static Connection& getSystem();
+
+       subscriptionId subscribeSignal(const std::string& sender,
+                                                                  const std::string& interface,
+                                                                  const std::string& object,
+                                                                  const std::string& member,
+                                                                  const signalCallback callback);
+
+
+       void unsubscribeSignal(subscriptionId id);
+
+       const Variant methodcall(const std::string& busName,
+                                                        const std::string& object,
+                                                        const std::string& interface,
+                                                        const std::string& method,
+                                                        int timeout,
+                                                        const std::string& replyType,
+                                                        const std::string& paramType,
+                                                        ...);
+
+private:
+       Connection(const std::string& address);
+
+       GDBusConnection* connection;
+};
+
+} // namespace dbus
+
+ #endif //! __RUNTIME_DBUS_CONNECTION_H__
diff --git a/common/dbus/error.cpp b/common/dbus/error.cpp
new file mode 100644 (file)
index 0000000..07a64f6
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "dbus/error.h"
+
+namespace dbus {
+
+Error::Error() :
+       error(nullptr)
+{
+}
+
+Error::~Error()
+{
+       if (error) {
+               g_error_free(error);
+       }
+}
+
+GError** Error::operator& ()
+{
+       return &error;
+}
+
+const GError* Error::operator-> () const
+{
+       return error;
+}
+
+Error::operator bool () const
+{
+       return error != nullptr;
+}
+
+} // namespace dbus
diff --git a/common/dbus/error.h b/common/dbus/error.h
new file mode 100644 (file)
index 0000000..d48c611
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_DBUS_ERROR_H__
+#define __RUNTIME_DBUS_ERROR_H__
+
+#include <iostream>
+#include <gio/gio.h>
+
+namespace dbus {
+
+class Error {
+public:
+       Error();
+       ~Error();
+
+       GError** operator& ();
+       const GError* operator-> () const;
+       operator bool () const;
+
+private:
+       GError* error;
+};
+
+} // namespace dbus
+
+#endif //!__RUNTIME_DBUS_ERROR_H__
diff --git a/common/dbus/variant.cpp b/common/dbus/variant.cpp
new file mode 100644 (file)
index 0000000..524a25f
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "dbus/variant.h"
+
+namespace dbus {
+
+Variant::Variant(GVariant* var) :
+       variant(var)
+{
+}
+
+Variant::Variant(Variant&& var) :
+       variant(var.variant)
+{
+       var.variant = nullptr;
+}
+
+Variant::Variant() :
+       variant(nullptr)
+{
+}
+
+Variant::~Variant()
+{
+       if (variant) {
+               g_variant_unref(variant);
+       }
+}
+
+Variant& Variant::operator=(GVariant* var)
+{
+       variant = var;
+       return *this;
+}
+
+Variant::operator bool () const
+{
+       return variant != nullptr;
+}
+
+void Variant::get(const std::string& format, ...) const
+{
+       va_list ap;
+
+       va_start(ap, format);
+       g_variant_get_va(variant, format.c_str(), NULL, &ap);
+       va_end(ap);
+}
+
+
+VariantIterator::VariantIterator(GVariantIter* it) :
+       iterator(it)
+{
+}
+
+VariantIterator::VariantIterator(VariantIterator&& it) :
+       iterator(it.iterator)
+{
+       it.iterator = nullptr;
+}
+
+VariantIterator::VariantIterator() :
+       iterator(nullptr)
+{
+}
+
+VariantIterator::~VariantIterator()
+{
+       if (iterator) {
+               g_variant_iter_free(iterator);
+       }
+}
+
+VariantIterator& VariantIterator::operator=(GVariantIter* it)
+{
+       iterator = it;
+       return *this;
+}
+
+VariantIterator::operator bool () const
+{
+       return iterator != nullptr;
+}
+
+GVariantIter** VariantIterator::operator & ()
+{
+       return &iterator;
+}
+
+bool VariantIterator::get(const std::string& format, ...) const
+{
+       GVariant *var;
+       va_list ap;
+       var = g_variant_iter_next_value(iterator);
+       if (var == NULL) {
+               return false;
+       }
+
+       va_start(ap, format);
+       g_variant_get_va(var, format.c_str(), NULL, &ap);
+       va_end(ap);
+
+       g_variant_unref(var);
+
+       return true;
+}
+
+} // namespace dbus
diff --git a/common/dbus/variant.h b/common/dbus/variant.h
new file mode 100644 (file)
index 0000000..9b4348b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_DBUS_VARIANT_H__
+#define __RUNTIME_DBUS_VARIANT_H__
+
+#include <string>
+#include <gio/gio.h>
+
+namespace dbus {
+
+class Variant {
+public:
+       Variant(GVariant* var);
+       Variant(Variant&& var);
+       Variant();
+       ~Variant();
+
+       Variant& operator=(GVariant* var);
+       operator bool () const;
+       GVariant* operator & ();
+
+       void get(const std::string& format, ...) const;
+private:
+       GVariant* variant;
+};
+
+class VariantIterator {
+public:
+       VariantIterator(GVariantIter* it);
+       VariantIterator(VariantIterator&& it);
+       VariantIterator();
+       ~VariantIterator();
+
+       VariantIterator& operator=(GVariantIter* it);
+       operator bool () const;
+       GVariantIter** operator & ();
+
+       bool get(const std::string& format, ...) const;
+private:
+       GVariantIter* iterator;
+};
+
+
+} // namespace dbus
+
+#endif //!__RUNTIME_DBUS_VARIANT_H__
diff --git a/common/error.cpp b/common/error.cpp
new file mode 100644 (file)
index 0000000..839d3ca
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <cstring>
+#include <cerrno>
+
+#include "error.h"
+
+namespace runtime {
+
+int Error::lastErrorCode()
+{
+       return errno;
+}
+
+std::string Error::message(int errorCode)
+{
+       char errmsg[256];
+       return ::strerror_r(errorCode, errmsg, sizeof(errmsg));
+}
+
+std::string Error::message()
+{
+       return message(lastErrorCode());
+}
+
+std::string GetSystemErrorMessage(int errorCode)
+{
+       return Error::message(errorCode);
+}
+
+std::string GetSystemErrorMessage()
+{
+       return Error::message();
+}
+
+} // namespace runtime
diff --git a/common/error.h b/common/error.h
new file mode 100644 (file)
index 0000000..f746c38
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_ERROR_H__
+#define __RUNTIME_ERROR_H__
+
+#include <string>
+
+namespace runtime {
+
+class Error {
+public:
+       static std::string message();
+       static std::string message(int errorCode);
+       static int lastErrorCode();
+};
+
+std::string GetSystemErrorMessage();
+std::string GetSystemErrorMessage(int errorCode);
+
+} // namespace runtime
+#endif //__RUNTIME_ERROR_H__
diff --git a/common/eventfd.cpp b/common/eventfd.cpp
new file mode 100644 (file)
index 0000000..a2943f3
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <unistd.h>
+
+#include <cstdint>
+
+#include "eventfd.h"
+#include "error.h"
+#include "exception.h"
+
+namespace runtime {
+
+EventFD::EventFD(unsigned int initval, int flags)
+{
+       fd = ::eventfd(initval, flags);
+       if (fd == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+}
+
+EventFD::~EventFD()
+{
+       if (fd != -1) {
+               ::close(fd);
+       }
+}
+
+void EventFD::close()
+{
+       ::close(fd);
+}
+
+void EventFD::send()
+{
+       const std::uint64_t val = 1;
+       if (::write(fd, &val, sizeof(val)) == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+}
+
+void EventFD::receive()
+{
+       std::uint64_t val;
+       if (::read(fd, &val, sizeof(val)) == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+}
+
+} // namespace runtime
diff --git a/common/eventfd.h b/common/eventfd.h
new file mode 100644 (file)
index 0000000..a642136
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_EVENTFD_H__
+#define __RUNTIME_EVENTFD_H__
+
+#include <sys/eventfd.h>
+
+namespace runtime {
+
+class EventFD {
+public:
+       EventFD(unsigned int initval = 0, int flags = EFD_SEMAPHORE | EFD_CLOEXEC);
+       ~EventFD();
+
+       EventFD(const EventFD&) = delete;
+       EventFD& operator=(const EventFD&) = delete;
+
+       void send();
+       void receive();
+       void close();
+
+       int getFd() const
+       {
+               return fd;
+       }
+
+private:
+       int fd;
+};
+
+} // namespace runtime
+
+#endif //__RUNTIME_EVENTFD_H__
diff --git a/common/exception.h b/common/exception.h
new file mode 100644 (file)
index 0000000..734019a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_EXCEPTION_H__
+#define __RUNTIME_EXCEPTION_H__
+
+#include <stdexcept>
+#include <string>
+
+namespace runtime {
+
+class Exception: public std::runtime_error {
+public:
+       Exception(const std::string& error) :
+               std::runtime_error(error)
+       {
+       }
+};
+} // namespace runtime
+#endif //__RUNTIME_EXCEPTION_H__
diff --git a/common/file-descriptor.h b/common/file-descriptor.h
new file mode 100644 (file)
index 0000000..d032c05
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_FILE_DESCRIPTOR_H__
+#define __RUNTIME_FILE_DESCRIPTOR_H__
+
+#include <unistd.h>
+
+#include <iostream>
+
+struct FileDescriptor {
+       FileDescriptor(int fd = -1, bool autoclose = false) :
+               fileDescriptor(fd), autoClose(autoclose)
+       {
+       }
+
+       FileDescriptor(const FileDescriptor&) = delete;
+       FileDescriptor(FileDescriptor&& rhs) :
+               fileDescriptor(rhs.fileDescriptor),
+               autoClose(rhs.autoClose)
+       {
+               rhs.fileDescriptor = -1;
+       }
+
+       ~FileDescriptor() {
+               if ((fileDescriptor != -1) && (autoClose == true)) {
+                       ::close(fileDescriptor);
+               }
+       }
+
+       FileDescriptor& operator=(const int fd) {
+               fileDescriptor = fd;
+               autoClose = false;
+               return *this;
+       }
+
+       FileDescriptor& operator=(FileDescriptor&& rhs) {
+               if (this != &rhs) {
+                       fileDescriptor = rhs.fileDescriptor;
+                       autoClose = rhs.autoClose;
+                       rhs.fileDescriptor = -1;
+               }
+
+               return *this;
+       }
+
+       int fileDescriptor;
+       bool autoClose;
+};
+
+#endif //__RUNTIME_FILE_DESCRIPTOR_H__
diff --git a/common/filesystem.cpp b/common/filesystem.cpp
new file mode 100755 (executable)
index 0000000..0897500
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/sendfile.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+#include "filesystem.h"
+#include "error.h"
+#include "exception.h"
+
+namespace runtime {
+
+File::File() :
+       descriptor(-1)
+{
+}
+
+File::File(const char* pathname) :
+       descriptor(-1), path(pathname)
+{
+}
+
+File::File(const std::string& pathname) :
+       descriptor(-1), path(pathname)
+{
+}
+
+File::File(const File& file) :
+       File(file.getPath())
+{
+}
+
+File::File(const std::string& pathname, int flags) :
+       File(pathname)
+{
+       open(flags);
+}
+
+File::~File()
+{
+       close();
+}
+
+bool File::exists() const
+{
+       struct stat st;
+       return (::stat(path.c_str(), &st) == 0);
+}
+
+bool File::canRead() const
+{
+       if (::access(path.c_str(), R_OK) == 0) {
+               return true;
+       }
+
+       return false;
+}
+
+bool File::canWrite() const
+{
+       if (::access(path.c_str(), W_OK) == 0) {
+               return true;
+       }
+
+       return false;
+}
+
+bool File::canExecute() const
+{
+       if (::access(path.c_str(), X_OK) == 0) {
+               return true;
+       }
+
+       return false;
+}
+
+bool File::isLink() const
+{
+       struct stat st;
+       if (::lstat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return S_ISLNK(st.st_mode);
+}
+
+bool File::isFile() const
+{
+       struct stat st;
+       if (::stat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return S_ISREG(st.st_mode);
+}
+
+bool File::isDirectory() const
+{
+       struct stat st;
+       if (::stat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return S_ISDIR(st.st_mode);
+}
+
+bool File::isDevice() const
+{
+       struct stat st;
+       if (::stat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode));
+}
+
+mode_t File::getMode() const
+{
+       struct stat st;
+       if (::stat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return st.st_mode;
+}
+
+uid_t File::getUid() const
+{
+       struct stat st;
+       if (::stat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return st.st_uid;
+}
+
+gid_t File::getGid() const
+{
+       struct stat st;
+       if (::stat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return st.st_gid;
+}
+
+size_t File::size() const
+{
+       struct stat st;
+       if (::stat(path.c_str(), &st) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       return st.st_size;
+}
+
+void File::create(mode_t mode)
+{
+       while (1) {
+               descriptor = ::creat(path.c_str(), mode);
+               if (descriptor == -1) {
+                       if (errno != EINTR) {
+                               continue;
+                       }
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+               return;
+       }
+}
+
+void File::open(int flags)
+{
+       while (1) {
+               descriptor = ::open(path.c_str(), flags);
+               if (descriptor == -1) {
+                       if (errno != EINTR) {
+                               continue;
+                       }
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+               return;
+       }
+}
+
+void File::close()
+{
+       if (descriptor != -1) {
+               while ((::close(descriptor) == -1) && (errno == EINTR));
+               descriptor = -1;
+       }
+}
+
+void File::read(void *buffer, const size_t size) const
+{
+       size_t total = 0;
+
+       while (total < size) {
+               int bytes = ::read(descriptor, reinterpret_cast<char*>(buffer) + total, size - total);
+               if (bytes >= 0) {
+                       total += bytes;
+               } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
+                       continue;
+               } else {
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+       }
+}
+
+void File::write(const void *buffer, const size_t size) const
+{
+       size_t written = 0;
+
+       while (written < size) {
+               int bytes = ::write(descriptor, reinterpret_cast<const char*>(buffer) + written, size - written);
+               if (bytes >= 0) {
+                       written += bytes;
+               } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
+                       continue;
+               } else {
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+       }
+}
+
+File File::copyTo(const std::string& destDir)
+{
+       const std::string& filename = getPath();
+       File destFile(destDir);
+       if (destFile.exists()) {
+               destFile = destDir + "/" + getName();
+       }
+
+       if (isDirectory()) {
+               DirectoryIterator iter(filename), end;
+               destFile.makeDirectory(false, getUid(), getGid());
+
+               while (iter != end) {
+                       iter->copyTo(destFile.getPath());
+                       ++iter;
+               }
+       } else {
+               open(O_RDONLY);
+               destFile.create(getMode());
+               ::sendfile(destFile.descriptor, descriptor, 0, size());
+               destFile.close();
+               close();
+       }
+
+       return destFile;
+}
+
+void File::remove(bool recursive)
+{
+       if (isDirectory()) {
+               if (recursive) {
+                       DirectoryIterator iter(path), end;
+                       while (iter != end) {
+                               iter->remove(true);
+                               ++iter;
+                       }
+               }
+               if (::rmdir(path.c_str()) != 0) {
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+       } else {
+               if (::unlink(path.c_str()) != 0) {
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+       }
+}
+
+void File::makeBaseDirectory(uid_t uid, gid_t gid)
+{
+       std::string::size_type i = path[0] != '/' ? -1 : 0;
+       const std::string& pathStr = path;
+       while ((i = pathStr.find('/', i + 1)) != std::string::npos) {
+               std::string substr = pathStr.substr(0, i);
+               int ret = ::mkdir(substr.c_str(), 0777);
+               if ((ret == -1) && (errno == EEXIST)) {
+                       continue;
+               } else if (ret == 0) {
+                       if ((uid | gid) != 0) {
+                               if (::chown(substr.c_str(), uid, gid) == -1) {
+                                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+                               }
+                       }
+               } else {
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+       }
+}
+
+void File::makeDirectory(bool recursive, uid_t uid, gid_t gid)
+{
+       if (recursive) {
+               makeBaseDirectory(uid, gid);
+       }
+
+       if (::mkdir(path.c_str(), 0777) == -1) {
+               throw runtime::Exception("mkdir failed in makeDirectory: " + path);
+       }
+
+       if ((uid | gid) != 0) {
+               chown(uid, gid);
+       }
+}
+
+void File::chown(uid_t uid, gid_t gid, bool recursive)
+{
+       if (::chown(path.c_str(), uid, gid) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       if (recursive && isDirectory()) {
+               DirectoryIterator iter(path), end;
+               while (iter != end) {
+                       iter->chown(uid, gid, true);
+                       ++iter;
+               }
+       }
+}
+
+void File::chmod(mode_t mode, bool recursive)
+{
+       if (::chmod(path.c_str(), mode) != 0) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       if (recursive && isDirectory()) {
+               DirectoryIterator iter(path), end;
+               while (iter != end) {
+                       iter->chmod(mode, true);
+                       ++iter;
+               }
+       }
+}
+
+void File::lock() const
+{
+       if (::flock(descriptor, LOCK_EX) == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+}
+
+void File::unlock() const
+{
+       if (::flock(descriptor, LOCK_UN) == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+}
+
+DirectoryIterator::DirectoryIterator()
+       : directoryHandle(nullptr)
+{
+}
+
+DirectoryIterator::DirectoryIterator(const std::string& dir)
+       : directoryHandle(nullptr)
+{
+       reset(dir);
+}
+
+DirectoryIterator::~DirectoryIterator()
+{
+       if (directoryHandle != nullptr) {
+               ::closedir(directoryHandle);
+       }
+}
+
+void DirectoryIterator::reset(const std::string& dir)
+{
+       if (directoryHandle != nullptr) {
+               ::closedir(directoryHandle);
+               directoryHandle = nullptr;
+       }
+
+       basename = dir;
+       directoryHandle = ::opendir(basename.c_str());
+       if (directoryHandle == nullptr) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       next();
+}
+
+void DirectoryIterator::next()
+{
+       std::string name;
+       struct dirent entry, *ent;
+
+       while (1) {
+               if (readdir_r(directoryHandle, &entry, &ent) != 0) {
+                       throw runtime::Exception(runtime::GetSystemErrorMessage());
+               }
+
+               if (ent == NULL)
+                       break;
+
+               if (ent->d_name[0] == '.' && ent->d_name[1] == '\0') {
+                       continue;
+               }
+
+               if (ent->d_name[0] == '.' &&
+                               ent->d_name[1] == '.' && ent->d_name[2] == '\0') {
+                       continue;
+               }
+
+               name = basename + "/" + std::string(ent->d_name);
+               break;
+       }
+
+       current = name;
+}
+
+DirectoryIterator& DirectoryIterator::operator=(const std::string& dir)
+{
+       reset(dir);
+       return *this;
+}
+
+DirectoryIterator& DirectoryIterator::operator++()
+{
+       next();
+       return *this;
+}
+
+static const struct mountOption {
+       const char* name;
+       int clear;
+       int flag;
+} mountOptions[] = {
+       { "defaults",      0, 0                },
+       { "ro",            0, MS_RDONLY        },
+       { "rw",            1, MS_RDONLY        },
+       { "suid",          1, MS_NOSUID        },
+       { "nosuid",        0, MS_NOSUID        },
+       { "dev",           1, MS_NODEV         },
+       { "nodev",         0, MS_NODEV         },
+       { "exec",          1, MS_NOEXEC        },
+       { "noexec",        0, MS_NOEXEC        },
+       { "sync",          0, MS_SYNCHRONOUS   },
+       { "async",         1, MS_SYNCHRONOUS   },
+       { "dirsync",       0, MS_DIRSYNC       },
+       { "remount",       0, MS_REMOUNT       },
+       { "mand",          0, MS_MANDLOCK      },
+       { "nomand",        1, MS_MANDLOCK      },
+       { "atime",         1, MS_NOATIME       },
+       { "noatime",       0, MS_NOATIME       },
+       { "diratime",      1, MS_NODIRATIME    },
+       { "nodiratime",    0, MS_NODIRATIME    },
+       { "bind",          0, MS_BIND          },
+       { "rbind",         0, MS_BIND | MS_REC },
+       { "relatime",      0, MS_RELATIME      },
+       { "norelatime",    1, MS_RELATIME      },
+       { "strictatime",   0, MS_STRICTATIME   },
+       { "nostrictatime", 1, MS_STRICTATIME   },
+       { NULL,            0, 0                },
+};
+
+static unsigned long parseMountOptions(const std::string& opts, std::string& mntdata)
+{
+       std::stringstream optsSstream(opts);
+       const struct mountOption* mo;
+       unsigned long mntflags = 0L;
+       std::string opt;
+
+       while (std::getline(optsSstream, opt, ',')) {
+               for (mo = mountOptions; mo->name != NULL; mo++) {
+                       if (opt == mo->name) {
+                               if (mo->clear) {
+                                       mntflags &= ~mo->flag;
+                               } else {
+                                       mntflags |= mo->flag;
+                               }
+                               break;
+                       }
+                       if (mo->name != NULL) {
+                               continue;
+                       }
+                       if (!mntdata.empty()) {
+                               mntdata += ",";
+                       }
+                       mntdata += opt;
+               }
+       }
+
+       return mntflags;
+}
+
+void Mount::mountEntry(const std::string& src, const std::string& dest, const std::string& type, const std::string& opts)
+{
+       int ret;
+       unsigned long mntflags;
+       std::string mntdata;
+
+       mntflags = parseMountOptions(opts, mntdata);
+
+       ret = ::mount(src.c_str(),
+                                 dest.c_str(),
+                                 type.c_str(),
+                                 mntflags & ~MS_REMOUNT,
+                                 mntdata.c_str());
+
+       if (ret) {
+               if ((mntflags & MS_REMOUNT) || (mntflags & MS_BIND)) {
+                       ret = ::mount(src.c_str(),
+                                                 dest.c_str(),
+                                                 type.c_str(),
+                                                 mntflags | MS_REMOUNT,
+                                                 mntdata.c_str());
+               }
+
+               if (ret) {
+                       throw runtime::Exception("failed to mount " + src + " on " + dest);
+               }
+       }
+}
+
+} // namespace runtime
diff --git a/common/filesystem.h b/common/filesystem.h
new file mode 100644 (file)
index 0000000..20b8a6e
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_FILESYSTEM_H__
+#define __RUNTIME_FILESYSTEM_H__
+
+#include <dirent.h>
+
+#include <string>
+#include <functional>
+
+namespace runtime {
+
+class File {
+public:
+       File();
+       File(const char* pathname);
+       File(const std::string& pathname);
+       File(const File& file);
+       File(const std::string& path, int flags);
+
+       ~File();
+
+       File& operator=(const std::string& pathname)
+       {
+               path = pathname;
+               return *this;
+       }
+
+       File& operator=(const File& file)
+       {
+               path = file.path;
+               return *this;
+       }
+
+       bool operator<(const File& file) const;
+       bool operator>(const File& file) const;
+       bool operator<=(const File& file) const;
+       bool operator>=(const File& file) const;
+
+       bool operator==(const File& file) const
+       {
+               return (path == file.path);
+       }
+
+       bool operator!=(const File& file) const
+       {
+               return !(path == file.path);
+       }
+
+       bool exists() const;
+       bool canRead() const;
+       bool canWrite() const;
+       bool canExecute() const;
+
+       bool isLink() const;
+       bool isFile() const;
+       bool isDirectory() const;
+       bool isDevice() const;
+
+       mode_t getMode() const;
+       uid_t getUid() const;
+       gid_t getGid() const;
+
+       size_t size() const;
+
+       void create(mode_t mode);
+       void open(int flags);
+       void read(void *buffer, const size_t size) const;
+       void write(const void *buffer, const size_t size) const;
+       void close();
+       File copyTo(const std::string& pathname);
+       void remove(bool recursive = false);
+       void makeBaseDirectory(uid_t uid = 0, gid_t gid = 0);
+       void makeDirectory(bool recursive = false, uid_t uid = 0, gid_t gid = 0);
+
+       void lock() const;
+       void unlock() const;
+
+       void chown(uid_t uid, gid_t gid, bool recursive = false);
+       void chmod(mode_t mode, bool recursive = false);
+
+       const std::string& getPath() const
+       {
+               return path;
+       }
+
+       const std::string getName() const
+       {
+               return path.substr(path.rfind('/') + 1);
+       }
+
+private:
+       int descriptor;
+       std::string path;
+};
+
+class DirectoryIterator {
+public:
+       DirectoryIterator();
+       DirectoryIterator(const std::string& dir);
+
+       ~DirectoryIterator();
+
+       DirectoryIterator& operator=(const std::string& dir);
+       DirectoryIterator& operator++();
+
+       bool operator==(const DirectoryIterator& iterator) const
+       {
+               return (current == iterator.current);
+       }
+
+       bool operator!=(const DirectoryIterator& iterator) const
+       {
+               return !(current == iterator.current);
+       }
+
+       const File& operator*() const
+       {
+               return current;
+       }
+
+       File& operator*()
+       {
+               return current;
+       }
+
+       const File* operator->() const
+       {
+               return &current;
+       }
+
+       File* operator->()
+       {
+               return &current;
+       }
+
+private:
+       void next();
+       void reset(const std::string& dir);
+
+       File current;
+       DIR* directoryHandle;
+       std::string basename;
+};
+
+class Mount final {
+public:
+       Mount() = delete;
+
+       static void mountEntry(const std::string& src, const std::string& dest,
+                                                  const std::string& type, const std::string& opts);
+};
+
+int Open(const std::string& path, int flags, mode_t mode);
+void Close(int fd);
+
+} // namespace runtime
+#endif //__RUNTIME_FILESYSTEM_H__
diff --git a/common/mainloop.cpp b/common/mainloop.cpp
new file mode 100644 (file)
index 0000000..dcb1d0e
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <unistd.h>
+#include <assert.h>
+#include <sys/epoll.h>
+
+#include <cstring>
+#include <iostream>
+
+#include <gio/gio.h>
+
+#include "error.h"
+#include "exception.h"
+#include "mainloop.h"
+
+#define MAX_EPOLL_EVENTS       16
+
+namespace runtime {
+
+namespace {
+
+gboolean GIOCallback(GIOChannel* channel, GIOCondition condition, void *data)
+{
+       Mainloop* mainloop = reinterpret_cast<Mainloop*>(data);
+       mainloop->dispatch(-1);
+       return TRUE;
+}
+
+} // namespace
+
+Mainloop::Mainloop() :
+       pollFd(::epoll_create1(EPOLL_CLOEXEC)),
+       stopped(false)
+{
+       if (pollFd == -1) {
+               throw Exception(GetSystemErrorMessage());
+       }
+}
+
+Mainloop::~Mainloop()
+{
+       if (!callbacks.empty()) {
+               //assert(0 && "callback list is not empty");
+       }
+
+       ::close(pollFd);
+}
+
+void Mainloop::addEventSource(const int fd, const Event events, Callback&& callback)
+{
+       epoll_event event;
+       std::lock_guard<Mutex> lock(mutex);
+
+       if (callbacks.find(fd) != callbacks.end()) {
+               throw Exception("Event source already registered");
+       }
+
+       ::memset(&event, 0, sizeof(epoll_event));
+
+       event.events = events;
+       event.data.fd = fd;
+
+       if (::epoll_ctl(pollFd, EPOLL_CTL_ADD, fd, &event) == -1) {
+               throw Exception(GetSystemErrorMessage());
+       }
+
+       callbacks.insert({fd, std::make_shared<Callback>(std::move(callback))});
+}
+
+void Mainloop::removeEventSource(const int fd)
+{
+       std::lock_guard<Mutex> lock(mutex);
+
+       auto iter = callbacks.find(fd);
+       if (iter == callbacks.end()) {
+               return;
+       }
+
+       callbacks.erase(iter);
+
+       ::epoll_ctl(pollFd, EPOLL_CTL_DEL, fd, NULL);
+}
+
+bool Mainloop::dispatch(const int timeout)
+{
+       int nfds;
+       epoll_event event[MAX_EPOLL_EVENTS];
+
+       do {
+               nfds = ::epoll_wait(pollFd, event, MAX_EPOLL_EVENTS, timeout);
+       } while ((nfds == -1) && (errno == EINTR));
+
+       if (nfds < 0) {
+               throw Exception(GetSystemErrorMessage());
+       }
+
+       for (int i = 0; i < nfds; i++) {
+               std::lock_guard<Mutex> lock(mutex);
+
+               auto iter = callbacks.find(event[i].data.fd);
+               if (iter == callbacks.end()) {
+                       continue;
+               }
+
+               std::shared_ptr<Callback> callback(iter->second);
+               try {
+                       if ((event[i].events & (EPOLLHUP | EPOLLRDHUP))) {
+                               event[i].events &= ~EPOLLIN;
+                       }
+
+                       (*callback)(event[i].data.fd, event[i].events);
+               } catch (std::exception& e) {
+                       std::cout << "EXCEPTION ON MAINLOOP" << std::endl;
+               }
+       }
+
+       return true;
+}
+
+void Mainloop::stop()
+{
+       wakeupSignal.send();
+}
+
+void Mainloop::prepare()
+{
+       auto wakeupMainloop = [this](int fd, Mainloop::Event event) {
+               wakeupSignal.receive();
+               removeEventSource(wakeupSignal.getFd());
+               stopped = true;
+       };
+
+       addEventSource(wakeupSignal.getFd(), EPOLLIN, wakeupMainloop);
+}
+
+void Mainloop::run(bool useGMainloop)
+{
+       prepare();
+
+       if (useGMainloop) {
+               GIOChannel* channel;
+               channel = g_io_channel_unix_new(pollFd);
+               if (channel == NULL) {
+                       std::cout << "GMAINLOOP CHANNEL ALLOC FAILED" << std::endl;
+                       return;
+               }
+               g_io_add_watch(channel, (GIOCondition)(G_IO_IN|G_IO_HUP), GIOCallback, this);
+               g_io_channel_unref(channel);
+
+               while (!stopped) {
+                       g_main_iteration(TRUE);
+               }
+       } else {
+               while (!stopped) {
+                       dispatch(-1);
+               }
+       }
+}
+
+} // namespace runtime
diff --git a/common/mainloop.h b/common/mainloop.h
new file mode 100644 (file)
index 0000000..4b55729
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_MAINLOOP_H__
+#define __RUNTIME_MAINLOOP_H__
+
+#include <sys/epoll.h>
+
+#include <string>
+#include <functional>
+#include <unordered_map>
+#include <memory>
+#include <mutex>
+#include <atomic>
+
+#include "eventfd.h"
+
+namespace runtime {
+
+class Mainloop {
+public:
+       typedef unsigned int Event;
+       typedef std::function<void(int fd, Event event)> Callback;
+
+       Mainloop();
+       ~Mainloop();
+
+       void addEventSource(const int fd, const Event events, Callback&& callback);
+       void removeEventSource(const int fd);
+       bool dispatch(const int timeout);
+       void run(bool useGMainloop = false);
+       void stop();
+
+private:
+       typedef std::recursive_mutex Mutex;
+
+       std::unordered_map<int, std::shared_ptr<Callback>> callbacks;
+       Mutex mutex;
+       int pollFd;
+       std::atomic<bool> stopped;
+       runtime::EventFD wakeupSignal;
+
+       void prepare();
+};
+
+} // namespace runtime
+
+#endif //__RUNTIME_MAINLOOP_H__
diff --git a/common/pam.cpp b/common/pam.cpp
new file mode 100644 (file)
index 0000000..4759cd5
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <vector>
+
+#include <security/pam_ext.h>
+#include <security/pam_modules.h>
+
+#include "pam.h"
+
+#include "exception.h"
+
+namespace runtime {
+
+PAM::PAM(const std::string& service, const std::string& user)
+{
+       struct pam_conv pamc;
+
+       int error = ::pam_start(service.c_str(), user.c_str(), &pamc, &pamh);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+}
+
+PAM::~PAM()
+{
+       int error = ::pam_end(pamh, PAM_SUCCESS);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+}
+
+void PAM::setData(const std::string &name, void* data, void (*cleanup)(pam_handle_t* pamh, void* data, int error))
+{
+       int error = ::pam_set_data(pamh, name.c_str(), data, cleanup);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+}
+
+const void* PAM::getData(const std::string &name) const
+{
+       const void* ret;
+       int error = ::pam_get_data(pamh, name.c_str(), &ret);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+       return ret;
+}
+
+void PAM::setItem(int item, void* data)
+{
+       int error = ::pam_set_item(pamh, item, data);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+}
+
+const void* PAM::getItem(int item) const
+{
+       const void* ret;
+       int error = ::pam_get_item(pamh, item, &ret);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+       return ret;
+}
+
+const std::string PAM::getUser(const std::string &prompt) const
+{
+       const char* user;
+       int error = ::pam_get_user(pamh, &user, prompt.c_str());
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+       return std::string(user);
+}
+
+void PAM::putEnv(const std::string &name_value)
+{
+       int error = ::pam_putenv(pamh, name_value.c_str());
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+}
+
+const std::string PAM::getEnv(const std::string &name) const
+{
+       const char* value = ::pam_getenv(pamh, name.c_str());
+       if (value == NULL) {
+               throw runtime::Exception("PAM Error");
+       }
+       return value;
+}
+
+const std::vector<std::string> PAM::getEnvList() const
+{
+       std::vector<std::string> ret;
+       char** array = ::pam_getenvlist(pamh);
+       if (array == NULL) {
+               throw runtime::Exception("PAM Error");
+       }
+       for (int i = 0; array[i] != NULL; i++) {
+               ret.push_back(array[i]);
+       }
+       return ret;
+}
+
+void PAM::syslog(const std::string &log, int priority)
+{
+       ::pam_syslog(pamh, priority, "%s", log.c_str());
+}
+
+
+int PAM::authenticate(int flags)
+{
+       return ::pam_authenticate(pamh, flags);
+}
+
+int PAM::setCredential(int flags)
+{
+       return ::pam_setcred(pamh, flags);
+}
+
+int PAM::accountManagement(int flags)
+{
+       return ::pam_acct_mgmt(pamh, flags);
+}
+
+int PAM::changeAuthenticationToken(int flags)
+{
+       return ::pam_chauthtok(pamh, flags);
+}
+
+void PAM::openSession(int flags)
+{
+       int error = ::pam_open_session(pamh, flags);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+}
+
+void PAM::closeSession(int flags)
+{
+       int error = ::pam_close_session(pamh, flags);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("PAM Error");
+       }
+}
+
+} // namespace runtime
diff --git a/common/pam.h b/common/pam.h
new file mode 100644 (file)
index 0000000..93e1b05
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_PAM_H__
+#define __RUNTIME_PAM_H__
+
+#include <string>
+#include <vector>
+#include <memory>
+
+#include <syslog.h>
+#include <security/pam_appl.h>
+
+namespace runtime {
+
+class PAM final {
+public:
+       PAM(PAM&&) = delete;
+       PAM(const PAM&) = delete;
+       PAM(const std::string& service, const std::string& user);
+       ~PAM();
+
+       PAM& operator=(const PAM&) = delete;
+       PAM& operator=(PAM &&) = delete;
+
+       void setData(const std::string &name, void* data, void (*cleanup)(pam_handle_t* pamh, void* data, int error));
+       const void* getData(const std::string &name) const;
+
+       void setItem(int item, void* data);
+       const void* getItem(int item) const;
+
+       const std::string getUser(const std::string &prompt = "") const;
+
+       void putEnv(const std::string &name_value);
+       const std::string getEnv(const std::string &name) const;
+       const std::vector<std::string> getEnvList() const;
+
+       void syslog(const std::string &log, int priority = LOG_ERR);
+
+       int authenticate(int flags);
+       int setCredential(int flags);
+       int accountManagement(int flags);
+       int changeAuthenticationToken(int flags);
+       void openSession(int flags);
+       void closeSession(int flags);
+
+private:
+       pam_handle_t* pamh;
+};
+
+} // namespace runtime
+#endif // __RUNTIME_PAM_H__
diff --git a/common/preprocessor.h b/common/preprocessor.h
new file mode 100644 (file)
index 0000000..ab653ba
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_PREPROCESSOR_H__
+#define __RUNTIME_PREPROCESSOR_H__
+
+#define STRINGIFY_(x) #x
+#define STRINGIFY(x)  STRINGIFY_(x)
+
+#define CONCATENATE(arg1, arg2)   CONCATENATE1(arg1, arg2)
+#define CONCATENATE1(arg1, arg2)  CONCATENATE2(arg1, arg2)
+#define CONCATENATE2(arg1, arg2)  arg1##arg2
+
+#define VAR_ARGS_SIZE(...)     VAR_ARGS_SIZE_(__VA_ARGS__, FOR_EACH_VAR_ARGS_RSEQ_N())
+#define VAR_ARGS_SIZE_(...)    FOR_EACH_VAR_ARGS_ARG_N(__VA_ARGS__)
+
+#define FOR_EACH_VAR_ARGS_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, N, ...) N
+#define FOR_EACH_VAR_ARGS_RSEQ_N() 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+#define FOR_EACH_VAR_ARGS_1(what, x, ...)  what(x)
+#define FOR_EACH_VAR_ARGS_2(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_1(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_3(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_2(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_4(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_3(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_5(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_4(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_6(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_5(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_7(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_6(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_8(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_7(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_9(what, x, ...)  what(x); FOR_EACH_VAR_ARGS_8(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_10(what, x, ...) what(x); FOR_EACH_VAR_ARGS_9(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_11(what, x, ...) what(x); FOR_EACH_VAR_ARGS_10(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_12(what, x, ...) what(x); FOR_EACH_VAR_ARGS_11(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_13(what, x, ...) what(x); FOR_EACH_VAR_ARGS_12(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_14(what, x, ...) what(x); FOR_EACH_VAR_ARGS_13(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_15(what, x, ...) what(x); FOR_EACH_VAR_ARGS_14(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_16(what, x, ...) what(x); FOR_EACH_VAR_ARGS_15(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_17(what, x, ...) what(x); FOR_EACH_VAR_ARGS_16(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_18(what, x, ...) what(x); FOR_EACH_VAR_ARGS_17(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_19(what, x, ...) what(x); FOR_EACH_VAR_ARGS_18(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_20(what, x, ...) what(x); FOR_EACH_VAR_ARGS_19(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_21(what, x, ...) what(x); FOR_EACH_VAR_ARGS_20(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_22(what, x, ...) what(x); FOR_EACH_VAR_ARGS_21(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_23(what, x, ...) what(x); FOR_EACH_VAR_ARGS_22(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_24(what, x, ...) what(x); FOR_EACH_VAR_ARGS_23(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_25(what, x, ...) what(x); FOR_EACH_VAR_ARGS_24(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_26(what, x, ...) what(x); FOR_EACH_VAR_ARGS_25(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_27(what, x, ...) what(x); FOR_EACH_VAR_ARGS_26(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_28(what, x, ...) what(x); FOR_EACH_VAR_ARGS_27(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_29(what, x, ...) what(x); FOR_EACH_VAR_ARGS_28(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_30(what, x, ...) what(x); FOR_EACH_VAR_ARGS_29(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_31(what, x, ...) what(x); FOR_EACH_VAR_ARGS_30(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS_32(what, x, ...) what(x); FOR_EACH_VAR_ARGS_31(what, __VA_ARGS__)
+
+#define FOR_EACH_VAR_ARGS_(N, what, ...)   CONCATENATE(FOR_EACH_VAR_ARGS_, N)(what, __VA_ARGS__)
+#define FOR_EACH_VAR_ARGS(what, ...)       FOR_EACH_VAR_ARGS_(VAR_ARGS_SIZE(__VA_ARGS__), what, __VA_ARGS__)
+
+#define SEQUENCE_1(how)  how(1)
+#define SEQUENCE_2(how)  SEQUENCE_1(how), how(2)
+#define SEQUENCE_3(how)  SEQUENCE_2(how), how(3)
+#define SEQUENCE_4(how)  SEQUENCE_3(how), how(4)
+#define SEQUENCE_5(how)  SEQUENCE_4(how), how(5)
+#define SEQUENCE_6(how)  SEQUENCE_5(how), how(6)
+#define SEQUENCE_7(how)  SEQUENCE_6(how), how(7)
+#define SEQUENCE_8(how)  SEQUENCE_7(how), how(8)
+#define SEQUENCE_9(how)  SEQUENCE_8(how), how(9)
+#define SEQUENCE_10(how) SEQUENCE_9(how), how(10)
+#define SEQUENCE_11(how) SEQUENCE_10(how), how(11)
+#define SEQUENCE_12(how) SEQUENCE_11(how), how(12)
+#define SEQUENCE_13(how) SEQUENCE_12(how), how(13)
+#define SEQUENCE_14(how) SEQUENCE_13(how), how(14)
+#define SEQUENCE_15(how) SEQUENCE_14(how), how(15)
+#define SEQUENCE_16(how) SEQUENCE_15(how), how(16)
+#define SEQUENCE_17(how) SEQUENCE_16(how), how(17)
+#define SEQUENCE_18(how) SEQUENCE_17(how), how(18)
+#define SEQUENCE_19(how) SEQUENCE_18(how), how(19)
+#define SEQUENCE_20(how) SEQUENCE_19(how), how(20)
+#define SEQUENCE_21(how) SEQUENCE_20(how), how(21)
+#define SEQUENCE_22(how) SEQUENCE_21(how), how(22)
+#define SEQUENCE_23(how) SEQUENCE_22(how), how(23)
+#define SEQUENCE_24(how) SEQUENCE_23(how), how(24)
+#define SEQUENCE_25(how) SEQUENCE_24(how), how(25)
+#define SEQUENCE_26(how) SEQUENCE_25(how), how(26)
+#define SEQUENCE_27(how) SEQUENCE_26(how), how(27)
+#define SEQUENCE_28(how) SEQUENCE_27(how), how(28)
+#define SEQUENCE_29(how) SEQUENCE_28(how), how(29)
+#define SEQUENCE_30(how) SEQUENCE_29(how), how(30)
+#define SEQUENCE_31(how) SEQUENCE_30(how), how(31)
+#define SEQUENCE_32(how) SEQUENCE_31(how), how(32)
+#define SEQUENCE(how, N) SEQUENCE_##N(how)
+
+#endif //!__RUNTIME_PREPROCESSOR_H__
diff --git a/common/process.cpp b/common/process.cpp
new file mode 100644 (file)
index 0000000..7428dab
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "process.h"
+#include "error.h"
+#include "exception.h"
+
+namespace runtime {
+
+Process::Process(const std::string& prog) :
+       status(-1), pid(-1), program(prog)
+{
+       args.push_back(prog);
+}
+
+Process::Process(const std::string& prog, const std::vector<std::string>& args) :
+       status(-1), pid(-1), program(prog), args(args)
+{
+}
+
+Process::~Process()
+{
+}
+
+int Process::execute()
+{
+       pid = ::fork();
+       if (pid == -1) {
+               return -1;
+       }
+
+       if (pid == 0) {
+               const char** argv = new const char *[args.size() + 1];
+
+               int i = 0;
+               for (std::string & arg : args) {
+                       argv[i++] = arg.c_str();
+               }
+               argv[i] = NULL;
+
+               ::execv(program.c_str(), const_cast<char* const*>(argv));
+               std::quick_exit(EXIT_FAILURE);
+       }
+
+       return pid;
+}
+
+int Process::waitForFinished()
+{
+       while (::waitpid(pid, &status, 0) == -1) {
+               if (errno != EINTR) {
+                       return -1;
+               }
+       }
+
+       return status;
+}
+
+bool Process::isRunning() const
+{
+       if (::kill(pid, 0) == 0) {
+               return true;
+       }
+
+       return false;
+}
+
+void Process::kill()
+{
+       if (::kill(pid, SIGKILL) == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+}
+
+void Process::terminate()
+{
+       if (::kill(pid, SIGINT) == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+}
+
+} // namespace runtime
diff --git a/common/process.h b/common/process.h
new file mode 100644 (file)
index 0000000..9b629a2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_PROCESS_H__
+#define __RUNTIME_PROCESS_H__
+
+#include <string>
+#include <vector>
+
+namespace runtime {
+
+class Process {
+public:
+       typedef pid_t Pid;
+
+       Process(const std::string& prog);
+       Process(const std::string& prog, const std::vector<std::string>& args);
+       Process(const Process& proc) = delete;
+
+       ~Process();
+
+       Process& operator=(const Process& proc) = delete;
+
+       int execute();
+       int start();
+       int waitForFinished();
+       int waitForStarted();
+       void terminate();
+       void kill();
+
+       bool isRunning() const;
+
+private:
+       int status;
+       Pid pid;
+       std::string program;
+       std::vector<std::string> args;
+};
+
+} // namespace runtime
+#endif //__RUNTIME_PROCESS_H__
diff --git a/common/reflection.h b/common/reflection.h
new file mode 100644 (file)
index 0000000..7f6bfde
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_REFLECTION_H__
+#define __RUNTIME_REFLECTION_H__
+
+#include <type_traits>
+
+#include "preprocessor.h"
+
+#define VISIT_ELEMENT(elem) v.visit(#elem, elem)
+
+#define REFLECTABLE(...)                            \
+template<typename V>                                \
+void accept(V v)                                    \
+{                                                   \
+       FOR_EACH_VAR_ARGS(VISIT_ELEMENT, __VA_ARGS__);  \
+}                                                   \
+template<typename V>                                \
+void accept(V v) const                              \
+{                                                   \
+       FOR_EACH_VAR_ARGS(VISIT_ELEMENT, __VA_ARGS__);  \
+}
+
+#define NO_REFLECTABLE_PROPERTY \
+       template<typename V>        \
+       static void accept(V) {}
+
+template<typename T>
+struct ReflectionTraitChecker {
+       struct Visitor {};
+
+       template <typename C> static std::true_type
+       test(decltype(std::declval<C>().template accept(Visitor()))*);
+
+       template <typename C> static std::false_type
+       test(...);
+
+       static constexpr bool value = std::is_same<decltype(test<T>(0)), std::true_type>::value;
+};
+
+template<typename T>
+struct IsReflectable : public std::integral_constant<bool, ReflectionTraitChecker<T>::value> {};
+
+#endif //!__RUNTIME_REFLECTION_H__
diff --git a/common/rmi/callback-holder.h b/common/rmi/callback-holder.h
new file mode 100644 (file)
index 0000000..fc22950
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RMI_CALLBACK_HOLDER_H__
+#define __RMI_CALLBACK_HOLDER_H__
+
+#include <utility>
+#include <functional>
+
+#include "message.h"
+
+namespace rmi {
+
+template<typename Type, typename... Args>
+struct MethodHandler {
+       typedef std::function<Type(Args&...)> type;
+};
+// using MethodHandler = std::function<Type(Args&...)>;
+
+template<typename Type, typename... Args>
+struct CallbackHolder {
+       template<int...>
+       struct Sequence {};
+
+       template<int N, int... S>
+       struct SequenceExpansion : SequenceExpansion<N-1, N-1, S...> {};
+
+       template<int... S>
+       struct SequenceExpansion<0, S...> {
+               typedef Sequence<S...> type;
+       };
+
+       std::tuple<Args...> parameters;
+       const typename MethodHandler<Type, Args...>::type& callback;
+
+       CallbackHolder(const typename MethodHandler<Type, Args...>::type& m) :
+               callback(m)
+       {
+       }
+
+       Type dispatch(Message& message)
+       {
+               return callCallback(message, typename SequenceExpansion<sizeof...(Args)>::type());
+       }
+
+       template<typename...R>
+       Type callCallback(Message& message, R&... args)
+       {
+               message.unpackParameters(args...);
+               return callback(args...);
+       }
+
+       template<int... S>
+       Type callCallback(Message& message, Sequence<S...>)
+       {
+               return callCallback(message, std::get<S>(parameters)...);
+       }
+};
+
+} // namespace rmi
+#endif //!__RMI_CALLBACK_HOLDER_H__
diff --git a/common/rmi/client.cpp b/common/rmi/client.cpp
new file mode 100644 (file)
index 0000000..a913446
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "client.h"
+
+namespace rmi {
+
+Client::Client(const std::string& path) :
+       address(path)
+{
+}
+
+Client::~Client()
+{
+       disconnect();
+}
+
+void Client::connect()
+{
+       connection = std::make_shared<Connection>(Socket::connect(address));
+
+       dispatcher = std::thread([this] { mainloop.run(); });
+}
+
+int Client::unsubscribe(const std::string& provider, int id)
+{
+       // file descriptor(id) is automatically closed when mainloop callback is destroyed.
+       mainloop.removeEventSource(id);
+       return 0;
+}
+
+int Client::subscribe(const std::string& provider, const std::string& name)
+{
+       Message request = connection->createMessage(Message::MethodCall, provider);
+       request.packParameters(name);
+       connection->send(request);
+
+       FileDescriptor response;
+       Message reply = connection->dispatch();
+       reply.disclose(response);
+
+       return response.fileDescriptor;
+}
+
+void Client::disconnect()
+{
+       mainloop.stop();
+       if (dispatcher.joinable()) {
+               dispatcher.join();
+       }
+}
+
+} // namespace rmi
diff --git a/common/rmi/client.h b/common/rmi/client.h
new file mode 100644 (file)
index 0000000..53fe5b1
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RMI_CLIENT_H__
+#define __RMI_CLIENT_H__
+
+#include <thread>
+#include <string>
+#include <memory>
+
+#include "error.h"
+#include "message.h"
+#include "connection.h"
+#include "mainloop.h"
+#include "callback-holder.h"
+
+namespace rmi {
+
+class Client {
+public:
+       Client(const std::string& address);
+       ~Client();
+
+       Client(const Client&) = delete;
+       Client& operator=(const Client&) = delete;
+
+       void connect();
+       void disconnect();
+
+       int subscribe(const std::string& provider, const std::string& name);
+
+       template<typename... Args>
+       int subscribe(const std::string& provider, const std::string& name,
+                                 const typename MethodHandler<void, Args...>::type& handler);
+
+       int unsubscribe(const std::string& provider, int handle);
+
+       template<typename Type, typename... Args>
+       Type methodCall(const std::string& method, Args&&... args);
+
+private:
+       std::string address;
+       std::shared_ptr<Connection> connection;
+       runtime::Mainloop mainloop;
+       std::thread dispatcher;
+};
+
+template<typename... Args>
+int Client::subscribe(const std::string& provider, const std::string& name,
+                                         const typename MethodHandler<void, Args...>::type& handler)
+{
+       int id = subscribe(provider, name);
+       if (id < 0) {
+               return -1;
+       }
+
+       std::shared_ptr<Socket> transport = std::make_shared<Socket>(id);
+
+       auto callback = [handler, transport, this](int fd, runtime::Mainloop::Event event) {
+               if ((event & EPOLLHUP) || (event & EPOLLRDHUP)) {
+                       mainloop.removeEventSource(fd);
+                       return;
+               }
+
+               try {
+                       Message msg;
+                       msg.decode(*transport);
+
+                       CallbackHolder<void, Args...> callback(handler);
+                       callback.dispatch(msg);
+               } catch (std::exception& e) {
+                       std::cout << e.what() << std::endl;
+               }
+       };
+
+       mainloop.addEventSource(id, EPOLLIN | EPOLLHUP | EPOLLRDHUP, callback);
+
+       return id;
+}
+
+template<typename Type, typename... Args>
+Type Client::methodCall(const std::string& method, Args&&... args)
+{
+       Message request = connection->createMessage(Message::MethodCall, method);
+       request.packParameters(std::forward<Args>(args)...);
+       connection->send(request);
+
+       Type response;
+       Message reply = connection->dispatch();
+       reply.disclose<Type>(response);
+
+       return response;
+}
+
+} // namespace rmi
+#endif //__RMI_CLIENT_H__
diff --git a/common/rmi/connection.cpp b/common/rmi/connection.cpp
new file mode 100644 (file)
index 0000000..9153a81
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <utility>
+
+#include "connection.h"
+
+namespace rmi {
+
+Connection::Connection(Socket&& sock) :
+       socket(std::move(sock))
+{
+}
+
+Connection::~Connection() noexcept
+{
+}
+
+Message Connection::createMessage(unsigned int type, const std::string& target)
+{
+       return Message(type, target);
+}
+
+void Connection::send(const Message& message) const
+{
+       std::lock_guard<std::mutex> lock(transmitMutex);
+       message.encode(socket);
+}
+
+Message Connection::dispatch() const
+{
+       Message message;
+       std::lock_guard<std::mutex> lock(receiveMutex);
+
+       message.decode(socket);
+       if (message.isError()) {
+               std::string exception;
+               message.disclose(exception);
+
+               throw runtime::Exception(exception);
+       }
+
+       return message;
+}
+
+} // namespace rmi
diff --git a/common/rmi/connection.h b/common/rmi/connection.h
new file mode 100644 (file)
index 0000000..0b943e2
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RMI_CONNECTION_H__
+#define __RMI_CONNECTION_H__
+
+#include <string>
+#include <mutex>
+
+#include "socket.h"
+#include "serialize.h"
+#include "message.h"
+
+namespace rmi {
+
+class Connection {
+public:
+       Connection(Socket&& sock);
+       Connection(const Connection&) = delete;
+       ~Connection() noexcept;
+
+       Connection& operator=(const Connection&) = delete;
+       Connection& operator=(Connection&) = delete;
+
+       Message createMessage(unsigned int type, const std::string& target);
+
+       void send(const Message& message) const;
+       Message dispatch() const;
+
+       int getFd() const
+       {
+               return socket.getFd();
+       }
+
+       Credentials getPeerCredentials() const
+       {
+               return socket.getPeerCredentials();
+       }
+
+private:
+       Socket socket;
+       mutable std::mutex receiveMutex;
+       mutable std::mutex transmitMutex;
+};
+
+} // namespace rmi
+#endif //__RMI_CONNECTION_H__
diff --git a/common/rmi/message-composer.cpp b/common/rmi/message-composer.cpp
new file mode 100644 (file)
index 0000000..cdb29aa
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "message-composer.h"
+
+namespace rmi {
+
+MessageComposer::MessageComposer(size_t caps) :
+       capacity(caps),
+       produce(0),
+       consume(0),
+       buffer(new char[caps])
+{
+}
+
+MessageComposer::MessageComposer(const MessageComposer& rhs) :
+       capacity(rhs.capacity),
+       produce(rhs.produce),
+       consume(rhs.consume),
+       buffer(new char[rhs.capacity])
+{
+       std::copy(rhs.buffer + consume, rhs.buffer + produce, buffer + consume);
+}
+
+MessageComposer::MessageComposer(MessageComposer&& rhs) :
+       capacity(0),
+       produce(0),
+       consume(0),
+       buffer(nullptr)
+{
+       buffer = rhs.buffer;
+       capacity = rhs.capacity;
+       produce = rhs.produce;
+       consume = rhs.consume;
+
+       // Release buffer pointer from the source object so that
+       // the destructor does not free the memory multiple times.
+
+       rhs.buffer = nullptr;
+       rhs.produce = 0;
+       rhs.consume = 0;
+}
+
+MessageComposer::~MessageComposer()
+{
+       if (buffer != nullptr) {
+               delete[] buffer;
+       }
+}
+
+MessageComposer& MessageComposer::operator=(const MessageComposer& rhs)
+{
+       if (this != &rhs) {
+               delete[] buffer;
+
+               capacity = rhs.capacity;
+               produce = rhs.produce;
+               consume = rhs.consume;
+               buffer = new char[capacity];
+               std::copy(rhs.buffer + consume, rhs.buffer + produce, buffer + consume);
+       }
+
+       return *this;
+}
+
+MessageComposer& MessageComposer::operator=(MessageComposer&& rhs)
+{
+       if (this != &rhs) {
+               // Free existing buffer
+               delete[] buffer;
+
+               // Copy the buffer pointer and its attributes from the
+               // source object.
+               buffer = rhs.buffer;
+               produce = rhs.produce;
+               consume = rhs.consume;
+               capacity = rhs.capacity;
+
+               // Release buffer pointer from the source object so that
+               // the destructor does not free the memory multiple times.
+               rhs.buffer = nullptr;
+               rhs.produce = 0;
+               rhs.consume = 0;
+               rhs.capacity = 0;
+       }
+
+       return *this;
+}
+
+void MessageComposer::write(const void* ptr, const size_t sz)
+{
+       size_t bytes = sz;
+       if ((produce + bytes) > capacity) {
+               bytes = capacity - produce;
+       }
+
+       ::memcpy(reinterpret_cast<char *>(buffer + produce), ptr, bytes);
+       produce += bytes;
+}
+
+void MessageComposer::read(void* ptr, const size_t sz)
+{
+       size_t bytes = sz;
+       if ((consume + bytes) > produce) {
+               bytes = produce - consume;
+       }
+
+       ::memcpy(ptr, reinterpret_cast<char *>(buffer) + consume, bytes);
+       consume += bytes;
+
+       // Reset cursors if there is no data
+       if (consume == produce) {
+               consume = produce = 0;
+       }
+}
+
+} // namespae rmi
diff --git a/common/rmi/message-composer.h b/common/rmi/message-composer.h
new file mode 100644 (file)
index 0000000..377b817
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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.
+ */
+
+#ifndef __RMI_MESSAGE_COMPOSER_H__
+#define __RMI_MESSAGE_COMPOSER_H__
+
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <memory>
+
+namespace rmi {
+
+class MessageComposer {
+public:
+       MessageComposer(size_t caps = 4096);
+       MessageComposer(const MessageComposer& rhs);
+       MessageComposer(MessageComposer&& rhs);
+
+       ~MessageComposer();
+
+       MessageComposer& operator=(const MessageComposer& rhs);
+       MessageComposer& operator=(MessageComposer&& rhs);
+
+       void write(const void* ptr, const size_t sz);
+       void read(void* ptr, const size_t sz);
+
+       void reserve(size_t size)
+       {
+               produce = size;
+       }
+
+       void reset()
+       {
+               produce = consume = 0;
+       }
+
+       char* begin() const
+       {
+               return buffer + consume;
+       }
+
+       char* end() const
+       {
+               return buffer + produce;
+       }
+
+       size_t size() const
+       {
+               return (end() - begin());
+       }
+
+private:
+       size_t capacity;
+       size_t produce;
+       size_t consume;
+       char *buffer;
+};
+
+} // namespae rmi
+#endif //__RMI_MESSAGE_COMPOSER_H__
diff --git a/common/rmi/message.cpp b/common/rmi/message.cpp
new file mode 100644 (file)
index 0000000..256da2c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "message.h"
+#include "exception.h"
+
+namespace rmi {
+
+std::atomic<unsigned int> Message::sequence(0);
+
+Message::Message() :
+       signature({sequence++, Invalid, ""})
+{
+}
+
+Message::Message(unsigned int id, unsigned int type, const std::string& target) :
+       signature({id, type, target})
+{
+       enclose(signature);
+}
+
+Message::Message(unsigned int type, const std::string& target) :
+       signature({sequence++, type, target})
+{
+       enclose(signature);
+}
+
+Message::Message(Message&& rhs)
+       : signature(std::move(rhs.signature)),
+         buffer(std::move(rhs.buffer)),
+         fileDescriptors(std::move(rhs.fileDescriptors))
+{
+}
+
+Message::~Message()
+{
+}
+
+Message::Message(const Message& rhs) :
+       signature(rhs.signature),
+       buffer(rhs.buffer)
+{
+       enclose(signature);
+}
+
+Message& Message::operator=(const Message& rhs)
+{
+       if (this != &rhs) {
+               buffer = rhs.buffer;
+               signature = rhs.signature;
+       }
+
+       return *this;
+}
+
+Message& Message::operator=(Message&& rhs)
+{
+       if (this != &rhs) {
+               buffer = std::move(rhs.buffer);
+               signature = std::move(rhs.signature);
+               fileDescriptors = std::move(rhs.fileDescriptors);
+       }
+
+       return *this;
+}
+
+Message Message::createReplyMessage() const
+{
+       return Message(id(), Reply, target());
+}
+
+Message Message::createErrorMessage(const std::string& message) const
+{
+       Message error(id(), Error, target());
+       error.enclose(message);
+
+       return error;
+}
+
+template<> void Message::enclose(FileDescriptor&& fd)
+{
+       if (fd.fileDescriptor == -1) {
+               throw runtime::Exception("Invalid file descriptor");
+       }
+
+       fileDescriptors.push_back(std::move(fd));
+}
+
+template<> void Message::disclose(FileDescriptor& fd)
+{
+       if (!fileDescriptors.empty()) {
+               fd.fileDescriptor = std::move(fileDescriptors.front()).fileDescriptor;
+               fileDescriptors.pop_front();
+       }
+}
+
+} // namespace rmi
diff --git a/common/rmi/message.h b/common/rmi/message.h
new file mode 100644 (file)
index 0000000..a54f360
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RMI_MESSAGE_H__
+#define __RMI_MESSAGE_H__
+
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <memory>
+#include <atomic>
+#include <deque>
+
+#include "message-composer.h"
+
+#include "reflection.h"
+#include "serialize.h"
+#include "file-descriptor.h"
+
+namespace rmi {
+
+class Message {
+public:
+       enum Type {
+               Invalid,
+               MethodCall,
+               Reply,
+               Error,
+               Signal
+       };
+
+       Message();
+       Message(unsigned int id, unsigned int type, const std::string&);
+       Message(unsigned int type, const std::string&);
+       Message(const Message& rhs);
+       Message(Message&& rhs);
+
+       ~Message();
+
+       Message& operator=(const Message& rhs);
+       Message& operator=(Message&& rhs);
+
+       // [TBD] Take arguments
+       Message createReplyMessage() const;
+       Message createErrorMessage(const std::string& message) const;
+
+       unsigned int id() const
+       {
+               return signature.id;
+       }
+
+       unsigned int type() const
+       {
+               return signature.type;
+       }
+
+       const std::string& target() const
+       {
+               return signature.target;
+       }
+
+       bool isInvalid() const
+       {
+               return type() == Invalid;
+       }
+
+       bool isError() const
+       {
+               return type() == Error;
+       }
+
+       bool isMethodCall() const
+       {
+               return type() == MethodCall;
+       }
+
+       bool isSignal() const
+       {
+               return type() == Signal;
+       }
+
+       bool isReply() const
+       {
+               return type() == Reply;
+       }
+
+       template<typename T>
+       void encode(const T& device) const;
+
+       template<typename T>
+       void decode(const T& device);
+
+       void packParameters()
+       {
+       }
+
+       template<typename F>
+       void packParameters(F&& arg);
+
+       template<typename F, typename...R>
+       void packParameters(F&& first, R&&... rest);
+
+       void unpackParameters()
+       {
+       }
+
+       template<typename F>
+       void unpackParameters(F& arg);
+
+       template<typename F, typename... R>
+       void unpackParameters(F& first, R&... rest);
+
+       template<typename DataType>
+       void enclose(DataType&& data);
+
+       template<typename DataType>
+       void disclose(DataType& data);
+
+private:
+       struct MessageHeader {
+               unsigned int id;    // Unique message id
+               unsigned int type;  // Mesage type
+               size_t length;// Total message length except MessageHeader itself
+               size_t ancillary;
+       };
+
+       struct MessageSignature {
+               unsigned int id;
+               unsigned int type;
+               std::string target;
+
+               REFLECTABLE(
+                       id,
+                       type,
+                       target
+               )
+       };
+
+       MessageSignature signature;
+       MessageComposer buffer;
+       std::deque<FileDescriptor> fileDescriptors;
+
+       static std::atomic<unsigned int> sequence;
+};
+
+template<typename F>
+void Message::packParameters(F&& arg)
+{
+       enclose<F>(std::forward<F>(arg));
+}
+
+template<typename F, typename...R>
+void Message::packParameters(F&& first, R&&... rest)
+{
+       packParameters(std::forward<F>(first));
+       packParameters(std::forward<R>(rest)...);
+}
+
+template<typename F>
+void Message::unpackParameters(F& arg)
+{
+       disclose<F>(arg);
+}
+
+template<typename F, typename... R>
+void Message::unpackParameters(F& first, R&... rest)
+{
+       unpackParameters(first);
+       unpackParameters(rest...);
+}
+
+template<typename DataType>
+void Message::enclose(DataType&& data)
+{
+       runtime::Serializer<MessageComposer> serializer(buffer);
+       runtime::SerializableArgument<DataType> arg(std::forward<DataType>(data));
+       arg.accept(serializer);
+}
+
+template<typename DataType>
+void Message::disclose(DataType& data)
+{
+       runtime::Deserializer<MessageComposer> deserializer(buffer);
+       runtime::DeserializableArgument<DataType> arg(data);
+       arg.accept(deserializer);
+}
+
+template<typename T>
+void Message::encode(const T& device) const
+{
+       MessageHeader header = {
+               signature.id,
+               signature.type,
+               buffer.size(),
+               fileDescriptors.size()
+       };
+
+       device.write(&header, sizeof(header));
+       device.write(buffer.begin(), header.length);
+
+       int i = 0, fds[fileDescriptors.size()];
+       for (const FileDescriptor& fd : fileDescriptors) {
+               fds[i++] = fd.fileDescriptor;
+       }
+
+       device.sendFileDescriptors(fds, fileDescriptors.size());
+}
+
+template<typename T>
+void Message::decode(const T& device)
+{
+       MessageHeader header;
+       device.read(&header, sizeof(header));
+       device.read(buffer.begin(), header.length);
+       buffer.reserve(header.length);
+
+       int fds[header.ancillary];
+
+       device.receiveFileDescriptors(fds, header.ancillary);
+       for (unsigned int i = 0; i < header.ancillary; i++) {
+               fileDescriptors.emplace_back(FileDescriptor(fds[i]));
+       }
+
+       disclose(signature);
+}
+
+template<> void Message::enclose(FileDescriptor&& fd);
+template<> void Message::disclose(FileDescriptor& fd);
+
+} // namespae rmi
+#endif //__RMI_MESSAGE_H__
diff --git a/common/rmi/notification.cpp b/common/rmi/notification.cpp
new file mode 100644 (file)
index 0000000..1e1dfd9
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "notification.h"
+#include "exception.h"
+#include "error.h"
+
+namespace rmi {
+
+Notification::Notification()
+{
+}
+
+Notification::Notification(const std::string& name) :
+       signalName(name)
+{
+}
+
+Notification::Notification(Notification&& rhs) :
+       signalName(std::move(rhs.signalName)),
+       subscribers(std::move(rhs.subscribers))
+{
+}
+
+SubscriptionId Notification::createSubscriber()
+{
+       int fds[2] = {-1, -1};
+       if (::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
+               throw runtime::Exception("Failed to create socket pair");
+       }
+
+       std::lock_guard<std::mutex> lock(subscriberLock);
+       subscribers.push_back(std::make_shared<Socket>(fds[0]));
+
+       return SubscriptionId(fds[0], fds[1]);
+}
+
+int Notification::removeSubscriber(const int id)
+{
+       std::lock_guard<std::mutex> lock(subscriberLock);
+
+       std::list<std::shared_ptr<Socket>>::iterator it = subscribers.begin();
+
+       while (it != subscribers.end()) {
+          if ((*it)->getFd() == id) {
+                       subscribers.erase(it);
+                       return 0;
+          }
+          ++it;
+       }
+
+       return -1;
+}
+
+} // namespace rmi
diff --git a/common/rmi/notification.h b/common/rmi/notification.h
new file mode 100644 (file)
index 0000000..22d802e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RMI_NOTIFICATION_H__
+#define __RMI_NOTIFICATION_H__
+
+#include <string>
+#include <vector>
+#include <mutex>
+#include <unordered_map>
+#include <list>
+#include <utility>
+#include <memory>
+
+#include "socket.h"
+#include "message.h"
+#include "audit/logger.h"
+
+namespace rmi {
+
+typedef std::pair<int, int> SubscriptionId;
+
+class Notification {
+public:
+       Notification();
+       Notification(const std::string& name);
+       Notification(const Notification&) = default;
+       Notification(Notification&&);
+
+       SubscriptionId createSubscriber();
+       int removeSubscriber(const int id);
+
+       template<typename... Args>
+       void notify(Args&&... args);
+
+private:
+       std::string signalName;
+       std::list<std::shared_ptr<Socket>> subscribers;
+       std::mutex subscriberLock;
+};
+
+template<typename... Args>
+void Notification::notify(Args&&... args)
+{
+       Message msg(Message::Signal, signalName);
+       msg.packParameters(std::forward<Args>(args)...);
+
+       std::lock_guard<std::mutex> lock(subscriberLock);
+
+       for (const std::shared_ptr<Socket>& subscriber : subscribers) {
+               try {
+                       msg.encode(*subscriber);
+               } catch (runtime::Exception& e) {
+                       ERROR(e.what());
+               }
+       }
+}
+
+} // namespae rmi
+#endif //__RMI_NOTIFICATION_H__
diff --git a/common/rmi/service.cpp b/common/rmi/service.cpp
new file mode 100644 (file)
index 0000000..0c3effb
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+
+#include "exception.h"
+#include "service.h"
+#include "message.h"
+#include "audit/logger.h"
+
+namespace rmi {
+
+thread_local Service::ProcessingContext Service::processingContext;
+
+Service::Service(const std::string& path) :
+       address(path), workqueue(5)
+{
+       setNewConnectionCallback(nullptr);
+       setCloseConnectionCallback(nullptr);
+}
+
+Service::~Service()
+{
+}
+
+void Service::start(bool useGMainloop)
+{
+       Socket socket(Socket::create(address));
+
+       auto accept = [&](int fd, runtime::Mainloop::Event event) {
+               onNewConnection(std::make_shared<Connection>(socket.accept()));
+       };
+
+       mainloop.addEventSource(socket.getFd(),
+                                                       EPOLLIN | EPOLLHUP | EPOLLRDHUP,
+                                                       accept);
+
+       mainloop.run(useGMainloop);
+}
+
+void Service::stop()
+{
+}
+
+Service::ConnectionRegistry::iterator Service::getConnectionIterator(const int id)
+{
+       return std::find_if(connectionRegistry.begin(), connectionRegistry.end(),
+                                               [id](const std::shared_ptr<Connection>& connection) {
+               return id == connection->getFd();
+       });
+}
+
+void Service::setPrivilegeChecker(const PrivilegeChecker& checker)
+{
+       auto check = [checker, this](const Credentials& cred, const std::string& privilege) {
+               return checker(cred, privilege);
+       };
+
+       onMethodCall = std::move(checker);
+}
+
+void Service::setNewConnectionCallback(const ConnectionCallback& connectionCallback)
+{
+       auto callback = [connectionCallback, this](const std::shared_ptr<Connection>& connection) {
+               auto handle = [&](int fd, runtime::Mainloop::Event event) {
+                       std::lock_guard<std::mutex> lock(stateLock);
+
+                       auto iter = getConnectionIterator(fd);
+                       if (iter == connectionRegistry.end()) {
+                               return;
+                       }
+
+                       if ((event & EPOLLHUP) || (event & EPOLLRDHUP)) {
+                               onCloseConnection(*iter);
+                               connectionRegistry.erase(iter);
+                               return;
+                       }
+
+                       onMessageProcess(*iter);
+               };
+
+               if ((connectionCallback == nullptr) ||
+                       (connectionCallback(*connection) == true)) {
+                       mainloop.addEventSource(connection->getFd(),
+                                                                       EPOLLIN | EPOLLHUP | EPOLLRDHUP,
+                                                                       handle);
+                       std::lock_guard<std::mutex> lock(stateLock);
+                       connectionRegistry.push_back(connection);
+               }
+       };
+
+       std::lock_guard<std::mutex> lock(stateLock);
+       onNewConnection = std::move(callback);
+}
+
+void Service::setCloseConnectionCallback(const ConnectionCallback& closeCallback)
+{
+       auto callback = [closeCallback, this](const std::shared_ptr<Connection>& connection) {
+               mainloop.removeEventSource(connection->getFd());
+               if (closeCallback) {
+                       closeCallback(*connection);
+               }
+       };
+
+       std::lock_guard<std::mutex> lock(stateLock);
+       onCloseConnection = std::move(callback);
+}
+
+void Service::createNotification(const std::string& name)
+{
+       std::lock_guard<std::mutex> lock(notificationLock);
+
+       if (notificationRegistry.count(name)) {
+               throw runtime::Exception("Notification already registered");
+       }
+
+       notificationRegistry.emplace(name, Notification(name));
+}
+
+int Service::subscribeNotification(const std::string& name)
+{
+       auto closeHandler = [&, name, this](int fd, runtime::Mainloop::Event event) {
+               if ((event & EPOLLHUP) || (event & EPOLLRDHUP)) {
+                       unsubscribeNotification(name, fd);
+                       return;
+               }
+       };
+
+       notificationLock.lock();
+       if (!notificationRegistry.count(name)) {
+               notificationLock.unlock();
+               return -1;
+       }
+
+       Notification& notification = notificationRegistry[name];
+       notificationLock.unlock();
+
+       try {
+               SubscriptionId slot = notification.createSubscriber();
+               mainloop.addEventSource(slot.first, EPOLLHUP | EPOLLRDHUP, closeHandler);
+               return slot.second;
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return -1;
+}
+
+int Service::unsubscribeNotification(const std::string& name, const int id)
+{
+       notificationLock.lock();
+
+       if (!notificationRegistry.count(name)) {
+               notificationLock.unlock();
+               return -1;
+       }
+
+       Notification& notification = notificationRegistry[name];
+       notificationLock.unlock();
+
+       mainloop.removeEventSource(id);
+
+       notification.removeSubscriber(id);
+
+       return 0;
+}
+
+void Service::onMessageProcess(const std::shared_ptr<Connection>& connection)
+{
+       // The connection object can be destroyed in main-thread when peer is closed.
+       // To make sure that the connection object is valid on that situation,
+       // we should increase the reference count of the shared_ptr by capturing it as value
+       auto process = [&, connection](Message& request) {
+               try {
+                       std::shared_ptr<MethodContext> methodContext = methodRegistry.at(request.target());
+
+                       processingContext = ProcessingContext(connection);
+                       if (onMethodCall(processingContext.credentials, methodContext->privilege) != true) {
+                               throw runtime::Exception("Permission denied");
+                       }
+
+                       connection->send(methodContext->dispatcher(request));
+               } catch (std::exception& e) {
+                       try {
+                               // Forward the exception to the peer
+                               connection->send(request.createErrorMessage(e.what()));
+                       } catch (std::exception& ex) {
+                               // The connection is abnormally closed by the peer.
+                               ERROR(ex.what());
+                       }
+               }
+       };
+
+       try {
+               workqueue.submit(std::bind(process, connection->dispatch()));
+       } catch (std::exception& e) {
+               ERROR(e.what());
+       }
+}
+
+} // namespace rmi
diff --git a/common/rmi/service.h b/common/rmi/service.h
new file mode 100644 (file)
index 0000000..0dee955
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RMI_SERVICE_H__
+#define __RMI_SERVICE_H__
+
+#include <mutex>
+#include <string>
+#include <functional>
+#include <memory>
+#include <vector>
+#include <list>
+#include <unordered_map>
+#include <thread>
+
+#include "preprocessor.h"
+#include "thread-pool.h"
+#include "mainloop.h"
+#include "connection.h"
+#include "message.h"
+#include "callback-holder.h"
+#include "notification.h"
+
+#define STRIP_(...)
+#define STRIP(x)         STRIP_ x
+
+#define TYPEOF____(...)   __VA_ARGS__
+#define TYPEOF___(...)   (__VA_ARGS__),
+#define TYPEOF__(x, ...) TYPEOF____ x
+#define TYPEOF_(...)     TYPEOF__(__VA_ARGS__)
+#define TYPEOF(x)        TYPEOF_(TYPEOF___ x, )
+
+#define PLACEHOLDER(n)   std::placeholders::_##n
+
+#define PROTOTYPE_(D, N) SEQUENCE(D, N)
+#define PROTOTYPE(...)   PROTOTYPE_(PLACEHOLDER, VAR_ARGS_SIZE(__VA_ARGS__))
+
+#define registerMethod(T, P, M, ...)                                          \
+setMethodHandler<TYPEOF(M), TYPEOF(STRIP(STRIP(M)))>                          \
+                               (P, STRINGIFY(TYPEOF(STRIP(M))), std::bind(&TYPEOF(STRIP(M)), T, \
+                               PROTOTYPE(TYPEOF(STRIP(STRIP(M))))))
+
+#define registerParametricMethod(T, P, M, ...)                                \
+setMethodHandler<TYPEOF(M), TYPEOF(STRIP(STRIP(M)))>                          \
+                               (P, STRINGIFY(TYPEOF(STRIP(M))), std::bind(&TYPEOF(STRIP(M)), T, \
+                               PROTOTYPE(TYPEOF(STRIP(STRIP(M))))))
+
+#define registerNonparametricMethod(T, P, M, ...)                             \
+setMethodHandler<TYPEOF(M)>                                                   \
+                               (P, STRINGIFY(TYPEOF(STRIP(M))), std::bind(&TYPEOF(STRIP(M)), T))
+
+namespace rmi {
+
+typedef std::function<bool(const Connection& connection)> ConnectionCallback;
+typedef std::function<bool(const Credentials& cred, const std::string& privilege)> PrivilegeChecker;
+
+class Service {
+public:
+       Service(const std::string& address);
+       ~Service();
+
+       Service(const Service&) = delete;
+       Service& operator=(const Service&) = delete;
+
+       void start(bool useGMainloop = false);
+       void stop();
+
+       void setPrivilegeChecker(const PrivilegeChecker& checker);
+       void setNewConnectionCallback(const ConnectionCallback& callback);
+       void setCloseConnectionCallback(const ConnectionCallback& callback);
+
+       template<typename Type, typename... Args>
+       void setMethodHandler(const std::string& privilege, const std::string& method,
+                                                 const typename MethodHandler<Type, Args...>::type& handler);
+
+       void createNotification(const std::string& name);
+       int subscribeNotification(const std::string& name);
+       int unsubscribeNotification(const std::string& name, const int id);
+
+       template <typename... Args>
+       void notify(const std::string& name, Args&&... args);
+
+       pid_t getPeerPid() const
+       {
+               return processingContext.credentials.pid;
+       }
+
+       uid_t getPeerUid() const
+       {
+               return processingContext.credentials.uid;
+       }
+
+       gid_t getPeerGid() const
+       {
+               return processingContext.credentials.gid;
+       }
+
+private:
+       struct ProcessingContext {
+               ProcessingContext() = default;
+               ProcessingContext(const std::shared_ptr<Connection>& connection) :
+                       credentials(connection->getPeerCredentials())
+               {
+               }
+
+               Credentials credentials;
+       };
+
+       typedef std::list<std::shared_ptr<Connection>> ConnectionRegistry;
+       typedef std::function<void(const std::shared_ptr<Connection>& connection)> CallbackDispatcher;
+
+       typedef std::function<Message(Message& message)> MethodDispatcher;
+
+       struct MethodContext {
+               MethodContext(const std::string& priv, MethodDispatcher&& disp) :
+                       privilege(priv), dispatcher(std::move(disp))
+               {
+               }
+
+               std::string privilege;
+               MethodDispatcher dispatcher;
+       };
+
+       typedef std::unordered_map<std::string, std::shared_ptr<MethodContext>> MethodRegistry;
+       typedef std::unordered_map<std::string, Notification> NotificationRegistry;
+
+       void onMessageProcess(const std::shared_ptr<Connection>& connection);
+
+       ConnectionRegistry::iterator getConnectionIterator(const int id);
+
+       CallbackDispatcher onNewConnection;
+       CallbackDispatcher onCloseConnection;
+       PrivilegeChecker onMethodCall;
+
+       MethodRegistry methodRegistry;
+       NotificationRegistry notificationRegistry;
+       ConnectionRegistry connectionRegistry;
+
+       runtime::Mainloop mainloop;
+       std::string address;
+
+       runtime::ThreadPool workqueue;
+       std::mutex stateLock;
+       std::mutex notificationLock;
+       std::mutex methodRegistryLock;
+
+       static thread_local ProcessingContext processingContext;
+};
+
+template<typename Type, typename... Args>
+void Service::setMethodHandler(const std::string& privilege, const std::string& method,
+                                                          const typename MethodHandler<Type, Args...>::type& handler)
+{
+       auto dispatchMethod = [handler](Message& message) {
+               CallbackHolder<Type, Args...> callback(handler);
+               Message reply = message.createReplyMessage();
+               reply.packParameters<Type>(callback.dispatch(message));
+
+               return reply;
+       };
+
+       std::lock_guard<std::mutex> lock(methodRegistryLock);
+
+       if (methodRegistry.count(method)) {
+               throw runtime::Exception("Method handler already registered");
+       }
+
+       methodRegistry[method] = std::make_shared<MethodContext>(privilege, dispatchMethod);
+}
+
+template <typename... Args>
+void Service::notify(const std::string& name, Args&&... args)
+{
+       std::lock_guard<std::mutex> lock(notificationLock);
+
+       Notification& slot = notificationRegistry.at(name);
+       slot.notify(name, std::forward<Args>(args)...);
+}
+
+} // namespace rmi
+
+#endif //__RMI_SERVICE_H__
diff --git a/common/rmi/socket.cpp b/common/rmi/socket.cpp
new file mode 100644 (file)
index 0000000..3df11ce
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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.
+ */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <cstring>
+#include <iostream>
+
+#include "error.h"
+#include "socket.h"
+
+namespace rmi {
+
+namespace {
+
+const int MAX_BACKLOG_SIZE = 100;
+
+void setCloseOnExec(int fd)
+{
+       if (::fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+}
+
+Credentials getCredentials(int fd)
+{
+       socklen_t length = 256;
+       char buf[256];
+       struct ucred cred;
+       socklen_t credsz = sizeof(cred);
+       if (::getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz)) {
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       if (::getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buf, &length)) {
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       return {cred.pid, cred.uid, cred.gid, buf};
+}
+
+} // namespace
+
+Socket::Socket(int fd, bool autoclose) :
+       socketFd(fd), autoClose(autoclose)
+{
+}
+
+Socket::Socket(Socket&& socket) noexcept :
+       socketFd(socket.socketFd),
+       autoClose(socket.autoClose)
+{
+       socket.socketFd = -1;
+}
+
+Socket::~Socket() noexcept
+{
+       if ((socketFd != -1) && (autoClose)) {
+               ::close(socketFd);
+       }
+}
+
+Socket Socket::accept()
+{
+       int sockfd = ::accept(socketFd, nullptr, nullptr);
+       if (sockfd == -1) {
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       setCloseOnExec(sockfd);
+
+       return Socket(sockfd);
+}
+
+int Socket::getFd() const
+{
+       return socketFd;
+}
+
+Credentials Socket::getPeerCredentials() const
+{
+       return getCredentials(socketFd);
+}
+
+void Socket::read(void *buffer, const size_t size) const
+{
+       size_t total = 0;
+
+       while (total < size) {
+               int bytes = ::read(socketFd, reinterpret_cast<char*>(buffer) + total, size - total);
+               if (bytes >= 0) {
+                       total += bytes;
+               } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
+                       continue;
+               } else {
+                       throw SocketException(runtime::GetSystemErrorMessage());
+               }
+       }
+}
+
+void Socket::write(const void *buffer, const size_t size) const
+{
+       size_t written = 0;
+
+       while (written < size) {
+               int bytes = ::write(socketFd, reinterpret_cast<const char*>(buffer) + written, size - written);
+               if (bytes >= 0) {
+                       written += bytes;
+               } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
+                       continue;
+               } else {
+                       throw SocketException(runtime::GetSystemErrorMessage());
+               }
+       }
+}
+
+void Socket::sendFileDescriptors(const int* fds, const size_t nr) const
+{
+       if (nr == 0) return;
+
+       int buf;
+       struct iovec iov = {
+               .iov_base = &buf,
+               .iov_len = sizeof(char)
+       };
+
+       char buffer[CMSG_SPACE(sizeof(int) * nr)];
+       ::memset(buffer, 0, sizeof(buffer));
+
+       struct msghdr msgh;
+       ::memset(&msgh, 0, sizeof(msgh));
+
+       msgh.msg_iov = &iov;
+       msgh.msg_iovlen = 1;
+       msgh.msg_control = buffer;
+       msgh.msg_controllen = sizeof(buffer);
+
+       struct cmsghdr *cmhp;
+       cmhp = CMSG_FIRSTHDR(&msgh);
+       cmhp->cmsg_level = SOL_SOCKET;
+       cmhp->cmsg_type = SCM_RIGHTS;
+       cmhp->cmsg_len = CMSG_LEN(sizeof(int) * nr);
+
+       ::memcpy(CMSG_DATA(cmhp), fds, sizeof(int) * nr);
+
+       int written = 0;
+       while (written < 1) {
+               ssize_t ret = ::sendmsg(socketFd, &msgh, MSG_NOSIGNAL);
+               if (ret >= 0) {
+                       written += ret;
+               } else if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR)) {
+                       throw SocketException(runtime::GetSystemErrorMessage());
+               }
+       }
+}
+
+void Socket::receiveFileDescriptors(int* fds, const size_t nr) const
+{
+       if (nr == 0) return;
+
+       char buf = '!';
+       struct iovec iov = {
+               .iov_base = &buf,
+               .iov_len = sizeof(char)
+       };
+
+       char buffer[CMSG_SPACE(sizeof(int) * nr) + CMSG_SPACE(sizeof(struct ucred))];
+       ::memset(buffer, 0, sizeof(buffer));
+
+       struct msghdr msgh;
+       ::memset(&msgh, 0, sizeof(msgh));
+
+       msgh.msg_iov = &iov;
+       msgh.msg_iovlen = 1;
+       msgh.msg_control = buffer;
+       msgh.msg_controllen = sizeof(buffer);
+
+       ssize_t bytes = 0;
+       while (bytes < 1) {
+               ssize_t ret = ::recvmsg(socketFd, &msgh, MSG_WAITALL);
+               if (ret >= 0) {
+                       bytes += ret;
+               } else {
+                       if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR)) {
+                               throw SocketException(runtime::GetSystemErrorMessage());
+                       }
+               }
+       }
+
+       int i = 0;
+       for (struct cmsghdr *cmhp = CMSG_FIRSTHDR(&msgh); cmhp != NULL; cmhp = CMSG_NXTHDR(&msgh, cmhp)) {
+               if ((cmhp->cmsg_level == SOL_SOCKET) && (cmhp->cmsg_type == SCM_RIGHTS)) {
+                       if (cmhp->cmsg_len != CMSG_LEN(sizeof(int) * nr)) {
+                               std::cout << "Invalid File Descriptor Table" << std::endl;
+                       }
+
+                       fds[i++] = *(reinterpret_cast<int*>(CMSG_DATA(cmhp)));
+               }
+       }
+}
+
+#ifdef USE_SYSTEMD_SOCKET_ACTIVATION
+int Socket::createSystemdSocket(const std::string& path)
+{
+       int n = ::sd_listen_fds(-1);
+       if (n < 0) {
+               throw SocketException("sd_listen_fds faield");
+       }
+
+       for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) {
+               if (::sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0) > 0) {
+                       setCloseOnExec(fd);
+                       return fd;
+               }
+       }
+
+       return -1;
+}
+#endif
+
+int Socket::createRegularSocket(const std::string& path)
+{
+       if (path.size() >= sizeof(sockaddr_un::sun_path)) {
+               throw SocketException(runtime::GetSystemErrorMessage(ENAMETOOLONG));
+       }
+
+       int sockfd = ::socket(AF_UNIX, SOCK_STREAM, 0);
+       if (sockfd == -1) {
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       setCloseOnExec(sockfd);
+
+       ::sockaddr_un addr;
+       addr.sun_family = AF_UNIX;
+       ::strncpy(addr.sun_path, path.c_str(), sizeof(sockaddr_un::sun_path));
+
+       if (addr.sun_path[0] == '@') {
+               addr.sun_path[0] = '\0';
+       } else {
+               unlink(path.c_str());
+       }
+
+       if (::bind(sockfd, reinterpret_cast<struct sockaddr *>(&addr), sizeof(struct sockaddr_un)) == -1) {
+               ::close(sockfd);
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       int optval = 1;
+       if (::setsockopt(sockfd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) {
+               ::close(sockfd);
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       if (::listen(sockfd, MAX_BACKLOG_SIZE) == -1) {
+               ::close(sockfd);
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       return sockfd;
+}
+
+Socket Socket::create(const std::string& path)
+{
+       int fd;
+
+#ifdef USE_SYSTEMD_SOCKET_ACTIVATION
+       fd = createSystemdSocket(path);
+       if (fd == -1) {
+               fd = createRegularSocket(path);
+       }
+#else
+       fd = createRegularSocket(path);
+#endif
+
+       return Socket(fd);
+}
+
+Socket Socket::connect(const std::string& path)
+{
+       if (path.size() >= sizeof(sockaddr_un::sun_path)) {
+               throw SocketException(runtime::GetSystemErrorMessage(ENAMETOOLONG));
+       }
+
+       int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
+       if (fd == -1) {
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       setCloseOnExec(fd);
+
+       sockaddr_un addr;
+       addr.sun_family = AF_UNIX;
+       ::strncpy(addr.sun_path, path.c_str(), sizeof(sockaddr_un::sun_path));
+
+       if (addr.sun_path[0] == '@') {
+               addr.sun_path[0] = '\0';
+       }
+
+       if (::connect(fd, reinterpret_cast<struct sockaddr *>(&addr), sizeof(struct sockaddr_un)) == -1) {
+               ::close(fd);
+               throw SocketException(runtime::GetSystemErrorMessage());
+       }
+
+       return Socket(fd);
+}
+
+} // namespace Ipc
diff --git a/common/rmi/socket.h b/common/rmi/socket.h
new file mode 100644 (file)
index 0000000..09a61bf
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RMI_SOCKET_H__
+#define __RMI_SOCKET_H__
+
+#include "exception.h"
+
+namespace rmi {
+
+class SocketException: public runtime::Exception {
+public:
+       SocketException(const std::string& msg) : runtime::Exception(msg) {}
+};
+
+struct Credentials {
+       pid_t pid;
+       uid_t uid;
+       gid_t gid;
+       std::string security;
+};
+
+class Socket {
+public:
+       explicit Socket(int socketFd = -1, bool autoclose = true);
+       Socket(Socket&& socket) noexcept;
+       ~Socket() noexcept;
+
+       Socket(const Socket&) = delete;
+       Socket& operator=(const Socket&) = delete;
+       Socket& operator=(Socket&) = delete;
+
+       Socket accept();
+       int getFd() const;
+       Credentials getPeerCredentials() const;
+
+       void write(const void* buffer, const size_t size) const;
+       void read(void* buffer, const size_t size) const;
+
+       void sendFileDescriptors(const int* fds, const size_t nr) const;
+       void receiveFileDescriptors(int* fds, const size_t nr) const;
+
+       static Socket create(const std::string& path);
+       static Socket connect(const std::string& path);
+
+private:
+       static int createRegularSocket(const std::string& path);
+
+#ifdef USE_SYSTEMD_SOCKET_ACTIVATION
+       static int createSystemdSocket(const std::string& path);
+#endif
+
+private:
+       int socketFd;
+       bool autoClose;
+};
+
+} // namespace rmi
+#endif //__RMI_SOCKET_H__
diff --git a/common/serialize.h b/common/serialize.h
new file mode 100644 (file)
index 0000000..f98dd31
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __RUNTIME_SERIALIZER_H__
+#define __RUNTIME_SERIALIZER_H__
+
+#include <vector>
+#include <string>
+#include <utility>
+
+#include "reflection.h"
+
+namespace runtime {
+
+template<typename T>
+struct SerializableArgument {
+       SerializableArgument(const T& arg) :
+               value(arg)
+       {
+       }
+
+       const T& value;
+       REFLECTABLE(value)
+};
+
+template<typename T>
+struct DeserializableArgument {
+       DeserializableArgument(T& arg) :
+               value(arg)
+       {
+       }
+
+       T& value;
+       REFLECTABLE(value)
+};
+
+template<class StorageType>
+class Serializer {
+public:
+       Serializer(StorageType& source) :
+               storage(source)
+       {
+       }
+
+       template<typename DataType>
+       void visit(const std::string&, const DataType& value)
+       {
+               visitInternal(value);
+       }
+
+private:
+       void visitInternal(const std::string& value)
+       {
+               visitInternal(value.size());
+               storage.write(value.c_str(), value.size());
+       }
+
+       template<typename DataType, typename std::enable_if<std::is_arithmetic<DataType>::value, int>::type = 0>
+       void visitInternal(const DataType& value)
+       {
+               storage.write(&value, sizeof(DataType));
+       }
+
+       template<typename DataType, typename std::enable_if<::IsReflectable<DataType>::value, int>::type = 0>
+       void visitInternal(DataType& value)
+       {
+               value.accept(*this);
+       }
+
+       template<typename DataType>
+       void visitInternal(const std::vector<DataType>& values)
+       {
+               visitInternal(values.size());
+               for (const DataType& value : values) {
+                       visitInternal(value);
+               }
+       }
+
+private:
+       StorageType& storage;
+};
+
+template<class StorageType>
+class Deserializer {
+public:
+       Deserializer(StorageType& source) :
+               storage(source)
+       {
+       }
+
+       template<typename DataType>
+       void visit(const std::string&, DataType& value)
+       {
+               visitInternal(value);
+       }
+
+private:
+       void visitInternal(std::string& value)
+       {
+               size_t size;
+               visitInternal(size);
+               value.resize(size);
+               storage.read(&value.front(), size);
+       }
+
+       template<typename DataType, typename std::enable_if<std::is_arithmetic<DataType>::value, int>::type = 0>
+       void visitInternal(DataType& value)
+       {
+               storage.read(&value, sizeof(DataType));
+       }
+
+       template<typename T, typename std::enable_if<::IsReflectable<T>::value, int>::type = 0>
+       void visitInternal(T& value)
+       {
+               value.accept(*this);
+       }
+
+       template<typename DataType>
+       void visitInternal(std::vector<DataType>& values)
+       {
+               size_t size;
+               visitInternal(size);
+               values.resize(size);
+
+               for (DataType& value : values) {
+                       visitInternal(value);
+               }
+       }
+
+private:
+       StorageType& storage;
+};
+
+} // namespace runtime
+
+#endif //__RUNTIME_SERIALIZER_H__
diff --git a/common/thread-pool.cpp b/common/thread-pool.cpp
new file mode 100644 (file)
index 0000000..bd1e496
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <unistd.h>
+
+#include "thread-pool.h"
+#include "exception.h"
+
+#define __BEGIN_CRITICAL__  { std::unique_lock<std::mutex> lock(this->queueMutex);
+#define __END_CRITICAL__    }
+
+namespace runtime {
+
+ThreadPool::ThreadPool(size_t threads)
+       : stop(false)
+{
+       for (size_t i = 0; i < threads; i++) {
+          workers.emplace_back([this] {
+                       while (true) {
+                               std::function<void()> task;
+
+                               __BEGIN_CRITICAL__
+                               condition.wait(lock, [this]{ return stop || !tasks.empty();});
+                               if (stop && tasks.empty()) {
+                                       return;
+                               }
+
+                               task = std::move(tasks.front());
+                               tasks.pop_front();
+                               __END_CRITICAL__
+
+                               task();
+                       }
+               });
+       }
+}
+
+ThreadPool::~ThreadPool()
+{
+       __BEGIN_CRITICAL__
+       stop = true;
+       __END_CRITICAL__
+
+       condition.notify_all();
+
+       for (std::thread &worker: workers) {
+               if (worker.joinable()) {
+                       worker.join();
+               }
+       }
+}
+
+void ThreadPool::submit(std::function<void()>&& task)
+{
+       __BEGIN_CRITICAL__
+       if (!stop) {
+               tasks.push_back(std::move(task));
+       }
+       __END_CRITICAL__
+
+       condition.notify_one();
+}
+
+} // namespace runtime
similarity index 58%
rename from libs/dpm/array.h
rename to common/thread-pool.h
index 77ac2a3..e00e4cf 100644 (file)
  *  limitations under the License
  */
 
-#ifndef __RUNTIME_ARRAY_H__
-#define __RUNTIME_ARRAY_H__
+#ifndef __RUNTIME_THREAD_POOL_H__
+#define __RUNTIME_THREAD_POOL_H__
 
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
 #include <vector>
-#include <utility>
+#include <deque>
 
 namespace runtime {
 
-template <typename T>
-class Array final {
+class ThreadPool {
 public:
-       Array() = delete;
-       Array(std::vector<T> &&list) :
-               list(std::move(list)), it(this->list.begin())
-       {
-       }
-
-       Array(const std::vector<T> &list) :
-               list(list), it(this->list.begin())
-       {
-       }
-
-       T *next()
-       {
-               if (it != list.end()) {
-                       return &(*it++);
-               }
-               return NULL;
-       }
-
-       bool isEnd()
-       {
-               return it == list.end();
-       }
+       ThreadPool(size_t threads);
+       ~ThreadPool();
+
+       void submit(std::function<void()>&& task);
 
 private:
-       std::vector<T> list;
-       typename std::vector<T>::iterator it;
+       std::vector<std::thread> workers;
+       std::deque<std::function<void()>> tasks;
+
+       std::mutex queueMutex;
+       std::condition_variable condition;
+       bool stop;
 };
 
 } // namespace runtime
 
-#endif // __RUNTIME_ARRAY_H__
+#endif //__RUNTIME_THREAD_POOL_H__
diff --git a/common/xml/document.cpp b/common/xml/document.cpp
new file mode 100644 (file)
index 0000000..f83fd2f
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <iostream>
+
+#include "document.h"
+#include "keepblanks.h"
+
+#include "exception.h"
+#include "audit/logger.h"
+
+namespace xml {
+
+Document::Document(const std::string& root, const std::string& version) :
+       implementation(xmlNewDoc((const xmlChar*)version.c_str()))
+{
+       if (implementation == nullptr) {
+               throw runtime::Exception("Failed to create document");
+       }
+
+       implementation->_private = this;
+
+       xmlNode* rootPtr = xmlNewNode(NULL, xmlStrdup((const xmlChar*)root.c_str()));
+       xmlDocSetRootElement(implementation, rootPtr);
+
+       rootNode = new Node(rootPtr);
+}
+
+Document::Document(xmlDoc* doc)
+       : implementation(doc)
+{
+       implementation->_private = this;
+
+       rootNode = new Node(xmlDocGetRootElement(implementation));
+}
+
+Document::~Document()
+{
+       if (rootNode != nullptr) {
+               delete rootNode;
+       }
+
+       xmlFreeDoc(implementation);
+}
+
+Node& Document::getRootNode()
+{
+       if (rootNode == nullptr) {
+               throw runtime::Exception("Empty document");
+       }
+
+       return *rootNode;
+}
+
+Node::NodeList Document::evaluate(const std::string& xpath)
+{
+       auto ctxt = xmlXPathNewContext(implementation);
+       if (ctxt == nullptr) {
+               throw runtime::Exception("Failed to create XPath context for " + xpath);
+       }
+
+       auto result = xmlXPathEval((const xmlChar*)xpath.c_str(), ctxt);
+       if (result == nullptr) {
+               xmlXPathFreeContext(ctxt);
+               throw runtime::Exception("Invalid XPath: " + xpath);
+       }
+
+       if (result ->type != XPATH_NODESET) {
+               xmlXPathFreeObject(result);
+               xmlXPathFreeContext(ctxt);
+
+               throw runtime::Exception("Only nodeset result types are supported");
+       }
+
+       auto nodeset = result->nodesetval;
+
+       Node::NodeList nodes;
+       if ((nodeset == nullptr) || (xmlXPathNodeSetIsEmpty(nodeset))) {
+               xmlXPathFreeContext(ctxt);
+               return nodes;
+       }
+
+       const int count = xmlXPathNodeSetGetLength(nodeset);
+
+       nodes.reserve(count);
+       for (int i = 0; i != count; i++) {
+               auto cnode = xmlXPathNodeSetItem(nodeset, i);
+               if (!cnode) {
+                       continue;
+               }
+
+               if (cnode->type == XML_NAMESPACE_DECL) {
+                       continue;
+               }
+
+               nodes.emplace_back(cnode);
+       }
+
+       xmlXPathFreeObject(result);
+       xmlXPathFreeContext(ctxt);
+
+       return nodes;
+}
+
+void Document::write(const std::string& filename, const std::string& encoding, bool formatted)
+{
+       KeepBlanks keepBlanks(KeepBlanks::Default);
+       xmlIndentTreeOutput = formatted;
+
+       xmlResetLastError();
+
+       const int result = xmlSaveFormatFileEnc(filename.c_str(),
+                                                                                       implementation,
+                                                                                       encoding.c_str(),
+                                                                                       formatted);
+       if (result == 0) {
+               throw runtime::Exception("Failed to write XML document");
+       }
+}
+
+} // namespace xml
diff --git a/common/xml/document.h b/common/xml/document.h
new file mode 100644 (file)
index 0000000..a5bdc93
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __XML_DOCUMENT_H__
+#define __XML_DOCUMENT_H__
+
+#include <string>
+#include <iostream>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#include "node.h"
+
+namespace xml {
+
+class Document {
+public:
+       Document(const std::string& root, const std::string& version = XML_DEFAULT_VERSION);
+       Document(xmlDoc* doc);
+
+       ~Document();
+
+       Node& getRootNode();
+
+       Node::NodeList evaluate(const std::string& xpath);
+       void write(const std::string& filename, const std::string& encoding, bool formatted);
+
+private:
+       Node* rootNode;
+       xmlDoc* implementation;
+};
+
+} // namespace xml
+#endif //__XML_DOCUMENT_H__
diff --git a/common/xml/keepblanks.cpp b/common/xml/keepblanks.cpp
new file mode 100644 (file)
index 0000000..3c38e0a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "keepblanks.h"
+
+namespace xml {
+
+KeepBlanks::KeepBlanks(bool value)
+{
+       preservedIndentTreeOutput = xmlIndentTreeOutput;
+       preservedKeepBlanksDefault = xmlKeepBlanksDefault(value ? 1 : 0);
+}
+
+KeepBlanks::~KeepBlanks()
+{
+       xmlKeepBlanksDefault(preservedKeepBlanksDefault);
+       xmlIndentTreeOutput = preservedIndentTreeOutput;
+}
+
+} // namespace xml
diff --git a/common/xml/keepblanks.h b/common/xml/keepblanks.h
new file mode 100644 (file)
index 0000000..7d5c2f4
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __XML_KEEPBLANKS_H__
+#define __XML_KEEPBLANKS_H__
+
+#include <libxml/globals.h>
+
+namespace xml {
+
+class KeepBlanks {
+public:
+       KeepBlanks(bool value);
+       ~KeepBlanks();
+
+       static const bool Default = true;
+
+private:
+       int preservedKeepBlanksDefault;
+       int preservedIndentTreeOutput;
+};
+
+} // namespace xml
+#endif //__XML_KEEPBLANKS_H__
diff --git a/common/xml/node.cpp b/common/xml/node.cpp
new file mode 100644 (file)
index 0000000..0d0c255
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "node.h"
+
+#include "exception.h"
+
+namespace xml {
+
+Node::Node(xmlNode* node) :
+       implementation(node)
+{
+}
+
+Node::Node(Node&& node) :
+       implementation(node.implementation)
+{
+}
+
+Node::~Node()
+{
+}
+
+Node::NodeList Node::getChildren() const
+{
+       NodeList nodeList;
+
+       auto child = implementation->xmlChildrenNode;
+       while (child != nullptr) {
+               nodeList.emplace_back(child);
+               child = child->next;
+       }
+
+       return nodeList;
+}
+
+Node Node::addNewChild(const std::string& name)
+{
+       xmlNode* nodePtr = xmlNewNode(NULL, xmlStrdup((const xmlChar*)name.c_str()));
+       if (nodePtr == nullptr) {
+               throw runtime::Exception("Can not create a new node");
+       }
+       xmlAddChild(implementation, nodePtr);
+
+       return Node(nodePtr);
+}
+
+std::string Node::getName() const
+{
+       return implementation->name ? (const char*)implementation->name : "";
+}
+
+void Node::setName(const std::string& name)
+{
+       xmlNodeSetName(implementation, (const xmlChar*)name.c_str());
+}
+
+std::string Node::getContent() const
+{
+       xmlChar* content = xmlNodeGetContent(implementation);
+       if (content == NULL) {
+               return "";
+       }
+       std::string ret((const char*)content);
+       xmlFree(content);
+       return ret;
+}
+
+void Node::setContent(const std::string& content)
+{
+       xmlNodeSetContent(implementation, (xmlChar*)content.c_str());
+}
+
+std::string Node::getProp(const std::string& name) const
+{
+       if (implementation->type != XML_ELEMENT_NODE) {
+               throw runtime::Exception("This node type does not have properties");
+       }
+
+       xmlChar* prop = xmlGetProp(implementation, (xmlChar*)name.c_str());
+       if (prop) {
+               std::string ret((const char*)prop);
+               xmlFree(prop);
+               return ret;
+       }
+
+       return "";
+}
+
+void Node::setProp(const std::string& name, const std::string& val)
+{
+       if (implementation->type != XML_ELEMENT_NODE) {
+               throw runtime::Exception("Can not set properties for this node type");
+       }
+
+       xmlSetProp(implementation, (xmlChar*)name.c_str(), (xmlChar*)val.c_str());
+}
+
+bool Node::isBlank() const
+{
+       return xmlIsBlankNode(const_cast<xmlNode*>(implementation));
+}
+
+} // namespace xml
diff --git a/common/xml/node.h b/common/xml/node.h
new file mode 100644 (file)
index 0000000..755d170
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __XML_NODE_H__
+#define __XML_NODE_H__
+
+#include <string>
+#include <ostream>
+#include <memory>
+#include <vector>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+namespace xml {
+
+class Node {
+public:
+       typedef std::vector<Node> NodeList;
+
+       explicit Node(xmlNode* node);
+       Node(Node&&);
+       Node(const Node&) = delete;
+
+       ~Node();
+
+       Node& operator=(const Node&) = delete;
+
+       NodeList getChildren() const;
+       Node addNewChild(const std::string& name);
+
+       std::string getName() const;
+       void setName(const std::string& name);
+
+       std::string getContent() const;
+       void setContent(const std::string& content);
+
+       std::string getProp(const std::string& name) const;
+       void setProp(const std::string& name, const std::string& val);
+
+       bool isBlank() const;
+
+private:
+       xmlNode* implementation;
+};
+
+} // namespace xml
+#endif //__XML_NODE_H__
diff --git a/common/xml/parser.cpp b/common/xml/parser.cpp
new file mode 100644 (file)
index 0000000..91c8d42
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+
+#include <libxml/parserInternals.h>
+
+#include "parser.h"
+#include "keepblanks.h"
+
+#include "exception.h"
+
+namespace xml {
+
+Document* Parser::parseContext(xmlParserCtxt* context, bool validate)
+{
+       if (context == nullptr) {
+               throw runtime::Exception("Could not create parser context");
+       }
+
+       KeepBlanks(false);
+
+       int options = 0;
+
+       if (validate) {
+               options |= XML_PARSE_DTDVALID;
+       } else {
+               options &= ~XML_PARSE_DTDVALID;
+       }
+
+       xmlCtxtUseOptions(context, options);
+
+       if (xmlParseDocument(context) < 0) {
+               xmlFreeParserCtxt(context);
+               throw runtime::Exception("Parsing failed");
+       }
+
+       xmlDoc* document = context->myDoc;
+
+       // We took the ownership on the doc
+       context->myDoc = nullptr;
+
+       xmlFreeParserCtxt(context);
+
+       return new Document(document);
+}
+
+Document* Parser::parseFile(const std::string& filename, bool validate)
+{
+       xmlParserCtxt* context = xmlCreateFileParserCtxt(filename.c_str());
+       if (context == nullptr) {
+               throw runtime::Exception("Could not create parser context");
+       }
+
+       if (context->directory == nullptr) {
+               context->directory = xmlParserGetDirectory(filename.c_str());
+       }
+
+       return parseContext(context, validate);
+}
+
+Document* Parser::parseString(const std::string& xml, bool validate)
+{
+       xmlParserCtxt* context = xmlCreateMemoryParserCtxt(xml.c_str(), xml.size() + 1);
+
+       if (context == nullptr) {
+               throw runtime::Exception("Could not create parser context");
+       }
+
+       return parseContext(context, validate);
+}
+
+} // namespace xml
diff --git a/common/xml/parser.h b/common/xml/parser.h
new file mode 100644 (file)
index 0000000..87b76dc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __XML_DOMPARSER_H__
+#define __XML_DOMPARSER_H__
+
+#include <string>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+#include "document.h"
+
+namespace xml {
+
+class Parser {
+public:
+       static Document* parseFile(const std::string& filename, bool validate = false);
+       static Document* parseString(const std::string& xml, bool validate = false);
+
+private:
+       static Document* parseContext(xmlParserCtxt* context, bool validate = false);
+};
+
+} // namespace xml
+#endif //__XML_DOMPARSER_H__
index 3536ff4..28c3602 100755 (executable)
@@ -59,13 +59,8 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-fvisibility=hid
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${LIB_SOVERSION})
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION   ${LIB_VERSION})
 
-PKG_CHECK_MODULES(LIBS_DEPS    REQUIRED
-                                                       klay
-                                                       glib-2.0
-)
-
-INCLUDE_DIRECTORIES(SYSTEM ${LIBS_DEPS_INCLUDE_DIRS} ${DPM_POLICY} ${DPM_LIBS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIBS_DEPS_LIBRARIES} pthread)
+INCLUDE_DIRECTORIES(SYSTEM ${DPM_COMMON} ${DPM_POLICY} ${DPM_LIBS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} pthread dpm-common)
 
 CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY)
 
index 73caa08..b9b6c52 100644 (file)
@@ -13,7 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "bluetooth.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index 5cb021d..124083a 100644 (file)
@@ -21,6 +21,8 @@
 #include "policy-client.h"
 #include "debug.h"
 
+#include "exception.h"
+
 DevicePolicyContext& GetDevicePolicyContext(void* handle)
 {
        assert(handle);
index 2134b05..cca4474 100644 (file)
@@ -13,7 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "location.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index c6950a1..4dbc778 100644 (file)
@@ -13,7 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "password.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index ce7dc9c..e9356a3 100644 (file)
@@ -13,6 +13,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "policy-client.h"
 
 namespace {
index f91caa5..c1ac082 100644 (file)
@@ -21,7 +21,7 @@
 #include <memory>
 #include <functional>
 
-#include <klay/rmi/client.h>
+#include "rmi/client.h"
 
 typedef std::function<void(const char*, const char*, void*)> PolicyChangeListener;
 typedef std::function<void(const char*, const char*, void*)> SignalListener;
index 307c597..b52580a 100644 (file)
@@ -13,7 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "restriction.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager
 {
index 1dd8e7e..733821a 100644 (file)
@@ -13,7 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "security.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index bd1a928..d49769f 100644 (file)
@@ -13,6 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
+#include "policy-client.h"
+
 #include "storage.hxx"
 
 namespace DevicePolicyManager {
index fb81e13..bc3c6c0 100644 (file)
@@ -13,7 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "wifi.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index 212aefb..4f0768b 100644 (file)
@@ -13,6 +13,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
 #include "zone.hxx"
 
 namespace DevicePolicyManager {
index 2b9d7de..e171a91 100755 (executable)
@@ -3,5 +3,12 @@
 lcov -c -d device-policy-manager-0.0.1/server/CMakeFiles/device-policy-manager.dir     \
         -d device-policy-manager-0.0.1/libs/CMakeFiles/dpm.dir \
         -d device-policy-manager-0.0.1/libs/CMakeFiles/dpm.dir/dpm     \
+        -d device-policy-manager-0.0.1/common/CMakeFiles/dpm-common.dir        \
+        -d device-policy-manager-0.0.1/common/CMakeFiles/dpm-common.dir/audit  \
+        -d device-policy-manager-0.0.1/common/CMakeFiles/dpm-common.dir/db     \
+        -d device-policy-manager-0.0.1/common/CMakeFiles/dpm-common.dir/auth   \
+        -d device-policy-manager-0.0.1/common/CMakeFiles/dpm-common.dir/xml    \
+        -d device-policy-manager-0.0.1/common/CMakeFiles/dpm-common.dir/dbus   \
+        -d device-policy-manager-0.0.1/common/CMakeFiles/dpm-common.dir/rmi    \
         -o info
 genhtml info -o out
index 323d427..e08689b 100755 (executable)
@@ -9,7 +9,6 @@ BuildRequires: gcc
 BuildRequires: cmake
 BuildRequires: pam-devel
 BuildRequires: gettext-tools
-BuildRequires: pkgconfig(klay)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(sqlite3)
@@ -148,7 +147,12 @@ Testcases for device policy manager and device policy client
 
 %files -n dpm-testcases
 %defattr(644,root,root,755)
+%attr(755,root,root) %{_bindir}/dpm-unit-tests
 %attr(755,root,root) %{_bindir}/dpm-api-tests
+%defattr(-,root,root,-)
+%{TZ_SYS_DATA}/dpm/sample-policy.xml
+%defattr(755,root,root,755)
+%{TZ_SYS_DATA}/dpm/unittest-proc.sh
 
 ## Tools Package #############################################################
 %package -n org.tizen.ode
index 564a434..f6ed25a 100644 (file)
@@ -17,6 +17,9 @@
 #ifndef __ADMINISTRATION_POLICY__
 #define __ADMINISTRATION_POLICY__
 
+#include <string>
+
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index a6ef8a1..ca50eac 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __APPLICATION_POLICY__
 #define __APPLICATION_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index c810ae2..3d5a23f 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __BLUETOOTH_POLICY__
 #define __BLUETOOTH_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index 306049a..c401d57 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __LOCATION_POLICY__
 #define __LOCATION_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index ccb5454..cd1a59b 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __PASSWORD_POLICY__
 #define __PASSWORD_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index ffaba33..ffb6a31 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __RESTRICTION_POLICY__
 #define __RESTRICTION_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager
index 4da3cbe..6a539f1 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __SECURITY_POLICY__
 #define __SECURITY_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index 6647fd9..89181dc 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __STORAGE_POLICY__
 #define __STORAGE_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index 4155db5..94e88f8 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __WIFI_POLICY__
 #define __WIFI_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index 848f929..6c68c5c 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __ZONE_POLICY__
 #define __ZONE_POLICY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index 1339499..0cec21a 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __ZONE_APP_PROXY__
 #define __ZONE_APP_PROXY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index f397d97..b7405e3 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __ZONE_PACKAGE_PROXY__
 #define __ZONE_PACKAGE_PROXY__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index 3612e0f..2f78489 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __ZONE_MANAGER__
 #define __ZONE_MANAGER__
 
+#include "data-type.h"
 #include "policy-context.hxx"
 
 namespace DevicePolicyManager {
index b81e16a..a7d32eb 100644 (file)
@@ -37,9 +37,6 @@ SET(POLICY                    administration.cpp
 
 SET(DEPENDENCY         glib-2.0
                                        gio-2.0
-                                       klay
-                                       libxml-2.0
-                                       sqlite3
                                        bundle
                                        aul
                                        appsvc
@@ -68,9 +65,9 @@ ADD_EXECUTABLE(${TARGET} ${FOUNDATION} ${POLICY})
 
 PKG_CHECK_MODULES(SERVER_DEPS REQUIRED ${DEPENDENCY})
 
-INCLUDE_DIRECTORIES(SYSTEM ${SERVER_DEPS_INCLUDE_DIRS} ${DPM_POLICY} ${DPM_SERVER})
+INCLUDE_DIRECTORIES(SYSTEM ${SERVER_DEPS_INCLUDE_DIRS} ${DPM_COMMON} ${DPM_POLICY} ${DPM_SERVER})
 
-TARGET_LINK_LIBRARIES(${TARGET} ${SERVER_DEPS_LIBRARIES} pthread sqlite3)
+TARGET_LINK_LIBRARIES(${TARGET} ${SERVER_DEPS_LIBRARIES} pthread dpm-common)
 
 SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fPIE")
 SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS "-pie")
index 53f9d00..e47d3c4 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-#include <klay/exception.h>
-#include <klay/audit/logger.h>
+
+#include "administration.hxx"
 
 #include "policy-builder.h"
 #include "client-manager.h"
-
-#include "administration.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index 518e36f..0c253d3 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-#include <memory>
-
-#include <klay/exception.h>
 
 #include "app-bundle.h"
 
+#include "error.h"
+#include "exception.h"
+#include "audit/logger.h"
+
 Bundle::Bundle() :
        handle(nullptr)
 {
index df01979..887f2a0 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <bundle.h>
 
+#include "exception.h"
+
 class Bundle {
 public:
        Bundle();
index 4ed4a1b..c3b6731 100644 (file)
 
 #include <privilege_manager.h>
 #include <privilege_info.h>
-#include <klay/exception.h>
-#include <klay/audit/logger.h>
 
+#include "application.hxx"
+
+#include "policy-builder.h"
 #include "packman.h"
 #include "launchpad.h"
-#include "policy-builder.h"
-
-#include "application.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index 5e4d505..0ffdc06 100644 (file)
  */
 
 #include <bluetooth.h>
-#include <bluetooth-api.h>
 #include <bluetooth_internal.h>
-#include <klay/exception.h>
-#include <klay/audit/logger.h>
-#include <klay/dbus/connection.h>
+#include <bluetooth-api.h>
+
+#include "bluetooth.hxx"
+#include "restriction.hxx"
 
 #include "privilege.h"
 #include "policy-builder.h"
-
-#include "bluetooth.hxx"
+#include "audit/logger.h"
+#include "dbus/connection.h"
 
 #define POLICY_ENFORCING_FAILED(ret)                    \
        (((ret) == BLUETOOTH_DPM_RESULT_ACCESS_DENIED) ||   \
index 9614308..46e07a2 100644 (file)
  *  limitations under the License
  */
 
-#include <string>
 #include <climits>
+#include <memory>
 #include <stdexcept>
-#include <klay/exception.h>
+#include <string>
+#include <limits>
 
+#include "client-manager.h"
 #include "policy.h"
 
-#include "client-manager.h"
+#include "exception.h"
+#include "audit/logger.h"
 
 namespace {
 
index 33fc401..395ff96 100644 (file)
 #include <string>
 #include <mutex>
 
-#include <klay/db/column.h>
-#include <klay/db/statement.h>
-#include <klay/db/connection.h>
-
 #include "policy.h"
 #include "policy-storage.h"
 
+#include "db/connection.h"
+#include "db/statement.h"
+#include "db/column.h"
+
 class Client {
 public:
        Client(const Client&) = delete;
index d0a1dbf..272261f 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
+#include <sys/types.h>
 #include <unistd.h>
 #include <signal.h>
-#include <sys/types.h>
 
 #include <aul.h>
-#include <klay/exception.h>
-#include <klay/audit/logger.h>
 
 #include "launchpad.h"
 
+#include "error.h"
+#include "exception.h"
+#include "audit/logger.h"
+#include "dbus/variant.h"
+#include "dbus/connection.h"
+
 Launchpad::Launchpad(const uid_t uid) :
        user(uid)
 {
index e5d3ceb..2435f35 100644 (file)
@@ -20,6 +20,7 @@
 #include <string>
 
 #include "app-bundle.h"
+#include "exception.h"
 
 class Launchpad {
 public:
index 786f7d8..a3d4b5c 100644 (file)
 
 #include <location_batch.h>
 
+#include "location.hxx"
+
 #include "privilege.h"
 #include "policy-builder.h"
-
-#include "location.hxx"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index 1ec6cb2..448df58 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <stdlib.h>
 #include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
 
-#include <cstdlib>
 #include <iostream>
 #include <stdexcept>
 
index 8739dce..834da17 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-#include <klay/exception.h>
-#include <klay/audit/logger.h>
+
+#include <sys/stat.h>
+#include <signal.h>
+
+#include <vector>
 
 #include "packman.h"
+#include "exception.h"
+#include "audit/logger.h"
 
 namespace {
 
index 9211fcc..95d4075 100644 (file)
 #ifndef __DPM_PACKMAN_H__
 #define __DPM_PACKMAN_H__
 
-#include <unistd.h>
 #include <sys/types.h>
+#include <unistd.h>
 
 #include <string>
-#include <vector>
 
 #include <package-manager.h>
 #include <pkgmgr-info.h>
index 4dd8c5c..facb447 100644 (file)
 
 #include <sys/types.h>
 
-#include <aul.h>
-#include <vconf.h>
+#include <auth-passwd-admin.h>
 #include <bundle.h>
+#include <aul.h>
 #include <notification.h>
+#include <vconf.h>
 #include <system_settings.h>
-#include <auth-passwd-admin.h>
-#include <klay/auth/user.h>
-#include <klay/audit/logger.h>
-
-#include "privilege.h"
-#include "policy-builder.h"
 
 #include "password.hxx"
 
+#include "policy-builder.h"
+#include "privilege.h"
+#include "auth/user.h"
+#include "audit/logger.h"
+
 #define SIMPLE_PASSWORD_LENGTH 4
 #define PASSWORD_EMPTY_STRING "\\n"
 
index 10b66a0..20aaa96 100644 (file)
  *  limitations under the License
  */
 
-#include <unistd.h>
-#include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
-#include <klay/error.h>
-#include <klay/exception.h>
-#include <klay/xml/parser.h>
-#include <klay/audit/logger.h>
+#include "policy-context.hxx"
 
 #include "policy-storage.h"
-#include "policy-context.hxx"
+
+#include "error.h"
+#include "exception.h"
+#include "audit/logger.h"
 
 namespace {
 
index 4a0ef39..d0e5f7c 100644 (file)
@@ -23,7 +23,9 @@
 
 #include "policy.h"
 
-#include <klay/xml/document.h>
+#include "xml/parser.h"
+#include "xml/document.h"
+#include "xml/node.h"
 
 class PolicyStorage {
 public:
index 625248c..042843d 100644 (file)
@@ -21,7 +21,8 @@
 #include <mutex>
 #include <memory>
 
-#include <klay/xml/node.h>
+#include "xml/document.h"
+#include "xml/node.h"
 
 class Policy {
 public:
index 2440a34..14c5929 100644 (file)
  */
 
 #include <vconf.h>
-#include <klay/exception.h>
-#include <klay/dbus/connection.h>
-#include <klay/audit/logger.h>
+
+#include "restriction.hxx"
 
 #include "privilege.h"
 #include "policy-builder.h"
-
-#include "restriction.hxx"
+#include "audit/logger.h"
+#include "dbus/connection.h"
 
 #define PULSEAUDIO_LOGIN_INTERFACE          \
        "org.pulseaudio.Server",                \
index d35aaad..bb795b1 100755 (executable)
 #include <vconf-keys.h>
 #include <dd-deviced.h>
 #include <dd-control.h>
-#include <klay/process.h>
-#include <klay/filesystem.h>
-#include <klay/audit/logger.h>
+
+#include "security.hxx"
 
 #include "privilege.h"
 #include "policy-builder.h"
 #include "launchpad.h"
-
-#include "security.hxx"
+#include "process.h"
+#include "filesystem.h"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index ab476bf..4ba4caa 100644 (file)
@@ -37,7 +37,7 @@ Server::Server()
 
        service->setPrivilegeChecker(std::bind(&Server::checkPeerPrivilege, this, _1, _2));
 
-       service->registerParametricMethod(this, "", (runtime::FileDescriptor)(Server::registerNotificationSubscriber)(std::string));
+       service->registerParametricMethod(this, "", (FileDescriptor)(Server::registerNotificationSubscriber)(std::string));
        service->registerParametricMethod(this, "", (int)(Server::unregisterNotificationSubscriber)(std::string, int));
 }
 
@@ -58,9 +58,9 @@ void Server::terminate()
        service->stop();
 }
 
-runtime::FileDescriptor Server::registerNotificationSubscriber(const std::string& name)
+FileDescriptor Server::registerNotificationSubscriber(const std::string& name)
 {
-       return runtime::FileDescriptor(service->subscribeNotification(name), true);
+       return FileDescriptor(service->subscribeNotification(name), true);
 }
 
 int Server::unregisterNotificationSubscriber(const std::string& name, int id)
index 9613a52..224b93a 100644 (file)
 #include <string>
 #include <memory>
 
-#include <klay/filesystem.h>
-#include <klay/file-descriptor.h>
-#include <klay/rmi/service.h>
-
 #include "policy-storage.h"
 
+#include "file-descriptor.h"
+#include "filesystem.h"
+#include "rmi/service.h"
+
 class Server {
 public:
        Server();
@@ -72,7 +72,7 @@ public:
                                         const std::string& event, const std::string& info);
        std::string getPolicy(const std::string& name) const;
 
-       runtime::FileDescriptor registerNotificationSubscriber(const std::string& name);
+       FileDescriptor registerNotificationSubscriber(const std::string& name);
        int unregisterNotificationSubscriber(const std::string& name, int id);
 
        bool checkPeerPrivilege(const rmi::Credentials& cred, const std::string& privilege);
index ef37d56..6d4dcea 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+
+ #include <dd-deviced.h>
+ #include <dd-control.h>
+
 #include <thread>
 
-#include <dd-deviced.h>
-#include <dd-control.h>
-#include <klay/process.h>
-#include <klay/exception.h>
-#include <klay/filesystem.h>
-#include <klay/dbus/variant.h>
-#include <klay/dbus/connection.h>
-#include <klay/audit/logger.h>
+#include "storage.hxx"
 
 #include "privilege.h"
 #include "policy-builder.h"
-
-#include "storage.hxx"
+#include "exception.h"
+#include "process.h"
+#include "filesystem.h"
+#include "dbus/connection.h"
+#include "dbus/variant.h"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index c0ddd24..4b388dd 100644 (file)
  *  limitations under the License
  */
 
+#include <arpa/inet.h>
 #include <cstdlib>
 #include <functional>
 #include <unordered_set>
 
 #include <glib.h>
 #include <vconf.h>
-#include <wifi.h>
 #include <vconf-keys.h>
-#include <arpa/inet.h>
-#include <klay/audit/logger.h>
-#include <klay/dbus/connection.h>
+#include <wifi.h>
+
+#include "wifi.hxx"
 
 #include "privilege.h"
-#include "app-bundle.h"
 #include "policy-builder.h"
 
-#include "wifi.hxx"
+#include "app-bundle.h"
+#include "audit/logger.h"
+#include "dbus/connection.h"
 
 #define NETCONFIG_INTERFACE            \
        "net.netconfig",                        \
index 0e74363..bf8649d 100755 (executable)
 #include <algorithm>
 
 #include <tzplatform_config.h>
-#include <klay/auth/user.h>
-#include <klay/audit/logger.h>
 
 #include "zone.hxx"
 #include "zone/zone.hxx"
 
-#include "launchpad.h"
 #include "privilege.h"
 #include "policy-builder.h"
+#include "error.h"
+#include "launchpad.h"
+#include "filesystem.h"
+#include "auth/user.h"
+#include "audit/logger.h"
 
 #define NAME_PATTERN "^[A-Za-z_][A-Za-z0-9_.-]*"
 
index 48a400d..841e11a 100644 (file)
 
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <system_settings.h>
 
 #include <unordered_map>
 
-#include <system_settings.h>
-#include <klay/auth/user.h>
-#include <klay/audit/logger.h>
+#include "zone/app-proxy.hxx"
 
+#include "policy-builder.h"
+#include "error.h"
 #include "packman.h"
 #include "launchpad.h"
-#include "policy-builder.h"
-
-#include "zone/app-proxy.hxx"
+#include "auth/user.h"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index 63d6389..2daeea1 100644 (file)
  */
 #include <sys/stat.h>
 #include <sys/types.h>
-
 #include <system_settings.h>
-#include <klay/auth/user.h>
-#include <klay/audit/logger.h>
-
-#include "packman.h"
-#include "policy-builder.h"
 
 #include "zone/package-proxy.hxx"
+#include "policy-builder.h"
+#include "error.h"
+#include "packman.h"
+#include "auth/user.h"
+#include "audit/logger.h"
 
 namespace DevicePolicyManager {
 
index c71d8c6..077edc1 100644 (file)
 
 #include <algorithm>
 
+#include <gum/gum-user.h>
+#include <gum/common/gum-user-types.h>
 #include <notification.h>
 #include <notification_internal.h>
 #include <tzplatform_config.h>
 #include <auth-passwd-admin.h>
-#include <gum/gum-user.h>
-#include <gum/common/gum-user-types.h>
-#include <klay/error.h>
-#include <klay/process.h>
-#include <klay/filesystem.h>
-#include <klay/auth/user.h>
-#include <klay/xml/parser.h>
-#include <klay/xml/document.h>
-#include <klay/dbus/connection.h>
-#include <klay/audit/logger.h>
 
+#include "zone/zone.hxx"
+#include "policy-builder.h"
+#include "error.h"
+#include "process.h"
 #include "packman.h"
 #include "launchpad.h"
-#include "policy-builder.h"
-
-#include "zone/zone.hxx"
+#include "filesystem.h"
+#include "auth/user.h"
+#include "xml/parser.h"
+#include "xml/document.h"
+#include "audit/logger.h"
+#include "dbus/connection.h"
 
 #define ZONE_DELEGATOR_APP  "org.tizen.keyguard"
 #define NOTIFICATION_SUB_ICON_PATH  DATA_PATH "/zone_noti_list_sub_icon.png"
index 59da9d6..ddaab5c 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-SET(API_TEST_TARGET    "dpm-api-tests")
 
-SET(API_TEST_SOURCES main.c
-                                        testbench.c
-                                        admin.c
-                                        application.c
-                                        context.c
-                                        bluetooth.c
-                                        manager.c
-                                        restriction.c
-                                        security.c
-                                        wifi.c
-)
+SET(DPM_TESTBENCH        ${DPM_TESTS}/testbench)
+SET(DPM_UNIT_TEST        ${DPM_TESTS}/unit)
+SET(DPM_API_TEST         ${DPM_TESTS}/api)
 
-INCLUDE("${TIZEN_PROFILE_NAME}.cmake")
-
-ADD_EXECUTABLE(${API_TEST_TARGET} ${API_TEST_SOURCES})
-
-INCLUDE_DIRECTORIES(SYSTEM ${DPM_LIBS} ${DPM_TESTS})
-
-TARGET_LINK_LIBRARIES(${API_TEST_TARGET} dpm glib-2.0)
-
-INSTALL(TARGETS ${API_TEST_TARGET} DESTINATION bin)
+ADD_SUBDIRECTORY(${DPM_UNIT_TEST})
+ADD_SUBDIRECTORY(${DPM_API_TEST})
diff --git a/tests/api/CMakeLists.txt b/tests/api/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8511ba4
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd 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.
+#
+SET(API_TEST_TARGET    "dpm-api-tests")
+
+SET(API_TEST_SOURCES main.c
+                                        testbench.c
+                                        admin.c
+                                        application.c
+                                        context.c
+                                        bluetooth.c
+                                        manager.c
+                                        restriction.c
+                                        security.c
+                                        wifi.c
+)
+
+INCLUDE("${TIZEN_PROFILE_NAME}.cmake")
+
+ADD_EXECUTABLE(${API_TEST_TARGET} ${API_TEST_SOURCES})
+
+INCLUDE_DIRECTORIES(SYSTEM ${DPM_LIBS} ${DPM_TESTS})
+
+TARGET_LINK_LIBRARIES(${API_TEST_TARGET} dpm)
+
+INSTALL(TARGETS ${API_TEST_TARGET} DESTINATION bin)
similarity index 100%
rename from tests/admin.c
rename to tests/api/admin.c
similarity index 100%
rename from tests/application.c
rename to tests/api/application.c
similarity index 100%
rename from tests/bluetooth.c
rename to tests/api/bluetooth.c
similarity index 100%
rename from tests/common.cmake
rename to tests/api/common.cmake
similarity index 100%
rename from tests/context.c
rename to tests/api/context.c
similarity index 100%
rename from tests/ivi.cmake
rename to tests/api/ivi.cmake
similarity index 100%
rename from tests/main.c
rename to tests/api/main.c
similarity index 100%
rename from tests/manager.c
rename to tests/api/manager.c
similarity index 100%
rename from tests/mobile.cmake
rename to tests/api/mobile.cmake
similarity index 100%
rename from tests/password.c
rename to tests/api/password.c
similarity index 100%
rename from tests/restriction.c
rename to tests/api/restriction.c
similarity index 100%
rename from tests/security.c
rename to tests/api/security.c
similarity index 100%
rename from tests/testbench.c
rename to tests/api/testbench.c
similarity index 100%
rename from tests/testbench.h
rename to tests/api/testbench.h
similarity index 100%
rename from tests/tv.cmake
rename to tests/api/tv.cmake
similarity index 100%
rename from tests/wifi.c
rename to tests/api/wifi.c
similarity index 100%
rename from tests/zone.c
rename to tests/api/zone.c
diff --git a/tests/testbench/testbench.cpp b/tests/testbench/testbench.cpp
new file mode 100644 (file)
index 0000000..bbd0df2
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string.h>
+#include <iostream>
+
+#include "testbench.h"
+
+namespace testbench {
+
+Source::Source(const std::string& file, long line, const std::string& msg) :
+       fileName(file), lineNumber(line), message(msg)
+{
+}
+
+TestResult::TestResult() :
+       __failureCount(0)
+{
+}
+
+TestResult::~TestResult()
+{
+}
+
+void TestResult::testsStarted()
+{
+}
+
+void TestResult::addFailure(const std::string& name, const Source& source)
+{
+       std::cout << "Testcase \"" << name << "\""
+                         << " failed: \"" << source.message << "\""
+                         << " line " << source.lineNumber
+                         << " in " << source.fileName << std::endl;
+
+       __failureCount++;
+}
+
+void TestResult::testsEnded()
+{
+       if (__failureCount > 0) {
+               std::cout << "\nThere were " << __failureCount << " failures" << std::endl;
+       } else {
+               std::cout << "\nThere were no test failures" << std::endl;
+       }
+}
+
+TestSuite::TestSuite(const std::string& name)
+       : __testName(name)
+{
+       Testbench::addTestSuite(this);
+}
+
+TestSuite::~TestSuite()
+{
+}
+
+void TestSuite::setup()
+{
+}
+
+void TestSuite::teardown()
+{
+}
+
+void TestSuite::run()
+{
+       setup();
+
+       TestCaseRegistry::iterator iter = __registry.begin();
+       while (iter != __registry.end()) {
+               TestSuite::TestCase& testcase = (*iter);
+
+               std::cout << "Entering testcase: "
+                                 << testcase.testName << std::endl;
+               try {
+                       (this->*testcase.function)();
+               } catch (...) {
+                       TEST_FAIL("Caught exception from " +
+                                         testcase.testName + " testcase");
+               }
+               std::cout << "Leaving testcase: "
+                                 << testcase.testName << std::endl;
+
+               iter++;
+       }
+
+       teardown();
+}
+
+void TestSuite::registerTestCase(TestFunction func, const std::string& name)
+{
+       __registry.push_back(TestCase(func, name));
+}
+
+bool TestSuite::check(long expected, long actual, const std::string& file, long line)
+{
+       if (expected == actual) {
+               return true;
+       }
+
+       std::stringstream stream;
+       stream << "expected " << expected << " but it was " << actual;
+       Testbench::report(__testName, Source(file, line, stream.str()));
+
+       return false;
+}
+
+std::unique_ptr<TestResult> Testbench::collector(new TestResult());
+
+void Testbench::addTestSuite(TestSuite *testSuite)
+{
+       instance().add(testSuite);
+}
+
+void Testbench::runAllTestSuites()
+{
+       instance().run();
+}
+
+Testbench& Testbench::instance()
+{
+       static Testbench testbench;
+       return testbench;
+}
+
+void Testbench::add(TestSuite *testSuite)
+{
+       __testSuites.push_back(testSuite);
+}
+
+void Testbench::report(const std::string& name, const Source& source)
+{
+       collector->addFailure(name, source);
+}
+
+void Testbench::run()
+{
+       collector->testsStarted();
+
+       TestSuiteRegistry::iterator iter = __testSuites.begin();
+       while (iter != __testSuites.end()) {
+               try {
+                       (*iter)->run();
+               } catch (...) {
+                       // Logging exception
+               }
+               iter++;
+       }
+
+       collector->testsEnded();
+}
+
+} //namespace testbench
diff --git a/tests/testbench/testbench.h b/tests/testbench/testbench.h
new file mode 100644 (file)
index 0000000..1fd6841
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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
+ */
+
+#ifndef __DPM_TESTBENCH_H__
+#define __DPM_TESTBENCH_H__
+
+#include <cstring>
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <sstream>
+
+namespace testbench {
+
+struct Source {
+       Source(const std::string& file, long line, const std::string& msg);
+
+       std::string fileName;
+       long lineNumber;
+       std::string     message;
+};
+
+class TestResult {
+public:
+       TestResult();
+       virtual ~TestResult();
+       virtual void testsStarted();
+       virtual void addFailure(const std::string& name, const Source& source);
+       virtual void testsEnded();
+
+private:
+       int     __failureCount;
+};
+
+class TestSuite {
+public:
+       TestSuite(const std::string& name);
+       virtual ~TestSuite();
+
+       TestSuite(const TestSuite&) = delete;
+       TestSuite& operator=(const TestSuite&) = delete;
+
+       void run();
+
+       const std::string& name() const {
+               return __testName;
+       }
+
+protected:
+       typedef void (TestSuite::*TestFunction)();
+
+       struct TestCase {
+               TestCase(TestFunction func, const std::string& name) :
+                       function(func), testName(name)
+               {
+               }
+
+               TestFunction function;
+               std::string testName;
+       };
+
+       virtual void setup();
+       virtual void teardown();
+
+#define addTest(func)  \
+       registerTestCase(static_cast<TestFunction>(&func), #func)
+
+#define addTestWithName(func, name)    \
+       registerTestCase(static_cast<TestFunction>(&func), name)
+
+       void registerTestCase(TestFunction func, const std::string& name);
+       bool check(long expected, long actual, const std::string& file, long line);
+
+protected:
+       std::string __testName;
+
+private:
+       typedef std::vector<TestCase> TestCaseRegistry;
+
+       TestCaseRegistry __registry;
+};
+
+class Testbench {
+public:
+       static void addTestSuite(TestSuite *testSuite);
+       static void runAllTestSuites();
+       static void report(const std::string& name, const Source& source);
+
+private:
+       static Testbench& instance();
+
+       void add(TestSuite *testSuite);
+       void run();
+
+private:
+       static std::unique_ptr<TestResult> collector;
+
+       typedef std::vector<TestSuite *> TestSuiteRegistry;
+       TestSuiteRegistry __testSuites;
+};
+
+#ifndef __FILENAME__
+#define __FILENAME__                                    \
+(::strrchr(__FILE__, '/') ? ::strrchr(__FILE__, '/') + 1 : __FILE__)
+#endif
+
+#define TESTCASE(TestName)                              \
+class TestName##TestCase : public testbench::TestSuite {\
+public:                                                 \
+       TestName##TestCase()                                \
+               : TestSuite(#TestName)                          \
+       {                                                   \
+               addTestWithName(TestName##TestCase::standalone, #TestName); \
+       }                                                   \
+       void standalone();                                  \
+} TestName##TestCase##Instance;                         \
+void TestName##TestCase::standalone()
+
+#define TEST_CHECK(condition)                           \
+{                                                       \
+       if (!(condition)) {                                 \
+               testbench::Testbench::report(__testName,        \
+               testbench::Source(__FILENAME__, __LINE__, #condition));  \
+               return;                                         \
+       }                                                   \
+}
+
+#define TEST_EXPECT(expected, actual)                   \
+{                                                       \
+       __typeof__(expected) _exp = (expected);             \
+       __typeof__(actual) _act = (actual);                 \
+       if (_exp != _act) {                                 \
+               std::stringstream _stream;                      \
+               _stream << "expected " << _exp                  \
+                               << " but it was " << _act;              \
+               testbench::Testbench::report(__testName,        \
+               testbench::Source(__FILENAME__, __LINE__, _stream.str())); \
+               return;                                         \
+       }                                                   \
+}
+
+#define TEST_FAIL(text)                                 \
+{                                                       \
+       testbench::Testbench::report(__testName,            \
+       testbench::Source(__FILENAME__, __LINE__, (text))); \
+       return;                                             \
+}
+} // namespace testbench
+#endif //!__DPM_TESTBENCH_H__
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..0960f61
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd 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.
+#
+SET(UNIT_TEST_TARGET   "dpm-unit-tests")
+
+SET(UNIT_TEST_SOURCES  main.cpp
+                                               database.cpp
+                                               dbus.cpp
+                                               eventfd.cpp
+                                               filesystem.cpp
+                                               logger.cpp
+                                               misc.cpp
+                                               proc.cpp
+                                               rmi.cpp
+                                               shadow.cpp
+                                               xml.cpp
+                                               ${DPM_TESTBENCH}/testbench.cpp
+)
+
+ADD_EXECUTABLE(${UNIT_TEST_TARGET} ${UNIT_TEST_SOURCES})
+
+PKG_CHECK_MODULES(TESTS_DEPS REQUIRED glib-2.0)
+INCLUDE_DIRECTORIES(SYSTEM ${TESTS_DEPS_INCLUDE_DIRS} ${DPM_COMMON} ${DPM_LIBS} ${DPM_TESTS})
+
+TARGET_LINK_LIBRARIES(${UNIT_TEST_TARGET} dpm-common)
+
+INSTALL(TARGETS ${UNIT_TEST_TARGET} DESTINATION bin)
+INSTALL(FILES   data/sample-policy.xml DESTINATION ${DATA_INSTALL_DIR})
+INSTALL(FILES   data/unittest-proc.sh DESTINATION ${DATA_INSTALL_DIR})
diff --git a/tests/unit/data/sample-policy.xml b/tests/unit/data/sample-policy.xml
new file mode 100755 (executable)
index 0000000..6768eac
--- /dev/null
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest>
+       <policy-version>0.1.0</policy-version>
+       <policy-group name="APPLICATION">
+               <policy name="SET_APP_INSTALLATION_MODE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_APP_UNINSTALLATION_MODE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+       </policy-group>
+
+       <policy-group name="ROAMING">
+               <policy name="ALLOW_SYNC" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="ALLOW_DATA" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="ALLOW_PUSH" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+       </policy-group>
+
+       <policy-group name="PASSWORD">
+               <policy name="SET_PASSWORD_QUALITY" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_MINIMUM_LENGTH" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_MAXIMUM_FAILED_FOR_WIPE" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_EXPIRE" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_MINIMUM_COMPLEX" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_PATTERN" status="OFF" retry="DEFAULT" priority="DEFAULT">empty</policy>
+               <policy name="SET_HISTORY" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_RECOVERY" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_LOCK_DELAY" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_INACTIVITY_TIME_DEVICE_LOCK" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_PASSWORD_CHANGE_TIMEOUT" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_MAXIMUM_CHARACTER_OCCURRENCES" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_MAXIMUM_NUMERIC_SEQUENCES_LENGTH" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_FORBIDDEN_STRINGS" status="OFF" retry="DEFAULT" priority="DEFAULT">empty</policy>
+       </policy-group>
+
+       <policy-group name="SECURITY">
+               <policy name="INTERNAL_STORAGE_ENCRYPTION" status="OFF" retry="DEFAULT" priority="DEFAULT"/>
+               <policy name="EXTERNAL_STORAGE_ENCRYPTION" status="OFF" retry="DEFAULT" priority="DEFAULT"/>
+               <policy name="ALLOW_INTERNET_SHARING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="ALLOW_DESKTOP_SYNC" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_REQUIRE_DEVICE_ENCRYPTION" status="OFF" retry="DEFAULT" priority="DEFAULT"/>
+               <policy name="SET_REQUIRE_STORAGE_CARD_ENCRYPTION" status="OFF" retry="DEFAULT" priority="DEFAULT"/>
+       </policy-group>
+
+       <policy-group name="WIFI">
+               <policy name="SET_ALLOW_WIFI" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_MINIMUM_REQUIRED_SECURITY" status="OFF" retry="DEFAULT" priority="DEFAULT">none</policy>
+               <policy name="SET_TLS_CERTIFICATE_SECURITY_LEVEL" status="OFF" retry="DEFAULT" priority="DEFAULT">none</policy>
+               <policy name="SET_PASSWORD_HIDDEN" status="OFF" retry="DEFAULT" priority="DEFAULT">disabled</policy>
+               <policy name="SET_ALLOW_USER_POLICY_CHANGES" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="ALLOW_WIFI_AP_SETTING_USER_MODIFICATION" status="OFF" retry="DEFAULT" priority="DEFAULT">enabled</policy>
+               <policy name="ACTIVATE_WIFI_SSID_RESTRICTION" status="OFF" retry="DEFAULT" priority="DEFAULT">disabled</policy>
+       </policy-group>
+
+       <policy-group name="BLUETOOTH">
+               <policy name="SET_ALLOW_BLUETOOTH" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_BLUETOOTH_OUTGOING_CALL" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_A2DP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_AVRCP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_BPP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_DUN_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_FTP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_HFP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_HSP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_PBAP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_SAP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_SPP_PROFILE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_DESKTOP_CONNECTIVITY_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_DISCOVERABLE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_PARINIG_STATE" satus="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_LIMITED_DISCOVERABLE_STATE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_BLUETOOTH_DATA_TRANSFER" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="ACTIVATE_BLUETOOTH_UUID_RESTRICTION" status="OFF" retry="DEFAULT" priority="DEFAULT">disabled</policy>
+               <policy name="ACTIVATE_BLUETOOTH_DEVICE_RESTRICTION" status="OFF" retry="DEFAULT" priority="DEFAULT">disabled</policy>
+       </policy-group>
+
+       <policy-group name="MISC">
+               <policy name="SET_ALLOW_CAMERA" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_MIC" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_LOCATION" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_SD_CARD" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_TEXT_MESSAGING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_POP_IMAP_EMAIL" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_BROWSER" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+       </policy-group>
+
+       <policy-group name="DEVICE_INVENTORY">
+               <policy name="ENABLE_CALL_CAPTURE" status="OFF" retry="DEFAULT" priority="DEFAULT">disabled</policy>
+               <policy name="ENABLE_SMS_CAPTURE" status="OFF" retry="DEFAULT" priority="DEFAULT">disabled</policy>
+               <policy name="ENABLE_WIFI_STATISTICS" status="OFF" retry="DEFAULT" priority="DEFAULT">enabled</policy>
+               </policy-group>
+
+       <policy-group name="PHONE_RESTRICTION">
+               <policy name="ENABLE_LIMIT_NUMBER_OF_CALLS" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="ENALBE_LIMIT_NUMBER_OF_SMS" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="ENABLE_LIMIT_USAGE_OF_DATA_CALL" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="ENABLE_EMERGENCY_CALL_ONLY" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_INCOMING_CALL_RESTRICTION" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_INCOMING_SMS_RESTRICTION" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_LIMIT_OF_DATA_CALLS" status="OFF" retry="DEFAULT" priority="DEFAULT">0,0,0</policy>
+               <policy name="SET_LIMIT_OF_INCOMING_CALLS" status="OFF" retry="DEFAULT" priority="DEFAULT">0,0,0</policy>
+               <policy name="SET_LIMIT_OF_INCOMING_SMS" status="OFF" retry="DEFAULT" priority="DEFAULT">0,0,0</policy>
+               <policy name="SET_LIMIT_OF_OUTGOING_CALLS" status="OFF" retry="DEFAULT" priority="DEFAULT">0,0,0</policy>
+               <policy name="SET_LIMIT_OF_OUTGOING_SMS" status="OFF" retry="DEFAULT" priority="DEFAULT">0,0,0</policy>
+               <policy name="SET_OUTGOING_CALL_RESTRICTION" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+               <policy name="SET_OUTGOING_SMS_RESTRICTION" status="OFF" retry="DEFAULT" priority="DEFAULT">0</policy>
+       </policy-group>
+
+       <policy-group name="RESTRICTION">
+               <policy name="SET_ALLOW_LOCATION_METHOD_NETWORK" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_LOCATION_METHOD_GPS" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_FACTORY_RESET" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_SETTINGS_CHANGES" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_NONMARKET_APPS" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_BACKGROUND_DATA" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_BACKUP" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_BLUETOOTH_TETHERING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_CELLULAR_DATA" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_CLIPBOARD_ENABLED" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_ENABLE_NFC" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_HOME_KEY" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_MOCK_LOCATION" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_SCREEN_CAPTURE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_SDCARD" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_TETHERING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_USB_DEBUGGING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_USB_KIES_AVAILABILITY" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_USB_MASS_STORAGE" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_USB_MEDIA_PLAYER_AVAILABILITY" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_USB_TETHERING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_WIFI_TETHERING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_ALLOW_VPN" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+       </policy-group>
+
+       <policy-group name="BROWSER">
+               <policy name="SET_AUTOFILL_SETTING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_COOKIES_SETTING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_FORCE_FRAUD_WARNING_SETTING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_JAVASCRIPT_SETTING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_POPUP_S_SETTING" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+       </policy-group>
+
+       <policy-group name="FIREWALL">
+               <policy name="SET_IPTABLES_ALLOW_RULES" status="OFF" retry="DEFAULT" priority="DEFAULT">empty</policy>
+               <policy name="SET_IPTABLES_DENY_RULES" status="OFF" retry="DEFAULT" priority="DEFAULT">empty</policy>
+               <policy name="SET_IPTABLES_OPTION" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_IPTABLES_PROXY_OPTION" status="OFF" retry="DEFAULT" priority="DEFAULT">allowed</policy>
+               <policy name="SET_IPTABLES_PROXY_RULES" status="OFF" retry="DEFAULT" priority="DEFAULT">empty</policy>
+               <policy name="SET_IPTABLES_REROUTE_RULES" status="OFF" retry="DEFAULT" priority="DEFAULT">empty</policy>
+       </policy-group>
+</manifest>
diff --git a/tests/unit/data/unittest-proc.sh b/tests/unit/data/unittest-proc.sh
new file mode 100755 (executable)
index 0000000..17a7b68
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+while true;
+do
+       sleep 4
+done
diff --git a/tests/unit/database.cpp b/tests/unit/database.cpp
new file mode 100644 (file)
index 0000000..e24b12c
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <iostream>
+#include <string>
+#include <stdexcept>
+
+#include "exception.h"
+
+#include "db/connection.h"
+#include "db/statement.h"
+#include "db/column.h"
+
+#include "testbench/testbench.h"
+
+const std::string TestbenchDataSource = "/tmp/dpm-testbench.db";
+
+TESTCASE(DatabaseTest)
+{
+       std::string query = "CREATE TABLE IF NOT EXISTS CLIENT("     \
+                                               "ID INTEGER PRIMARY KEY AUTOINCREMENT,"  \
+                                               "PKG TEXT,"                              \
+                                               "KEY TEXT,"                              \
+                                               "IS_USED INTEGER,"                       \
+                                               "USER INTEGER)";
+
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               db.exec(query);
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(InvalidStatementTest)
+{
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, "INVALID STATEMENT");
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(InvalidStatementTest2)
+{
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               db.exec("INVALID");
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ColumnBindTestWithIndex1)
+{
+       std::string query = "INSERT INTO CLIENT VALUES (NULL, ?, ?, ?, ?)";
+
+       try {
+               const char *str = "PACKAGE";
+               void *blob = (void *)str;
+               double user = 5001;
+               sqlite3_int64 used = 1;
+               std::string key = "test key";
+
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, query);
+               stmt.bind(1, blob, 8);
+               stmt.bind(2, key);
+               stmt.bind(3, used);
+               stmt.bind(4, user);
+               stmt.exec();
+               database::Statement select(db, "SELECT * FROM CLIENT");
+
+               TEST_EXPECT(5, select.getColumnCount());
+               stmt.clearBindings();
+               stmt.reset();
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(ColumnBindTestWithIndex2)
+{
+       std::string query = "INSERT INTO CLIENT VALUES (NULL, ?, ?, ?, ?)";
+
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, query);
+               stmt.bind(1, "TEST PACKAGE");
+               stmt.bind(2, "TEST KEY");
+               stmt.bind(3, false);
+               stmt.bind(4, 5001);
+               stmt.exec();
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(ColumnBindTestWithName1)
+{
+       std::string query = "INSERT INTO CLIENT VALUES (NULL, :PKG, :KEY, :IS_USED, :USER)";
+
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, query);
+               stmt.bind(":PKG", "TEST PACKAGE");
+               stmt.bind(":KEY", "TEST KEY");
+               stmt.bind(":IS_USED", true);
+               stmt.bind(":USER", 5001);
+               stmt.exec();
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(ColumnBindNullTest)
+{
+       std::string query = "INSERT INTO CLIENT VALUES (NULL, :PKG, :KEY, :IS_USED, :USER)";
+
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, query);
+               stmt.bind(":PKG");
+               stmt.bind(2);
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(ColumnBindTestWithName2)
+{
+       std::string query = "INSERT INTO CLIENT VALUES (NULL, :PKG, :KEY, :IS_USED, :USER)";
+
+       try {
+               const char *str = "PACKAGE";
+               void *blob = (void *)str;
+               double user = 5001;
+               sqlite3_int64 used = 1;
+               std::string key = "test key";
+
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, query);
+               stmt.bind(":PKG", blob, 8);
+               stmt.bind(":KEY", key);
+               stmt.bind(":IS_USED", used);
+               stmt.bind(":USER", user);
+               stmt.exec();
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(ColumnTest)
+{
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement select(db, "SELECT * FROM CLIENT");
+               while (select.step()) {
+                       for (int  i = 0; i < select.getColumnCount(); i++) {
+                               if (select.isNullColumn(i)) {
+                                       continue;
+                               }
+                               select.getColumnName(i);
+                       }
+                       std::cout << std::endl;
+
+                       database::Column id = select.getColumn(0);
+                       database::Column pkg = select.getColumn(1);
+                       database::Column key = select.getColumn(2);
+                       database::Column used = select.getColumn(3);
+
+                       id.getName(); id.getInt(); id.getInt64(); id.getDouble(); id.getType(); id.getBytes(); id.getDouble();
+                       pkg.getName(); pkg.getText(); pkg.getType(); pkg.getBytes(); pkg.getBlob();
+                       key.getName(); key.getText(); key.getType(); key.getBytes(); key.getBlob();
+                       used.getName(); used.getInt(); used.getInt64(); used.getDouble(); used.getType(); used.getBytes();
+               }
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(ColumnOutRange1)
+{
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement select(db, "SELECT * FROM CLIENT");
+               select.step();
+               database::Column column = select.getColumn(32);
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ColumnOutRange2)
+{
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement select(db, "SELECT * FROM CLIENT");
+               select.step();
+               select.isNullColumn(32);
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ColumnOutRange3)
+{
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement select(db, "SELECT * FROM CLIENT");
+               select.step();
+               select.getColumnName(32);
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ColumnBindOutRange1)
+{
+       std::string query = "INSERT INTO CLIENT VALUES (NULL, :PKG, :KEY, :IS_USED, :USER)";
+
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, query);
+               try {
+                       stmt.bind(":TPK", "TEST PACKAGE");
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(":TPK", (int)10);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(":TPK", (sqlite3_int64)10);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(":TPK", (double)10);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(":TPK", "invalid");
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(":TPK", std::string("invalid"));
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(":TPK", (void *)NULL, 12);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(":TPK");
+               } catch (runtime::Exception& e) {
+               }
+
+               stmt.exec();
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ColumnBindOutRange2)
+{
+       std::string query = "INSERT INTO CLIENT VALUES (NULL, :PKG, :KEY, :IS_USED, :USER)";
+
+       try {
+               database::Connection db(TestbenchDataSource, database::Connection::ReadWrite | database::Connection::Create);
+               database::Statement stmt(db, query);
+               try {
+                       stmt.bind(32, "TEST PACKAGE");
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(32, (int)10);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(32, (sqlite3_int64)10);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(32, (double)10);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(32, "invalid");
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(32, std::string("invalid"));
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(32, (void *)NULL, 12);
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       stmt.bind(32);
+               } catch (runtime::Exception& e) {
+               }
+
+               stmt.exec();
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(InvalidDB)
+{
+       try {
+               database::Connection db("/tmp/invalid.db", database::Connection::ReadWrite);
+       } catch (runtime::Exception& e) {
+       }
+}
diff --git a/tests/unit/dbus.cpp b/tests/unit/dbus.cpp
new file mode 100644 (file)
index 0000000..d1e5695
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "exception.h"
+#include "dbus/connection.h"
+#include "dbus/variant.h"
+#include "audit/logger.h"
+
+#include "testbench/testbench.h"
+
+TESTCASE(DbusNegativeTest)
+{
+       try {
+               dbus::Connection &systemDBus = dbus::Connection::getSystem();
+               systemDBus.methodcall("Unknown", "Unknown", "Unknown", "Unknown", -1, "", "");
+       } catch (std::exception& e) {
+       }
+}
diff --git a/tests/unit/eventfd.cpp b/tests/unit/eventfd.cpp
new file mode 100644 (file)
index 0000000..3e7c376
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <vector>
+
+#include "eventfd.h"
+#include "error.h"
+#include "exception.h"
+#include "audit/logger.h"
+
+#include "testbench/testbench.h"
+
+TESTCASE(EventFdHandleNegative)
+{
+       try {
+               runtime::EventFD evtfd(0, -1);
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(EventFdSendPositive)
+{
+       try {
+               runtime::EventFD evtfd;
+               evtfd.send();
+               evtfd.receive();
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(EventFdSendNegative)
+{
+       try {
+               runtime::EventFD evtfd;
+               evtfd.close();
+               evtfd.send();
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(EventFdReceiveNegative)
+{
+       try {
+               runtime::EventFD evtfd;
+               evtfd.close();
+               evtfd.receive();
+       } catch (runtime::Exception& e) {
+       }
+}
+
+
diff --git a/tests/unit/filesystem.cpp b/tests/unit/filesystem.cpp
new file mode 100644 (file)
index 0000000..4047a55
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include <iostream>
+#include <string>
+#include <stdexcept>
+
+#include "exception.h"
+#include "filesystem.h"
+
+#include "testbench/testbench.h"
+
+TESTCASE(DirectoryIteration)
+{
+       runtime::DirectoryIterator iter("/dev");
+       runtime::DirectoryIterator end;
+
+       TEST_EXPECT(false, iter == end);
+
+       while (iter != end) {
+               ++iter;
+       }
+}
+
+TESTCASE(FileIO)
+{
+       char testbuf[100] = "Test Data";
+       runtime::File tmp("/tmp/test-file");
+       try {
+               tmp.create(755);
+               tmp.lock();
+               tmp.write(testbuf, ::strlen(testbuf));
+               tmp.unlock();
+               tmp.close();
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+
+       char readbuf[100];
+       try {
+               runtime::File tmpFile("/tmp/test-file", O_RDWR);
+               tmpFile.read(readbuf, ::strlen(testbuf));
+               tmpFile.close();
+               tmpFile.remove();
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(DirOperation)
+{
+       runtime::File testDir("/tmp/dpm-unit-test/dir");
+       try {
+               testDir.makeDirectory(true, ::getuid(), ::getgid());
+               testDir.chown(::getuid(), ::getgid(), false);
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+
+       runtime::File dir("/tmp/dpm-unit-test");
+       try {
+               dir.chmod(777, true);
+               dir.remove(true);
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(FileAttribute)
+{
+       runtime::File tmp("/tmp");
+
+       TEST_EXPECT(true, tmp.exists());
+       TEST_EXPECT(true, tmp.canRead());
+       TEST_EXPECT(true, tmp.canWrite());
+       TEST_EXPECT(true, tmp.canExecute());
+       TEST_EXPECT(false, tmp.isLink());
+       TEST_EXPECT(false, tmp.isFile());
+       TEST_EXPECT(true, tmp.isDirectory());
+       TEST_EXPECT(false, tmp.isDevice());
+
+       std::cout << " UID: " << tmp.getUid()
+                         << " GID: " << tmp.getGid()
+                         << " Size: " << tmp.size()
+                         << " Mode: " << tmp.getMode()
+                         << " Path: " << tmp.getPath()
+                         << " File: " << tmp.getName() << std::endl;
+}
+
+TESTCASE(FileAttributeNegative)
+{
+       try {
+               runtime::File tmp("/unknown");
+
+               TEST_EXPECT(false, tmp.exists());
+               TEST_EXPECT(false, tmp.canRead());
+               TEST_EXPECT(false, tmp.canWrite());
+               TEST_EXPECT(false, tmp.canExecute());
+
+               try {
+                       tmp.isLink();
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       tmp.isFile();
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       tmp.isDirectory();
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       tmp.isDevice();
+               } catch (runtime::Exception& e) {
+               }
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(FileDevice)
+{
+       runtime::File tmp("/dev/kmem");
+
+       TEST_EXPECT(true, tmp.isDevice());
+}
+
+TESTCASE(FileSymlinkTest)
+{
+       runtime::File tmp("/var");
+
+       TEST_EXPECT(true, tmp.isLink());
+}
+
+TESTCASE(FileReferenceTest)
+{
+       runtime::File one("/tmp");
+       runtime::File two(one);
+}
diff --git a/tests/unit/logger.cpp b/tests/unit/logger.cpp
new file mode 100644 (file)
index 0000000..a0e1809
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <vector>
+
+#include "array.h"
+#include "error.h"
+#include "exception.h"
+#include "audit/logger.h"
+
+#include "testbench/testbench.h"
+
+TESTCASE(LogMacroTest)
+{
+    TRACE("Trace");
+    INFO("Info");
+    DEBUG("Debug");
+    WARN("Warning");
+    ERROR("Error");
+}
+
+TESTCASE(LogSeverityTest)
+{
+       try {
+               audit::LogLevelToString((audit::LogLevel)-1);
+       } catch (runtime::Exception& e) {
+       }
+}
diff --git a/tests/unit/main.cpp b/tests/unit/main.cpp
new file mode 100644 (file)
index 0000000..c053fc0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "testbench/testbench.h"
+#include "audit/logger.h"
+
+int main(int /*argc*/, char** /*argv*/)
+{
+       audit::Logger::setLogLevel(audit::LogLevel::Trace);
+       testbench::Testbench::runAllTestSuites();
+
+       return 0;
+}
diff --git a/tests/unit/misc.cpp b/tests/unit/misc.cpp
new file mode 100644 (file)
index 0000000..b8f2c82
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <vector>
+
+#include "array.h"
+#include "error.h"
+#include "exception.h"
+#include "audit/logger.h"
+
+#include "testbench/testbench.h"
+
+TESTCASE(ErrorMessage)
+{
+       std::cout << "Error Message: " << runtime::GetSystemErrorMessage(EINTR) << std::endl;
+}
+
+TESTCASE(Array)
+{
+       std::vector<std::string> vec = {
+               "abc",
+               "def"
+       };
+
+       runtime::Array<std::string> array(std::move(vec));
+       while (array.isEnd() == false) {
+               std::string* str = array.next();
+               TEST_EXPECT(true, str != nullptr);
+       }
+}
+
+TESTCASE(ArrayCopy)
+{
+       std::vector<std::string> vec = {
+               "abc",
+               "def"
+       };
+
+       runtime::Array<std::string> array(vec);
+       while (array.isEnd() == false) {
+               std::string* str = array.next();
+               TEST_EXPECT(true, str != nullptr);
+       }
+}
+
diff --git a/tests/unit/proc.cpp b/tests/unit/proc.cpp
new file mode 100644 (file)
index 0000000..505de01
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <vector>
+
+#include "exception.h"
+#include "process.h"
+#include "audit/logger.h"
+
+#include "testbench/testbench.h"
+
+TESTCASE(ProcWithArg)
+{
+       try {
+               std::vector<std::string> args = {
+                       "-l",
+                       "-a"
+               };
+               runtime::Process proc("/bin/ls > /dev/null", args);
+               TEST_EXPECT(true, proc.execute() != -1);
+               proc.waitForFinished();
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ProcKill)
+{
+       try {
+               runtime::Process proc("/opt/data/unittest-proc.sh");
+               TEST_EXPECT(true, proc.execute() != -1);
+               if (proc.isRunning()) {
+                       proc.kill();
+                       proc.waitForFinished();
+               }
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ProcTerminate)
+{
+       try {
+               runtime::Process proc("/opt/data/unittest-proc.sh");
+               TEST_EXPECT(true, proc.execute() != -1);
+               if (proc.isRunning()) {
+                       proc.terminate();
+                       proc.waitForFinished();
+               }
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(ProcInvalidProcess)
+{
+       try {
+               runtime::Process proc("/opt/data/unittest-proc.sh");
+               TEST_EXPECT(true, proc.execute() != -1);
+               proc.terminate();
+               proc.waitForFinished();
+               TEST_EXPECT(false, proc.isRunning());
+               try {
+                       proc.kill();
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       proc.terminate();
+               } catch (runtime::Exception& e) {
+               }
+
+               try {
+                       proc.waitForFinished();
+               } catch (runtime::Exception& e) {
+               }
+       } catch (runtime::Exception& e) {
+       }
+}
diff --git a/tests/unit/rmi.cpp b/tests/unit/rmi.cpp
new file mode 100644 (file)
index 0000000..ffcff81
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <iostream>
+#include <string>
+#include <stdexcept>
+#include <utility>
+
+#include "data-type.h"
+#include "file-descriptor.h"
+#include "rmi/service.h"
+#include "rmi/client.h"
+#include "audit/logger.h"
+
+#include "testbench/testbench.h"
+
+const std::string IPC_TEST_ADDRESS = "/tmp/.dpm-test";
+
+class TestServer {
+public:
+       TestServer()
+       {
+               service.reset(new rmi::Service(IPC_TEST_ADDRESS));
+
+               service->registerMethod(this, "", (String)(TestServer::method1)(String));
+               service->registerMethod(this, "", (String)(TestServer::method2)(String, String));
+               service->registerMethod(this, "", (String)(TestServer::method3)(String, String, String));
+               service->registerMethod(this, "", (String)(TestServer::method4)(String, String, String, String));
+
+               service->registerMethod(this, "", (FileDescriptor)(TestServer::signalProvider)(std::string));
+               service->registerMethod(this, "", (FileDescriptor)(TestServer::policyNotificationProvider)(std::string));
+
+               service->registerNonparametricMethod(this, "", (int)(TestServer::sendSignal)());
+               service->registerNonparametricMethod(this, "", (int)(TestServer::sendPolicyChangeNotification)());
+
+               service->createNotification("TestPolicyChanged");
+               service->createNotification("TestSignal");
+       }
+
+       void run()
+       {
+               service->start();
+       }
+
+       String method1(String& arg1)
+       {
+               return String("Method1 result");
+       }
+
+       String method2(String& arg1, String& arg2)
+       {
+               return String("Method2 result");
+       }
+
+       String method3(String& arg1, String& arg2, String& arg3)
+       {
+               return String("Method3 result");
+       }
+
+       String method4(String& arg1, String& arg2, String& arg3, String& arg4)
+       {
+               return String("Method4 result");
+       }
+
+       int sendPolicyChangeNotification()
+       {
+               service->notify("TestPolicyChanged", 1234);
+               return 0;
+       }
+
+       int sendSignal()
+       {
+               service->notify("TestSignal");
+               return 0;
+       }
+
+       FileDescriptor signalProvider(const std::string& name)
+       {
+               return service->subscribeNotification(name);
+       }
+
+       FileDescriptor policyNotificationProvider(const std::string& name)
+       {
+               return service->subscribeNotification(name);
+       }
+
+private:
+       std::unique_ptr<rmi::Service> service;
+};
+
+class TestClient {
+public:
+       TestClient() :
+               signalTriggered(false),
+               policyChangeNotificationTriggered(false)
+       {
+       }
+
+       void connect()
+       {
+               auto policyChangedListener = [this](const std::string& name, int value) {
+                       policyChangeNotificationTriggered = true;
+               };
+
+               auto policySignalListener = [this](const std::string& name) {
+                       signalTriggered = true;
+               };
+
+               client.reset(new rmi::Client(IPC_TEST_ADDRESS));
+               client->connect();
+
+               client->subscribe<std::string, int>("TestServer::policyNotificationProvider",
+                                                                                       "TestPolicyChanged", policyChangedListener);
+               client->subscribe<std::string>("TestServer::signalProvider",
+                                                                          "TestSignal", policySignalListener);
+       }
+
+       void disconnect()
+       {
+               client.reset();
+       }
+
+       String method1(String& arg1)
+       {
+               return client->methodCall<String>("TestServer::method1", arg1);
+       }
+
+       String method2(String& arg1, String& arg2)
+       {
+               return client->methodCall<String>("TestServer::method2", arg1, arg2);
+       }
+
+       String method3(String& arg1, String& arg2, String& arg3)
+       {
+               return client->methodCall<String>("TestServer::method3", arg1, arg2, arg3);
+       }
+
+       String method4(String& arg1, String& arg2, String& arg3, String& arg4)
+       {
+               return client->methodCall<String>("TestServer::method4", arg1, arg2, arg3, arg4);
+       }
+
+       void requestSignal()
+       {
+               signalTriggered = false;
+               client->methodCall<int>("TestServer::sendSignal");
+               while (!signalTriggered) {
+                       ::sleep(1);
+               }
+       }
+
+       void requestPolicyChangeNotification()
+       {
+               policyChangeNotificationTriggered = false;
+               client->methodCall<int>("TestServer::sendPolicyChangeNotification");
+               while (!policyChangeNotificationTriggered) {
+                       sleep(1);
+               }
+       }
+
+       String invalidMethod(String& arg)
+       {
+               return client->methodCall<String>("TestServer::invalidMethod", arg);
+       }
+
+private:
+       volatile bool signalTriggered;
+       volatile bool policyChangeNotificationTriggered;
+       std::unique_ptr<rmi::Client> client;
+};
+
+int WaitForFile(const std::string& path, const unsigned int timeout)
+{
+       struct stat st;
+       unsigned int loop = 0;
+
+       while (stat(path.c_str(), &st) == -1) {
+               if (errno != ENOENT) {
+                       ERROR("Error on waitting for: " + path);
+                       return -1;
+               }
+
+               if (((++loop) * 100) > timeout) {
+                       ERROR("Error on waitting for: " + path);
+                       return -1;
+               }
+
+               usleep(100 * 1000);
+       }
+
+       return 0;
+}
+
+int WaitForPid(pid_t pid)
+{
+       int status, ret;
+       char errmsg[256];
+
+       do {
+               ret = waitpid(pid, &status, 0);
+               if (ret == -1) {
+                       if (errno != EINTR) {
+                               ERROR("Wait Pid failed: " + std::to_string(pid) + "(" + strerror_r(errno, errmsg, sizeof(errmsg)) + ")");
+                               return -1;
+                       }
+               }
+       } while (ret == EINTR || ret != pid);
+
+       return status;
+}
+
+pid_t PrepareTestServer(void)
+{
+       ::unlink(IPC_TEST_ADDRESS.c_str());
+
+       pid_t pid = fork();
+
+       if (pid < 0) {
+               return -1;
+       }
+
+       if (pid == 0) {
+               try {
+                       TestServer server;
+                       server.run();
+               } catch (std::exception& e) {
+                       ERROR(e.what());
+                       return -1;
+               }
+
+               return 0;
+       }
+
+       return pid;
+}
+
+class IpcTestSuite : public testbench::TestSuite {
+public:
+       IpcTestSuite(const std::string& name) :
+               testbench::TestSuite(name)
+       {
+               addTest(IpcTestSuite::connectionTest);
+               addTest(IpcTestSuite::remoteMethodCallTest);
+               addTest(IpcTestSuite::notificationTest);
+       }
+
+       void setup()
+       {
+               pid = PrepareTestServer();
+               if (pid == -1) {
+                       ERROR("Preparing test server failed");
+                       return;
+               }
+
+               WaitForFile(IPC_TEST_ADDRESS, 1000);
+       }
+
+       void teardown()
+       {
+               if (::kill(pid, SIGTERM) == -1) {
+                       return;
+               }
+
+               int status = WaitForPid(pid);
+               if (status == -1 || !WIFEXITED(status)) {
+                       return;
+               }
+       }
+
+       void connectionTest()
+       {
+               try {
+                       TestClient client;
+                       client.connect();
+                       client.disconnect();
+               } catch (runtime::Exception& e) {
+                       ERROR(e.what());
+               }
+       }
+
+       void notificationTest()
+       {
+               try {
+                       TestClient client;
+                       client.connect();
+
+                       client.requestSignal();
+                       client.requestPolicyChangeNotification();
+
+                       client.disconnect();
+               } catch (runtime::Exception& e) {
+                       ERROR(e.what());
+               }
+       }
+
+       void remoteMethodCallTest()
+       {
+               try {
+                       TestClient client;
+                       client.connect();
+
+                       String param1("First Parameter");
+                       String param2("Second Parameter");
+                       String param3("Third Parameter");
+                       String param4("Fourth Parameter");
+
+                       String result1 = client.method1(param1);
+                       String result2 = client.method2(param1, param2);
+                       String result3 = client.method3(param1, param2, param3);
+                       String result4 = client.method4(param1, param2, param3, param4);
+
+                       client.requestSignal();
+                       client.requestPolicyChangeNotification();
+
+                       client.disconnect();
+               } catch (runtime::Exception& e) {
+                       ERROR(e.what());
+               }
+       }
+
+private:
+       pid_t pid;
+};
+
+IpcTestSuite ipcTestSuite("IpcTestSuite");
diff --git a/tests/unit/shadow.cpp b/tests/unit/shadow.cpp
new file mode 100644 (file)
index 0000000..52a1d3d
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <string>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "auth/user.h"
+#include "auth/group.h"
+
+#include "exception.h"
+#include "auth/user.h"
+#include "auth/group.h"
+#include "testbench/testbench.h"
+
+TESTCASE(GetGroupTest)
+{
+       try {
+               runtime::Group group("users");
+               runtime::Group another(group);
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(GetUserTest)
+{
+       try {
+               runtime::User user("root");
+               runtime::User another(user);
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(GetGroupNegativeTest)
+{
+       try {
+               runtime::Group group("invalid");
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(GetGroupNegativeTest2)
+{
+       try {
+               runtime::Group group(-1);
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(GetUserNegativetest)
+{
+       try {
+               runtime::User user("invalid");
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(GetUserNegativetest2)
+{
+       try {
+               runtime::User user(-1);
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(GetCurrentGroupTest)
+{
+       try {
+               runtime::Group group;
+               runtime::Group another(group.getGid());
+       } catch (runtime::Exception& e) {
+       }
+}
+
+TESTCASE(GetCurrentUserTest)
+{
+       try {
+               runtime::User user;
+               runtime::User another(user.getUid());
+       } catch (runtime::Exception& e) {
+       }
+}
diff --git a/tests/unit/xml.cpp b/tests/unit/xml.cpp
new file mode 100644 (file)
index 0000000..56f80dc
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd 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 <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <iostream>
+#include <string>
+#include <stdexcept>
+
+#include "exception.h"
+
+#include "xml/parser.h"
+#include "xml/document.h"
+#include "audit/logger.h"
+
+#include "testbench/testbench.h"
+
+const std::string testXmlFilePath = "/opt/data/dpm/sample-policy.xml";
+
+TESTCASE(XPath)
+{
+       try {
+               xml::Document* document = xml::Parser::parseFile(testXmlFilePath);
+               xml::Node::NodeList nodes = document->evaluate("//policy-group[@name='APPLICATION']/policy[@name='SET_APP_INSTALLATION_MODE']");
+               xml::Node::NodeList::iterator iter = nodes.begin();
+
+               TEST_EXPECT(false, iter == nodes.end());
+
+               while (iter != nodes.end()) {
+                       ++iter;
+               }
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(XmlDomTree)
+{
+       try {
+               xml::Document* document = xml::Parser::parseFile(testXmlFilePath);
+
+               xml::Node& root = document->getRootNode();
+
+               xml::Node::NodeList list = root.getChildren();
+               xml::Node::NodeList::iterator iter = list.begin();
+
+               TEST_EXPECT(false, iter == list.end());
+
+               while (iter != list.end()) {
+                       ++iter;
+               }
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(XmlGenerate)
+{
+       try {
+               xml::Document doc("TestNode", "0.1");
+               xml::Node &root = doc.getRootNode();
+               xml::Node node = root.addNewChild("ChildNode");
+               TEST_EXPECT("ChildNode", node.getName());
+
+               node.setName("ModifiedChildNode");
+               TEST_EXPECT("ModifiedChildNode", node.getName());
+
+               node.setContent("Content");
+               TEST_EXPECT("Content", node.getContent());
+
+               node.setProp("Prop", "Value");
+               TEST_EXPECT("Value", node.getProp("Prop"));
+
+               doc.write("/tmp/test.xml", "UTF-8", true);
+       } catch (runtime::Exception& e) {
+               TEST_FAIL(e.what());
+       }
+}
+
+TESTCASE(XmlException)
+{
+       try {
+               xml::Parser::parseFile("Invalid Source");
+       } catch (runtime::Exception& e) {
+       }
+}
index b407ac1..1b92cfb 100644 (file)
@@ -5,8 +5,8 @@ INCLUDE_DIRECTORIES(./include)
 
 FIND_PACKAGE(PkgConfig REQUIRED)
 PKG_CHECK_MODULES(dpm_syspopup_pkgs REQUIRED
-       dlog
-       glib-2.0
+               dlog
+               glib-2.0
        bundle
        efl-extension
        elementary
index a76e356..44a6cb1 100644 (file)
@@ -30,15 +30,13 @@ SET_TARGET_PROPERTIES(${ZONE_CLI_NAME} PROPERTIES PREFIX ""
        LINK_FLAGS "-pie"
 )
 
-PKG_CHECK_MODULES(ZONE_CLI_DEPS        REQUIRED
-                                                               klay
-                                                               glib-2.0
-                                                               libxml-2.0
-                                                               capi-appfw-package-manager
-                                                               capi-appfw-app-manager
+PKG_CHECK_MODULES(ZONE_CLI_DEPS  REQUIRED
+                                                                glib-2.0
+                                                                capi-appfw-package-manager
+                                                                capi-appfw-app-manager
 )
 
-INCLUDE_DIRECTORIES(SYSTEM ${ZONE_CLI_DEPS_INCLUDE_DIRS} ${ZONE_MODULE} ${ZONE_LIBS})
-TARGET_LINK_LIBRARIES(${ZONE_CLI_NAME} ${ZONE_CLI_DEPS_LIBRARIES} zone)
+INCLUDE_DIRECTORIES(SYSTEM ${ZONE_CLI_DEPS_INCLUDE_DIRS} ${DPM_COMMON} ${ZONE_MODULE} ${ZONE_LIBS})
+TARGET_LINK_LIBRARIES(${ZONE_CLI_NAME} ${ZONE_CLI_DEPS_LIBRARIES} dpm-common zone)
 
 INSTALL(TARGETS ${ZONE_CLI_NAME} DESTINATION sbin)
index f5fb71b..65a502c 100644 (file)
  */
 
 #define _XOPEN_SOURCE
-#include <grp.h>
 #include <glib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <getopt.h>
 #include <sys/wait.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 
-#include <klay/exception.h>
-#include <klay/filesystem.h>
-#include <klay/auth/user.h>
-
-#include <zone/app-proxy.h>
-#include <zone/package-proxy.h>
+#include <grp.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <fcntl.h>
 
-#include <cstring>
 #include <string>
 #include <vector>
-#include <utility>
 #include <iostream>
+#include <utility>
+
+#include <zone/package-proxy.h>
+#include <zone/app-proxy.h>
 
 #include "session.h"
 
+#include "error.h"
+#include "exception.h"
+#include "filesystem.h"
+#include "auth/user.h"
+
 
 #define DEFAULT_SHELL "/bin/bash"
 
index 85f5d7e..6575ea5 100755 (executable)
@@ -37,13 +37,12 @@ SET(CAPI_INCLUDE_FILES  zone/zone.h
 
 SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
 
-PKG_CHECK_MODULES(ZONE_LIBS_DEPS       REQUIRED
-                                                                       klay
-                                                                       glib-2.0
-                                                                       capi-appfw-package-manager
-                                                                       capi-appfw-app-manager
-                                                                       capi-appfw-app-control
-                                                                       libtzplatform-config
+PKG_CHECK_MODULES(ZONE_LIBS_DEPS  REQUIRED
+                                                                 glib-2.0
+                                                                 capi-appfw-package-manager
+                                                                 capi-appfw-app-manager
+                                                                 capi-appfw-app-control
+                                                                 libtzplatform-config
 )
 
 ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES})
@@ -51,8 +50,8 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-fvisibility=hid
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${LIB_SOVERSION})
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION   ${LIB_VERSION})
 
-INCLUDE_DIRECTORIES(SYSTEM ${ZONE_LIBS_DEPS_INCLUDE_DIRS} ${DPM_POLICY} ${DPM_LIBS} ${ZONE_LIBS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${ZONE_LIBS_DEPS_LIBRARIES} pthread)
+INCLUDE_DIRECTORIES(SYSTEM ${ZONE_LIBS_DEPS_INCLUDE_DIRS} ${DPM_COMMON} ${DPM_POLICY} ${DPM_LIBS} ${ZONE_LIBS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${ZONE_LIBS_DEPS_LIBRARIES} pthread dpm-common)
 
 CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY)
 
index d3e568f..51275e5 100644 (file)
@@ -22,6 +22,8 @@
 #include "app-proxy.h"
 #include "app-info-internal.h"
 
+#include "error.h"
+#include "auth/user.h"
 #include "policy-client.h"
 #include "zone/app-proxy.hxx"
 
index c6fb1fb..8fc20aa 100644 (file)
 #include <pkgmgr-info.h>
 #include <package-manager.h>
 #include <tzplatform_config.h>
-#include <klay/auth/user.h>
 
 #include "zone.h"
 #include "debug.h"
 #include "package-proxy.h"
 #include "package-info-internal.h"
 
+#include "error.h"
+#include "auth/user.h"
 #include "policy-client.h"
 #include "zone/package-proxy.hxx"
 
index 420e322..a580bb4 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "zone/zone.h"
 
+#include "error.h"
 #include "debug.h"
 #include "array.h"
 
index 024ff11..c62674c 100644 (file)
@@ -38,13 +38,8 @@ MARK_AS_ADVANCED(PAM_INCLUDE_DIR PAM_LIBRARY)
 INCLUDE(FindPackageHandleStandardArgs)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(PAM DEFAULT_MSG PAM_LIBRARY PAM_INCLUDE_DIR)
 
-PKG_CHECK_MODULES(ZONE_PAM_DEPS        REQUIRED
-                                                               klay
-                                                               libxml-2.0
-)
-
-INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${ZONE_PAM_DEPS_INCLUDE_DIRS})
-TARGET_LINK_LIBRARIES(${ZONE_PAM_NAME} ${PAM_LIBRARY} ${ZONE_PAM_DEPS_LIBRARIES} pthread)
+INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${DPM_COMMON})
+TARGET_LINK_LIBRARIES(${ZONE_PAM_NAME} ${PAM_LIBRARY} dpm-common pthread)
 
 TARGET_COMPILE_DEFINITIONS(${ZONE_PAM_NAME} PRIVATE
        CONF_PATH="${CONF_INSTALL_DIR}"
index 171d839..36ffd9a 100644 (file)
@@ -21,15 +21,12 @@ SET(ZONE_VOLUME_MANAGER_SOURCES key-manager.cpp
                                                                main.cpp
 )
 
-PKG_CHECK_MODULES(ZONE_VOLUME_MANAGER_DEPS     REQUIRED
-                                                                                       klay
-                                                                                       key-manager
-)
+PKG_CHECK_MODULES(ZONE_VOLUME_MANAGER_DEPS REQUIRED key-manager)
 
 ADD_EXECUTABLE(${ZONE_VOLUME_MANAGER_TARGET} ${ZONE_VOLUME_MANAGER_SOURCES})
 
-INCLUDE_DIRECTORIES(SYSTEM ${ZONE_VOLUME_MANAGER_DEPS_INCLUDE_DIRS} ${ZONE_LIBS})
+INCLUDE_DIRECTORIES(SYSTEM ${ZONE_VOLUME_MANAGER_DEPS_INCLUDE_DIRS} ${ZONE_LIBS} ${DPM_COMMON})
 
-TARGET_LINK_LIBRARIES(${ZONE_VOLUME_MANAGER_TARGET} ${ZONE_VOLUME_MANAGER_DEPS_LIBRARIES})
+TARGET_LINK_LIBRARIES(${ZONE_VOLUME_MANAGER_TARGET} ${ZONE_VOLUME_MANAGER_DEPS_LIBRARIES} dpm-common)
 
 INSTALL(TARGETS ${ZONE_VOLUME_MANAGER_TARGET} DESTINATION sbin)
index d6440f6..334eca6 100755 (executable)
  */
 
 
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
 
-#include <cstring>
-#include <cstdlib>
 #include <string>
 #include <iomanip>
 #include <sstream>
 #include <iostream>
 
-#include <klay/error.h>
-#include <klay/exception.h>
-
+#include "exception.h"
 #include "key-generator.h"
 
+#include "error.h"
+#include "exception.h"
+
 #define RAND_READ_BYTES 8
 #define PBKDF2_ITERATION 1000
 #define SHA_BLOCKSIZE 64
index d143c31..78b0d83 100755 (executable)
 
 #include <string>
 
-#include <klay/exception.h>
 #include <ckmc/ckmc-manager.h>
 
 #include "key-manager.h"
 
+#include "exception.h"
 
 #define addAliasPrefix(alias)  \
        (ckmcIdSystem + ckmcIdSeperator + alias)
index c5ad1ba..0fab661 100755 (executable)
  *  limitations under the License
  */
 
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <string.h>
 #include <getopt.h>
-#include <sys/stat.h>
-#include <sys/mount.h>
-#include <sys/types.h>
 
-#include <cstring>
 #include <string>
 #include <vector>
 #include <iostream>
 
-#include <klay/error.h>
-#include <klay/exception.h>
-#include <klay/audit/logger.h>
-
 #include "ecryptfs.h"
 #include "kernel-keyring.h"
 #include "key-manager.h"
 #include "key-generator.h"
 
+#include "error.h"
+#include "exception.h"
+#include "audit/logger.h"
+
 int generateKey(const std::string& keyName)
 {
        if (KeyManager::isKeyExist(keyName)) {