Initial commit 18/31418/1
authorJosé Bollo <jose.bollo@open.eurogiciel.org>
Thu, 4 Dec 2014 12:32:01 +0000 (13:32 +0100)
committerJosé Bollo <jose.bollo@open.eurogiciel.org>
Thu, 4 Dec 2014 12:32:01 +0000 (13:32 +0100)
Change-Id: I9ca327b87ab77ab28136ffc0c20b3aec42450dcb
Signed-off-by: José Bollo <jose.bollo@open.eurogiciel.org>
16 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0644]
packaging/vconf-buxton.manifest [new file with mode: 0644]
packaging/vconf-buxton.spec [new file with mode: 0644]
src/CMakeLists.txt [new file with mode: 0644]
src/log.h [new file with mode: 0644]
src/vconf-buxton-backup-mem-layer.sh [new file with mode: 0755]
src/vconf-buxton-init-from-vconf.sh [new file with mode: 0755]
src/vconf-buxton-keys.h [new file with mode: 0644]
src/vconf-buxton-restore-mem-layer.sh [new file with mode: 0755]
src/vconf-buxton-setup.service [new file with mode: 0644]
src/vconf-buxton-tool.c [new file with mode: 0644]
src/vconf-buxton.c [new file with mode: 0644]
src/vconf-buxton.h [new file with mode: 0644]
src/vconf-buxton.pc.in [new file with mode: 0644]
src/vconf-buxton.sym [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d12070d
--- /dev/null
@@ -0,0 +1,37 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(vconf-buxton C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCLUDEDIR "\${prefix}/include/vconf")
+SET(VERSION_MAJOR 0)
+SET(VERSION_MINOR 1)
+SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.0")
+SET(BINDIR "${PREFIX}/bin")
+SET(SYSTEMDDIR "lib/systemd/system")
+
+set(CMAKE_SKIP_BUILD_RPATH true)
+
+SET(SRCS vconf-buxton.c)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED glib-2.0 vconf-internal-keys libbuxton)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+#ADD_DEFINITIONS("-Werror")
+ADD_DEFINITIONS("-Wall")
+#ADD_DEFINITIONS("-Wextra")
+#ADD_DEFINITIONS("-ansi")
+#ADD_DEFINITIONS("-pedantic")
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+add_subdirectory(src)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/packaging/vconf-buxton.manifest b/packaging/vconf-buxton.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/vconf-buxton.spec b/packaging/vconf-buxton.spec
new file mode 100644 (file)
index 0000000..efadc59
--- /dev/null
@@ -0,0 +1,91 @@
+# set overwrite_vconf by default
+%bcond_without overwrite_vconf
+
+%if %{with overwrite_vconf}
+%define libname vconf
+%define toolname vconftool
+%else
+%define libname vconf-buxton
+%define toolname vconf-buxton-tool
+%endif
+
+Name:       vconf-buxton
+Summary:    Configuration system library
+Version:    0.1
+Release:    1
+Group:      System/Libraries
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+Source1001:    vconf-buxton.manifest
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(libbuxton)
+BuildRequires:  pkgconfig(vconf-internal-keys)
+Obsoletes: vconf
+
+%description 
+Configuration system library having vconf API and buxton backend
+
+%package devel
+Summary:    Vconf-buxton (devel)
+Requires:   %{name} = %{version}-%{release}
+Requires:   vconf-buxton = %{version}-%{release}
+Requires:   vconf-buxton-keys-devel = %{version}-%{release}
+Obsoletes:  vconf-devel
+
+%description devel
+Vconf library (devel)
+
+%package keys-devel
+Summary:    Vconf-buxton (devel)
+Requires:   %{name} = %{version}-%{release}
+Requires:   vconf-buxton = %{version}-%{release}
+Requires:   vconf-internal-keys-devel
+Obsoletes:  vconf-keys-devel
+
+%description keys-devel
+Vconf key management header files
+
+%prep
+%setup -q -n %{name}-%{version}
+cp %{SOURCE1001} .
+
+%build
+%cmake -DLIBNAME:STRING=%{libname} -DTOOLNAME:STRING=%{toolname} .
+make %{?jobs:-j%jobs}
+
+%install
+%make_install
+mv %{buildroot}%{_unitdir}/vconf-buxton-setup.service %{buildroot}%{_unitdir}/%{libname}-setup.service
+mkdir -p %{buildroot}%{_unitdir}/basic.target.wants
+ln -sf ../%{libname}-setup.service %{buildroot}%{_unitdir}/basic.target.wants/
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%license LICENSE.APLv2
+%{_bindir}/%{toolname}
+%{_bindir}/vconf-buxton-init-from-vconf.sh
+%{_bindir}/vconf-buxton-restore-mem-layer.sh
+%{_bindir}/vconf-buxton-backup-mem-layer.sh
+%{_libdir}/lib%{libname}.so.*
+%{_unitdir}/basic.target.wants/%{libname}-setup.service
+%{_unitdir}/%{libname}-setup.service
+
+%files devel
+%manifest %{name}.manifest
+%{_includedir}/vconf/vconf-buxton.h
+%{_libdir}/pkgconfig/%{libname}.pc
+%{_libdir}/lib%{libname}.so
+
+%files keys-devel
+%manifest %{name}.manifest
+%{_includedir}/vconf/vconf-buxton-keys.h
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8e2701f
--- /dev/null
@@ -0,0 +1,37 @@
+
+SET(SRCS vconf-buxton.c)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--version-script=vconf-buxton.sym")
+
+IF(NOT DEFINED LIBNAME)
+  SET(LIBNAME ${PROJECT_NAME})
+ENDIF()
+
+IF(NOT DEFINED TOOLNAME)
+  SET(TOOLNAME vconf-buxton-tool)
+ENDIF()
+
+
+ADD_LIBRARY(${LIBNAME} SHARED ${SRCS})
+SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${VERSION})
+TARGET_LINK_LIBRARIES(${LIBNAME} ${glib_pkg_LDFLAGS} ${pkgs_LDFLAGS})
+
+ADD_EXECUTABLE(${TOOLNAME} vconf-buxton-tool.c)
+TARGET_LINK_LIBRARIES(${TOOLNAME} ${pkgs_LDFLAGS} ${glib_pkg_LDFLAGS} ${LIBNAME})
+
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${LIBNAME}.pc @ONLY)
+SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${LIBNAME}.pc")
+
+INSTALL(TARGETS ${LIBNAME} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(TARGETS ${TOOLNAME} DESTINATION bin)
+INSTALL(PROGRAMS ${CMAKE_SOURCE_DIR}/src/vconf-buxton-init-from-vconf.sh DESTINATION bin)
+INSTALL(PROGRAMS ${CMAKE_SOURCE_DIR}/src/vconf-buxton-restore-mem-layer.sh DESTINATION bin)
+INSTALL(PROGRAMS ${CMAKE_SOURCE_DIR}/src/vconf-buxton-backup-mem-layer.sh DESTINATION bin)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/vconf-buxton.h DESTINATION include/vconf)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/vconf-buxton-keys.h DESTINATION include/vconf)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/src/vconf-buxton-setup.service DESTINATION ${SYSTEMDDIR})
+
diff --git a/src/log.h b/src/log.h
new file mode 100644 (file)
index 0000000..2161c8d
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,103 @@
+/*
+ * libslp-setting
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hakjoo Ko <hakjoo.ko@samsung.com>
+ *
+ * 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 __VCONF_BUXTON_LOG_H__
+#define __VCONF_BUXTON_LOG_H__
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+
+/************** Error ***************/
+#ifdef VCONF_SYSLOG_OUT
+#include <syslog.h>
+
+#define INFO(fmt, arg...) \
+               do { \
+                       syslog(LOG_INFO, "[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \
+               }while(0)
+#define ERR(fmt, arg...) \
+               do { \
+                       syslog(LOG_ERR, "[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \
+               }while(0)
+#define WARN(fmt, arg...) \
+               do { \
+                       syslog(LOG_ERR, "[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \
+               }while(0)
+
+#else
+#include <stdlib.h>
+
+#define INFO(fmt, arg...) \
+               do { \
+                       fprintf(stdout,"[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \
+               }while(0)
+#define WARN(fmt, arg...) \
+               do { \
+                       fprintf(stderr,"[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \
+               }while(0)
+#define ERR(fmt, arg...) \
+               do { \
+                       fprintf(stderr,"[%s:%d] "fmt"\n", __FILE__, __LINE__, ##arg); \
+               }while(0)
+#endif
+
+
+/************** Return ***************/
+#define ret_if(expr) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) -> %s() return", #expr, __FUNCTION__); \
+                       return; \
+               } \
+       } while (0)
+#define retv_if(expr, val) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) -> %s() return", #expr, __FUNCTION__); \
+                       return (val); \
+               } \
+       } while (0)
+#define retm_if(expr, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR(fmt, ##arg); \
+                       return; \
+               } \
+       } while (0)
+#define retvm_if(expr, val, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR(fmt, ##arg); \
+                       return (val); \
+               } \
+       } while (0)
+#define retex_if(expr, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR(fmt, ##arg); \
+                       goto CATCH; \
+               } \
+       } while (0)
+
+
+#endif                         /* __VCONF_BUXTON_LOG_H__ */
diff --git a/src/vconf-buxton-backup-mem-layer.sh b/src/vconf-buxton-backup-mem-layer.sh
new file mode 100755 (executable)
index 0000000..6fd13cf
--- /dev/null
@@ -0,0 +1,79 @@
+#!/bin/bash
+#
+#     This script backup the buxton system layer temp that is
+#     in memory to the system layer base. All keys are copied
+#     prefixed with memory_init/ .
+#
+#     See vconf-buxton-restore-mem-layer.sh
+#
+# author: jose.bollo@open.eurogiciel.org
+
+layermem=temp
+layerdb=base
+groupmem=vconf
+groupdb=vconf
+label=User
+
+reset=$(printf '\e[0m')
+red=$(printf '\e[1;31m')
+green=$(printf '\e[1;32m')
+
+#
+# check that buxton service is available
+#
+if ! buxtonctl -s check > /dev/null
+then
+    echo "${red}ERROR: can not connect to buxton service${reset}"
+    exit 1
+fi
+
+#
+# create the group for vconf
+#
+if buxtonctl -s list-groups "$layerdb" | grep -q "found group $groupdb"
+then
+    echo "${green}group $groupdb already exists${reset}"
+elif buxtonctl -s create-group "$layerdb" "$groupdb"
+then
+    echo "${green}group $groupdb succesfully created${reset}"
+else
+    echo "${red}ERROR: can't create group '$groupdb' for layer '$layerdb'${reset}"
+    exit 1
+fi
+
+#
+# Ensure label for the group
+#
+if buxtonctl -s set-label "$layerdb" "$groupdb" "$label"
+then
+    echo "${green}group $groupdb succesfully set to label '$label'${reset}"
+else
+    echo "${red}ERROR: can't set label '$label' to group '$groupdb' for layer '$layerdb'${reset}"
+    exit 1
+fi
+
+
+buxtonctl -s list-keys "$layermem" "$groupmem" |
+sed 's:^found key ::' |
+while read keymem
+do
+    keydb="memory_init/$keymem"
+    if ! q=$(buxtonctl -s get "$layermem" "$groupmem" "$keymem")
+    then
+        echo "${red}ERROR can't get value of $keymem${reset}"
+    else
+        type=$(echo -n "$q" | sed 's/.* = \([^:]*\): .*/\1/')
+        value=$(echo -n "$q" | sed 's/.* = [^:]*: \(.*\)/\1/')
+        echo -n "${reset}setting $keydb, $type: $value ..."
+        if ! buxtonctl -s -- set-$type "$layerdb" "$groupdb" "$keydb" "$value"
+        then
+            echo "${red}ERROR WHILE SETTING VALUE${reset}"
+        elif ! buxtonctl -s set-label "$layerdb" "$groupdb" "$keydb" "$label"
+        then
+            echo "${red}ERROR WHILE SETTING LABEL${reset}"
+        else
+            echo "${green}done${reset}"
+        fi
+    fi
+done
+
diff --git a/src/vconf-buxton-init-from-vconf.sh b/src/vconf-buxton-init-from-vconf.sh
new file mode 100755 (executable)
index 0000000..72e4b61
--- /dev/null
@@ -0,0 +1,101 @@
+#!/bin/bash
+#
+#     This script initialize the buxton database with the values
+#     from the vconf database.
+#
+# author: jose.bollo@open.eurogiciel.org
+
+export LANG=
+root=/usr/kdb
+
+layer=base
+group=vconf
+label=User
+
+reset=$(printf '\e[0m')
+red=$(printf '\e[1;31m')
+green=$(printf '\e[1;32m')
+
+
+#
+# create the default group for vconf
+#
+if buxtonctl list-groups "$layer" | grep -q "found group $group"
+then
+    echo "${green}group $group already exists${reset}"
+elif buxtonctl create-group "$layer" "$group"
+then
+    echo "${green}group $group succesfully created${reset}"
+else
+    echo "${red}ERROR: can't create group '$group' for layer '$layer'${reset}"
+    exit 1
+fi
+
+#
+# Ensure label for the group
+#
+if buxtonctl set-label "$layer" "$group" "$label"
+then
+    echo "${green}group $group succesfully set to label '$label'${reset}"
+else
+    echo "${red}ERROR: can't set label '$label' to group '$group' for layer '$layer'${reset}"
+    exit 1
+fi
+
+#
+# loop on keys of the vconf file system
+#
+find $root -type f |
+while read file
+do
+    key=${file#$root/}
+    #
+    # extract type and value of the key
+    #
+    ktype=$(head -c4 < $file | od -t d4 | awk '{print $2;exit}')
+    case $ktype in
+    40) # string
+        type=string
+        value=$(tail -c+5 < $file | sed 's:\(\\\|"\):\\&:g')
+        ;;
+    41) # integer
+        type=int32
+        value=$(tail -c+5 < $file | od -t d4 | awk '{print $2;exit}')
+        ;;
+    42) # double
+        type=double
+        value=$(tail -c+5 < $file | od -t f8 | awk '{print $2;exit}')
+        ;;
+    43) # boolean
+        type=bool
+        value=$(tail -c+5 < $file | od -t d4 | awk '{print $2;exit}')
+        ;;
+    *) # not a known type
+        echo "${red}ERROR: unknown type $ktype for file $file${reset}"
+        continue
+    esac
+    #
+    # compute the layer
+    #
+    case "${key%%/*}" in
+    memory_init|db|file)
+        ;;
+    *)
+        echo "${red}ERROR not a valid key prefix $key${reset}"
+        continue
+    esac
+    #
+    # set the key to buxton
+    #
+    echo -n "${reset}setting [$layer.$group:$type] $key = $value ..."
+    if ! buxtonctl -- "set-$type" "$layer" "$group" "$key" "$value"
+    then
+        echo "${red}ERROR WHILE SETTING VALUE${reset}"
+    elif ! buxtonctl set-label "$layer" "$group" "$key" "$label"
+    then
+        echo "${red}ERROR WHILE SETTING LABEL${reset}"
+    else
+        echo "${green}done${reset}"
+    fi
+done
+
diff --git a/src/vconf-buxton-keys.h b/src/vconf-buxton-keys.h
new file mode 100644 (file)
index 0000000..272e1c6
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * libslp-setting
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Hakjoo Ko <hakjoo.ko@samsung.com>
+ *
+ * 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 __VCONF_BUXTON_KEYS_H__
+#define __VCONF_BUXTON_KEYS_H__
+
+#include "vconf-internal-keys.h"
+
+/**
+ * This file defines keys and values.
+ *
+ * @file        vconf-keys.h
+ * @defgroup    vconf_key Definitions of shared Keys
+ * @ingroup     VCONF
+ * @author      Hyungdeuk Kim (hd3.kim@samsung.com)
+ * @version     0.3
+ * @brief       This file has the definitions of shared keys.
+ *
+ * add keys(key name) and values(enum) here for shared keys....
+ *
+ */
+
+/*
+ * ========================== System Manager Notification
+ * ============================= 
+ */
+/**
+ * @defgroup vconf_key_SystemManager System Manager Keys
+ * @ingroup vconf_key
+ * @addtogroup vconf_key_SystemManager
+ * @{
+ * @brief Maintainer: giyeol.ok@samsung.com
+ */
+
+/**
+ * @brief usbhost status
+ *
+ * 0 : Remove \n
+ * 1 : Add \n
+ * 2 : Over current \n
+ */
+#define VCONFKEY_SYSMAN_USB_HOST_STATUS             "memory/sysman/usbhost_status"
+enum {
+    VCONFKEY_SYSMAN_USB_HOST_DISCONNECTED = 0,
+    VCONFKEY_SYSMAN_USB_HOST_CONNECTED,
+    VCONFKEY_SYSMAN_USB_HOST_OVERCURRENT
+};
+
+/**
+ * @brief mmc status
+ *
+ * 0 : Remove \n
+ * 1 : mount \n
+ * 2 : insert(not mount) \n
+ */
+#define VCONFKEY_SYSMAN_MMC_STATUS                  "memory/sysman/mmc"
+enum {
+    VCONFKEY_SYSMAN_MMC_REMOVED = 0,
+    VCONFKEY_SYSMAN_MMC_MOUNTED,
+    VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED
+};
+
+/**
+ * @brief earkey status
+ *
+ * 0 : not press \n
+ * 1 : press \n
+ */
+#define VCONFKEY_SYSMAN_EARJACKKEY                  "memory/sysman/earjack_key"
+
+/**
+ * @brief cradle status
+ *
+ * 0 : Remove \n
+ * 1 : Add \n
+ */
+#define VCONFKEY_SYSMAN_CRADLE_STATUS               "memory/sysman/cradle_status"
+
+/**
+ * @}
+ */
+
+
+/*
+ * =============================== Wifi
+ * ====================================== 
+ */
+/**
+ * @defgroup vconf_key_Wifi Wifi Keys
+ * @ingroup vconf_key
+ * @addtogroup vconf_key_Wifi
+ * @{
+ * @brief Maintainer : dwmax.lee@samsung.com
+ */
+
+/**
+ * @Wi-Fi Direct state
+ *
+ * 0: Power off \n
+ * 1: Power on \n
+ * 2: Discoverable mode \n
+ * 3: Connected with peer as GC \n
+ * 4: Connected with peer as GO
+ */
+#define VCONFKEY_WIFI_DIRECT_STATE                  "memory/wifi_direct/state"
+enum {
+       /** Power off */
+    VCONFKEY_WIFI_DIRECT_DEACTIVATED = 0,
+       /** Power on */
+    VCONFKEY_WIFI_DIRECT_ACTIVATED,
+       /** Discoverable mode */
+    VCONFKEY_WIFI_DIRECT_DISCOVERING,
+       /** Connected with peer as GC */
+    VCONFKEY_WIFI_DIRECT_CONNECTED,
+       /** Connected with peer as GO */
+    VCONFKEY_WIFI_DIRECT_GROUP_OWNER
+};
+
+/**
+ * @}
+ */
+
+
+
+/*
+ * ================================= BT
+ * =====================================
+ */
+/**
+ * @defgroup vconf_key_BT BT Keys
+ * @ingroup vconf_key
+ * @addtogroup vconf_key_BT
+ * @{
+ * @brief Maintainer : chanyeol.park@samsung.com
+ */
+
+/** \
+ * @brief Bluetooth status
+ *
+ * 0x0000 : Bluetooth OFF \n
+ * 0x0001 : Bluetooth ON \n
+ * 0x0002 : Discoverable mode \n
+ * 0x0004 : In transfering \n
+*/
+#define VCONFKEY_BT_STATUS                          "db/bluetooth/status"
+enum {
+       /** Bluetooth OFF */
+    VCONFKEY_BT_STATUS_OFF = 0x0000,
+       /** Bluetooth ON */
+    VCONFKEY_BT_STATUS_ON = 0x0001,
+       /** Discoverable mode */
+    VCONFKEY_BT_STATUS_BT_VISIBLE = 0x0002,
+       /** In transfering */
+    VCONFKEY_BT_STATUS_TRANSFER = 0x0004
+};
+
+/**
+ * @brief Bluetooth Connected status
+ *
+ * 0x0000 : Not connected \n
+ * 0x0001 : Headset connected \n
+ * 0x0002 : A2DP headset connected \n
+ * 0x0004 : HID connected \n
+ * 0x0008 : PAN connected \n
+ * 0x0010 : SAP connected \n
+ * 0x0020 : PBAP connected \n
+*/
+#define VCONFKEY_BT_DEVICE                          "memory/bluetooth/device"
+enum {
+       /** Not connected */
+    VCONFKEY_BT_DEVICE_NONE = 0x0000,
+       /** Headset connected */
+    VCONFKEY_BT_DEVICE_HEADSET_CONNECTED = 0x0001,
+       /** A2DP headset connected */
+    VCONFKEY_BT_DEVICE_A2DP_HEADSET_CONNECTED = 0x0002,
+       /** HID connected */
+    VCONFKEY_BT_DEVICE_HID_CONNECTED = 0x0004,
+       /** PAN connected */
+    VCONFKEY_BT_DEVICE_PAN_CONNECTED = 0x0008,
+       /** SAP connected */
+    VCONFKEY_BT_DEVICE_SAP_CONNECTED = 0x0010,
+       /** PBAP connected */
+    VCONFKEY_BT_DEVICE_PBAP_CONNECTED = 0x0020
+};
+
+
+/*
+ * Media sound path for BT 
+ */
+enum {
+       /** Media Player Select Speaker */
+    VCONFKEY_BT_PLAYER_SELECT_SPEAKER = 0x00,
+       /** Media Player Select Bluetooth */
+    VCONFKEY_BT_PLAYER_SELECT_BLUETOOTH = 0x01,
+       /** BT application Select Speaker */
+    VCONFKEY_BT_APP_SELECT_SPEAKER = 0x02,
+       /** BT application Select Bluetooth */
+    VCONFKEY_BT_APP_SELECT_BLUETOOTH = 0x04
+};
+
+/**
+ * @}
+ */
+
+/*
+ * =========================== IDLE lock
+ * =======================================
+ */
+/**
+ * @defgroup vconf_key_idleLock idleLock Keys
+ * @ingroup vconf_key
+ * @addtogroup vconf_key_idleLock
+ * @{
+ * @brief Maintainer : seungtaek.chung@samsung.com, wonil22.choi@samsung.com hyoyoung.chang@samsung.com angelkim@samsung.com
+ */
+
+/**
+ * @brief lock screen status
+ *
+ * VCONFKEY_IDLE_UNLOCK : unlocked state \n
+ * VCONFKEY_IDLE_LOCK : locked state \n
+ */
+#define VCONFKEY_IDLE_LOCK_STATE                    "memory/idle_lock/state"
+enum {
+       /** unlocked state */
+    VCONFKEY_IDLE_UNLOCK = 0x00,
+       /** locked state */
+    VCONFKEY_IDLE_LOCK
+};
+
+/**
+ * @brief wallpaper of lock screen
+ *
+ * Value : Wallpaper file path in the lock screen  \n
+ */
+#define VCONFKEY_IDLE_LOCK_BGSET                    "db/idle_lock/bgset"
+
+/**
+ * @}
+ */
+
+
+
+/*
+ * =========================== pwlock
+ * =======================================
+ */
+/**
+ * @defgroup vconf_key_pwlock Lock application for password verification: phone, pin, sum, network, etc.
+ * @ingroup vconf_key
+ * @addtogroup vconf_key_pwlock
+ * @{
+ * @brief Maintainer : seungtaek.chung@samsung.com miju52.lee@samsung.com
+ *        Used module : pwlock
+ *
+ */
+
+/**
+ * @brief mobex engine status
+ *
+ * VCONFKEY_PWLOCK_BOOTING_UNLOCK : unlocked state in boointg time \n
+ * VCONFKEY_PWLOCK_BOOTING_LOCK : locked state in boointg time \n
+ * VCONFKEY_PWLOCK_RUNNING_UNLOCK : unlocked state in running time \n
+ * VCONFKEY_PWLOCK_RUNNING_LOCK : locked state in running time \n
+ */
+#define VCONFKEY_PWLOCK_STATE                       "memory/pwlock/state"
+enum {
+       /** unlocked state in boointg time */
+    VCONFKEY_PWLOCK_BOOTING_UNLOCK = 0x00,
+       /** locked state in boointg time */
+    VCONFKEY_PWLOCK_BOOTING_LOCK,
+       /** unlocked state in running time */
+    VCONFKEY_PWLOCK_RUNNING_UNLOCK,
+       /** locked state in running time */
+    VCONFKEY_PWLOCK_RUNNING_LOCK
+};
+/**
+ * @}
+ */
+
+
+
+/*
+ * =========================== browser
+ * =======================================
+ */
+/**
+ * @defgroup vconf_key_browser browser public keys
+ * @ingroup vconf_key
+ * @addtogroup vconf_key_browser
+ * @{
+ * @brief Maintainer : sangpyo7.kim@samsung.com ibchang@samsung.com
+ *
+ */
+
+/**
+ * @brief browser user agent string
+ *
+ * Value : The user agent string currently being used by embeded browser \n
+ */
+#define VCONFKEY_BROWSER_USER_AGENT            "db/browser/user_agent"
+
+/**
+ * @brief browser user agent profile
+ *
+ * Value : The user agent string profile currently being used by embeded browser for 2G network \n
+ */
+#define VCONFKEY_BROWSER_USER_AGENT_PROFILE_2G         "db/browser/user_agent_profile_2G"
+
+/**
+ * @brief browser user agent profile
+ *
+ * Value : The user agent string profile currently being used by embeded browser for 3G network \n
+ */
+#define VCONFKEY_BROWSER_USER_AGENT_PROFILE_3G         "db/browser/user_agent_profile_3G"
+
+/**
+ * @brief browser user agent profile
+ *
+ * Value : The user agent string profile currently being used by embeded browser for 4G network \n
+ */
+#define VCONFKEY_BROWSER_USER_AGENT_PROFILE_4G         "db/browser/user_agent_profile_4G"
+
+/**
+ * @}
+ */
+#endif                         /* __VCONF_BUXTON_KEYS_H__ */
diff --git a/src/vconf-buxton-restore-mem-layer.sh b/src/vconf-buxton-restore-mem-layer.sh
new file mode 100755 (executable)
index 0000000..2a74517
--- /dev/null
@@ -0,0 +1,79 @@
+#!/bin/bash
+#
+#     This script initialize the buxton system layer temp (in memory)
+#     with values from the system layer base. It searchs the keys of
+#     prefix memory_init/ and copy their value to memory.
+#
+#     See vconf-buxton-backup-mem-layer.sh
+#
+# author: jose.bollo@open.eurogiciel.org
+
+layerdb=base
+layermem=temp
+groupdb=vconf
+groupmem=vconf
+label=User
+
+reset=$(printf '\e[0m')
+red=$(printf '\e[1;31m')
+green=$(printf '\e[1;32m')
+
+#
+# check that buxton service is available
+#
+if ! buxtonctl -s check > /dev/null
+then
+    echo "${red}ERROR: can not connect to buxton service${reset}"
+    exit 1
+fi
+
+#
+# create the group for in memory vconf
+#
+if buxtonctl -s list-groups "$layermem" | grep -q "found group $groupmem"
+then
+    echo "${green}group $groupmem already exists${reset}"
+elif buxtonctl -s create-group "$layermem" "$groupmem"
+then
+    echo "${green}group $groupmem succesfully created${reset}"
+else
+    echo "${red}ERROR: can't create group '$groupmem' for layer '$layermem'${reset}"
+    exit 1
+fi
+
+#
+# Ensure label for the group
+#
+if buxtonctl -s set-label "$layermem" "$groupmem" "$label"
+then
+    echo "${green}group $groupmem succesfully set to label '$label'${reset}"
+else
+    echo "${red}ERROR: can't set label '$label' to group '$groupmem' for layer '$layermem'${reset}"
+    exit 1
+fi
+
+
+buxtonctl -s list-keys "$layerdb" "$groupdb" memory_init/ |
+sed 's:^found key ::' |
+while read keydb
+do
+    keymem=${keydb#memory_init/}
+    if ! q=$(buxtonctl -s get "$layerdb" "$groupdb" "$keydb")
+    then
+        echo "${red}ERROR can't get value of $keydb${reset}"
+    else
+        type=$(echo -n "$q" | sed 's/.* = \([^:]*\): .*/\1/')
+        value=$(echo -n "$q" | sed 's/.* = [^:]*: \(.*\)/\1/')
+        echo -n "${reset}setting $keymem, $type: $value ..."
+        if ! buxtonctl -s -- set-$type "$layermem" "$groupmem" "$keymem" "$value"
+        then
+            echo "${red}ERROR WHILE SETTING VALUE${reset}"
+        elif ! buxtonctl -s set-label "$layermem" "$groupmem" "$keymem" "$label"
+        then
+            echo "${red}ERROR WHILE SETTING LABEL${reset}"
+        else
+            echo "${green}done${reset}"
+        fi
+    fi
+done
+
diff --git a/src/vconf-buxton-setup.service b/src/vconf-buxton-setup.service
new file mode 100644 (file)
index 0000000..8fbed67
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=Initialize the vconf-buxton memory storage
+DefaultDependencies=no
+Requires=buxton.service
+After=buxton.service
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/vconf-buxton-restore-mem-layer.sh
+#ExecStop=/usr/bin/vconf-buxton-backup-mem-layer.sh
+
+[Install]
+WantedBy=basic.target
+
diff --git a/src/vconf-buxton-tool.c b/src/vconf-buxton-tool.c
new file mode 100644 (file)
index 0000000..8303911
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * Author: José Bollo <jose.bollo@open.eurogiciel.org>
+ * Author: Hakjoo Ko <hakjoo.ko@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "vconf-buxton.h"
+#include "log.h"
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <wordexp.h>
+#include <glib.h>
+
+enum
+{
+  VCONFTOOL_TYPE_NO = 0x00,
+  VCONFTOOL_TYPE_STRING,
+  VCONFTOOL_TYPE_INT,
+  VCONFTOOL_TYPE_DOUBLE,
+  VCONFTOOL_TYPE_BOOL
+};
+
+static char *guid = NULL;
+static char *uid = NULL;
+static char *vconf_type = NULL;
+static int is_recursive = FALSE;
+static int is_initialization = FALSE;
+static int is_forced = FALSE;
+static int get_num = 0;
+
+static GOptionEntry entries[] = {
+  {"type", 't', 0, G_OPTION_ARG_STRING, &vconf_type, "type of value",
+   "int|bool|double|string"},
+  {"recursive", 'r', 0, G_OPTION_ARG_NONE, &is_recursive,
+   "retrieve keys recursively", NULL},
+  {"guid", 'g', 0, G_OPTION_ARG_STRING, &guid, "group permission", NULL},
+  {"uid", 'u', 0, G_OPTION_ARG_STRING, &uid, "user permission", NULL},
+  {"initialization", 'i', 0, G_OPTION_ARG_NONE, &is_initialization,
+   "memory backend initialization", NULL},
+  {"force", 'f', 0, G_OPTION_ARG_NONE, &is_forced,
+   "overwrite vconf values by force", NULL},
+  {NULL}
+};
+
+static void get_operation (const char *input);
+static void print_keylist (keylist_t * keylist);
+
+static char usage[] =
+  "Usage:\n"
+  "\n"
+  "[Set vconf value]\n"
+  "       %1$s set -t <TYPE> <KEY NAME> <VALUE> <OPTIONS>\n"
+  "                 <TYPE>=int|bool|double|string\n"
+  "\n"
+  "       Ex) %1$s set -t string db/testapp/key1 \"This is test\" \n"
+  "\n"
+  "       <OPTIONS>\n"
+  "          any option is ignored! (compatibility)\n"
+  "\n"
+  "[Get vconf value]\n"
+  "       %1$s get <OPTIONS> <KEY NAME>\n"
+  "\n"
+  "       <OPTIONS>\n"
+  "          -r : retrieve all keys included in sub-directorys \n"
+  "       Ex) %1$s get db/testapp/key1\n"
+  "           %1$s get db/testapp/\n"
+  "\n"
+  "[Unset vconf value]\n"
+  "       %1$s unset <KEY NAME>\n"
+  "\n" "       Ex) %1$s unset db/testapp/key1\n" "\n"
+  "\n"
+  "[Set vconf label (Smack)]\n"
+  "       %1$s label <KEY NAME> <SMACK LABEL>\n"
+  "\n" "       Ex) %1$s label db/testapp/key1 User::Share\n" "\n";
+
+static void
+print_help (const char *cmd)
+{
+  fprintf (stderr, usage, cmd);
+}
+
+static int
+check_type (void)
+{
+  if (vconf_type)
+    {
+      if (!strncasecmp (vconf_type, "int", 3))
+       return VCONFTOOL_TYPE_INT;
+      else if (!strncasecmp (vconf_type, "string", 6))
+       return VCONFTOOL_TYPE_STRING;
+      else if (!strncasecmp (vconf_type, "double", 6))
+       return VCONFTOOL_TYPE_DOUBLE;
+      else if (!strncasecmp (vconf_type, "bool", 4))
+       return VCONFTOOL_TYPE_BOOL;
+    }
+  return VCONFTOOL_TYPE_NO;
+}
+
+int
+main (int argc, char **argv)
+{
+  int set_type;
+
+  GError *error = NULL;
+  GOptionContext *context;
+
+  context = g_option_context_new ("- vconf library tool");
+  g_option_context_add_main_entries (context, entries, NULL);
+  g_option_context_set_help_enabled (context, FALSE);
+  g_option_context_set_ignore_unknown_options (context, TRUE);
+
+  if (!g_option_context_parse (context, &argc, &argv, &error))
+    {
+      g_print ("option parsing failed: %s\n", error->message);
+      exit (1);
+    }
+
+  if (argc < 2)
+    {
+      print_help (argv[0]);
+      return 1;
+    }
+
+  if (!strcmp (argv[1], "set"))
+    {
+      set_type = check_type ();
+      if (argc < 4 || !set_type)
+       {
+         print_help (argv[0]);
+         return 1;
+       }
+
+      switch (set_type)
+       {
+       case VCONFTOOL_TYPE_STRING:
+         vconf_set_str (argv[2], argv[3]);
+         break;
+       case VCONFTOOL_TYPE_INT:
+         vconf_set_int (argv[2], atoi (argv[3]));
+         break;
+       case VCONFTOOL_TYPE_DOUBLE:
+         vconf_set_dbl (argv[2], atof (argv[3]));
+         break;
+       case VCONFTOOL_TYPE_BOOL:
+         vconf_set_bool (argv[2], !!atoi (argv[3]));
+         break;
+       default:
+         fprintf (stderr, "never reach");
+         exit (1);
+       }
+
+    }
+  else if (!strcmp (argv[1], "get"))
+    {
+      if (argv[2])
+       get_operation (argv[2]);
+      else
+       print_help (argv[0]);
+    }
+  else if (!strcmp (argv[1], "unset"))
+    {
+      if (argv[2])
+       vconf_unset (argv[2]);
+      else
+       print_help (argv[0]);
+    }
+  else if (!strcmp (argv[1], "label"))
+    {
+      if (argv[2] && argv[3])
+       vconf_set_label (argv[2], argv[3]);
+      else
+       print_help (argv[0]);
+    }
+  else
+    fprintf (stderr, "%s is a invalid command\n", argv[1]);
+  return 0;
+}
+
+static void
+get_operation (const char *input)
+{
+  keylist_t *keylist;
+
+  keylist = vconf_keylist_new ();
+  if (is_recursive)
+    {
+      vconf_scan (keylist, input, VCONF_GET_KEY_REC);
+    }
+  else
+    {
+      vconf_keylist_add_null (keylist, input);
+      vconf_refresh (keylist);
+    }
+  vconf_keylist_sort (keylist);
+  print_keylist (keylist);
+  if (!get_num)
+    printf ("No data\n");
+  vconf_keylist_free (keylist);
+}
+
+static void
+print_keylist (keylist_t * keylist)
+{
+  keynode_t *node;
+
+  vconf_keylist_rewind (keylist);
+  while ((node = vconf_keylist_nextnode (keylist)))
+    {
+      switch (vconf_keynode_get_type (node))
+       {
+       case VCONF_TYPE_INT:
+         printf ("%s, value = %d (int)\n",
+                 vconf_keynode_get_name (node),
+                 vconf_keynode_get_int (node));
+         get_num++;
+         break;
+       case VCONF_TYPE_BOOL:
+         printf ("%s, value = %d (bool)\n",
+                 vconf_keynode_get_name (node),
+                 vconf_keynode_get_bool (node));
+         get_num++;
+         break;
+       case VCONF_TYPE_DOUBLE:
+         printf ("%s, value = %f (double)\n",
+                 vconf_keynode_get_name (node),
+                 vconf_keynode_get_dbl (node));
+         get_num++;
+         break;
+       case VCONF_TYPE_STRING:
+         printf ("%s, value = %s (string)\n",
+                 vconf_keynode_get_name (node),
+                 vconf_keynode_get_str (node));
+         get_num++;
+         break;
+       default:
+         break;
+       }
+    }
+}
diff --git a/src/vconf-buxton.c b/src/vconf-buxton.c
new file mode 100644 (file)
index 0000000..3d9b196
--- /dev/null
@@ -0,0 +1,2077 @@
+/*
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * Author: José Bollo <jose.bollo@open.eurogiciel.org>
+ * Author: Hakjoo Ko <hakjoo.ko@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Note on conditionnal compilation: The following defines are controlling the compilation.
+ *
+ * NO_MULTITHREADING
+ *     Defining NO_MULTITHREADING removes multithreading support.
+ *     Defining it is not a good idea.
+ *
+ * NO_GLIB
+ *     Defining NO_GLIB removes support of GLIB main loop used for notification
+ *     Defining it implies to dig code to find some replacement (new API verbs to create).
+ *
+ * REMOVE_PREFIXES
+ *     Removes the prefixe of the keys depending (depends on the layer).
+ *     Defining it is not a good idea.
+ *
+ * The best is to not define any of the conditional value and let use the default.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <buxton.h>
+#if !defined(NO_GLIB)
+#include <glib.h>
+#endif
+#if !defined(NO_MULTITHREADING)
+#include <pthread.h>
+#endif
+
+#include "vconf-buxton.h"
+#include "log.h"
+
+#define VCONF_OK      0
+#define VCONF_ERROR  -1
+
+/*================= SECTION definition of types =============*/
+
+/*
+ * internal types for keys 
+ */
+enum keytype
+{
+  type_unset,                  /* type unset or unknown */
+  type_directory,              /* a directory, not a real key */
+  type_delete,                 /* key to be deleted */
+  type_string,                 /* key of type string */
+  type_int,                    /* key of type integer */
+  type_double,                 /* key of type double */
+  type_bool                    /* key of type boolean */
+};
+
+/*
+ * union for storing values 
+ */
+union keyvalue
+{
+  int i;                       /* storage of integers */
+  int b;                       /* storage of booleans */
+  double d;                    /* storage of doubles */
+  char *s;                     /* storage of strings */
+};
+
+/*
+ * structure for keys 
+ */
+struct _keynode_t
+{
+  enum keytype type;           /* type of the key */
+  union keyvalue value;                /* value of the key */
+  keynode_t *next;             /* linking to the next key */
+  keylist_t *list;             /* the containing list */
+  const char *keyname;         /* name of the key */
+};
+
+/*
+ * structure for list of keys 
+ */
+struct _keylist_t
+{
+  int num;                     /* count of keys in the list */
+  keynode_t *head;             /* first key of the list */
+  keynode_t *cursor;           /* iterator on keys for clients */
+  int cb_active;               /* callback global activity */
+  int cb_status;               /* callback global status */
+  unsigned cb_sent;            /* callback global count of sent queries */
+  unsigned cb_received;                /* callback global count of
+                                * received responses */
+};
+
+/*
+ * data for the callback of scanning 
+ */
+struct scanning_data
+{
+  int pending;                 /* is the scan pending? */
+  int cb_status;               /* status of the call back */
+  int want_directories;                /* is scanning directories? */
+  int want_keys;               /* is scanning keys? */
+  int is_recursive;            /* is scanning recursively? */
+  size_t dirlen;               /* length of the directory */
+  keylist_t *keylist;          /* keylist to fill */
+  const char *prefix;          /* prefix to add in front of names */
+  const char *directory;       /* scanned directory */
+};
+
+/*
+ * data when translating vconf names to buxton names. ** the rule is that
+ * name == prefix/key 
+ */
+struct layer_key
+{
+  const char *layer;           /* identified layer-name */
+  const char *prefix;          /* vconf prefix of the name (without
+                                * trailing /) */
+  const char *key;             /* buxton key-name (without leading /) */
+};
+
+/*
+ * singleton data for facilities 
+ */
+struct singleton
+{
+  keylist_t list;              /* the list */
+  keynode_t node;              /* its single node */
+};
+
+/*
+ * structure for notifications 
+ */
+struct notify
+{
+  int status;                  /* callback status */
+  vconf_callback_fn callback;  /* the user callback */
+  void *userdata;              /* the user data */
+  keynode_t *keynode;          /* the recorded key node */
+  struct notify *next;         /* tink to the next notification */
+};
+
+/*================= SECTION local variables =============*/
+
+/*
+ * maximum length of key-names 
+ */
+static size_t keyname_maximum_length = 2030;
+
+/*
+ * maximum length of group-names 
+ */
+static size_t keygroup_maximum_length = 1010;
+
+/*
+ * association from prefixes to layers 
+ */
+static const char *assoc_prefix_layer[][2] = {
+  {"db", "base"},
+  {"file", "base"},
+  {"memory", "temp"},
+  {"memory_init", "base"},
+  {"user", "user"},
+  {NULL, NULL}
+};
+
+/*
+ * default timeout in scanning responses 
+ */
+static int default_timeout = 5000;     /* in milliseconds */
+
+/*
+ * instance of the buxton client 
+ */
+static BuxtonClient the_buxton_client = 0;
+
+/*
+ * the file handle number for polling buxton events 
+ */
+static int the_buxton_client_fd = 0;
+
+/*
+ * flag indacating if the buxton client is set or not 
+ */
+static char the_buxton_client_is_set = 0;
+
+/*
+ * the group to use if default group is unset 
+ */
+static const char initial_default_group[] = "vconf";
+
+/*
+ * the default group to use 
+ */
+static char *default_group = NULL;
+
+/*
+ * the notify keylist 
+ */
+static keylist_t *notify_keylist = NULL;
+
+/*
+ * the notify entries 
+ */
+static struct notify *notify_entries = NULL;
+
+/*
+ * the count of lists
+ */
+static int internal_list_count = 0;
+
+#if !defined(NO_GLIB)
+/*
+ * link to the glib main loop 
+ */
+static GSource *glib_source = NULL;
+#endif
+
+#if !defined(NO_MULTITHREADING)
+/*
+ * multithreaded protection
+ * CAUTION: always use the given order!
+ */
+static pthread_mutex_t mutex_notify = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mutex_counter = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mutex_buxton = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mutex_group = PTHREAD_MUTEX_INITIALIZER;
+#define LOCK(x) pthread_mutex_lock(&mutex_##x)
+#define UNLOCK(x) pthread_mutex_unlock(&mutex_##x)
+#else
+#define LOCK(x)
+#define UNLOCK(x)
+#endif
+
+/*================= SECTION utils =============*/
+
+/*
+ * duplication of a string with validation of the length 
+ */
+static inline char *
+_dup_ (const char *source, size_t maxlen, const char *tag)
+{
+  size_t length;
+  char *result;
+
+  assert (source != NULL);
+  length = strlen (source);
+  if (length >= maxlen)
+    {
+      ERR ("Invalid argument: %s is too long", tag);
+      return NULL;
+    }
+  result = malloc (++length);
+  if (result == NULL)
+    {
+      ERR ("Can't allocate memory for %s", tag);
+      return NULL;
+    }
+  memcpy (result, source, length);
+  return result;
+}
+
+/*================= SECTION groupname utils =============*/
+
+static inline char *
+_dup_groupname_ (const char *groupname)
+{
+  return _dup_ (groupname, keygroup_maximum_length, "group-name");
+}
+
+static inline int
+_ensure_default_group_ ()
+{
+  int result = VCONF_OK;
+
+  LOCK (group);
+  if (default_group == NULL)
+    {
+      default_group = _dup_groupname_ (initial_default_group);
+      if (default_group == NULL)
+       result = VCONF_ERROR;
+    }
+  UNLOCK (group);
+
+  return result;
+}
+
+/*================= SECTION key utils =============*/
+
+static inline void
+_keynode_free_ (keynode_t * keynode)
+{
+  assert (keynode != NULL);
+  if (keynode->type == type_string)
+    free (keynode->value.s);
+  free (keynode);
+}
+
+static inline size_t
+_check_keyname_ (const char *keyname)
+{
+  size_t result;
+
+  assert (keyname != NULL);
+
+  if (*keyname == '/')
+    {
+      return 0;
+    }
+
+  for (result = 0; keyname[result]; result++)
+    {
+      if (keyname[result] == '/' && keyname[result + 1] == '/')
+       {
+         return 0;
+       }
+    }
+
+  return result;
+}
+
+/*================= SECTION list utils =============*/
+
+/*
+ * search in 'keylist' an entry of 'keyname' and return it if found or
+ * NULL if not found. 'previous' if not NULL and if the entry is found
+ * will recieve the address of the pointer referencing the returned node. 
+ */
+static inline keynode_t *
+_keylist_lookup_ (keylist_t * keylist,
+                 const char *keyname, keynode_t *** previous)
+{
+  keynode_t *node, **prev;
+  size_t length = 1 + strlen (keyname);
+
+  prev = &keylist->head;
+  node = keylist->head;
+  while (node)
+    {
+      assert (node->keyname != NULL);
+      if (!memcmp (keyname, node->keyname, length))
+       {
+         if (previous)
+           *previous = prev;
+         return node;
+       }
+
+      prev = &node->next;
+      node = node->next;
+    }
+  return NULL;
+}
+
+static inline keynode_t *
+_keylist_add_ (keylist_t * keylist, const char *keyname, enum keytype type)
+{
+  keynode_t *result;
+  char *name;
+  size_t length;
+
+  /*
+   * not found, create it 
+   */
+  length = _check_keyname_ (keyname);
+  retvm_if (!length, NULL, "invalid keyname");
+  retvm_if (length > keyname_maximum_length, NULL, "keyname too long");
+  result = malloc (1 + length + sizeof *result);
+  retvm_if (result == NULL, NULL, "allocation of keynode failed");
+  result->type = type;
+  result->value.s = NULL;
+
+  result->list = keylist;
+  name = (char *) (result + 1);
+  result->keyname = name;
+  memcpy (name, keyname, length + 1);
+
+  result->next = keylist->head;
+  keylist->head = result;
+  keylist->num++;
+
+  return result;
+}
+
+static inline keynode_t *
+_keylist_getadd_ (keylist_t * keylist, const char *keyname, enum keytype type)
+{
+  keynode_t *result;
+
+  /*
+   * search keynode of keyname 
+   */
+  result = _keylist_lookup_ (keylist, keyname, NULL);
+  if (result == NULL)
+    {
+      /*
+       * not found, create it 
+       */
+      result = _keylist_add_ (keylist, keyname, type);
+    }
+  else if (result->type != type)
+    {
+      if (result->type == type_string)
+       free (result->value.s);
+      result->type = type;
+      result->value.s = NULL;
+    }
+  return result;
+}
+
+static inline int
+_keylist_init_singleton_ (struct singleton *singleton, const char *keyname,
+                         enum keytype type)
+{
+  int status;
+
+  if (!_check_keyname_ (keyname))
+    {
+      ERR ("Invalid key name(%s)", keyname);
+      return VCONF_ERROR;
+    }
+  status = _ensure_default_group_ ();
+  if (status != VCONF_OK)
+    return status;
+
+  memset (singleton, 0, sizeof *singleton);
+  singleton->list.num = 1;
+  singleton->list.head = &singleton->node;
+  singleton->node.keyname = keyname;
+  singleton->node.type = type;
+  singleton->node.list = &singleton->list;
+
+  return VCONF_OK;
+}
+
+
+/*================= SECTION buxton =============*/
+
+static void
+_check_close_buxton_ ()
+{
+  BuxtonClient bc;
+
+  LOCK (notify);
+  LOCK (counter);
+  if (internal_list_count == 0 && notify_entries == NULL)
+    if (internal_list_count == 0 && notify_entries == NULL)
+      {
+       LOCK (buxton);
+       bc = the_buxton_client;
+       the_buxton_client_is_set = 0;
+       the_buxton_client = NULL;
+       the_buxton_client_fd = -1;
+       UNLOCK (buxton);
+       if (bc)
+         buxton_close (bc);
+      }
+  UNLOCK (counter);
+  UNLOCK (notify);
+}
+
+static void
+_try_to_open_buxton_ ()
+{
+  the_buxton_client_fd = buxton_open (&the_buxton_client);
+  if (the_buxton_client_fd < 0)
+    {
+      ERR ("can't connect to buxton server: %m");
+      errno = ENOTCONN;
+      the_buxton_client = NULL;
+    }
+}
+
+static inline int
+_open_buxton_ ()
+{
+  LOCK (buxton);
+  if (!the_buxton_client_is_set)
+    {
+      /*
+       * first time, try to connect to buxton 
+       */
+      the_buxton_client_is_set = 1;
+      _try_to_open_buxton_ ();
+    }
+  UNLOCK (buxton);
+  return the_buxton_client != NULL;
+}
+
+
+static inline BuxtonClient
+_buxton_ ()
+{
+  BuxtonClient result = the_buxton_client;
+  assert (result != NULL);
+  return result;
+}
+
+static inline int
+_handle_buxton_response_ (int lock)
+{
+  int result;
+
+  if (lock)
+    LOCK (buxton);
+  result = buxton_client_handle_response (_buxton_ ());
+  if (result < 0)
+    ERR ("Error in buxton_client_handle_response: %m");
+  if (lock)
+    UNLOCK (buxton);
+  return result;
+}
+
+static inline int
+_dispatch_buxton_ (int writing, int lock)
+{
+  int status;
+  struct pollfd pfd;
+
+  assert (_buxton_ () != NULL);
+
+  pfd.fd = the_buxton_client_fd;
+  pfd.events = writing ? POLLIN | POLLOUT : POLLIN;
+  for (;;)
+    {
+      pfd.revents = 0;
+      status = poll (&pfd, 1, default_timeout);
+      if (status == -1)
+       {
+         if (errno != EINTR)
+           {
+             return VCONF_ERROR;
+           }
+       }
+      else if (status == 1)
+       {
+         if (pfd.revents & POLLIN)
+           {
+             status = _handle_buxton_response_ (lock);
+             if (status < 0)
+               {
+                 return VCONF_ERROR;
+               }
+             if (!writing)
+               {
+                 return VCONF_OK;
+               }
+           }
+         if (pfd.revents & POLLOUT)
+           {
+             return VCONF_OK;
+           }
+         else
+           {
+             return VCONF_ERROR;
+           }
+       }
+    }
+}
+
+static inline int
+_wait_buxton_response_ (int *pending)
+{
+  int result;
+
+  do
+    {
+      result = _dispatch_buxton_ (0, 1);
+    }
+  while (result == VCONF_OK && *pending);
+  return result;
+}
+
+static inline int
+_get_layer_key_ (const char *keyname, struct layer_key *laykey)
+{
+  int i, j;
+  const char *prefix;
+
+  /*
+   * get the names 
+   */
+  i = 0;
+  prefix = assoc_prefix_layer[i][0];
+  while (prefix != NULL)
+    {
+      for (j = 0; prefix[j] && prefix[j] == keyname[j]; j++);
+      if (!prefix[j] && (!keyname[j] || keyname[j] == '/'))
+       {
+         laykey->prefix = prefix;
+         laykey->layer = assoc_prefix_layer[i][1];
+#if defined(REMOVE_PREFIXES)
+         laykey->key = keyname + j + (keyname[j] == '/');
+#else
+         laykey->key = keyname;
+#endif
+         return VCONF_OK;
+       }
+      i++;
+      prefix = assoc_prefix_layer[i][0];
+    }
+  ERR ("Invalid argument: wrong prefix of key(%s)", keyname);
+  return VCONF_ERROR;
+}
+
+static inline BuxtonKey
+_get_buxton_key_ (keynode_t * node)
+{
+  BuxtonDataType type;
+  struct layer_key laykey;
+
+  /*
+   * get layer and key 
+   */
+  if (_get_layer_key_ (node->keyname, &laykey) != VCONF_OK)
+    {
+      return NULL;
+    }
+
+  /*
+   * get type 
+   */
+  switch (node->type)
+    {
+    case type_string:
+      type = BUXTON_TYPE_STRING;
+      break;
+    case type_int:
+      type = BUXTON_TYPE_INT32;
+      break;
+    case type_double:
+      type = BUXTON_TYPE_DOUBLE;
+      break;
+    case type_bool:
+      type = BUXTON_TYPE_BOOLEAN;
+      break;
+    default:
+      type = BUXTON_TYPE_UNSET;
+    }
+
+  return buxton_key_create (default_group, laykey.key, laykey.layer, type);
+}
+
+/*================= SECTION set/unset/refresh =============*/
+
+static void
+_cb_inc_received_ (BuxtonResponse resp, keynode_t * keynode)
+{
+  keylist_t *list;
+
+  assert (keynode != NULL);
+  assert (keynode->list != NULL);
+
+  list = keynode->list;
+  list->cb_received++;
+  if (buxton_response_status (resp) != 0)
+    {
+      ERR ("Buxton returned error %d for key %s",
+          buxton_response_status (resp), keynode->keyname);
+      list->cb_status = VCONF_ERROR;
+    }
+}
+
+static int
+_set_response_to_keynode_ (BuxtonResponse resp, keynode_t * keynode,
+                          int force)
+{
+  enum keytype type;
+  BuxtonDataType buxtyp;
+  void *buxval;
+
+  assert (keynode != NULL);
+  assert (buxton_response_status (resp) == 0);
+
+  buxtyp = buxton_response_value_type (resp);
+  switch (buxtyp)
+    {
+    case BUXTON_TYPE_STRING:
+      type = type_string;
+      break;
+    case BUXTON_TYPE_INT32:
+      type = type_int;
+      break;
+    case BUXTON_TYPE_DOUBLE:
+      type = type_double;
+      break;
+    case BUXTON_TYPE_BOOLEAN:
+      type = type_bool;
+      break;
+    default:
+      return VCONF_ERROR;
+    }
+
+  if (force && type != keynode->type && keynode->type != type_unset)
+    return VCONF_ERROR;
+
+  buxval = buxton_response_value (resp);
+  if (buxval == NULL)
+    return VCONF_ERROR;
+
+  if (keynode->type == type_string)
+    free (keynode->value.s);
+
+  keynode->type = type;
+  switch (type)
+    {
+    case type_string:
+      keynode->value.s = buxval;
+      return VCONF_OK;
+    case type_int:
+      keynode->value.i = (int) *(int32_t *) buxval;
+      break;
+    case type_double:
+      keynode->value.d = *(double *) buxval;
+      break;
+    case type_bool:
+      keynode->value.b = *(bool *) buxval;
+      break;
+    default:
+      assert (0);
+      break;
+    }
+  free (buxval);
+  return VCONF_OK;
+}
+
+static void
+_cb_refresh_ (BuxtonResponse resp, keynode_t * keynode)
+{
+  keylist_t *list;
+
+  assert (keynode != NULL);
+  assert (keynode->list != NULL);
+  assert (buxton_response_type (resp) == BUXTON_CONTROL_GET);
+
+  list = keynode->list;
+  list->cb_received++;
+  if (buxton_response_status (resp) != 0)
+    {
+      ERR ("Error %d while getting buxton key %s",
+          buxton_response_status (resp), keynode->keyname);
+      list->cb_status = VCONF_ERROR;
+    }
+  else if (_set_response_to_keynode_ (resp, keynode, 0) != VCONF_OK)
+    {
+      list->cb_status = VCONF_ERROR;
+    }
+}
+
+static void
+_cb_scan_ (BuxtonResponse resp, struct scanning_data *data)
+{
+  char *buxname;
+  char *name;
+  char *term;
+  uint32_t count;
+  uint32_t index;
+  keylist_t *keylist;
+  keynode_t *keynode;
+  int length;
+
+  data->pending = 0;
+
+  /*
+   * check the response status 
+   */
+  if (buxton_response_status (resp) != 0)
+    {
+      ERR ("Error while getting list of names from buxton");
+      data->cb_status = VCONF_ERROR;
+      return;
+    }
+
+  /*
+   * iterate on the list of names 
+   */
+  assert (data->directory[data->dirlen - 1] == '/');
+  keylist = data->keylist;
+  count = buxton_response_list_names_count (resp);
+  index = 0;
+  while (index < count)
+    {
+      /*
+       * get the name 
+       */
+      buxname = buxton_response_list_names_item (resp, index++);
+      if (buxname == NULL)
+       {
+         ERR ("Unexpected NULL name returned by buxton");
+         data->cb_status = VCONF_ERROR;
+         return;
+       }
+
+      /*
+       * normalise the name 
+       */
+#if defined(REMOVE_PREFIXES)
+      length = asprintf (&name, "%s/%s", data->prefix, buxname);
+#else
+      length = asprintf (&name, "%s", buxname);
+#endif
+      free (buxname);
+      if (length < 0)
+       {
+         ERR ("Memory allocation error");
+         data->cb_status = VCONF_ERROR;
+         return;
+       }
+      assert (_check_keyname_ (name));
+      assert (!memcmp (data->directory, name, data->dirlen));
+
+      /*
+       * add key if requested 
+       */
+      term = strchr (name + data->dirlen, '/');
+      if (data->want_keys && (data->is_recursive || term == NULL))
+       {
+         keynode = _keylist_getadd_ (keylist, name, type_unset);
+         if (keynode == NULL)
+           {
+             free (name);
+             data->cb_status = VCONF_ERROR;
+             return;
+           }
+       }
+
+      /*
+       * add directories if requested 
+       */
+      if (data->want_directories)
+       {
+         while (term != NULL)
+           {
+             *term = 0;
+             keynode = _keylist_getadd_ (keylist, name, type_directory);
+             if (keynode == NULL)
+               {
+                 free (name);
+                 data->cb_status = VCONF_ERROR;
+                 return;
+               }
+             if (!data->is_recursive)
+               {
+                 break;
+               }
+             *term = '/';
+             term = strchr (term + 1, '/');
+           }
+       }
+
+      free (name);
+    }
+  data->cb_status = VCONF_OK;
+}
+
+
+static inline int
+_async_set_ (keynode_t * keynode)
+{
+  void *data;
+  int status;
+  BuxtonKey key;
+
+  assert (keynode != NULL);
+
+  switch (keynode->type)
+    {
+    case type_string:
+      data = keynode->value.s;
+      break;
+    case type_int:
+    case type_double:
+    case type_bool:
+      data = &keynode->value;
+      break;
+    default:
+      return 0;
+    }
+
+  key = _get_buxton_key_ (keynode);
+  if (key == NULL)
+    {
+      return -1;
+    }
+
+  status = buxton_set_value (_buxton_ (), key,
+                            data,
+                            (BuxtonCallback) _cb_inc_received_, keynode,
+                            false);
+  buxton_key_free (key);
+
+  if (status == 0)
+    {
+      return 1;
+    }
+
+  ERR ("Error while calling buxton_set_value: %m");
+  return -1;
+}
+
+static inline int
+_async_unset_ (keynode_t * keynode)
+{
+  int status;
+  BuxtonKey key;
+
+  assert (keynode != NULL);
+
+  if (keynode->type != type_delete)
+    {
+      return 0;
+    }
+
+  key = _get_buxton_key_ (keynode);
+  if (key == NULL)
+    {
+      return -1;
+    }
+
+  status = buxton_unset_value (_buxton_ (), key,
+                              (BuxtonCallback) _cb_inc_received_,
+                              keynode, false);
+  buxton_key_free (key);
+
+  if (status == 0)
+    {
+      return 1;
+    }
+
+  ERR ("Error while calling buxton_unset_value: %m");
+  return -1;
+}
+
+static inline int
+_async_set_or_unset_ (keynode_t * keynode, const char *unused)
+{
+  assert (keynode != NULL);
+
+  switch (keynode->type)
+    {
+    case type_unset:
+    case type_directory:
+      return 0;
+    case type_delete:
+      return _async_unset_ (keynode);
+    default:
+      return _async_set_ (keynode);
+    }
+}
+
+static inline int
+_async_refresh_ (keynode_t * keynode, const char *unused)
+{
+  int status;
+  BuxtonKey key;
+
+  assert (keynode != NULL);
+
+  switch (keynode->type)
+    {
+    case type_unset:
+    case type_string:
+    case type_int:
+    case type_double:
+    case type_bool:
+      break;
+    default:
+      return 0;
+    }
+
+  key = _get_buxton_key_ (keynode);
+  if (key == NULL)
+    {
+      return -1;
+    }
+
+  status = buxton_get_value (_buxton_ (), key,
+                            (BuxtonCallback) _cb_refresh_, keynode, false);
+  buxton_key_free (key);
+
+  if (status == 0)
+    {
+      return 1;
+    }
+
+  ERR ("Error while calling buxton_get_value: %m");
+  return -1;
+}
+
+static inline int
+_async_set_label_ (keynode_t * keynode, const char *label)
+{
+  int status;
+  BuxtonKey key;
+
+  assert (keynode != NULL);
+
+  key = _get_buxton_key_ (keynode);
+  if (key == NULL)
+    {
+      return -1;
+    }
+
+  status = buxton_set_label (_buxton_ (), key, label,
+                            (BuxtonCallback) _cb_inc_received_,
+                            keynode, false);
+  buxton_key_free (key);
+
+  if (status == 0)
+    {
+      return 1;
+    }
+
+  ERR ("Error while calling buxton_set_label: %m");
+  return -1;
+}
+
+
+static int
+_apply_buxton_on_list_ (keylist_t * keylist,
+                       int (*async) (keynode_t *, const char *),
+                       const char *data)
+{
+  keynode_t *keynode;
+  int status;
+  int sent;
+
+  assert (keylist != NULL);
+
+  status = _open_buxton_ ();
+  retvm_if (!status, VCONF_ERROR, "Can't connect to buxton");
+  assert (_buxton_ () != NULL);
+
+  retvm_if (keylist->cb_active != 0, VCONF_ERROR,
+           "Already active in vconf-buxton");
+
+  LOCK(buxton);
+
+  keylist->cb_active = 1;
+  keylist->cb_status = VCONF_OK;
+  keylist->cb_sent = 0;
+  keylist->cb_received = 0;
+
+  keynode = keylist->head;
+  status = _dispatch_buxton_ (1, 0);
+  while (keynode != NULL && status == VCONF_OK)
+    {
+      sent = async (keynode, data);
+      keynode = keynode->next;
+      if (sent < 0)
+       {
+         status = VCONF_ERROR;
+       }
+      else if (sent > 0)
+       {
+         keylist->cb_sent += sent;
+         status = _dispatch_buxton_ (1, 0);
+       }
+    }
+
+  /*
+   * get the responses 
+   */
+  while (status == VCONF_OK && keylist->cb_sent != keylist->cb_received)
+    {
+      status = _dispatch_buxton_ (0, 0);
+    }
+
+  if (status == VCONF_OK && keylist->cb_status != VCONF_OK)
+    status = keylist->cb_status;
+  keylist->cb_active = 0;
+
+  UNLOCK(buxton);
+
+  _check_close_buxton_ ();
+
+  return status;
+}
+
+/*================= SECTION notification =============*/
+
+static void
+_cb_notify_ (BuxtonResponse resp, struct notify *notif)
+{
+  switch (buxton_response_type (resp))
+    {
+    case BUXTON_CONTROL_NOTIFY:
+    case BUXTON_CONTROL_UNNOTIFY:
+      notif->status =
+       buxton_response_status (resp) == 0 ? VCONF_OK : VCONF_ERROR;
+      break;
+    case BUXTON_CONTROL_CHANGED:
+      if (_set_response_to_keynode_ (resp, notif->keynode, 1) == VCONF_OK)
+       {
+         UNLOCK (buxton);
+         notif->callback (notif->keynode, notif->userdata);
+         LOCK (buxton);
+       }
+      break;
+    default:
+      break;
+    }
+}
+
+static int
+_notify_reg_unreg_ (struct notify *notif, bool reg)
+{
+  int status;
+  BuxtonKey key;
+
+  status = _open_buxton_ ();
+  retvm_if (!status, VCONF_ERROR, "Can't connect to buxton");
+
+  LOCK(buxton);
+  key = _get_buxton_key_ (notif->keynode);
+  retvm_if (key == NULL, VCONF_ERROR, "Can't create buxton key");
+  notif->status = VCONF_OK;    /* on success calback isn't called! */
+  status =
+    (reg ? buxton_register_notification :
+     buxton_unregister_notification) (_buxton_ (), key,
+                                     (BuxtonCallback) _cb_notify_,
+                                     notif, false);
+  buxton_key_free (key);
+  UNLOCK(buxton);
+  return status == 0 && notif->status == VCONF_OK ? VCONF_OK : VCONF_ERROR;
+}
+
+#if !defined(NO_GLIB)
+/*================= SECTION glib =============*/
+
+static gboolean
+_cb_glib_ (GIOChannel * src, GIOCondition cond, gpointer data)
+{
+  _handle_buxton_response_ (1);
+  return G_SOURCE_CONTINUE;
+}
+
+static int
+_glib_start_watch_ ()
+{
+  GIOChannel *gio;
+
+  if (glib_source != NULL)
+    return VCONF_OK;
+
+  gio = g_io_channel_unix_new (the_buxton_client_fd);
+  retvm_if (gio == NULL, VCONF_ERROR, "Error: create a new GIOChannel");
+
+  g_io_channel_set_flags (gio, G_IO_FLAG_NONBLOCK, NULL);
+
+  glib_source = g_io_create_watch (gio, G_IO_IN);
+  if (glib_source == NULL)
+    {
+      ERR ("Error: create a new GSource");
+      g_io_channel_unref (gio);
+      return VCONF_ERROR;
+    }
+
+  g_source_set_callback (glib_source, (GSourceFunc) _cb_glib_, NULL, NULL);
+  g_source_attach (glib_source, NULL);
+  g_io_channel_unref (gio);
+  g_source_unref (glib_source);
+
+  return VCONF_OK;
+}
+
+static void
+_glib_stop_watch_ ()
+{
+  if (glib_source != NULL)
+    {
+      g_source_destroy (glib_source);
+      glib_source = NULL;
+    }
+}
+#endif
+
+/*================= SECTION VCONF API =============*/
+
+const char *
+vconf_keynode_get_name (keynode_t * keynode)
+{
+  retvm_if (keynode == NULL, NULL, "Invalid argument: keynode is NULL");
+  retvm_if (keynode->keyname == NULL, NULL, "The name of keynode is NULL");
+
+  return keynode->keyname;
+}
+
+int
+vconf_keynode_get_type (keynode_t * keynode)
+{
+  retvm_if (keynode == NULL,
+           VCONF_ERROR, "Invalid argument: keynode is NULL");
+
+  switch (keynode->type)
+    {
+    case type_directory:
+      return VCONF_TYPE_DIR;
+    case type_string:
+      return VCONF_TYPE_STRING;
+    case type_int:
+      return VCONF_TYPE_INT;
+    case type_double:
+      return VCONF_TYPE_DOUBLE;
+    case type_bool:
+      return VCONF_TYPE_BOOL;
+    default:
+      return VCONF_TYPE_NONE;
+    }
+}
+
+int
+vconf_keynode_get_int (keynode_t * keynode)
+{
+  retvm_if (keynode == NULL,
+           VCONF_ERROR, "Invalid argument: keynode is NULL");
+  retvm_if (keynode->type != type_int, VCONF_ERROR,
+           "The type of keynode(%s) is not INT", keynode->keyname);
+
+  return keynode->value.i;
+}
+
+double
+vconf_keynode_get_dbl (keynode_t * keynode)
+{
+  retvm_if (keynode == NULL, -1.0, "Invalid argument: keynode is NULL");
+  retvm_if (keynode->type != type_double, -1.0,
+           "The type of keynode(%s) is not DBL", keynode->keyname);
+
+  return keynode->value.d;
+}
+
+int
+vconf_keynode_get_bool (keynode_t * keynode)
+{
+  retvm_if (keynode == NULL,
+           VCONF_ERROR, "Invalid argument: keynode is NULL");
+  retvm_if (keynode->type != type_bool, VCONF_ERROR,
+           "The type of keynode(%s) is not BOOL", keynode->keyname);
+
+  return !!(keynode->value.b);
+}
+
+char *
+vconf_keynode_get_str (keynode_t * keynode)
+{
+  retvm_if (keynode == NULL, NULL, "Invalid argument: keynode is NULL");
+  retvm_if (keynode->type != type_string, NULL,
+           "The type of keynode(%s) is not STR", keynode->keyname);
+
+  return keynode->value.s;
+}
+
+int
+vconf_set_default_group (const char *groupname)
+{
+  char *copy;
+
+  copy = _dup_groupname_ (groupname);
+  if (copy == NULL)
+    return VCONF_ERROR;
+  free (default_group);
+  default_group = copy;
+  return VCONF_OK;
+}
+
+keylist_t *
+vconf_keylist_new ()
+{
+  keylist_t *result;
+  if (_ensure_default_group_ () != VCONF_OK)
+    return NULL;
+  result = calloc (1, sizeof (keylist_t));
+  LOCK (counter);
+  internal_list_count += (result != NULL);
+  UNLOCK (counter);
+  return result;
+}
+
+int
+vconf_keylist_free (keylist_t * keylist)
+{
+  keynode_t *keynode, *temp;
+
+  retvm_if (keylist == NULL,
+           VCONF_ERROR, "Invalid argument: keylist is NULL");
+
+  keynode = keylist->head;
+  free (keylist);
+  while (keynode)
+    {
+      temp = keynode->next;
+      _keynode_free_ (keynode);
+      keynode = temp;
+    }
+
+  LOCK (counter);
+  internal_list_count -= (internal_list_count > 0);
+  UNLOCK (counter);
+  _check_close_buxton_ ();
+  return 0;
+}
+
+int
+vconf_keylist_rewind (keylist_t * keylist)
+{
+  retvm_if (keylist == NULL,
+           VCONF_ERROR, "Invalid argument: keylist is NULL");
+
+  keylist->cursor = NULL;
+
+  return 0;
+}
+
+keynode_t *
+vconf_keylist_nextnode (keylist_t * keylist)
+{
+  keynode_t *result;
+
+  retvm_if (keylist == NULL, NULL, "Invalid argument: keylist is NULL");
+
+  result = keylist->cursor;
+  result = result == NULL ? keylist->head : result->next;
+  keylist->cursor = result;
+
+  return result;
+}
+
+int
+vconf_keylist_lookup (keylist_t * keylist,
+                     const char *keyname, keynode_t ** return_node)
+{
+  keynode_t *keynode;
+
+  retvm_if (keylist == NULL,
+           VCONF_ERROR, "Invalid argument: keylist is NULL");
+  retvm_if (keyname == NULL,
+           VCONF_ERROR, "Invalid argument: keyname is NULL");
+  retvm_if (return_node == NULL,
+           VCONF_ERROR, "Invalid argument: return_node is NULL");
+
+  keynode = _keylist_lookup_ (keylist, keyname, NULL);
+  if (NULL == keynode)
+    return 0;
+
+  if (return_node)
+    *return_node = keynode;
+  return keynode->type;
+}
+
+static int
+_cb_sort_keynodes (const void *a, const void *b)
+{
+  register const keynode_t *kna = *(const keynode_t **) a;
+  register const keynode_t *knb = *(const keynode_t **) b;
+  return strcmp (kna->keyname, knb->keyname);
+}
+
+int
+vconf_keylist_sort (keylist_t * keylist)
+{
+  int index;
+  keynode_t **nodes, *keynode;
+
+  retvm_if (keylist == NULL,
+           VCONF_ERROR, "Invalid argument: keylist is NULL");
+
+  if (keylist->num <= 1)
+    return VCONF_OK;
+
+  nodes = malloc (keylist->num * sizeof *nodes);
+  retvm_if (nodes == NULL, VCONF_ERROR, "can't allocate memory for sorting");
+
+  index = 0;
+  keynode = keylist->head;
+  while (keynode != NULL)
+    {
+      assert (index < keylist->num);
+      nodes[index++] = keynode;
+      keynode = keynode->next;
+    }
+  assert (index == keylist->num);
+
+  qsort (nodes, index, sizeof *nodes, _cb_sort_keynodes);
+
+  while (index)
+    {
+      nodes[--index]->next = keynode;
+      keynode = nodes[index];
+    }
+  keylist->head = keynode;
+  free (nodes);
+  return VCONF_OK;
+}
+
+int
+vconf_keylist_add_int (keylist_t * keylist, const char *keyname,
+                      const int value)
+{
+  keynode_t *keynode;
+
+  retvm_if (keylist == NULL,
+           VCONF_ERROR, "Invalid argument: keylist is NULL");
+  retvm_if (keyname == NULL,
+           VCONF_ERROR, "Invalid argument: keyname is NULL");
+
+  keynode = _keylist_getadd_ (keylist, keyname, type_int);
+  if (keynode == NULL)
+    return VCONF_ERROR;
+
+  keynode->value.i = value;
+  return keylist->num;
+}
+
+int
+vconf_keylist_add_bool (keylist_t * keylist, const char *keyname,
+                       const int value)
+{
+  keynode_t *keynode;
+
+  retvm_if (keylist == NULL,
+           VCONF_ERROR, "Invalid argument: keylist is NULL");
+  retvm_if (keyname == NULL,
+           VCONF_ERROR, "Invalid argument: keyname is NULL");
+
+  keynode = _keylist_getadd_ (keylist, keyname, type_bool);
+  if (keynode == NULL)
+    return VCONF_ERROR;
+
+  keynode->value.b = !!value;
+  return keylist->num;
+}
+
+int
+vconf_keylist_add_dbl (keylist_t * keylist,
+                      const char *keyname, const double value)
+{
+  keynode_t *keynode;
+
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is NULL");
+  retvm_if (keyname == NULL, VCONF_ERROR,
+           "Invalid argument: keyname is NULL");
+
+  keynode = _keylist_getadd_ (keylist, keyname, type_double);
+  if (keynode == NULL)
+    return VCONF_ERROR;
+
+  keynode->value.d = value;
+  return keylist->num;
+}
+
+int
+vconf_keylist_add_str (keylist_t * keylist,
+                      const char *keyname, const char *value)
+{
+  keynode_t *keynode;
+  char *copy;
+
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is NULL");
+  retvm_if (keyname == NULL, VCONF_ERROR,
+           "Invalid argument: keyname is NULL");
+
+  copy = strdup (value == NULL ? "" : value);
+  retvm_if (copy == NULL, VCONF_ERROR, "Allocation of memory failed");
+
+  keynode = _keylist_getadd_ (keylist, keyname, type_string);
+  if (keynode == NULL)
+    {
+      free (copy);
+      return VCONF_ERROR;
+    }
+
+  free (keynode->value.s);
+  keynode->value.s = copy;
+  return keylist->num;
+}
+
+int
+vconf_keylist_add_null (keylist_t * keylist, const char *keyname)
+{
+  keynode_t *keynode;
+
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is NULL");
+  retvm_if (keyname == NULL, VCONF_ERROR,
+           "Invalid argument: keyname is NULL");
+
+  keynode = _keylist_getadd_ (keylist, keyname, type_unset);
+  if (keynode == NULL)
+    return VCONF_ERROR;
+
+  return keylist->num;
+}
+
+int
+vconf_keylist_del (keylist_t * keylist, const char *keyname)
+{
+  keynode_t *keynode, **previous = NULL;
+
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is NULL");
+  retvm_if (keyname == NULL, VCONF_ERROR,
+           "Invalid argument: keyname is NULL");
+
+  keynode = _keylist_lookup_ (keylist, keyname, &previous);
+  if (keynode == NULL)
+    return VCONF_ERROR;
+
+  *previous = keynode->next;
+  keylist->num--;
+  _keynode_free_ (keynode);
+
+  return VCONF_OK;
+}
+
+int
+vconf_set (keylist_t * keylist)
+{
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is NULL");
+
+  return _apply_buxton_on_list_ (keylist, _async_set_or_unset_, NULL);
+}
+
+int
+vconf_set_labels (keylist_t * keylist, const char *label)
+{
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is NULL");
+
+  retvm_if (label == NULL, VCONF_ERROR, "Invalid argument: name is NULL");
+
+  return _apply_buxton_on_list_ (keylist, _async_set_label_, label);
+}
+
+int
+vconf_sync_key (const char *keyname)
+{
+  /*
+   * does nothing succefully 
+   */
+  return 0;
+}
+
+int
+vconf_refresh (keylist_t * keylist)
+{
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is NULL");
+
+  return _apply_buxton_on_list_ (keylist, _async_refresh_, NULL);
+}
+
+int
+vconf_scan (keylist_t * keylist, const char *dirpath, get_option_t option)
+{
+  char *dircopy;
+  struct layer_key laykey;
+  struct scanning_data data;
+  int status;
+
+  retvm_if (keylist == NULL, VCONF_ERROR,
+           "Invalid argument: keylist is null");
+  retvm_if (keylist->num != 0, VCONF_ERROR,
+           "Invalid argument: keylist not empty");
+  retvm_if (dirpath == NULL, VCONF_ERROR,
+           "Invalid argument: dirpath is null");
+  retvm_if (_check_keyname_ (dirpath) == 0, VCONF_ERROR,
+           "Invalid argument: dirpath is not valid");
+
+  status = _open_buxton_ ();
+  if (!status)
+    {
+      ERR ("Can't connect to buxton");
+      return VCONF_ERROR;
+    }
+
+  data.keylist = keylist;
+
+  switch (option)
+    {
+    case VCONF_GET_KEY:
+      data.want_directories = 0;
+      data.want_keys = 1;
+      data.is_recursive = 0;
+      break;
+    case VCONF_GET_ALL:
+      data.want_directories = 1;
+      data.want_keys = 1;
+      data.is_recursive = 0;
+      break;
+    case VCONF_GET_DIR:
+      data.want_directories = 1;
+      data.want_keys = 0;
+      data.is_recursive = 0;
+      break;
+    case VCONF_GET_KEY_REC:
+      data.want_directories = 0;
+      data.want_keys = 1;
+      data.is_recursive = 1;
+      break;
+    case VCONF_GET_ALL_REC:
+      data.want_directories = 1;
+      data.want_keys = 1;
+      data.is_recursive = 1;
+      break;
+    case VCONF_GET_DIR_REC:
+      data.want_directories = 0;
+      data.want_keys = 1;
+      data.is_recursive = 1;
+      break;
+    default:
+      ERR ("Invalid argument: Bad option value");
+      return VCONF_ERROR;
+    }
+
+  data.dirlen = strlen (dirpath);
+  assert (data.dirlen);
+  if (dirpath[data.dirlen - 1] == '/')
+    {
+      data.directory = dirpath;
+      dircopy = NULL;
+    }
+  else
+    {
+      status = asprintf (&dircopy, "%s/", dirpath);
+      retvm_if (status < 0, VCONF_ERROR,
+               "No more memory for copying dirpath");
+      data.directory = dircopy;
+      data.dirlen++;
+    }
+
+  status = _get_layer_key_ (data.directory, &laykey);
+  if (status != VCONF_OK)
+    {
+      return status;
+    }
+
+  data.prefix = laykey.prefix;
+  if (!laykey.key[0])
+    {
+      laykey.key = NULL;
+    }
+
+  data.pending = 1;
+  assert (_buxton_ () != NULL);
+  status = buxton_list_names (_buxton_ (), laykey.layer, default_group,
+                             laykey.key, (BuxtonCallback) _cb_scan_,
+                             &data, false);
+  if (!status)
+    status = _wait_buxton_response_ (&data.pending);
+
+  free (dircopy);
+
+  retvm_if (status, VCONF_ERROR, "Error while calling buxton_list_names: %m");
+  if (data.cb_status != VCONF_OK)
+    {
+      return VCONF_ERROR;
+    }
+
+  return vconf_refresh (keylist);
+}
+
+int
+vconf_get (keylist_t * keylist, const char *dirpath, get_option_t option)
+{
+  if (option == VCONF_REFRESH_ONLY
+      || (option == VCONF_GET_KEY && keylist->num != 0))
+    {
+      return vconf_refresh (keylist);
+    }
+  else
+    {
+      return vconf_scan (keylist, dirpath, option);
+    }
+}
+
+int
+vconf_unset (const char *keyname)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_delete);
+  if (status == VCONF_OK)
+    {
+      status = vconf_set (&single.list);
+    }
+  return status;
+
+}
+
+int
+vconf_exists (const char *keyname)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_unset);
+  if (status == VCONF_OK)
+    {
+      status = vconf_refresh (&single.list);
+      if (status == VCONF_OK && single.node.type == type_string)
+       free (single.node.value.s);
+    }
+  return status;
+
+}
+
+int
+vconf_unset_recursive (const char *in_dir)
+{
+  struct _keylist_t *keylist;
+  struct _keynode_t *keynode;
+  int status;
+
+  retvm_if (in_dir == NULL, VCONF_ERROR, "Invalid argument: dir is null");
+
+  keylist = vconf_keylist_new ();
+  if (keylist == NULL)
+    return VCONF_ERROR;
+
+  status = vconf_scan (keylist, in_dir, VCONF_GET_KEY_REC);
+  if (status == VCONF_OK)
+    {
+      for (keynode = keylist->head; keynode; keynode = keynode->next)
+       keynode->type = type_delete;
+      status = vconf_set (keylist);
+    }
+  vconf_keylist_free (keylist);
+  return status;
+}
+
+int
+vconf_notify_key_changed (const char *keyname, vconf_callback_fn cb,
+                         void *user_data)
+{
+  int status;
+  struct notify *notif;
+  keynode_t *keynode, *aknode;
+  keylist_t *alist;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is null");
+  retvm_if (cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
+  status = _open_buxton_ ();
+  retvm_if (!status, VCONF_ERROR, "Can't connect to buxton");
+  status = vconf_exists (keyname);
+  retvm_if (status != VCONF_OK, VCONF_ERROR, "key %s doesn't exist", keyname);
+
+
+  /*
+   * create the notification 
+   */
+  notif = malloc (sizeof *notif);
+  retvm_if (notif == NULL, VCONF_ERROR,
+           "Allocation of notify structure failed");
+
+  /*
+   * ensure existing list 
+   */
+  LOCK (notify);
+  if (notify_keylist == NULL)
+    {
+      notify_keylist = vconf_keylist_new ();
+      if (notify_keylist == NULL)
+       {
+         UNLOCK (notify);
+         free (notif);
+         return VCONF_ERROR;
+       }
+    }
+
+  /*
+   * search keynode of keyname 
+   */
+  keynode = _keylist_lookup_ (notify_keylist, keyname, NULL);
+  if (keynode == NULL)
+    {
+      /*
+       * not found, create it with type unset 
+       */
+      keynode = _keylist_add_ (notify_keylist, keyname, type_unset);
+      if (keynode == NULL)
+       {
+         UNLOCK (notify);
+         free (notif);
+         return VCONF_ERROR;
+       }
+    }
+
+  /*
+   * init the notification 
+   */
+  notif->callback = cb;
+  notif->userdata = user_data;
+  notif->keynode = keynode;
+  notif->next = notify_entries;
+  notify_entries = notif;
+  UNLOCK (notify);
+
+  /*
+   * record the notification 
+   */
+  status = _notify_reg_unreg_ (notif, true);
+  if (status != VCONF_OK)
+    {
+      vconf_ignore_key_changed (keyname, cb);
+      return VCONF_ERROR;
+    }
+
+#if !defined(NO_GLIB)
+  return _glib_start_watch_ ();
+#else
+  return VCONF_OK;
+#endif
+}
+
+int
+vconf_ignore_key_changed (const char *keyname, vconf_callback_fn cb)
+{
+  struct notify *entry, **prevent, *delent, **prevdelent;
+  keynode_t *keynode, **prevnod;
+  int fcount;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is null");
+  retvm_if (cb == NULL, VCONF_ERROR, "Invalid argument: cb(%p)", cb);
+  status = _open_buxton_ ();
+  retvm_if (!status, VCONF_ERROR, "Can't connect to buxton");
+
+  fcount = 0;
+  status = VCONF_ERROR;
+  delent = NULL;
+
+  LOCK (notify);
+  if (notify_keylist != NULL)
+    {
+      keynode = _keylist_lookup_ (notify_keylist, keyname, &prevnod);
+      if (keynode != NULL)
+       {
+         prevdelent = &delent;
+         prevent = &notify_entries;
+         entry = notify_entries;
+         while (entry != NULL)
+           {
+             if (entry->keynode == keynode)
+               {
+                 if (entry->callback == cb)
+                   {
+                     *prevdelent = entry;
+                     prevdelent = &entry->next;
+                     entry = entry->next;
+                     continue;
+                   }
+                 fcount++;
+               }
+             *prevent = entry;
+             prevent = &entry->next;
+             entry = entry->next;
+           }
+         *prevent = NULL;
+         *prevdelent = NULL;
+         if (fcount == 0)
+           *prevnod = keynode->next;
+#if !defined(NO_GLIB)
+         if (notify_entries == NULL)
+           _glib_stop_watch_ ();
+#endif
+         if (delent != NULL)
+           {
+             UNLOCK (notify);
+             while (delent != NULL)
+               {
+                 entry = delent;
+                 delent = entry->next;
+                 _notify_reg_unreg_ (entry, false);
+                 free (entry);
+               }
+             if (fcount == 0)
+               _keynode_free_ (keynode);
+             return VCONF_OK;
+           }
+       }
+    }
+  UNLOCK (notify);
+  ERR ("Not found: can't remove notification for key(%s)", keyname);
+
+  return VCONF_ERROR;
+}
+
+int
+vconf_set_int (const char *keyname, const int intval)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_int);
+  if (status == VCONF_OK)
+    {
+      single.node.value.i = intval;
+      status = vconf_set (&single.list);
+    }
+  return status;
+}
+
+int
+vconf_set_bool (const char *keyname, const int boolval)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_bool);
+  if (status == VCONF_OK)
+    {
+      single.node.value.b = (bool) boolval;
+      status = vconf_set (&single.list);
+    }
+  return status;
+}
+
+int
+vconf_set_dbl (const char *keyname, const double dblval)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_double);
+  if (status == VCONF_OK)
+    {
+      single.node.value.d = dblval;
+      status = vconf_set (&single.list);
+    }
+  return status;
+}
+
+int
+vconf_set_str (const char *keyname, const char *strval)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_string);
+  if (status == VCONF_OK)
+    {
+      single.node.value.s = (char *) strval;
+      status = vconf_set (&single.list);
+    }
+  return status;
+}
+
+int
+vconf_get_int (const char *keyname, int *intval)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_int);
+  if (status == VCONF_OK)
+    {
+      status = vconf_refresh (&single.list);
+      if (status == VCONF_OK)
+       *intval = single.node.value.i;
+    }
+  return status;
+}
+
+int
+vconf_set_label (const char *keyname, const char *label)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  retvm_if (label == NULL, VCONF_ERROR, "Invalid argument: name is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_unset);
+  if (status == VCONF_OK)
+    {
+      status = vconf_set_labels (&single.list, label);
+    }
+  return status;
+}
+
+int
+vconf_get_bool (const char *keyname, int *boolval)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_bool);
+  if (status == VCONF_OK)
+    {
+      status = vconf_refresh (&single.list);
+      if (status == VCONF_OK)
+       *boolval = (int) single.node.value.b;
+    }
+  return status;
+}
+
+int
+vconf_get_dbl (const char *keyname, double *dblval)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, VCONF_ERROR, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_double);
+  if (status == VCONF_OK)
+    {
+      status = vconf_refresh (&single.list);
+      if (status == VCONF_OK)
+       *dblval = single.node.value.d;
+    }
+  return status;
+}
+
+char *
+vconf_get_str (const char *keyname)
+{
+  struct singleton single;
+  int status;
+
+  retvm_if (keyname == NULL, NULL, "Invalid argument: key is NULL");
+
+  status = _keylist_init_singleton_ (&single, keyname, type_string);
+  if (status != VCONF_OK)
+    return NULL;
+
+  single.node.value.s = NULL;
+  status = vconf_refresh (&single.list);
+  if (status != VCONF_OK)
+    return NULL;
+
+  return single.node.value.s;
+}
diff --git a/src/vconf-buxton.h b/src/vconf-buxton.h
new file mode 100644 (file)
index 0000000..1b639bb
--- /dev/null
@@ -0,0 +1,976 @@
+/*
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * Author: José Bollo <jose.bollo@open.eurogiciel.org>
+ * Author: Hakjoo Ko <hakjoo.ko@samsung.com>
+ *
+ * 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 __VCONF_BUXTON_H__
+#define __VCONF_BUXTON_H__
+
+#define VCONF_BUXTON  "1.0"
+
+/**
+ * @addtogroup APPLICATION_FRAMEWORK
+ * @{
+ *
+ * @defgroup    VCONF VConf
+ * @author      Sangjung Woo (sangjung.woo@samsung.com)
+ * @version     0.2
+ * @brief       A library for reading/writing Configuration Data
+ *
+ * @section Header To use Them:
+ * @code
+ * #include <vconf.h>
+ * @endcode
+ *
+ * @section Properties
+ * - Convenient API
+ * - Guarantee Transaction(db backend only)
+ * - Apply Key-List concept
+ * - Changeable Backend
+ * - Simple Notification based on inotify
+ *
+ * @section Backend key has below backend.
+ * - db => use libsqlfs ex) db/a/b
+ * \n Lowest speed, highest robustness, correctly sync
+ * - memory => use tmpfs ex) memory/a/b
+ * \n Highest speed, volitile
+ * - file => use basic file system(not support atomicity) ex) file/a/b
+ * \n Higher speed, lower robustness(Not guarantee atomicity)
+ *
+ * @section example Simple Example
+ * @code
+ #include <stdio.h>
+ #include <vconf.h>
+
+ const char *key1_name="db/test/key1";
+
+ int main(int argc, char **argv)
+ {
+   int key1_value;
+
+   if(vconf_set_int(key1_name,1))
+      fprintf(stderr, "vconf_set_int FAIL\n");
+   else
+      printf("vconf_set_int OK\n");
+
+   if(vconf_get_int(key1_name, &key1_value))
+      fprintf(stderr, "vconf_get_int FAIL\n");
+   else
+      printf("vconf_get_int OK(key1 value is %d)\n", key1_value);
+
+   return 0;
+ }
+ * @endcode
+ *
+ */
+
+/**
+ * @addtogroup VCONF
+ * @{
+ */
+
+#include "vconf-buxton-keys.h"
+
+#ifdef __cplusplus
+extern          "C" {
+#endif
+
+/**
+ * VCONF_GET_KEY, VCONF_GET_ALL, VCONF_GET_DIR
+ * \n Use for vconf_get()
+ * @see vconf_get()
+ */
+    enum get_option_t {
+       VCONF_GET_KEY = 0,
+           /**< get only keys */
+       VCONF_GET_ALL,
+           /**< get keys and directorys */
+       VCONF_GET_DIR,
+          /**< get only directorys */
+       VCONF_REFRESH_ONLY,
+           /**< get only keys */
+       VCONF_GET_KEY_REC,
+           /**< get only keys recursively */
+       VCONF_GET_ALL_REC,
+           /**< get keys and directorys recursively */
+       VCONF_GET_DIR_REC
+          /**< get only directorys recursively */
+    };
+
+    typedef enum get_option_t get_option_t;
+
+    enum vconf_t {
+       VCONF_TYPE_NONE = 0,
+                  /**< Vconf none type for Error detection */
+       VCONF_TYPE_STRING = 40,
+                  /**< Vconf string type */
+       VCONF_TYPE_INT = 41,
+                  /**< Vconf integer type */
+       VCONF_TYPE_DOUBLE = 42,
+                  /**< Vconf double type */
+       VCONF_TYPE_BOOL = 43,
+                  /**< Vconf boolean type */
+       VCONF_TYPE_DIR
+                  /**< Vconf directory type */
+    };
+
+
+/**
+ * keynode_t is an opaque type, it must be
+ * used via accessor functions.
+ * @see vconf_keynode_get_name(), vconf_keynode_get_type()
+ * @see vconf_keynode_get_bool(), vconf_keynode_get_dbl(), vconf_keynode_get_int(), vconf_keynode_get_str()
+ */
+    typedef struct _keynode_t keynode_t;
+
+/**
+ * keylist_t is an opaque type, it must be
+ * used via accessor functions.
+ * @see vconf_keylist_new(), vconf_keylist_free()
+ * @see vconf_keylist_add_bool(),vconf_keylist_add_str(), vconf_keylist_add_dbl(), vconf_keylist_add_int()
+ * @see vconf_keylist_del(), vconf_keylist_add_null()
+ * @see vconf_keylist_lookup(), vconf_keylist_nextnode(), vconf_keylist_rewind()
+ */
+    typedef struct _keylist_t keylist_t;
+
+
+/**
+ * This is the signature of a callback function added with vconf_notify_key_changed().
+ * \n The callback function is invoked when the key is set.
+ * @see keynode_t
+ */
+    typedef void    (*vconf_callback_fn) (keynode_t * node,
+                                         void *user_data);
+
+/************************************************
+ * keynode handling APIs                        *
+ ************************************************/
+
+/**
+ * This function gets Key name of the keynode.
+ * @param[in] keynode The Key
+ * @return Key Name of the keynode
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_notify_key_changed(), vconf_keynode_get_bool, vconf_keynode_get_type, vconf_keynode_get_str, vconf_keynode_get_int, vconf_keynode_get_dbl, keynode_t, vconf_t
+ */
+    const char     *vconf_keynode_get_name(keynode_t * keynode);
+
+/**
+ * This function gets value type of the keynode.
+ * @param[in] keynode The Key
+ * @return Type of the keynode
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_notify_key_changed(), vconf_keynode_get_name, vconf_keynode_get_bool, vconf_keynode_get_str, vconf_keynode_get_int, vconf_keynode_get_dbl, keynode_t, vconf_t
+ */
+    int             vconf_keynode_get_type(keynode_t * keynode);
+
+/**
+ * This function gets Integer value of the keynode.
+ * @param[in] keynode The Key
+ * @return Integer value, or 0 if no value is obtained
+ ** @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_notify_key_changed(), vconf_keynode_get_name, vconf_keynode_get_bool, vconf_keynode_get_type, vconf_keynode_get_str, vconf_keynode_get_dbl, keynode_t, vconf_t
+ */
+    int             vconf_keynode_get_int(keynode_t * keynode);
+
+/**
+ * This function gets Double value of the keynode.
+ * @param[in] keynode The Key
+ * @return Double value, or 0.0 if no value is obtained
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_notify_key_changed(), vconf_keynode_get_name, vconf_keynode_get_bool, vconf_keynode_get_type, vconf_keynode_get_str, vconf_keynode_get_int, keynode_t, vconf_t
+ */
+    double          vconf_keynode_get_dbl(keynode_t * keynode);
+
+/**
+ * This function gets Boolean value of the keynode.
+ * @param[in] keynode The Key
+ * @return Boolean value, -1 on error (Integer value 1 is 'True', and 0 is 'False')
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_notify_key_changed(), vconf_keynode_get_name, vconf_keynode_get_type, vconf_keynode_get_str, vconf_keynode_get_int, vconf_keynode_get_dbl, keynode_t, vconf_t
+ */
+    int             vconf_keynode_get_bool(keynode_t * keynode);
+
+/**
+ * This function gets String value of the keynode.
+ * @param[in] keynode The Key
+ * @return String value, or NULL if no value is obtained
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_notify_key_changed(), vconf_keynode_get_name, vconf_keynode_get_bool, vconf_keynode_get_type, vconf_keynode_get_int, vconf_keynode_get_dbl, keynode_t, vconf_t
+ */
+    char           *vconf_keynode_get_str(keynode_t * keynode);
+
+
+/************************************************
+ * keylist handling APIs
+ ************************************************/
+
+/**
+ * Set the default group of key lists created using vconf_keylist_new.
+ * @param[in] groupname The name of the default group to bind to
+ * @return 0 in case of success or -1 in case of error of allocation
+ * @see vconf_keylist_new()
+ */
+    int             vconf_set_default_group(const char *groupname);
+
+/**
+ * Allocate, initialize and return a new Keylist object bound to the default group.
+ * Return value keylist_t* pointer must be relised by calling vconf_keylist_free()
+ * @return The pointer of New keylist, NULL on error
+ * @pre None
+ * @post None
+ * @see vconf_set(), vconf_get(), vconf_keylist_create(), vconf_keylist_free(), vconf_set_default_group()
+ */
+    keylist_t      *vconf_keylist_new(void);
+
+/**
+ * A destructor for Keylist objects.<br>
+ * After calling vconf_keylist_new(), developer have to call this function for release internal memory.
+ * @param[in] keylist Key List
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_new()
+ */
+    int             vconf_keylist_free(keylist_t * keylist);
+
+/**
+ * This function moves the current Keynode position to the first items.
+ * @param[in] keylist Key List
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_nextnode(), vconf_keylist_rewind(), vconf_keylist_nextnode()
+ * @par example
+ * @code
+    int r =0;
+    keylist_t* pKeyList = NULL;
+    pKeyList = vconf_keylist_new();
+
+    r = vconf_get(pKeyList, KEY_PARENT, VCONF_GET_KEY);
+    if (r) {
+       tet_infoline("vconf_get() failed in positive test case");
+       tet_result(TET_FAIL);
+       return;
+    }
+
+    vconf_keylist_nextnode(pKeyList);
+    vconf_keylist_nextnode(pKeyList);
+
+    // Move first position from KeyList
+    r = vconf_keylist_rewind(pKeyList);
+    if (r<0) {
+       tet_infoline("vconf_keylist_rewind() failed in positive test case");
+       tet_result(TET_FAIL);
+       return;
+    }
+
+    while(vconf_keylist_nextnode(pKeyList)) ;
+ * @endcode
+ */
+    int             vconf_keylist_rewind(keylist_t * keylist);
+
+/**
+ * This function looks for a Keynode contained in keylist that matches keyname.
+ * @param[in] keylist Key List
+ * @param[in] keyname Key to find
+ * @param[out] return_node pointer of keynode to set
+ * @return Type of the found key that is vconf_t enumeration value
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), keynode_t, vconf_t
+ * @par example
+ * @code
+#include <stdio.h>
+#include <vconf.h>
+
+int main()
+{
+       int r = 0;
+       int nResult = 0;
+       keylist_t* pKeyList = NULL;
+       keynode_t *pKeyNode;
+
+       pKeyList = vconf_keylist_new();
+       r = vconf_get(pKeyList, KEY_PARENT, VCONF_GET_KEY);
+       if (r<0) {
+               printf("vconf_get() failed in positive test case");
+               return -1;
+       }
+
+       r = vconf_keylist_lookup(pKeyList, KEY_02, &pKeyNode);
+       if (r<0) {
+               printf("vconf_get() failed in positive test case");
+               return -1;
+       }
+
+       nResult = vconf_keynode_get_int(pKeyNode);
+       if(nResult !=KEY_02_INT_VALUE)
+       {
+               printf("vconf_get() failed in positive test case");
+               return -1;
+
+       }
+
+       vconf_keylist_free(pKeyList);
+       return 0;
+}
+ * @endcode
+ */
+    int             vconf_keylist_lookup(keylist_t * keylist,
+                                        const char *keyname,
+                                        keynode_t ** return_node);
+
+/**
+ * This function returns the next Key in a Keylist.
+ * Next key is known by the keylist internal cursor.
+ * @param[in] keylist Key List
+ * @return The next Keynode, NULL on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_rewind(), vconf_keylist_nextnode(), keynode_t
+ */
+    keynode_t      *vconf_keylist_nextnode(keylist_t * keylist);
+
+/**
+ * This function sorts the list in alphabetical order (with LANG=C)
+ * @param[in] keylist Key List
+ * @return 0 if done, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ */
+    int             vconf_keylist_sort(keylist_t * keylist);
+
+/**
+ * This function appends a new Keynode included integer value to the keylist.
+ * \n If same keyname exist, the keynode will change.
+ * @param[in] keylist Key List
+ * @param[in] keyname Key
+ * @param[in] value The integer value
+ * @return Number of keynode included in the keylist, -1 on error
+ * @see vconf_set(), vconf_get()
+ */
+    int             vconf_keylist_add_int(keylist_t * keylist,
+                                         const char *keyname,
+                                         const int value);
+
+/**
+ * This function appends a new Keynode included boolean value to the keylist.
+ * \n If same keyname exist, the keynode will change.
+ * @param[in] keylist Key List
+ * @param[in] keyname Key
+ * @param[in] value The boolean value
+ * @return Number of keynode included in the keylist, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_add_int(), vconf_keylist_add_str(), vconf_keylist_add_dbl(), vconf_keylist_add_bool(), vconf_keylist_del(), vconf_keylist_add_null()
+ */
+    int             vconf_keylist_add_bool(keylist_t * keylist,
+                                          const char *keyname,
+                                          const int value);
+
+/**
+ * This function appends a new Keynode included double value to the keylist.
+ * \n If same keyname exist, the keynode will change.
+ * @param[in] keylist Key List
+ * @param[in] keyname Key
+ * @param[in] value The double value
+ * @return Number of keynode included in the keylist, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_add_int(), vconf_keylist_add_str(), vconf_keylist_add_dbl(), vconf_keylist_add_bool(), vconf_keylist_del(), vconf_keylist_add_null()
+ */
+    int             vconf_keylist_add_dbl(keylist_t * keylist,
+                                         const char *keyname,
+                                         const double value);
+
+/**
+ * This function appends a new Keynode included string value to the keylist.
+ * \n If same keyname exist, the keynode will change.
+ * @param[in] keylist Key List
+ * @param[in] keyname Key
+ * @param[in] value The pointer of string value
+ * @return Number of keynode included in the keylist, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_add_int(), vconf_keylist_add_str(), vconf_keylist_add_dbl(), vconf_keylist_add_bool(), vconf_keylist_del(), vconf_keylist_add_null()
+ */
+    int             vconf_keylist_add_str(keylist_t * keylist,
+                                         const char *keyname,
+                                         const char *value);
+
+/**
+ * This function Appends a new Keynode to the keylist without value.
+ * \n Use for vconf_get()
+ * @param[in] keylist Key List
+ * @param[in] keyname Key
+ * @return Number of keynode included in the keylist, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_add_int(), vconf_keylist_add_str(), vconf_keylist_add_dbl(), vconf_keylist_add_bool(), vconf_keylist_del(), vconf_keylist_add_null()
+ */
+    int             vconf_keylist_add_null(keylist_t * keylist,
+                                          const char *keyname);
+
+/**
+ * This function removes the keynode that matches keyname.
+ * @param[in] keylist the keylist included the keyname
+ * @param[in] keyname key
+ * @return 0 on success, -1(Invalid parameter), -2(Not exist keyname in keylist) on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_add_int(), vconf_keylist_add_str(), vconf_keylist_add_dbl(), vconf_keylist_add_bool(), vconf_keylist_del(), vconf_keylist_add_null()
+ */
+    int             vconf_keylist_del(keylist_t * keylist,
+                                     const char *keyname);
+
+/************************************************
+ * setting APIs                                 *
+ ************************************************/
+
+/**
+ * This function sets the keys included in keylist.
+ * \n If you use db backend, keylist is handled as one transaction.
+ * @param[in] keylist the keylist which should contain changed keys
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set(), vconf_get(), vconf_keylist_add_int(), vconf_keylist_add_str(), vconf_keylist_add_dbl(), vconf_keylist_add_bool(), vconf_keylist_del(), vconf_keylist_add_null()
+ * @par example
+ * @code
+#include <stdio.h>
+#include <vconf.h>
+
+int main()
+{
+   keylist_t *kl=NULL;
+   const char *keyname_list[3]={"db/test/key1", "db/test/key2", "db/test/key3"};
+
+   // Transaction Test(all or nothing is written)
+   kl = vconf_keylist_new();
+
+   vconf_keylist_add_int(kl, keyname_list[0], 1);
+   vconf_keylist_add_str(kl, keyname_list[1], "transaction Test");
+   vconf_keylist_add_dbl(kl, keyname_list[2], 0.3);
+   if(vconf_set(kl))
+      fprintf(stderr, "nothing is written\n");
+   else
+      printf("everything is written\n");
+
+   vconf_keylist_free(kl);
+
+   // You can set items which have different backend.
+   kl = vconf_keylist_new();
+
+   vconf_keylist_add_int(kl, "memory/a/xxx1", 4);
+   vconf_keylist_add_str(kl, "file/a/xxx2", "test 3");
+   vconf_keylist_add_dbl(kl, "db/a/xxx3", 0.3);
+   vconf_set(kl)
+
+   vconf_keylist_free(kl);
+   return 0;
+}
+ * @endcode
+ */
+    int             vconf_set(keylist_t * keylist);
+
+/**
+ * This function sets the integer value of given key.
+ * @param[in]  keyname key
+ * @param[in]  intval integer value to set (0 is also allowed as a value.)
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set_bool(), vconf_set_dbl(), vconf_set_str()
+ */
+    int             vconf_set_int(const char *keyname, const int intval);
+
+/**
+ * This function sets the boolean value of given key.
+ * @param[in]  keyname key
+ * @param[in]  boolval boolean value(1 or 0) to set.  (Integer value 1 is 'True', and 0 is 'False')
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set_int(), vconf_set_dbl(), vconf_set_str()
+ * @par example
+ * @code
+#include <stdio.h>
+#include <vconf.h>
+
+ const char *key1_name="memory/test/key1";
+
+ int main(int argc, char **argv)
+ {
+   int key1_value;
+
+   if(vconf_set_bool(key1_name, 1))
+      fprintf(stderr, "vconf_set_bool FAIL\n");
+   else
+      printf("vconf_set_bool OK\n");
+
+   if(vconf_get_bool(key1_name, &key1_value))
+      fprintf(stderr, "vconf_get_bool FAIL\n");
+   else
+      printf("vconf_get_bool OK(key1 value is %d)\n", key1_value);
+
+   return 0;
+ }
+ * @endcode
+ */
+    int             vconf_set_bool(const char *keyname, const int boolval);
+
+/**
+ * This function sets the double value of given key.
+ * @param[in]  keyname key
+ * @param[in]  dblval double value to set (0.0 is also allowed as a value.)
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set_int(), vconf_set_bool(), vconf_set_str()
+ */
+    int             vconf_set_dbl(const char *keyname,
+                                 const double dblval);
+
+/**
+ * This function sets the string value of given key.
+ * @param[in]  keyname key
+ * @param[in]  strval string value to set
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_set_bool(), vconf_set_dbl(), vconf_set_int()
+ */
+    int             vconf_set_str(const char *keyname, const char *strval);
+
+/************************************************
+ * setting label APIs                           *
+ ************************************************/
+
+/**
+ * This function set the smack label of its keys
+ * @param[in] keylist Key List
+ * @param[in] label The label to set
+ * @return 0 if done, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ */
+    int             vconf_set_labels(keylist_t * keylist, const char *label);
+
+/**
+ * This function set the smack label of its keys
+ * @param[in] keylist Key List
+ * @param[in] label The label to set
+ * @return 0 if done, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ */
+    int             vconf_set_label(const char *keyname, const char *label);
+
+/************************************************
+ * getting APIs                                 *
+ ************************************************/
+
+/**
+ * This function reads the database to refresh the values of
+ * the keys in 'keylist'.
+ * @param[in]  keylist the keylist whose values have to be refreshed
+ * @return 0 on success, -1 on error
+ * @see vconf_keylist_lookup, vconf_keylist_nextnode, vconf_keylist_rewind
+ */
+    int             vconf_refresh(keylist_t * keylist);
+
+/**
+ * This function retrieves the keys or subdirectory in in_parentDIR.<br>
+ * @param[in]  keylist keylist created by vconf_keylist_new(), MUST be empty
+ * @param[in]  in_parentDIR parent DIRECTORY of needed keys
+ * @param[in]  option VCONF_GET_KEY|VCONF_GET_DIR|VCONF_GET_ALL|VCONF_GET_KEY_REC|VCONF_GET_DIR_REC|VCONF_GET_ALL_REC
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remkar None
+ * @par example
+ * @code
+#include <stdio.h>
+#include <vconf.h>
+
+int main()
+{
+   keylist_t *kl=NULL;
+   keynode_t *temp_node;
+   const char *vconfkeys1="db/test/key1";
+   const char *parent_dir="db/test";
+
+   kl = vconf_keylist_new();
+   if(vconf_scan(kl, parent_dir, VCONF_GET_KEY))
+      fprintf(stderr, "vconf_get FAIL(%s)", vconfkeys1);
+   else
+      printf("vconf_get OK(%s)", vconfkeys1);
+
+   while((temp_node = vconf_keylist_nextnode(kl))) {
+      switch(vconf_keynode_get_type(temp_node)) {
+       case VCONF_TYPE_INT:
+               printf("key = %s, value = %d\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_int(temp_node));
+               break;
+       case VCONF_TYPE_BOOL:
+               printf("key = %s, value = %d\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_bool(temp_node));
+               break;
+       case VCONF_TYPE_DOUBLE:
+               printf("key = %s, value = %f\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_dbl(temp_node));
+               break;
+       case VCONF_TYPE_STRING:
+               printf("key = %s, value = %s\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_str(temp_node));
+               break;
+       default:
+               printf("Unknown Type\n");
+      }
+   }
+   vconf_keylist_free(kl);
+}
+ * @endcode
+ */
+    int             vconf_scan(keylist_t * keylist,
+                              const char *in_parentDIR,
+                              get_option_t option);
+
+/**
+ * This function get the keys or subdirectory in in_parentDIR.<br>
+ * If keylist has any key information, vconf only retrieves the keys.<br>
+ * @param[in]  keylist keylist created by vconf_keylist_new()
+ * @param[in]  in_parentDIR parent DIRECTORY of needed keys
+ * @param[in]  option VCONF_GET_KEY|VCONF_GET_DIR|VCONF_GET_ALL|VCONF_REFRESH_ONLY|VCONF_GET_KEY_REC|VCONF_GET_DIR_REC|VCONF_GET_ALL_REC
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remkar None
+ * @par example
+ * @code
+#include <stdio.h>
+#include <vconf.h>
+
+int main()
+{
+   keylist_t *kl=NULL;
+   keynode_t *temp_node;
+   const char *vconfkeys1="db/test/key1";
+   const char *parent_dir="db/test";
+
+   kl = vconf_keylist_new();
+   if(vconf_get(kl, parent_dir, VCONF_GET_KEY))
+      fprintf(stderr, "vconf_get FAIL(%s)", vconfkeys1);
+   else
+      printf("vconf_get OK(%s)", vconfkeys1);
+
+   while((temp_node = vconf_keylist_nextnode(kl))) {
+      switch(vconf_keynode_get_type(temp_node)) {
+       case VCONF_TYPE_INT:
+               printf("key = %s, value = %d\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_int(temp_node));
+               break;
+       case VCONF_TYPE_BOOL:
+               printf("key = %s, value = %d\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_bool(temp_node));
+               break;
+       case VCONF_TYPE_DOUBLE:
+               printf("key = %s, value = %f\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_dbl(temp_node));
+               break;
+       case VCONF_TYPE_STRING:
+               printf("key = %s, value = %s\n",
+                       vconf_keynode_get_name(temp_node), vconf_keynode_get_str(temp_node));
+               break;
+       default:
+               printf("Unknown Type\n");
+      }
+   }
+   vconf_keylist_free(kl);
+}
+ * @endcode
+ */
+    int             vconf_get(keylist_t * keylist,
+                             const char *in_parentDIR,
+                             get_option_t option);
+
+/**
+ * This function get the integer value of given key.
+ *
+ * @param[in]  keyname key
+ * @param[out] intval output buffer
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remkar None
+ * @see vconf_get_bool, vconf_get_dbl, vconf_get_str
+ * @par example
+ * @code
+#include <stdio.h>
+#include <vconf.h>
+
+const char *key1_name="db/test/key1";
+
+int main(int argc, char **argv)
+{
+   int key1_value;
+
+   if(vconf_set_int(key1_name,1))
+      fprintf(stderr, "vconf_set_int FAIL\n");
+   else
+      printf("vconf_set_int OK\n");
+
+   if(vconf_get_int(key1_name, &key1_value))
+      fprintf(stderr, "vconf_get_int FAIL\n");
+   else
+      printf("vconf_get_int OK(key1 value is %d)\n", key1_value);
+
+   return 0;
+}
+ * @endcode
+ */
+    int             vconf_get_int(const char *keyname, int *intval);
+
+/**
+ * This function get the boolean value(1 or 0) of given key.
+ * @param[in]  keyname key
+ * @param[out] boolval output buffer
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_get_int(), vconf_get_dbl(), vconf_get_str()
+ */
+    int             vconf_get_bool(const char *keyname, int *boolval);
+
+/**
+ * This function get the double value of given key.
+ * @param[in]  keyname key
+ * @param[out] dblval output buffer
+ * @return 0 on success, -1 on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_get_int(), vconf_get_bool(), vconf_get_str()
+ */
+    int             vconf_get_dbl(const char *keyname, double *dblval);
+
+/**
+ * This function gets the string value of given key.
+ * \n You have to free this returned value.
+ * @param[in]  keyname key
+ * @return allocated pointer of key value on success, NULL on error
+ * @pre None
+ * @post None
+ * @remarks None
+ * @see vconf_get_int(), vconf_get_dbl(), vconf_get_bool()
+ * @par example
+ * @code
+   #include <stdio.h>
+   #include <vconf.h>
+
+   char *get_str=vconf_get_str("db/test/test1");
+   if(get_str) {
+      printf("vconf_get_str OK(value = %s)", get_str);
+      free(get_str);
+   }else
+      fprintf(stderr, "vconf_get_str FAIL");
+ * @endcode
+ */
+    char           *vconf_get_str(const char *keyname);
+
+/**
+ * This function deletes given key from backend system.
+ * @param[in]  keyname key
+ * @return 0 on success, -1 on error
+ */
+    int             vconf_unset(const char *keyname);
+
+/**
+ * This function checks if the given key exists from backend system.
+ * @param[in]  keyname key
+ * @return 0 on success: exists, -1 on error or not existing
+ */
+    int             vconf_exists(const char *keyname);
+
+/**
+ * This function synchronizes the given key(only file backend) with storage device.
+ * @param[in]  keyname key
+ * @return 0 on success, -1 on error
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @par example
+ * @code
+ if(vconf_set_int("file/test/key1",1))
+    fprintf(stderr, "vconf_set_int FAIL\n");
+ else {
+    printf("vconf_set_int OK\n");
+    vconf_sync_key("file/test/key1");
+ }
+ * @endcode
+ */
+    int             vconf_sync_key(const char *keyname);
+
+/**
+ * This function deletes all keys and directories below given Directory from backend system.
+ * @param[in]  in_dir  Directory name for removing
+ * @return 0 on success, -1 on error
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @par example
+ * @code
+   vconf_set_int("db/test/key1",1);
+   vconf_set_int("db/test/test1/key1",1);
+   vconf_set_int("db/test/test2/key1",1);
+   vconf_set_int("db/test/key2",1);
+
+   if(vconf_unset_recursive("db/test"))
+      fprintf(stderr, "vconf_unset_recursive FAIL\n");
+   else
+      printf("vconf_unset_recursive OK(deleted db/test\n");
+
+ * @endcode
+ */
+    int             vconf_unset_recursive(const char *in_dir);
+
+/**
+ * This function adds a change callback for given key,
+ * which is called when the key is set or unset.
+ * \n Information(#keynode_t) of the key that changed is delivered to #vconf_callback_fn,
+ * or if the key is deleted, the @link #keynode_t keynode @endlink has #VCONF_TYPE_NONE as type.
+ * \n Multiple vconf_callback_fn functions may exist for one key.
+ * \n The callback is issued in the context of the glib main loop.
+ * \n WARNING: This callback mechanism DOES NOT GUARANTEE consistency of data chage. For example,
+ * When you have a callback for a certain key, assume that two or more processes are trying to
+ * change the value of the key competitively. In this case, your callback function will always
+ * get 'CURRENT' value, not the value raised the notify that caused run of the callback.  So,
+ * do not use vconf callback when competitive write for a key is happening. In such case, use
+ * socket-based IPC(dbus or something else) instead.
+ *
+ * @param[in]   keyname  key
+ * @param[in]   cb      callback function
+ * @param[in]   user_data    callback data
+ * @return 0 on success, -1 on error
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_ignore_key_changed
+ * @par example
+ * @code
+ void test_cb(keynode_t *key, void* data)
+ {
+    switch(vconf_keynode_get_type(key))
+    {
+       case VCONF_TYPE_INT:
+       printf("key = %s, value = %d(int)\n",
+               vconf_keynode_get_name(key), vconf_keynode_get_int(key));
+       break;
+       case VCONF_TYPE_BOOL:
+       printf("key = %s, value = %d(bool)\n",
+               vconf_keynode_get_name(key), vconf_keynode_get_bool(key));
+       break;
+       case VCONF_TYPE_DOUBLE:
+       printf("key = %s, value = %f(double)\n",
+               vconf_keynode_get_name(key), vconf_keynode_get_dbl(key));
+       break;
+       case VCONF_TYPE_STRING:
+       printf("key = %s, value = %s(string)\n",
+               vconf_keynode_get_name(key), vconf_keynode_get_str(key));
+       break;
+       default:
+       fprintf(stderr, "Unknown Type(%d)\n", vconf_keynode_get_type(key));
+       break;
+    }
+    return;
+ }
+
+ int main()
+ {
+    int i;
+    GMainLoop *event_loop;
+
+    g_type_init();
+
+    vconf_notify_key_changed("db/test/test1", test_cb, NULL);
+
+    event_loop = g_main_loop_new(NULL, FALSE);
+    g_main_loop_run(event_loop);
+
+    vconf_ignore_key_changed("db/test/test1", test_cb);
+    return 0;
+ }
+ * @endcode
+ */
+    int             vconf_notify_key_changed(const char *keyname,
+                                            vconf_callback_fn cb,
+                                            void *user_data);
+
+/**
+ * This function removes a change callback for given key,
+ * which was added by vconf_notify_key_changed().
+ * @param[in]   keyname  key
+ * @param[in]   cb      callback function
+ * @return 0 on success, -1 on error
+ * @pre Nome
+ * @post None
+ * @remarks None
+ * @see vconf_notify_key_changed()
+ */
+    int             vconf_ignore_key_changed(const char *keyname,
+                                            vconf_callback_fn cb);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @} @}
+ */
+#endif                         /* __VCONF_BUXTON_H__ */
diff --git a/src/vconf-buxton.pc.in b/src/vconf-buxton.pc.in
new file mode 100644 (file)
index 0000000..b107382
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: vconf-buxton
+Description: configuration system library
+Version: @VERSION@
+Libs: -L${libdir} -lvconf-buxton -lpthread
+Cflags: -I${includedir}
diff --git a/src/vconf-buxton.sym b/src/vconf-buxton.sym
new file mode 100644 (file)
index 0000000..423f3ff
--- /dev/null
@@ -0,0 +1,44 @@
+VCONF_BUXTON_1.0 {
+       global:
+               vconf_keynode_get_name;
+               vconf_keynode_get_type;
+               vconf_keynode_get_int;
+               vconf_keynode_get_dbl;
+               vconf_keynode_get_bool;
+               vconf_keynode_get_str;
+               vconf_set_default_group;
+               vconf_keylist_new;
+               vconf_keylist_free;
+               vconf_keylist_lookup;
+               vconf_keylist_rewind;
+               vconf_keylist_nextnode;
+               vconf_keylist_sort;
+               vconf_keylist_add_int;
+               vconf_keylist_add_bool;
+               vconf_keylist_add_dbl;
+               vconf_keylist_add_str;
+               vconf_keylist_add_null;
+               vconf_keylist_del;
+               vconf_set;
+               vconf_set_int;
+               vconf_set_bool;
+               vconf_set_dbl;
+               vconf_set_str;
+               vconf_refresh;
+               vconf_scan;
+               vconf_get;
+               vconf_get_int;
+               vconf_get_bool;
+               vconf_get_dbl;
+               vconf_get_str;
+               vconf_unset;
+               vconf_sync_key;
+               vconf_unset_recursive;
+               vconf_notify_key_changed;
+               vconf_ignore_key_changed;
+               vconf_set_label;
+               vconf_set_labels;
+       local:
+               *;
+};
+