--- /dev/null
+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)
--- /dev/null
+
+ 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.
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+# 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
+
--- /dev/null
+
+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})
+
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
+
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+#!/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
+
--- /dev/null
+[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
+
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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 = ¬ify_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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+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}
--- /dev/null
+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:
+ *;
+};
+