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)
ADD_DEFINITIONS(-DUG_WAYLAND)
+ADD_SUBDIRECTORY(${DPM_COMMON})
ADD_SUBDIRECTORY(${DPM_SERVER})
ADD_SUBDIRECTORY(${DPM_LIBS})
ADD_SUBDIRECTORY(${DPM_TOOLS})
--- /dev/null
+#
+# 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})
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 ¤t;
+ }
+
+ File* operator->()
+ {
+ return ¤t;
+ }
+
+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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
* 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
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)
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "bluetooth.hxx"
+#include "audit/logger.h"
namespace DevicePolicyManager {
#include "policy-client.h"
#include "debug.h"
+#include "exception.h"
+
DevicePolicyContext& GetDevicePolicyContext(void* handle)
{
assert(handle);
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "location.hxx"
+#include "audit/logger.h"
namespace DevicePolicyManager {
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "password.hxx"
+#include "audit/logger.h"
namespace DevicePolicyManager {
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "policy-client.h"
namespace {
#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;
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "restriction.hxx"
+#include "audit/logger.h"
namespace DevicePolicyManager
{
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "security.hxx"
+#include "audit/logger.h"
namespace DevicePolicyManager {
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
+#include "policy-client.h"
+
#include "storage.hxx"
namespace DevicePolicyManager {
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "wifi.hxx"
+#include "audit/logger.h"
namespace DevicePolicyManager {
* See the License for the specific language governing permissions and
* limitations under the License
*/
+
#include "zone.hxx"
namespace DevicePolicyManager {
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
BuildRequires: cmake
BuildRequires: pam-devel
BuildRequires: gettext-tools
-BuildRequires: pkgconfig(klay)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libxml-2.0)
BuildRequires: pkgconfig(sqlite3)
%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
#ifndef __ADMINISTRATION_POLICY__
#define __ADMINISTRATION_POLICY__
+#include <string>
+
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __APPLICATION_POLICY__
#define __APPLICATION_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __BLUETOOTH_POLICY__
#define __BLUETOOTH_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __LOCATION_POLICY__
#define __LOCATION_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __PASSWORD_POLICY__
#define __PASSWORD_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __RESTRICTION_POLICY__
#define __RESTRICTION_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager
#ifndef __SECURITY_POLICY__
#define __SECURITY_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __STORAGE_POLICY__
#define __STORAGE_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __WIFI_POLICY__
#define __WIFI_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __ZONE_POLICY__
#define __ZONE_POLICY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __ZONE_APP_PROXY__
#define __ZONE_APP_PROXY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __ZONE_PACKAGE_PROXY__
#define __ZONE_PACKAGE_PROXY__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
#ifndef __ZONE_MANAGER__
#define __ZONE_MANAGER__
+#include "data-type.h"
#include "policy-context.hxx"
namespace DevicePolicyManager {
SET(DEPENDENCY glib-2.0
gio-2.0
- klay
- libxml-2.0
- sqlite3
bundle
aul
appsvc
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")
* 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 {
* 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)
{
#include <bundle.h>
+#include "exception.h"
+
class Bundle {
public:
Bundle();
#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 {
*/
#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) || \
* 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 {
#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;
* 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)
{
#include <string>
#include "app-bundle.h"
+#include "exception.h"
class Launchpad {
public:
#include <location_batch.h>
+#include "location.hxx"
+
#include "privilege.h"
#include "policy-builder.h"
-
-#include "location.hxx"
+#include "audit/logger.h"
namespace DevicePolicyManager {
* 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>
* 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 {
#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>
#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"
* 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 {
#include "policy.h"
-#include <klay/xml/document.h>
+#include "xml/parser.h"
+#include "xml/document.h"
+#include "xml/node.h"
class PolicyStorage {
public:
#include <mutex>
#include <memory>
-#include <klay/xml/node.h>
+#include "xml/document.h"
+#include "xml/node.h"
class Policy {
public:
*/
#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", \
#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 {
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));
}
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)
#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();
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);
* 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 {
* 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", \
#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_.-]*"
#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 {
*/
#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 {
#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"
# 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})
--- /dev/null
+#
+# 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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__
--- /dev/null
+#
+# 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})
--- /dev/null
+<?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>
--- /dev/null
+#!/bin/bash
+
+while true;
+do
+ sleep 4
+done
--- /dev/null
+/*
+ * 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) {
+ }
+}
--- /dev/null
+/*
+ * 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) {
+ }
+}
--- /dev/null
+/*
+ * 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) {
+ }
+}
+
+
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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) {
+ }
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
+
--- /dev/null
+/*
+ * 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) {
+ }
+}
--- /dev/null
+/*
+ * 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");
--- /dev/null
+/*
+ * 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) {
+ }
+}
--- /dev/null
+/*
+ * 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) {
+ }
+}
FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(dpm_syspopup_pkgs REQUIRED
- dlog
- glib-2.0
+ dlog
+ glib-2.0
bundle
efl-extension
elementary
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)
*/
#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"
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})
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)
#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"
#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"
#include "zone/zone.h"
+#include "error.h"
#include "debug.h"
#include "array.h"
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}"
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)
*/
+#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
#include <string>
-#include <klay/exception.h>
#include <ckmc/ckmc-manager.h>
#include "key-manager.h"
+#include "exception.h"
#define addAliasPrefix(alias) \
(ckmcIdSystem + ckmcIdSeperator + alias)
* 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)) {