同步主线代码
This commit is contained in:
parent
26b5d64117
commit
c818bcb574
|
@ -186,6 +186,7 @@ Package: libkysdk-conf2-tools
|
|||
Architecture: any
|
||||
Section: utils
|
||||
Depends: libkysdk-conf2 (= ${binary:Version}),
|
||||
python3-tk,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Multi-Arch: same
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
usr/bin/kconf2 usr/bin
|
||||
usr/bin/kconf2-editor usr/bin
|
||||
src/conf2/tools/gschema_xml2yaml.py usr/bin
|
||||
src/conf2/tools/kconf2-editor usr/bin
|
||||
src/conf2/tools/health-check usr/bin
|
||||
src/conf2/tools/gschema_xml2yaml usr/bin
|
||||
|
|
|
@ -3,10 +3,23 @@ src/conf2/service/conf2Utils.py usr/bin
|
|||
src/conf2/service/conf2-server.py usr/bin
|
||||
src/conf2/service/kysdk-conf2.conf etc/dbus-1/system.d
|
||||
src/conf2/service/kysdk-conf2.service lib/systemd/system
|
||||
src/conf2/service/conf2-session-server.py usr/bin
|
||||
src/conf2/service/kysdk-conf2.desktop etc/xdg/autostart/
|
||||
src/conf2/configs/conf2.yaml etc/kylin-config/
|
||||
|
||||
# dbus control
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit etc/dbus-1/conf
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit usr/share/dbus-1/conf
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit.verify etc/dbus-1/conf
|
||||
src/conf2/service/com.kylin.kysdk.conf2.limit.verify usr/share/dbus-1/conf
|
||||
src/conf2/service/conf2-session-server.py usr/bin
|
||||
src/conf2/service/kysdk-conf2.desktop etc/xdg/autostart/
|
||||
src/conf2/configs/conf2.yaml etc/kylin-config/
|
||||
|
||||
# sync-config
|
||||
bin/sync-config-system usr/bin
|
||||
src/conf2/sync-config/com.kylin.kysdk.SyncConfig.conf etc/dbus-1/system.d
|
||||
src/conf2/sync-config/com.kylin.kysdk.SyncConfig.service lib/systemd/system
|
||||
bin/sync-config-session usr/bin
|
||||
src/conf2/sync-config/com.kylin.kysdk.SyncConfig.desktop etc/xdg/autostart/
|
||||
|
||||
# update-db
|
||||
src/conf2/service/conf2-update.py usr/bin
|
||||
src/conf2/service/conf2-update-db.service lib/systemd/system
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
base_version=2.4.0
|
||||
base_version=2.5.0
|
||||
|
||||
Name: libkysdk-config
|
||||
Description: kysdk base layer config component
|
||||
Requires: kysdk-utils
|
||||
Version: 2.5.0
|
||||
Cflags: -I/usr/include/kysdk/kysdk-base/
|
||||
Libs: -lkyconf
|
||||
Libs: -lkyconf
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GLIB REQUIRED glib-2.0 gio-2.0 gtk+-3.0)
|
||||
pkg_check_modules(GTK REQUIRED gtk+-3.0)
|
||||
pkg_check_modules(GLIB REQUIRED glib-2.0 gio-2.0)
|
||||
# pkg_check_modules(GTK REQUIRED gtk+-3.0)
|
||||
include_directories(${GLIB_INCLUDE_DIRS} )
|
||||
|
||||
include_directories(api)
|
||||
|
||||
add_subdirectory(api)
|
||||
add_subdirectory(sync-config)
|
||||
|
||||
add_executable(kconf2 tools/kconf2-tool.c )
|
||||
target_link_libraries(kconf2 kyconf2)
|
||||
|
||||
add_executable(kconf2-editor tools/kconf2-editor.c )
|
||||
target_link_libraries(kconf2-editor kyconf2 ${GTK_LIBRARIES})
|
||||
# add_executable(kconf2-editor tools/kconf2-editor.c )
|
||||
# target_link_libraries(kconf2-editor kyconf2 ${GTK_LIBRARIES})
|
||||
|
||||
add_executable(kyconf2-test test/kyconf2-test.c)
|
||||
target_link_libraries(kyconf2-test kyconf2)
|
||||
|
@ -18,8 +21,8 @@ target_link_libraries(kyconf2-test kyconf2)
|
|||
install(TARGETS kconf2
|
||||
DESTINATION /usr/bin)
|
||||
|
||||
install(TARGETS kconf2-editor
|
||||
DESTINATION /usr/bin)
|
||||
# install(TARGETS kconf2-editor
|
||||
# DESTINATION /usr/bin)
|
||||
|
||||
install(TARGETS kyconf2-test
|
||||
DESTINATION /usr/bin)
|
||||
|
|
|
@ -282,7 +282,9 @@ static KSettingsSchema *_get_schema(const char *id, const char *version)
|
|||
int rc = sqlite3_open(db_file, &db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
if (0 == strcmp(db_file, "/root/.config/kylin-config/user.db"))
|
||||
if ((0 == strcmp(db_file, "/root/.config/kylin-config/user.db")) ||
|
||||
(0 == strcmp(db_file, "/home/lightdm/.config/kylin-config/user.db")) ||
|
||||
(0 == strcmp(db_file, "/home/messagebus/.config/kylin-config/user.db")))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed! %s try to open /etc/kylin-config/user.db.\n", __func__, db_file, sqlite3_errmsg(db));
|
||||
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
|
||||
|
@ -378,6 +380,30 @@ out:
|
|||
return schema;
|
||||
}
|
||||
|
||||
static char *_get_db_file_path(char *buffer, size_t size)
|
||||
{
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
char db_file[PATH_MAX];
|
||||
if (0 == strcmp(user_name, "root"))
|
||||
snprintf(buffer, size, "/root/.config/kylin-config/user.db");
|
||||
else
|
||||
snprintf(buffer, size, "/home/%s/.config/kylin-config/user.db", user_name);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void _get_schemas()
|
||||
{
|
||||
char ***apps = NULL, ***versions = NULL, ***configures = NULL;
|
||||
|
@ -387,7 +413,7 @@ static void _get_schemas()
|
|||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
|
@ -401,7 +427,7 @@ static void _get_schemas()
|
|||
sprintf(db_file, "/root/.config/kylin-config/user.db");
|
||||
else
|
||||
sprintf(db_file, "/home/%s/.config/kylin-config/user.db", user_name);
|
||||
// syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s \n", __func__, db_file);
|
||||
// syslog(LOG_DEBUG, "[kysdk-conf2] %s -> :open %s \n", __func__, db_file);
|
||||
|
||||
// 读取数据库数据
|
||||
sqlite3 *db = NULL;
|
||||
|
@ -411,9 +437,12 @@ static void _get_schemas()
|
|||
int rc = sqlite3_open(db_file, &db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
if (0 == strcmp(db_file, "/root/.config/kylin-config/user.db"))
|
||||
// 华为云项目中,systemd屏蔽用户目录;lighdm没有用户目录 所以读取etc下的数据
|
||||
if ((0 == strcmp(db_file, "/root/.config/kylin-config/user.db")) ||
|
||||
(0 == strcmp(db_file, "/home/lightdm/.config/kylin-config/user.db")) ||
|
||||
(0 == strcmp(db_file, "/home/messagebus/.config/kylin-config/user.db")))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed! %s try to open /etc/kylin-config/user.db.\n", __func__, db_file, sqlite3_errmsg(db));
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed : %s! try to open /etc/kylin-config/user.db.\n", __func__, db_file, sqlite3_errmsg(db));
|
||||
rc = sqlite3_open("/etc/kylin-config/user.db", &db);
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
|
@ -422,9 +451,12 @@ static void _get_schemas()
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :open %s failed : %s\n", __func__, db_file, sqlite3_errmsg(db));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char sql[100];
|
||||
rc = sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, &err_msg);
|
||||
if (rc != SQLITE_OK)
|
||||
|
@ -468,7 +500,7 @@ static void _get_schemas()
|
|||
}
|
||||
sqlite3_close(db);
|
||||
|
||||
if (!apps || !versions || ! configures)
|
||||
if (!apps || !versions || !configures)
|
||||
return;
|
||||
|
||||
// 顶层hash, 元素为appData:hash(versionData:hash(s:KSettingsSchema))
|
||||
|
@ -476,7 +508,7 @@ static void _get_schemas()
|
|||
schemas_table = g_hash_table_new_full(data_hash, data_equal, app_data_destroy, (GDestroyNotify)g_hash_table_destroy);
|
||||
if (NULL == schemas_table)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat hash Table failed\n", __func__);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> :Creat hash Table failed\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -496,7 +528,7 @@ static void _get_schemas()
|
|||
{
|
||||
AppData *app_data = NULL;
|
||||
VersionData *version_data = NULL;
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read a new version id %s, old id is %d\n", __func__, configures[i][1], version_id);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Read a new version id %s, old id is %d\n", __func__, configures[i][1], version_id);
|
||||
version_id = atoi(configures[i][1]);
|
||||
|
||||
version_data = calloc(1, sizeof *version_data);
|
||||
|
@ -506,7 +538,7 @@ static void _get_schemas()
|
|||
// 版本id对应的应用id改变
|
||||
if (app_id != atoi(VER_COLUMN[1]))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read a new app id %s, old id is %d\n", __func__, VER_COLUMN[1], app_id);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Read a new app id %s, old id is %d\n", __func__, VER_COLUMN[1], app_id);
|
||||
app_id = atoi(VER_COLUMN[1]);
|
||||
|
||||
app_data = calloc(1, sizeof *app_data);
|
||||
|
@ -519,7 +551,7 @@ static void _get_schemas()
|
|||
version = g_hash_table_new_full(data_hash, data_equal, version_data_destroy, (GDestroyNotify)g_hash_table_destroy);
|
||||
if (NULL == version)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat hash2 Table failed\n", __func__);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> :Creat hash2 Table failed\n", __func__);
|
||||
app_data_destroy(app_data);
|
||||
version_data_destroy(version_data);
|
||||
goto out;
|
||||
|
@ -537,19 +569,19 @@ static void _get_schemas()
|
|||
g_hash_table_insert(version, version_data, schemas);
|
||||
if (NULL == schemas)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Creat schemas hash Table failed\n", __func__);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> :Creat schemas hash Table failed\n", __func__);
|
||||
version_data_destroy(version_data);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
version_data_destroy(version_data);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read %s configure wiht version number %s\n", __func__, APP_COLUMN[1], VER_COLUMN[2]);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Read %s configure wiht version number %s\n", __func__, APP_COLUMN[1], VER_COLUMN[2]);
|
||||
|
||||
schema = g_hash_table_lookup(schemas, APP_COLUMN[1]);
|
||||
if (NULL == schema)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Creat node %s\n", __func__, APP_COLUMN[1]);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Creat node %s\n", __func__, APP_COLUMN[1]);
|
||||
schema = calloc(1, sizeof *schema);
|
||||
if (NULL == schema)
|
||||
goto out;
|
||||
|
@ -560,7 +592,7 @@ static void _get_schemas()
|
|||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
|
||||
if (schema->values)
|
||||
{
|
||||
g_hash_table_destroy(schema->values);
|
||||
|
@ -604,7 +636,7 @@ static void _get_schemas()
|
|||
}
|
||||
sprintf(parent_name, "%s%s", APP_COLUMN[1], tmp);
|
||||
}
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> %s's parent name %s\n", __func__, node_name, parent_name);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> %s's parent name %s\n", __func__, node_name, parent_name);
|
||||
|
||||
// 给父组件增加子组件名
|
||||
KSettingsSchema *parent_schema = g_hash_table_lookup(schemas, parent_name);
|
||||
|
@ -624,7 +656,7 @@ static void _get_schemas()
|
|||
schema = g_hash_table_lookup(schemas, schema_name);
|
||||
if (NULL == schema)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Creat node %s\n", __func__, schema_name);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Creat node %s\n", __func__, schema_name);
|
||||
schema = calloc(1, sizeof *schema);
|
||||
if (NULL == schema)
|
||||
{
|
||||
|
@ -646,7 +678,7 @@ static void _get_schemas()
|
|||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Clear node %s\n", __func__, APP_COLUMN[1]);
|
||||
if (schema->values)
|
||||
{
|
||||
g_hash_table_destroy(schema->values);
|
||||
|
@ -673,7 +705,7 @@ static void _get_schemas()
|
|||
}
|
||||
else if (0 == strcmp(node_type, "key"))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Read %s configure %s wiht version number %s\n", __func__, schema->id, node_name, schema->version);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> Read %s configure %s wiht version number %s\n", __func__, schema->id, node_name, schema->version);
|
||||
// hash表 s:hash(s:s)
|
||||
if (NULL == schema->values)
|
||||
schema->values = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_destroy);
|
||||
|
@ -769,22 +801,24 @@ KSettingsSchema *kdk_conf2_schema_table_lookup(const char *id, const char *versi
|
|||
|
||||
GHashTableIter iter;
|
||||
g_hash_table_iter_init(&iter, schemas_table);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer*)(&app_data), (gpointer*)(&version_hash)))
|
||||
while (g_hash_table_iter_next(&iter, (gpointer*)&app_data, (gpointer*)&version_hash))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> find %s\n", __func__, app_data->name);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> find %s\n", __func__, app_data->name);
|
||||
if (0 == strcmp(app_data->name, list[0]))
|
||||
{
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> find app :%s\n", __func__, app_data->name);
|
||||
VersionData *version_data = NULL;
|
||||
GHashTable *schemas = NULL;
|
||||
version = version ? version : app_data->default_version;
|
||||
|
||||
GHashTableIter iter_version;
|
||||
g_hash_table_iter_init(&iter_version, version_hash);
|
||||
while (g_hash_table_iter_next(&iter_version, (gpointer*)(&version_data), (gpointer*)(&schemas)))
|
||||
while (g_hash_table_iter_next(&iter_version, (gpointer*)&version_data, (gpointer*)&schemas))
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> find %s '%s configure\n", __func__, app_data->name, version_data->name);
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> find %s '%s configure\n", __func__, app_data->name, version_data->name);
|
||||
if (0 == strcmp(version_data->name, version))
|
||||
{
|
||||
syslog(LOG_DEBUG, "[kysdk-conf2] %s -> find version :%s\n", __func__, version_data->name);
|
||||
result = g_hash_table_lookup(schemas, id);
|
||||
break;
|
||||
}
|
||||
|
@ -1055,6 +1089,20 @@ void kdk_conf2_schema_update_schemas_table()
|
|||
_get_schemas();
|
||||
}
|
||||
|
||||
void kdk_conf2_schema_key_set_value(GHashTable *key, char *value)
|
||||
{
|
||||
if (g_hash_table_contains(key, "custom_value"))
|
||||
g_hash_table_replace(key, "custom_value", strdup(value));
|
||||
else
|
||||
g_hash_table_insert(key, "custom_value", strdup(value));
|
||||
}
|
||||
|
||||
void kdk_conf2_schema_key_reset(GHashTable *key)
|
||||
{
|
||||
if (g_hash_table_contains(key, "custom_value"))
|
||||
g_hash_table_remove(key, "custom_value");
|
||||
}
|
||||
|
||||
// 重新读取某个schema的配置
|
||||
KSettingsSchema *kdk_conf2_schema_reload(const char *id, const char *version)
|
||||
{
|
||||
|
@ -1066,7 +1114,7 @@ KSettingsSchema *kdk_conf2_schema_reload(const char *id, const char *version)
|
|||
|
||||
GHashTableIter iter;
|
||||
g_hash_table_iter_init(&iter, schemas_table);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer*)(&app_data), (gpointer*)(&version_hash)))
|
||||
while (g_hash_table_iter_next(&iter, (gpointer*)&app_data, (gpointer*)&version_hash))
|
||||
{
|
||||
if (0 == strcmp(app_data->name, list[0]))
|
||||
{
|
||||
|
@ -1075,7 +1123,7 @@ KSettingsSchema *kdk_conf2_schema_reload(const char *id, const char *version)
|
|||
|
||||
GHashTableIter iter_version;
|
||||
g_hash_table_iter_init(&iter_version, version_hash);
|
||||
while (g_hash_table_iter_next(&iter_version, (gpointer*)(&version_data), (gpointer*)(&schemas)))
|
||||
while (g_hash_table_iter_next(&iter_version, (gpointer*)&version_data, (gpointer*)&schemas))
|
||||
{
|
||||
if (0 == strcmp(version_data->name, version))
|
||||
{
|
||||
|
|
|
@ -96,6 +96,10 @@ extern "C"
|
|||
|
||||
void kdk_conf2_schema_update_schemas_table();
|
||||
|
||||
void kdk_conf2_schema_key_set_value(GHashTable *key, char *value);
|
||||
|
||||
void kdk_conf2_schema_key_reset(GHashTable *key);
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <gio/gsettings.h>
|
||||
|
||||
#include "libkysettings.h"
|
||||
#include "ksettingsschema.h"
|
||||
|
@ -46,7 +45,6 @@ typedef struct _KSettingsPrivate
|
|||
GMainContext *main_context;
|
||||
KSettingsSchema *schema;
|
||||
GDBusConnection *conn;
|
||||
GSettings *gsettings;
|
||||
guint sub_id[2];
|
||||
} KSettingsPrivate;
|
||||
|
||||
|
@ -107,11 +105,6 @@ static void k_settings_finalize(GObject *object)
|
|||
g_dbus_connection_signal_unsubscribe(ksettings->priv->conn, ksettings->priv->sub_id[SIGNAL_CHANGED]);
|
||||
g_dbus_connection_signal_unsubscribe(ksettings->priv->conn, ksettings->priv->sub_id[SIGNAL_RELOAD]);
|
||||
g_object_unref(ksettings->priv->conn);
|
||||
if (ksettings->priv->gsettings)
|
||||
{
|
||||
g_settings_sync();
|
||||
g_object_unref(ksettings->priv->gsettings);
|
||||
}
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(k_settings_parent_class)->finalize(object);
|
||||
|
@ -164,20 +157,6 @@ static void *_g_main_loop_thread(void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void _on_gsettings_key_changed(GSettings *setting, const char *key, void *user_data)
|
||||
{
|
||||
GVariant *value = g_settings_get_value(setting, key);
|
||||
KSettings *ksetting = (KSettings *)user_data;
|
||||
char *conf2_value = kdk_conf2_get_value(ksetting, key);
|
||||
if (0 == strcmp(conf2_value, g_variant_print(value, TRUE)))
|
||||
return;
|
||||
if (kdk_conf2_set_value(ksetting, key, g_variant_print(value, TRUE)))
|
||||
{
|
||||
// g_signal_emit(ksetting, k_settings_signals[SIGNAL_CHANGED], g_quark_from_string(key), key);
|
||||
}
|
||||
g_variant_unref(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief _on_key_changed DBus服务中key_changed信号响应函数
|
||||
* @param connection
|
||||
|
@ -206,34 +185,9 @@ static void _on_key_changed(GDBusConnection *connection,
|
|||
ksettings->priv->schema = kdk_conf2_schema_reload(id, version);
|
||||
g_signal_emit(ksettings, k_settings_signals[SIGNAL_CHANGED], g_quark_from_string(key), key);
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s changed signal\n", key);
|
||||
if (ksettings->priv->gsettings)
|
||||
{
|
||||
const gchar *endptr = NULL;
|
||||
GError *error = NULL;
|
||||
GVariant *gsetting_value = g_settings_get_value(ksettings->priv->gsettings, key);
|
||||
if (NULL != gsetting_value)
|
||||
{
|
||||
char *value = kdk_conf2_get_value(ksettings, key);
|
||||
if (0 != strcmp(value, g_variant_print(gsetting_value, TRUE)))
|
||||
{
|
||||
char *type = kdk_conf2_get_type(ksettings, key);
|
||||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE(type), value, NULL, &endptr, &error);
|
||||
if (NULL == variant)
|
||||
{
|
||||
klog_err("[kysdk-conf2] %s -> %s\n", __func__, error->message);
|
||||
return;
|
||||
}
|
||||
g_settings_set_value(ksettings->priv->gsettings, key, variant);
|
||||
g_settings_sync();
|
||||
g_variant_unref(variant);
|
||||
}
|
||||
g_variant_unref(gsetting_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_free(schema_id);
|
||||
g_free(schema_version);
|
||||
mutex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -386,6 +340,124 @@ static int _call_method(const char *method, const char *id, const char *version,
|
|||
return response;
|
||||
}
|
||||
|
||||
static int _compare_versions(char *version1, char *version2)
|
||||
{
|
||||
if (version1 != NULL && version2 == NULL)
|
||||
return 1;
|
||||
else if (version1 == NULL && version2 != NULL)
|
||||
return -1;
|
||||
else if (version1 == NULL && version2 == NULL)
|
||||
return 0;
|
||||
|
||||
int result = 0;
|
||||
|
||||
char v1[64], v2[64];
|
||||
memset(v1, 0, 64);
|
||||
strcpy(v1, version1);
|
||||
memset(v2, 0, 64);
|
||||
strcpy(v2, version2);
|
||||
|
||||
char *save_ptr1 = NULL;
|
||||
char *save_ptr2 = NULL;
|
||||
char *token1;
|
||||
char *token2;
|
||||
token1 = strtok_r(v1, ".-k", &save_ptr1);
|
||||
token2 = strtok_r(v2, ".-k", &save_ptr2);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (token1 != NULL && token2 != NULL)
|
||||
{
|
||||
int num1 = atoi(token1);
|
||||
int num2 = atoi(token2);
|
||||
|
||||
if (num1 > num2)
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
else if (num1 < num2)
|
||||
{
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (token1 == NULL && token2 != NULL)
|
||||
{
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
else if (token1 != NULL && token2 == NULL)
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
else if (token1 == NULL && token2 == NULL)
|
||||
break;
|
||||
|
||||
token1 = strtok_r(NULL, ".-k", &save_ptr1);
|
||||
token2 = strtok_r(NULL, ".-k", &save_ptr2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *_check_version(const char *id, const char *version)
|
||||
{
|
||||
if (version != NULL)
|
||||
return version;
|
||||
|
||||
AppData *app_data = NULL;
|
||||
GHashTable *version_hash = NULL;
|
||||
char app[64];
|
||||
int size = 0;
|
||||
char *p = id;
|
||||
while (*p != '.' && *p != '\0')
|
||||
{
|
||||
size++;
|
||||
p++;
|
||||
}
|
||||
strncpy(app, id, size);
|
||||
|
||||
GHashTableIter iter;
|
||||
g_hash_table_iter_init(&iter, schemas_table);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer*)&app_data, (gpointer*)&version_hash))
|
||||
{
|
||||
if (0 == strcmp(app_data->name, app))
|
||||
{
|
||||
VersionData *version_data = NULL;
|
||||
GHashTable *schemas = NULL;
|
||||
// TODO: 读取配置文件获取最大最小版本
|
||||
char *min_version = "1.2.0.0-0k0.0";
|
||||
char *max_version = "2.5.1.0-0k0.0";
|
||||
if ((-1 == _compare_versions(min_version, app_data->default_version)) &&
|
||||
(1 == _compare_versions(max_version, app_data->default_version)))
|
||||
{
|
||||
return app_data->default_version;
|
||||
}
|
||||
|
||||
GHashTableIter iter_version;
|
||||
g_hash_table_iter_init(&iter_version, version_hash);
|
||||
char *tmp = NULL;
|
||||
while (g_hash_table_iter_next(&iter_version, (gpointer*)&version_data, (gpointer*)&schemas))
|
||||
{
|
||||
if (0 == strcmp(version_data->name, app_data->default_version))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((-1 == _compare_versions(min_version, version_data->name)) &&
|
||||
(1 == _compare_versions(max_version, version_data->name)))
|
||||
{
|
||||
// 返回符合要求的版本中,最高的版本
|
||||
tmp = _compare_versions(version_data->name, tmp) > 0 ? version_data->name : tmp;
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KSettings *kdk_conf2_new(const char *id, const char *version)
|
||||
{
|
||||
if (NULL == id)
|
||||
|
@ -403,6 +475,14 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// version = _check_version(id, version);
|
||||
// if (NULL == version)
|
||||
// {
|
||||
// syslog(LOG_INFO, "[kysdk-conf2] There is no version number that meets the requirements\n");
|
||||
// return NULL;
|
||||
// }
|
||||
// syslog(LOG_INFO, "[kysdk-conf2] Use the %s version of the configuration file\n", version);
|
||||
|
||||
KSettingsSchema *schema = kdk_conf2_schema_table_lookup(id, version);
|
||||
if (NULL == schema)
|
||||
{
|
||||
|
@ -417,88 +497,87 @@ KSettings *kdk_conf2_new(const char *id, const char *version)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const char * const *gsettings_schemas = g_settings_list_schemas();
|
||||
if (gsettings_schemas)
|
||||
{
|
||||
for (int i = 0; gsettings_schemas[i]; i++)
|
||||
{
|
||||
char *p = strstr(gsettings_schemas[i], id);
|
||||
if (NULL == p)
|
||||
continue;
|
||||
int len = strlen(id);
|
||||
if (*(p + len) == '\0')
|
||||
{
|
||||
ksettings->priv->gsettings = g_settings_new(gsettings_schemas[i]);
|
||||
g_signal_connect(ksettings->priv->gsettings, "changed", G_CALLBACK(_on_gsettings_key_changed), ksettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksettings->priv->schema = schema;
|
||||
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
int is_dbus_daemon = 0;
|
||||
char process_name[256];
|
||||
FILE *fp = fopen("/proc/self/comm", "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
fgets(process_name, sizeof(process_name), fp);
|
||||
fclose(fp);
|
||||
// 去除末尾换行符
|
||||
process_name[strcspn(process_name, "\n")] = 0;
|
||||
if (0 == strcmp(process_name, "dbus-daemon"))
|
||||
is_dbus_daemon = 1;
|
||||
}
|
||||
|
||||
// 创建dbus服务的链接,用于调用接口及接收信号
|
||||
GError *error = NULL;
|
||||
if (0 == strcmp(user_name, "root"))
|
||||
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
else
|
||||
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (error != NULL)
|
||||
if (!is_dbus_daemon)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] Connection Error: %s\n", error->message);
|
||||
g_object_unref(ksettings);
|
||||
ksettings = NULL;
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
uid_t uid = getuid(); // 获取当前进程的用户ID
|
||||
char user_name[128] = {0};
|
||||
struct passwd *pw = getpwuid(uid); // 获取用户ID对应的用户信息结构体
|
||||
if (NULL == pw)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :Get user name failed! use root config\n", __func__);
|
||||
strcpy(user_name, "root");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(user_name, pw->pw_name);
|
||||
endpwent();
|
||||
}
|
||||
|
||||
// 监听key_changed信号
|
||||
ksettings->priv->sub_id[0] = g_dbus_connection_signal_subscribe(ksettings->priv->conn,
|
||||
"com.kylin.kysdk.conf2", // 消息来源 (NULL 表示任意)
|
||||
"com.kylin.kysdk.conf2", // 接口名称
|
||||
"key_changed", // 信号名称
|
||||
"/com/kylin/kysdk/conf2", // 对象路径 (NULL 表示任意)
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
_on_key_changed,
|
||||
ksettings,
|
||||
NULL);
|
||||
// 监听重载信号
|
||||
ksettings->priv->sub_id[1] = g_dbus_connection_signal_subscribe(ksettings->priv->conn,
|
||||
"com.kylin.kysdk.conf2", // 消息来源 (NULL 表示任意)
|
||||
"com.kylin.kysdk.conf2", // 接口名称
|
||||
"updated", // 信号名称
|
||||
"/com/kylin/kysdk/conf2", // 对象路径 (NULL 表示任意)
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
_on_updated,
|
||||
ksettings,
|
||||
NULL);
|
||||
// 创建dbus服务的链接,用于调用接口及接收信号
|
||||
GError *error = NULL;
|
||||
if (0 == strcmp(user_name, "root"))
|
||||
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
|
||||
else
|
||||
ksettings->priv->conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
syslog(LOG_INFO, "[kysdk-conf2] Connection Error: %s\n", error->message);
|
||||
g_object_unref(ksettings);
|
||||
ksettings = NULL;
|
||||
g_error_free(error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 创建glib的事件处理循环,单独起线程。
|
||||
// 如果循环已经启动,增加dbus_signal_loop的引用计数
|
||||
if (NULL == dbus_signal_loop)
|
||||
{
|
||||
dbus_signal_loop = g_main_loop_new(NULL, FALSE);
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, _g_main_loop_thread, NULL);
|
||||
// 监听key_changed信号
|
||||
ksettings->priv->sub_id[0] = g_dbus_connection_signal_subscribe(ksettings->priv->conn,
|
||||
"com.kylin.kysdk.conf2", // 消息来源 (NULL 表示任意)
|
||||
"com.kylin.kysdk.conf2", // 接口名称
|
||||
"key_changed", // 信号名称
|
||||
"/com/kylin/kysdk/conf2", // 对象路径 (NULL 表示任意)
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
_on_key_changed,
|
||||
ksettings,
|
||||
NULL);
|
||||
// 监听重载信号
|
||||
ksettings->priv->sub_id[1] = g_dbus_connection_signal_subscribe(ksettings->priv->conn,
|
||||
"com.kylin.kysdk.conf2", // 消息来源 (NULL 表示任意)
|
||||
"com.kylin.kysdk.conf2", // 接口名称
|
||||
"updated", // 信号名称
|
||||
"/com/kylin/kysdk/conf2", // 对象路径 (NULL 表示任意)
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
_on_updated,
|
||||
ksettings,
|
||||
NULL);
|
||||
|
||||
// 创建glib的事件处理循环,单独起线程。
|
||||
// 如果循环已经启动,增加dbus_signal_loop的引用计数
|
||||
if (NULL == dbus_signal_loop)
|
||||
{
|
||||
dbus_signal_loop = g_main_loop_new(NULL, FALSE);
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, _g_main_loop_thread, NULL);
|
||||
}
|
||||
else
|
||||
g_main_loop_ref(dbus_signal_loop);
|
||||
ref_count++;
|
||||
}
|
||||
else
|
||||
g_main_loop_ref(dbus_signal_loop);
|
||||
ref_count++;
|
||||
return ksettings;
|
||||
}
|
||||
|
||||
|
@ -509,12 +588,30 @@ void kdk_conf2_ksettings_destroy(KSettings *ksettings)
|
|||
|
||||
g_object_unref(ksettings);
|
||||
|
||||
// 减少dbus_signal_loop的引用计数
|
||||
// 如果归零则停止事件循环
|
||||
g_main_loop_unref(dbus_signal_loop);
|
||||
int is_dbus_daemon = 0;
|
||||
char process_name[256];
|
||||
FILE *fp = fopen("/proc/self/comm", "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
fgets(process_name, sizeof(process_name), fp);
|
||||
fclose(fp);
|
||||
// 去除末尾换行符
|
||||
process_name[strcspn(process_name, "\n")] = 0;
|
||||
if (0 == strcmp(process_name, "dbus-daemon"))
|
||||
is_dbus_daemon = 1;
|
||||
}
|
||||
|
||||
if (!is_dbus_daemon)
|
||||
{
|
||||
// 减少dbus_signal_loop的引用计数
|
||||
// 如果归零则停止事件循环
|
||||
g_main_loop_unref(dbus_signal_loop);
|
||||
}
|
||||
if (0 == (--ref_count))
|
||||
{
|
||||
g_main_loop_quit(dbus_signal_loop);
|
||||
g_hash_table_destroy(schemas_table);
|
||||
schemas_table = NULL;
|
||||
// g_main_loop_quit(dbus_signal_loop);
|
||||
dbus_signal_loop = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -620,16 +717,22 @@ int kdk_conf2_set_value(KSettings *ksettings, const char *key, const char *value
|
|||
char *id = kdk_conf2_schema_get_id(ksettings->priv->schema);
|
||||
char *version = kdk_conf2_schema_get_version(ksettings->priv->schema);
|
||||
if (NULL == curr_value || 0 != strcmp(curr_value, value))
|
||||
{
|
||||
result = _call_method("set",
|
||||
id,
|
||||
version,
|
||||
key, value);
|
||||
if (result)
|
||||
{
|
||||
key_hash = kdk_conf2_schema_get_key(ksettings->priv->schema, key);
|
||||
kdk_conf2_schema_key_set_value(key_hash, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
result = TRUE;
|
||||
g_free(id);
|
||||
g_free(version);
|
||||
g_free(curr_value);
|
||||
|
||||
syslog(LOG_INFO, "[kysdk-conf2] %s -> Set value finished. Return %s\n", __func__, result ? "true" : "false");
|
||||
return result;
|
||||
}
|
||||
|
@ -1130,10 +1233,15 @@ void kdk_conf2_reset(KSettings *ksettings, const char *key)
|
|||
syslog(LOG_INFO, "[kysdk-conf2] %s -> :reset %s value\n", __func__, key);
|
||||
char *id = kdk_conf2_schema_get_id(ksettings->priv->schema);
|
||||
char *version = kdk_conf2_schema_get_version(ksettings->priv->schema);
|
||||
_call_method("reset",
|
||||
id,
|
||||
version,
|
||||
key, NULL);
|
||||
int result = _call_method("reset",
|
||||
id,
|
||||
version,
|
||||
key, NULL);
|
||||
if (result)
|
||||
{
|
||||
GHashTable *key_hash = kdk_conf2_schema_get_key(ksettings->priv->schema, key);
|
||||
kdk_conf2_schema_key_reset(key_hash);
|
||||
}
|
||||
g_free(id);
|
||||
g_free(version);
|
||||
}
|
||||
|
@ -1217,6 +1325,11 @@ char **kdk_conf2_list_schemas(const char *app, const char *version)
|
|||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if (0 == ref_count)
|
||||
{
|
||||
g_hash_table_destroy(schemas_table);
|
||||
schemas_table = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,172 +29,546 @@ extern "C"
|
|||
typedef struct _KSettings KSettings;
|
||||
|
||||
typedef void (*KCallBack) (void);
|
||||
// typedef void (*KCallBack) (KSettings *ksettings,
|
||||
// const char *key,
|
||||
// void *user_data);
|
||||
|
||||
/**
|
||||
* @brief 创建指定id,指定version的配置句柄
|
||||
*
|
||||
* @param id 配置id,从应用名开始到目标组的路径,每个组名以"."分割
|
||||
* @param version 配置版本号
|
||||
* @return KSettings* 配置组的句柄,每个句柄存储一个组的所有配置数据
|
||||
*/
|
||||
KSettings * kdk_conf2_new (const char *id,
|
||||
const char *version);
|
||||
|
||||
/**
|
||||
* @brief 销毁配置句柄
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
*/
|
||||
void kdk_conf2_ksettings_destroy (KSettings *ksettings);
|
||||
|
||||
/**
|
||||
* @brief 获取句柄的配置id
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @return char* 配置id,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_id (KSettings *ksettings);
|
||||
|
||||
/**
|
||||
* @brief 获取句柄的配置版本
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @return char* 配置版本,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_version (KSettings *ksettings);
|
||||
|
||||
/**
|
||||
* @brief 获取配置句柄的子组配置句柄
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param name 子组名
|
||||
* @return KSettings* 子组句柄
|
||||
*/
|
||||
KSettings * kdk_conf2_get_child (KSettings *ksettings,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* @brief 列举配置组的所有子组
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @return char** 子组列表,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char ** kdk_conf2_list_children (KSettings *ksettings);
|
||||
|
||||
/**
|
||||
* @brief 列举配置组的所有键
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @return char** 键名列表,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char ** kdk_conf2_list_keys (KSettings *ksettings);
|
||||
|
||||
/**
|
||||
* @brief 获取配置项的取值范围
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 取值范围,如果是数字类型返回字符串"[min,max]",如果是枚举返回字符串"{nick : value}"
|
||||
*/
|
||||
char * kdk_conf2_get_range (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 检查要设置的值是否在键的取值范围内
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的值
|
||||
* @return int 可视作bool类型,0表示否,1表示是
|
||||
*/
|
||||
int kdk_conf2_range_check (KSettings *ksettings,
|
||||
const char *key,
|
||||
const char *value);
|
||||
|
||||
/**
|
||||
* @brief 设置键的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_value (KSettings *ksettings,
|
||||
const char *key,
|
||||
const char *value);
|
||||
|
||||
/**
|
||||
* @brief 获取键的值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 符合glib类型标签的数据字符串,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_value (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取键的默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 符合glib类型标签的数据字符串,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_default_value (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置bool类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 键值,bool类型,即0或1
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_boolean (KSettings *ksettings,
|
||||
const char *key,
|
||||
int value);
|
||||
|
||||
/**
|
||||
* @brief 获取bool类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 0表示FALSE,1表示TRUE
|
||||
*/
|
||||
int kdk_conf2_get_boolean (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取bool类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 0表示FALSE,1表示TRUE
|
||||
*/
|
||||
int kdk_conf2_get_default_boolean (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置double类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 键值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_double (KSettings *ksettings,
|
||||
const char *key,
|
||||
double value);
|
||||
|
||||
/**
|
||||
* @brief 获取double类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return double 配置值
|
||||
*/
|
||||
double kdk_conf2_get_double (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取double类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return double 配置值
|
||||
*/
|
||||
double kdk_conf2_get_default_double (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置枚举类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_enum (KSettings *ksettings,
|
||||
const char *key,
|
||||
int value);
|
||||
|
||||
/**
|
||||
* @brief 获取枚举类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 枚举值
|
||||
*/
|
||||
int kdk_conf2_get_enum (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取枚举类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 枚举值
|
||||
*/
|
||||
int kdk_conf2_get_default_enum (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置int类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的键值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_int (KSettings *ksettings,
|
||||
const char *key,
|
||||
int value);
|
||||
|
||||
/**
|
||||
* @brief 获取int类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 键值
|
||||
*/
|
||||
int kdk_conf2_get_int (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取int类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 键值
|
||||
*/
|
||||
int kdk_conf2_get_default_int (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置int64类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的键值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_int64 (KSettings *ksettings,
|
||||
const char *key,
|
||||
long value);
|
||||
|
||||
/**
|
||||
* @brief 获取int64类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return long 键值
|
||||
*/
|
||||
long kdk_conf2_get_int64 (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取int64类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return long 键值
|
||||
*/
|
||||
long kdk_conf2_get_default_int64 (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置uint类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的键值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_uint (KSettings *ksettings,
|
||||
const char *key,
|
||||
unsigned int value);
|
||||
|
||||
/**
|
||||
* @brief 获取uint类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return unsigned int 键值
|
||||
*/
|
||||
unsigned int kdk_conf2_get_uint (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取uint类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return unsigned int 键值
|
||||
*/
|
||||
unsigned int kdk_conf2_get_default_uint (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置uint64类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的键值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_uint64 (KSettings *ksettings,
|
||||
const char *key,
|
||||
unsigned long value);
|
||||
|
||||
/**
|
||||
* @brief 获取uint64类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return unsigned long 键值
|
||||
*/
|
||||
unsigned long kdk_conf2_get_uint64 (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取uint64类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return unsigned long 键值
|
||||
*/
|
||||
unsigned long kdk_conf2_get_default_uint64 (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置string类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的键值,符合类型标签的字符串
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_string (KSettings *ksettings,
|
||||
const char *key,
|
||||
const char *value);
|
||||
|
||||
/**
|
||||
* @brief 获取string类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 符合类型标签的字符串,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_string (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取string类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 符合类型标签的字符串,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_default_string (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 设置字符串列表类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @param value 要设置的键值
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_set_strv (KSettings *ksettings,
|
||||
const char *key,
|
||||
const char * const *value);
|
||||
|
||||
/**
|
||||
* @brief 获取字符串列表类型的键值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char** 字符串列表,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char ** kdk_conf2_get_strv (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取字符串列表类型的键默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char** 字符串列表,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char ** kdk_conf2_get_default_strv (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取键的详细描述
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 键的描述,不存在返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_descrition (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取键的简要描述
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 键的简述,不存在返回NULL。返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_summary (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 获取键的类型标签字符串
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return char* 键的类型标枪字符串,返回值需要释放
|
||||
*/
|
||||
char * kdk_conf2_get_type (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 将键值复位为默认值
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
*/
|
||||
void kdk_conf2_reset (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 检查键值是否可写
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 可视作bool类型,0表示否,1表示是
|
||||
*/
|
||||
int kdk_conf2_is_writable (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief 检测组内是否存在某个键
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param key 键名
|
||||
* @return int 可视作bool类型,0表示否,1表示是
|
||||
*/
|
||||
int kdk_conf2_has_key (KSettings *ksettings,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief changed信号的回调原型,注册时强转成KCallBack类型
|
||||
*
|
||||
*/
|
||||
typedef void (*changed) (KSettings *ksettings,
|
||||
const char *key,
|
||||
void *user_data);
|
||||
/**
|
||||
* @brief 注册回调函数相应信号,信号的回调函数参数各不相同但连接时都需要强转为KCallBack类型
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @param signal_name 信号名 信号名"changed",如果监听指定键,则写作"changed:key"
|
||||
* @param handler 回调函数
|
||||
* @param user_data 用户数据
|
||||
* @return unsigned long 信号连接id
|
||||
*/
|
||||
unsigned long kdk_conf2_connect_signal (KSettings *ksettings,
|
||||
const char *signal_name,
|
||||
KCallBack handler,
|
||||
void *user_data);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 重新加载配置文件
|
||||
*
|
||||
*/
|
||||
void kdk_conf2_reload (void);
|
||||
|
||||
/**
|
||||
* @brief 列举指定app,指定version的所有id
|
||||
*
|
||||
* @param app 应用名
|
||||
* @param version 版本号
|
||||
* @return char** id列表,失败返回NULL。返回值需要释放
|
||||
*/
|
||||
char ** kdk_conf2_list_schemas (const char *app,
|
||||
const char *version);
|
||||
|
||||
/**
|
||||
* @brief 将配置数据以app为单位生成配置文件到指定目录
|
||||
*
|
||||
* @param path 路径
|
||||
* @return int 可视作bool类型,0表示失败,1表示成功
|
||||
*/
|
||||
int kdk_conf2_save_user_configure (const char *path);
|
||||
|
||||
/**
|
||||
* @brief 以旧id的配置为模板,创建一个新的id
|
||||
*
|
||||
* @param old_id 旧的配置id
|
||||
* @param new_id 新的配置id
|
||||
* @param version 旧id的版本号,新id将自动创建在这个版本号下
|
||||
* @return KSettings* 新id的配置句柄,失败返回NULL
|
||||
*/
|
||||
KSettings * kdk_conf2_new_extends_id (const char *old_id,
|
||||
const char *new_id,
|
||||
const char *version);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 检查配置id是否存在
|
||||
*
|
||||
* @param id 配置id
|
||||
* @param version 配置版本
|
||||
* @return int 可视作bool类型,0表示否,1表示是
|
||||
*/
|
||||
int kdk_conf2_is_schema (const char *id,
|
||||
const char *version);
|
||||
|
||||
/**
|
||||
* @brief 获取组的简要描述
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @return char* 组的简述,不存在返回NULL。
|
||||
*/
|
||||
char * kdk_conf2_get_schema_summary (KSettings *ksettings);
|
||||
|
||||
/**
|
||||
* @brief 获取组的纤细描述
|
||||
*
|
||||
* @param ksettings 配置句柄
|
||||
* @return char* 组的描述,不存在返回NULL。
|
||||
*/
|
||||
char * kdk_conf2_get_schema_desription (KSettings *ksettings);
|
||||
#if __cplusplus
|
||||
}
|
||||
|
|
|
@ -5,4 +5,6 @@ key4 = /usr/bin/ukui-settings-daemon
|
|||
key5 = /usr/sbin/lightdm
|
||||
key6 = /usr/bin/ukui-screensaver-dialog
|
||||
key7 = /usr/sbin/ukui-greeter
|
||||
key8 = /lib/systemd/systemd-logind
|
||||
key8 = /lib/systemd/systemd-logind
|
||||
key9 = /usr/bin/sync-config-system
|
||||
key10 = /usr/bin/sync-config-session
|
||||
|
|
|
@ -1 +1 @@
|
|||
f45558b6a1cb69ceb6e4e58d8b9a47b551db8543
|
||||
40a1a38e65f5ae16cbe035b6812e4326741366ac
|
||||
|
|
|
@ -43,7 +43,7 @@ class KYSettingsDBusService(dbus.service.Object):
|
|||
self._converter = conf2Utils.Converter(logger)
|
||||
self._watchdog = conf2Utils.FileWatche('/etc/kylin-config/basic', self)
|
||||
|
||||
self._reload()
|
||||
# self._reload()
|
||||
|
||||
if os.path.exists('/etc/dbus-1/conf/com.kylin.kysdk.conf2.limit'):
|
||||
conf = ConfigParser()
|
||||
|
@ -55,43 +55,6 @@ class KYSettingsDBusService(dbus.service.Object):
|
|||
|
||||
logger.info(f'DBus Class init end')
|
||||
|
||||
def isAllowedCaller(self,sender):
|
||||
if sender is None:
|
||||
return
|
||||
pid = self.getSenderPid(sender)
|
||||
self.checkSenderEnv(pid)
|
||||
exe_file = '/proc/%u/exe' % pid
|
||||
real_file = os.readlink(exe_file)
|
||||
if real_file.startswith('/usr/bin/python'):
|
||||
cmd_file = '/proc/%u/cmdline' % pid
|
||||
with open(cmd_file, 'r') as cf:
|
||||
cmd_line = cf.readline()
|
||||
cmds = cmd_line.split('\0')
|
||||
if len(cmds) >= 2:
|
||||
real_file = cmds[1]
|
||||
if real_file not in programWhiteList:
|
||||
raise dbus.exceptions.DBusException('[%s] dbus method control,operation not permitted' % real_file)
|
||||
|
||||
def getSenderPid(self,sender):
|
||||
system_bus = dbus.SystemBus()
|
||||
dbus_obj = system_bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
|
||||
inter_obj = dbus.Interface(dbus_obj, dbus_interface='org.freedesktop.DBus')
|
||||
try:
|
||||
pid = inter_obj.GetConnectionUnixProcessID(sender)
|
||||
except dbus.DBusException as e:
|
||||
raise dbus.exceptions.DBusException('[%s] dbus method control,operation not permitted' % sender)
|
||||
return pid
|
||||
|
||||
def checkSenderEnv(self, pid):
|
||||
env_file = '/proc/%u/environ' % pid
|
||||
with open(env_file, 'r') as ef:
|
||||
env_lines = ef.readline()
|
||||
env_details = env_lines.replace('\0', '\n').split('\n')
|
||||
for env_detail in env_details:
|
||||
key = env_detail.split('=')[0]
|
||||
if key in envBlackList:
|
||||
raise dbus.exceptions.DBusException('[%u] dbus method control,env forbidden' % pid)
|
||||
|
||||
# 重载
|
||||
def _reload(self):
|
||||
if self._converter.update_read_only_db():
|
||||
|
@ -112,7 +75,6 @@ class KYSettingsDBusService(dbus.service.Object):
|
|||
# 设置一个配置的值
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='sssss', out_signature='i', sender_keyword='sender')
|
||||
def set(self, user, id, version, key, value, sender = None):
|
||||
# self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.set('/root/.config/kylin-config/user.db', id, version, key, value)
|
||||
|
@ -127,7 +89,6 @@ class KYSettingsDBusService(dbus.service.Object):
|
|||
# 恢复单个默认值
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='i', sender_keyword='sender')
|
||||
def reset(self,user, id, version, key, sender = None):
|
||||
# self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.reset('/root/.config/kylin-config/user.db', id, version, key)
|
||||
|
@ -142,14 +103,12 @@ class KYSettingsDBusService(dbus.service.Object):
|
|||
# 恢复整个id的默认值
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='', out_signature='i', sender_keyword='sender')
|
||||
def reload(self, sender = None):
|
||||
# self.isAllowedCaller(sender)
|
||||
success = self._reload()
|
||||
self.updated() if success else None
|
||||
return success
|
||||
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ss', out_signature='b', sender_keyword='sender')
|
||||
def save(self, user, path, sender = None):
|
||||
# self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.save('/root/.config/kylin-config/user.db', path)
|
||||
|
@ -160,7 +119,6 @@ class KYSettingsDBusService(dbus.service.Object):
|
|||
#复制old_id的配置到new_id的位置,并将新的数据写入到数据库
|
||||
@dbus.service.method("com.kylin.kysdk.conf2", in_signature='ssss', out_signature='b', sender_keyword='sender')
|
||||
def extends_id(self, old_id:str, new_id:str, version:str, user:str, sender = None):
|
||||
# self.isAllowedCaller(sender)
|
||||
success = False
|
||||
if user == 'root':
|
||||
success = self._converter.extends_id(old_id, new_id, version, '/root/.config/kylin-config/user.db')
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=KYLIN CONF2 UPDATE DB
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/conf2-update.py
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/python3.8
|
||||
import os
|
||||
import logging
|
||||
import conf2Utils
|
||||
|
||||
os.makedirs('/etc/kylin-config', exist_ok=True)
|
||||
logging.basicConfig(filename='/etc/kylin-config/systembus.log',
|
||||
level=logging.DEBUG,
|
||||
format='%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S')
|
||||
logger = logging.getLogger()
|
||||
converter = conf2Utils.Converter(logger)
|
||||
|
||||
logger.info('update db start')
|
||||
if converter.update_read_only_db():
|
||||
converter.update_user_db('/root/.config/kylin-config/user.db')
|
||||
logger.info('update db end')
|
|
@ -28,6 +28,7 @@ class Converter:
|
|||
|
||||
def update_user_db(self, path):
|
||||
if not os.path.exists(self._ro_db):
|
||||
self.logger.info(f'/etc/kylin-config/user.db not existed')
|
||||
return False
|
||||
|
||||
existed = self._update_table_structure(path)
|
||||
|
@ -37,6 +38,8 @@ class Converter:
|
|||
self._user_dict = self._db2dict(path)
|
||||
else:
|
||||
data = self._db2dict(self._ro_db)
|
||||
if self._user_dict == {}:
|
||||
self._user_dict = self._db2dict(path)
|
||||
self._del_discarded_key(self._user_dict, data)
|
||||
self._merge_dict(self._user_dict, data)
|
||||
|
||||
|
@ -186,16 +189,16 @@ class Converter:
|
|||
return False
|
||||
|
||||
# 用于kconf2-editor保存文件,仅有普通用户权限,root用户没有图形化界面
|
||||
def editor_save(self, data, dest_path):
|
||||
def editor_save(self, apps:list, data, dest_path):
|
||||
try:
|
||||
self.logger.info(f'editor_save begin')
|
||||
|
||||
#将用户配置写入到复制的只读视图里
|
||||
self._value_override_default(data)
|
||||
|
||||
for key in data:
|
||||
with open(f'{dest_path}/{key}.yaml', 'w') as yaml_file:
|
||||
yaml_file.write(yaml.safe_dump({key:data[key]}, allow_unicode = True))
|
||||
for app in apps:
|
||||
with open(f'{dest_path}/{app}.yaml', 'w') as yaml_file:
|
||||
yaml_file.write(yaml.safe_dump({app:data[app]}, allow_unicode = True))
|
||||
|
||||
self.logger.info(f'editor_save end')
|
||||
return True
|
||||
|
@ -601,7 +604,21 @@ class Converter:
|
|||
num = int(num, 10)
|
||||
enum_range[element['_nick']] = num
|
||||
range = str(enum_range)
|
||||
|
||||
elif value_type == 'bool':
|
||||
value_type = 'b'
|
||||
elif value_type == 'int':
|
||||
value_type = 'i'
|
||||
elif value_type == 'int64':
|
||||
value_type = 'x'
|
||||
elif value_type == 'uint':
|
||||
value_type = 'u'
|
||||
elif value_type == 'uint64':
|
||||
value_type = 't'
|
||||
elif value_type == 'double':
|
||||
value_type = 'd'
|
||||
elif value_type == 'string':
|
||||
value_type = 's'
|
||||
|
||||
cursor.execute('''INSERT INTO configures
|
||||
(version_id, node_name, node_type, permission, description, summary, parent, value_type, custom_value, default_value, range)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
|
||||
|
|
|
@ -3,7 +3,8 @@ Type=Application
|
|||
Exec=/usr/bin/conf2-session-server.py
|
||||
TryExec=/usr/bin/conf2-session-server.py
|
||||
Name=KYSDK-CONF2-SESSION-BUS
|
||||
X-UKUI-Autostart-Phase=Initialization
|
||||
Icon=
|
||||
Keywords=session;kysdk-conf2-session
|
||||
Comment=This session date you into sdk
|
||||
NoDisplay=true
|
||||
NoDisplay=true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[Unit]
|
||||
Description=KYLIN CONF2 DBUS
|
||||
Before=systemd-logind.service
|
||||
Before=systemd-logind.service com.kylin.kysdk.SyncConfig.service
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
add_executable(sync-config-system system.c sync-dbus-server.c gdbus/libsyncconfig.c)
|
||||
target_link_libraries(sync-config-system ${GLIB_LIBRARIES} ${GIO_LIBRARIES} kyconf2 kylog)
|
||||
|
||||
add_executable(sync-config-session session.c sync-dbus-server.c gdbus/libsyncconfig.c)
|
||||
target_link_libraries(sync-config-session ${GLIB_LIBRARIES} ${GIO_LIBRARIES} kyconf2 kylog)
|
||||
|
||||
# 包含 GNU 安装目录设置
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# 设置 CMAKE_INSTALL_LIBDIR 变量
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "armv8l")
|
||||
set(CMAKE_INSTALL_LIBDIR "/usr/lib/arm-linux-gnueabihf/")
|
||||
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64")
|
||||
set(CMAKE_INSTALL_LIBDIR "/usr/lib/mips64el-linux-gnuabi64/")
|
||||
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i686")
|
||||
set(CMAKE_INSTALL_LIBDIR "/usr/lib/i386-linux-gnu/")
|
||||
else()
|
||||
set(CMAKE_INSTALL_LIBDIR "/usr/lib/${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu/")
|
||||
endif()
|
||||
|
||||
# 安装文件
|
||||
install(TARGETS sync-config-session
|
||||
DESTINATION /usr/bin)
|
||||
|
||||
install(TARGETS sync-config-system
|
||||
DESTINATION /usr/bin)
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
|
||||
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
|
||||
<!-- Only user root can own the alsa service -->
|
||||
<policy user="root">
|
||||
<allow own="com.kylin.kysdk.SyncConfig" />
|
||||
<allow send_destination="com.kylin.kysdk.SyncConfig" />
|
||||
<allow receive_sender="com.kylin.kysdk.SyncConfig" />
|
||||
</policy>
|
||||
|
||||
<policy context="default">
|
||||
<allow send_destination="com.kylin.kysdk.SyncConfig" />
|
||||
<!-- remove the following line for debug -->
|
||||
<!--
|
||||
<allow send_interface="com.jd.ccis"/>
|
||||
-->
|
||||
</policy>
|
||||
|
||||
</busconfig>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Exec=/usr/bin/sync-config-session
|
||||
TryExec=/usr/bin/sync-config-session
|
||||
Name=KYSDK-CONF2-SYNC-CONFIG-BUS
|
||||
X-UKUI-Autostart-Phase=Initialization
|
||||
Icon=
|
||||
Keywords=session;
|
||||
Comment=This session date you into sdk
|
||||
NoDisplay=true
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=KYLIN CONF2 SYNC DBUS
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
Restart=always
|
||||
RestartSec=1
|
||||
BusName=com.kylin.kysdk.SyncConfig
|
||||
ExecStart=/usr/bin/sync-config-system
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<node>
|
||||
<interface name="com.kylin.kysdk.SyncConfig">
|
||||
<signal name="state">
|
||||
<arg name="state" type="i"/>
|
||||
</signal>
|
||||
|
||||
<method name="RegisterSchema">
|
||||
<arg name="Conf2Id" direction="in" type="s"/>
|
||||
<arg name="SchemaId" direction="in" type="s"/>
|
||||
<arg name="SchemaPath" direction="in" type="s"/>
|
||||
<arg name="ArgOut" direction="out" type="b"/>
|
||||
</method>
|
||||
|
||||
<method name="UnregisterSchema">
|
||||
<arg name="SchemaId" direction="in" type="s"/>
|
||||
<arg name="SchemaPath" direction="in" type="s"/>
|
||||
<arg name="ArgOut" direction="out" type="b"/>
|
||||
</method>
|
||||
</interface>
|
||||
</node>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* This file is generated by gdbus-codegen, do not modify it.
|
||||
*
|
||||
* The license of this code is the same as for the D-Bus interface description
|
||||
* it was derived from. Note that it links to GLib, so must comply with the
|
||||
* LGPL linking clauses.
|
||||
*/
|
||||
|
||||
#ifndef __LIBSYNCCONFIG_H__
|
||||
#define __LIBSYNCCONFIG_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Declarations for com.kylin.kysdk.SyncConfig */
|
||||
|
||||
#define SYNC_CONFIG_TYPE_ (sync_config__get_type ())
|
||||
#define SYNC_CONFIG_(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SYNC_CONFIG_TYPE_, SyncConfig))
|
||||
#define SYNC_CONFIG_IS_(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SYNC_CONFIG_TYPE_))
|
||||
#define SYNC_CONFIG__GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), SYNC_CONFIG_TYPE_, SyncConfigIface))
|
||||
|
||||
struct _SyncConfig;
|
||||
typedef struct _SyncConfig SyncConfig;
|
||||
typedef struct _SyncConfigIface SyncConfigIface;
|
||||
|
||||
struct _SyncConfigIface
|
||||
{
|
||||
GTypeInterface parent_iface;
|
||||
|
||||
|
||||
gboolean (*handle_register_schema) (
|
||||
SyncConfig *object,
|
||||
GDBusMethodInvocation *invocation,
|
||||
const gchar *arg_Conf2Id,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_SchemaPath);
|
||||
|
||||
gboolean (*handle_unregister_schema) (
|
||||
SyncConfig *object,
|
||||
GDBusMethodInvocation *invocation,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_SchemaPath);
|
||||
|
||||
void (*state) (
|
||||
SyncConfig *object,
|
||||
gint arg_state);
|
||||
|
||||
};
|
||||
|
||||
GType sync_config__get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDBusInterfaceInfo *sync_config__interface_info (void);
|
||||
guint sync_config__override_properties (GObjectClass *klass, guint property_id_begin);
|
||||
|
||||
|
||||
/* D-Bus method call completion functions: */
|
||||
void sync_config__complete_register_schema (
|
||||
SyncConfig *object,
|
||||
GDBusMethodInvocation *invocation,
|
||||
gboolean ArgOut);
|
||||
|
||||
void sync_config__complete_unregister_schema (
|
||||
SyncConfig *object,
|
||||
GDBusMethodInvocation *invocation,
|
||||
gboolean ArgOut);
|
||||
|
||||
|
||||
|
||||
/* D-Bus signal emissions functions: */
|
||||
void sync_config__emit_state (
|
||||
SyncConfig *object,
|
||||
gint arg_state);
|
||||
|
||||
|
||||
|
||||
/* D-Bus method calls: */
|
||||
void sync_config__call_register_schema (
|
||||
SyncConfig *proxy,
|
||||
const gchar *arg_Conf2Id,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_SchemaPath,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean sync_config__call_register_schema_finish (
|
||||
SyncConfig *proxy,
|
||||
gboolean *out_ArgOut,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
gboolean sync_config__call_register_schema_sync (
|
||||
SyncConfig *proxy,
|
||||
const gchar *arg_Conf2Id,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_SchemaPath,
|
||||
gboolean *out_ArgOut,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
void sync_config__call_unregister_schema (
|
||||
SyncConfig *proxy,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_SchemaPath,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean sync_config__call_unregister_schema_finish (
|
||||
SyncConfig *proxy,
|
||||
gboolean *out_ArgOut,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
gboolean sync_config__call_unregister_schema_sync (
|
||||
SyncConfig *proxy,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_SchemaPath,
|
||||
gboolean *out_ArgOut,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
||||
|
||||
/* ---- */
|
||||
|
||||
#define SYNC_CONFIG_TYPE__PROXY (sync_config__proxy_get_type ())
|
||||
#define SYNC_CONFIG__PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SYNC_CONFIG_TYPE__PROXY, SyncConfigProxy))
|
||||
#define SYNC_CONFIG__PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SYNC_CONFIG_TYPE__PROXY, SyncConfigProxyClass))
|
||||
#define SYNC_CONFIG__PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SYNC_CONFIG_TYPE__PROXY, SyncConfigProxyClass))
|
||||
#define SYNC_CONFIG_IS__PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SYNC_CONFIG_TYPE__PROXY))
|
||||
#define SYNC_CONFIG_IS__PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SYNC_CONFIG_TYPE__PROXY))
|
||||
|
||||
typedef struct _SyncConfigProxy SyncConfigProxy;
|
||||
typedef struct _SyncConfigProxyClass SyncConfigProxyClass;
|
||||
typedef struct _SyncConfigProxyPrivate SyncConfigProxyPrivate;
|
||||
|
||||
struct _SyncConfigProxy
|
||||
{
|
||||
/*< private >*/
|
||||
GDBusProxy parent_instance;
|
||||
SyncConfigProxyPrivate *priv;
|
||||
};
|
||||
|
||||
struct _SyncConfigProxyClass
|
||||
{
|
||||
GDBusProxyClass parent_class;
|
||||
};
|
||||
|
||||
GType sync_config__proxy_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 44, 0)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SyncConfigProxy, g_object_unref)
|
||||
#endif
|
||||
|
||||
void sync_config__proxy_new (
|
||||
GDBusConnection *connection,
|
||||
GDBusProxyFlags flags,
|
||||
const gchar *name,
|
||||
const gchar *object_path,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
SyncConfig *sync_config__proxy_new_finish (
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
SyncConfig *sync_config__proxy_new_sync (
|
||||
GDBusConnection *connection,
|
||||
GDBusProxyFlags flags,
|
||||
const gchar *name,
|
||||
const gchar *object_path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
void sync_config__proxy_new_for_bus (
|
||||
GBusType bus_type,
|
||||
GDBusProxyFlags flags,
|
||||
const gchar *name,
|
||||
const gchar *object_path,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
SyncConfig *sync_config__proxy_new_for_bus_finish (
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
SyncConfig *sync_config__proxy_new_for_bus_sync (
|
||||
GBusType bus_type,
|
||||
GDBusProxyFlags flags,
|
||||
const gchar *name,
|
||||
const gchar *object_path,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
||||
/* ---- */
|
||||
|
||||
#define SYNC_CONFIG_TYPE__SKELETON (sync_config__skeleton_get_type ())
|
||||
#define SYNC_CONFIG__SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SYNC_CONFIG_TYPE__SKELETON, SyncConfigSkeleton))
|
||||
#define SYNC_CONFIG__SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SYNC_CONFIG_TYPE__SKELETON, SyncConfigSkeletonClass))
|
||||
#define SYNC_CONFIG__SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SYNC_CONFIG_TYPE__SKELETON, SyncConfigSkeletonClass))
|
||||
#define SYNC_CONFIG_IS__SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SYNC_CONFIG_TYPE__SKELETON))
|
||||
#define SYNC_CONFIG_IS__SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SYNC_CONFIG_TYPE__SKELETON))
|
||||
|
||||
typedef struct _SyncConfigSkeleton SyncConfigSkeleton;
|
||||
typedef struct _SyncConfigSkeletonClass SyncConfigSkeletonClass;
|
||||
typedef struct _SyncConfigSkeletonPrivate SyncConfigSkeletonPrivate;
|
||||
|
||||
struct _SyncConfigSkeleton
|
||||
{
|
||||
/*< private >*/
|
||||
GDBusInterfaceSkeleton parent_instance;
|
||||
SyncConfigSkeletonPrivate *priv;
|
||||
};
|
||||
|
||||
struct _SyncConfigSkeletonClass
|
||||
{
|
||||
GDBusInterfaceSkeletonClass parent_class;
|
||||
};
|
||||
|
||||
GType sync_config__skeleton_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 44, 0)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (SyncConfigSkeleton, g_object_unref)
|
||||
#endif
|
||||
|
||||
SyncConfig *sync_config__skeleton_new (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __LIBSYNCCONFIG_H__ */
|
|
@ -0,0 +1,8 @@
|
|||
#include "sync-dbus-server.h"
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
monitoring_requires_synchronized_configuration();
|
||||
init_gdbus_server(G_BUS_TYPE_SESSION);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,464 @@
|
|||
#include "sync-dbus-server.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <gio/gsettings.h>
|
||||
#include <libkylog.h>
|
||||
#include <../api/libkysettings.h>
|
||||
|
||||
/***************************************dbus服务********************************************/
|
||||
|
||||
static SyncConfig *skeleton = NULL;
|
||||
|
||||
static gboolean on_handle_register_schema(SyncConfig *skeleton, GDBusMethodInvocation *invocation,
|
||||
const gchar *arg_Conf2Id,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_Path,
|
||||
gpointer user_data)
|
||||
{
|
||||
printf("Regester call %s\n", arg_Conf2Id);
|
||||
|
||||
sync_config__complete_register_schema(skeleton, invocation, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean on_handle_unregister_schema(SyncConfig *skeleton, GDBusMethodInvocation *invocation,
|
||||
const gchar *arg_SchemaId,
|
||||
const gchar *arg_Path,
|
||||
gpointer user_data)
|
||||
{
|
||||
printf("Unregester call\n");
|
||||
sync_config__complete_unregister_schema(skeleton, invocation, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接上bus daemon的回调
|
||||
**/
|
||||
void on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
|
||||
{
|
||||
klog_info("on_bus_acquired has been invoked, name is %s\n", name);
|
||||
GError *error = NULL;
|
||||
skeleton = sync_config__skeleton_new();
|
||||
// 连接方法同步处理函数
|
||||
g_signal_connect(G_OBJECT(skeleton), "handle-register-schema", G_CALLBACK(on_handle_register_schema), NULL);
|
||||
g_signal_connect(G_OBJECT(skeleton), "handle-unregister-schema", G_CALLBACK(on_handle_unregister_schema), NULL);
|
||||
// 发布服务到总线
|
||||
g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skeleton), connection, "/com/kylin/kysdk/syncConfig", &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
klog_err("Error: Failed to export object. Reason: %s.\n", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功注册busName的回调
|
||||
**/
|
||||
void on_bus_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* busName丢失的回调,一般是server挂了??
|
||||
**/
|
||||
void on_bus_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试发送信号函数,调用Hello.h自动生成的方法
|
||||
**/
|
||||
static gint status_value = 1;
|
||||
static gboolean emit_test_state_signal(gconstpointer p)
|
||||
{
|
||||
printf("emit_test_status_signal invoked\n");
|
||||
if (skeleton != NULL)
|
||||
{
|
||||
sync_config__emit_state(skeleton, status_value);
|
||||
}
|
||||
status_value++;
|
||||
}
|
||||
|
||||
gboolean init_gdbus_server(GBusType type)
|
||||
{
|
||||
guint owner_id;
|
||||
GMainLoop *loop;
|
||||
#if !GLIB_CHECK_VERSION(2, 35, 0)
|
||||
g_type_init();
|
||||
#endif
|
||||
owner_id = g_bus_own_name(type, "com.kylin.kysdk.SyncConfig",
|
||||
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||
on_bus_acquired, on_bus_name_acquired, on_bus_name_lost, NULL, NULL);
|
||||
|
||||
// 测试,每3s发一次signal
|
||||
// g_timeout_add(3000, (GSourceFunc)emit_test_state_signal, NULL);
|
||||
|
||||
// 主线程进入循环
|
||||
loop = g_main_loop_new(NULL, FALSE);
|
||||
g_main_loop_run(loop);
|
||||
|
||||
g_bus_unown_name(owner_id);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***************************************同步配置********************************************/
|
||||
#define OUT
|
||||
#define KPATH_LEN 512
|
||||
#define APP_LEN 128
|
||||
#define VER_LEN 32
|
||||
#define LINE_LEN 4096
|
||||
|
||||
struct _conf2_gsetting_handle_duple
|
||||
{
|
||||
KSettings *ksetting;
|
||||
GSettings *gsetting;
|
||||
};
|
||||
// static GPtrArray *handle_array = g_ptr_array_new();
|
||||
|
||||
|
||||
static void _on_gsettings_key_changed(GSettings *gsetting, const char *key, void *user_data)
|
||||
{
|
||||
GVariant *value = g_settings_get_value(gsetting, key);
|
||||
KSettings *ksetting = (KSettings *)user_data;
|
||||
char *conf2_value = kdk_conf2_get_value(ksetting, key);
|
||||
if (0 == strcmp(conf2_value, g_variant_print(value, TRUE)))
|
||||
return;
|
||||
int ret = kdk_conf2_set_value(ksetting, key, g_variant_print(value, TRUE));
|
||||
if (ret)
|
||||
{
|
||||
printf("_on_gsettings_key_changed\n");
|
||||
// g_signal_emit(ksetting, k_settings_signals[SIGNAL_CHANGED], g_quark_from_string(key), key);
|
||||
}
|
||||
g_variant_unref(value);
|
||||
}
|
||||
|
||||
static void _on_conf2_key_changed(KSettings *ksetting, const char *key, void *user_data)
|
||||
{
|
||||
GSettings *gsetting = (GSettings*)user_data;
|
||||
const gchar *endptr = NULL;
|
||||
GError *error = NULL;
|
||||
GVariant *gsetting_value = g_settings_get_value(gsetting, key);
|
||||
if (NULL != gsetting_value)
|
||||
{
|
||||
char *value = kdk_conf2_get_value(ksetting, key);
|
||||
if (0 != strcmp(value, g_variant_print(gsetting_value, TRUE)))
|
||||
{
|
||||
char *type = kdk_conf2_get_type(ksetting, key);
|
||||
GVariant *variant = g_variant_parse(G_VARIANT_TYPE(type), value, NULL, &endptr, &error);
|
||||
if (NULL == variant)
|
||||
{
|
||||
// klog_err("[kysdk-conf2] %s -> %s\n", __func__, error->message);
|
||||
return;
|
||||
}
|
||||
printf("_on_conf2_key_changed\n");
|
||||
g_settings_set_value(gsetting, key, variant);
|
||||
g_settings_sync();
|
||||
g_variant_unref(variant);
|
||||
}
|
||||
g_variant_unref(gsetting_value);
|
||||
}
|
||||
}
|
||||
|
||||
static char *_conf2_id_in_gsetting_schemas(const char *conf2_id, const char **gsetting_schemas)
|
||||
{
|
||||
for(; *gsetting_schemas; gsetting_schemas++)
|
||||
{
|
||||
if (g_str_has_suffix(*gsetting_schemas, conf2_id))
|
||||
return *gsetting_schemas;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 比较两个版本号的大小
|
||||
*
|
||||
* @param version1 版本号
|
||||
* @param version2 版本号
|
||||
* @return int version1大于version时返回1, 等于返回0, 小于返回-1
|
||||
*/
|
||||
static int _compare_versions(char *version1, char *version2)
|
||||
{
|
||||
if (version1 != NULL && version2 == NULL)
|
||||
return 1;
|
||||
else if (version1 == NULL && version2 != NULL)
|
||||
return -1;
|
||||
else if (version1 == NULL && version2 == NULL)
|
||||
return 0;
|
||||
|
||||
int result = 0;
|
||||
|
||||
char v1[64], v2[64];
|
||||
memset(v1, 0, 64);
|
||||
strcpy(v1, version1);
|
||||
memset(v2, 0, 64);
|
||||
strcpy(v2, version2);
|
||||
|
||||
char *save_ptr1 = NULL;
|
||||
char *save_ptr2 = NULL;
|
||||
char *token1;
|
||||
char *token2;
|
||||
token1 = strtok_r(v1, ".-k", &save_ptr1);
|
||||
token2 = strtok_r(v2, ".-k", &save_ptr2);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (token1 != NULL && token2 != NULL)
|
||||
{
|
||||
int num1 = atoi(token1);
|
||||
int num2 = atoi(token2);
|
||||
|
||||
if (num1 > num2)
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
else if (num1 < num2)
|
||||
{
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (token1 == NULL && token2 != NULL)
|
||||
{
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
else if (token1 != NULL && token2 == NULL)
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
else if (token1 == NULL && token2 == NULL)
|
||||
break;
|
||||
|
||||
token1 = strtok_r(NULL, ".-k", &save_ptr1);
|
||||
token2 = strtok_r(NULL, ".-k", &save_ptr2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline gboolean _copy_str_check(char *dest, char *src, size_t length)
|
||||
{
|
||||
// 去掉前面空格
|
||||
g_strchug(src);
|
||||
/*本行内容应该是 【应用名:】,如果不是以":"结尾,说明文件内容格式错误*/
|
||||
char *dot = strchr(src, ':');
|
||||
if (NULL != dot)
|
||||
{
|
||||
int len = dot - src;
|
||||
strncpy(dest, src, len < length - 1 ? len : length);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean _get_conf2_app(FILE *fp, OUT char *app)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
char line[LINE_LEN], *dot = NULL;
|
||||
int version_indent = 0;
|
||||
while (fgets(line, LINE_LEN, fp))
|
||||
{
|
||||
// 无缩进且不是注释,既第一行内容
|
||||
dot = strchr("#\t ", line[0]);
|
||||
if (NULL == dot)
|
||||
{
|
||||
result = _copy_str_check(app, line, APP_LEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean _get_conf2_version(FILE *fp, OUT char *version)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
char line[LINE_LEN], *dot = NULL;
|
||||
int version_indent = 0;
|
||||
while (fgets(line, LINE_LEN, fp))
|
||||
{
|
||||
// 获取版本号的缩进,缩进最短的正文既版本号
|
||||
if (0 == version_indent)
|
||||
{
|
||||
for (;; version_indent++)
|
||||
{
|
||||
// line[version_indent]不是空格
|
||||
if (NULL == strchr("\t ", line[version_indent]))
|
||||
{
|
||||
// 注释行,缩进计数归零
|
||||
if ('#' == line[version_indent])
|
||||
version_indent = 0;
|
||||
else
|
||||
{
|
||||
// 这行正文既一个版本号
|
||||
if (FALSE == _copy_str_check(version, line, VER_LEN))
|
||||
{
|
||||
printf("111%s\n", line);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
break; // for循环
|
||||
}
|
||||
}
|
||||
continue; // while循环
|
||||
}
|
||||
// 检查这一行是不是版本号
|
||||
int i = 0;
|
||||
for (; i < version_indent; i++)
|
||||
{
|
||||
// 空格不够
|
||||
if (NULL == strchr("\t ", line[i]))
|
||||
{
|
||||
// 注释行或空行
|
||||
if (NULL != strchr("#\n", line[i]))
|
||||
break; // for循环
|
||||
else
|
||||
{
|
||||
// TODO: log 文件缩进格式错误
|
||||
printf("222%s\n", line);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i == version_indent)
|
||||
{
|
||||
if((line[i] != '#') && (line[i] != ' ') && (line[i] != '\t'))
|
||||
{
|
||||
|
||||
char tmp[VER_LEN];
|
||||
memset(tmp, 0, VER_LEN);
|
||||
if (FALSE == _copy_str_check(tmp, line, VER_LEN))
|
||||
{
|
||||
// TODO: log 文件格式错误
|
||||
printf("333%s\n", line);
|
||||
return result;
|
||||
}
|
||||
if ( -1 == _compare_versions(version, tmp))
|
||||
{
|
||||
strcpy(version, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
自解析yaml格式文件,并获取应用名和版本号。
|
||||
注意:dbus-daemon会把自己的文件安装到basic目录,且后缀名为yaml,但
|
||||
文件内部的格式并不是yaml格式
|
||||
*/
|
||||
static gboolean _get_conf2_app_and_version(const char *file, OUT char *app, OUT char *version)
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
|
||||
memset(app, 0, APP_LEN);
|
||||
memset(version, 0, VER_LEN);
|
||||
|
||||
FILE *fp = fopen(file, "r");
|
||||
if (NULL == fp)
|
||||
{
|
||||
// TODO: 文件打开失败
|
||||
return result;
|
||||
}
|
||||
|
||||
result = _get_conf2_app(fp, app);
|
||||
if (FALSE == result)
|
||||
{
|
||||
// TODO: log 文件内容不符合yaml格式
|
||||
goto out;
|
||||
}
|
||||
result = _get_conf2_version(fp, version);
|
||||
if (FALSE == result)
|
||||
{
|
||||
// TODO: log 文件内容不符合yaml格式
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
fclose(fp);
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean _connect_signal_sync_config(const char *conf2_id, const char *conf2_version, const char *gsetting_id, const char *gsetting_path)
|
||||
{
|
||||
GSettings *gsetting = NULL;
|
||||
KSettings *ksetting = NULL;
|
||||
if ( NULL == gsetting_path)
|
||||
gsetting = g_settings_new(gsetting_id);
|
||||
else
|
||||
gsetting = g_settings_new_with_path(gsetting_id, gsetting_path);
|
||||
|
||||
ksetting = kdk_conf2_new(conf2_id, conf2_version);
|
||||
|
||||
if (!(gsetting && ksetting))
|
||||
{
|
||||
// TODO: log 创建句柄失败
|
||||
g_object_unref(gsetting);
|
||||
kdk_conf2_ksettings_destroy(ksetting);
|
||||
return FALSE;
|
||||
}
|
||||
g_signal_connect(gsetting, "changed", G_CALLBACK(_on_gsettings_key_changed), ksetting);
|
||||
kdk_conf2_connect_signal(ksetting, "changed", (KCallBack)_on_conf2_key_changed, gsetting);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int monitoring_requires_synchronized_configuration()
|
||||
{
|
||||
const char * const *gsetting_schemas = g_settings_list_schemas();
|
||||
|
||||
DIR *dir = NULL;
|
||||
struct dirent *dire = NULL;
|
||||
dir = opendir("/etc/kylin-config/basic");
|
||||
if (NULL == dir)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (NULL != (dire = readdir(dir)))
|
||||
{
|
||||
char file_name[KPATH_LEN];
|
||||
memset(file_name, 0, KPATH_LEN);
|
||||
char *dot = strrchr(dire->d_name, '.');
|
||||
if (NULL == dot)
|
||||
{
|
||||
// log
|
||||
continue;
|
||||
}
|
||||
size_t len = dot - dire->d_name;
|
||||
strncpy(file_name, dire->d_name, len);
|
||||
// 文件名与gsetting的id相同,需要同步
|
||||
if (g_strv_contains(gsetting_schemas, file_name))
|
||||
{
|
||||
// 获取应用名和版本号
|
||||
g_snprintf(file_name, KPATH_LEN, "/etc/kylin-config/basic/%s", dire->d_name);
|
||||
char app[APP_LEN], version[VER_LEN];
|
||||
memset(app, 0, APP_LEN);
|
||||
memset(version, 0, VER_LEN);
|
||||
if (FALSE == _get_conf2_app_and_version(file_name, app, version))
|
||||
{
|
||||
// TODO: 记录日志读取文件内应用与app失败
|
||||
continue;
|
||||
}
|
||||
char **ksetting_schemas = kdk_conf2_list_schemas(app, version);
|
||||
if (NULL == ksetting_schemas)
|
||||
{
|
||||
//TODO: log 获取conf2中app的version版本的id列表失败
|
||||
continue;
|
||||
}
|
||||
for(char **tmp = ksetting_schemas; *tmp; tmp++)
|
||||
{
|
||||
char *gsetting_id = NULL;
|
||||
if(NULL != (gsetting_id = _conf2_id_in_gsetting_schemas(*tmp, gsetting_schemas)))
|
||||
_connect_signal_sync_config(*tmp, version, gsetting_id, NULL);
|
||||
}
|
||||
g_strfreev(ksetting_schemas);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef SYNC_DBUS_SERVER_H
|
||||
#define SYNC_DBUS_SERVER_H
|
||||
|
||||
#include "gdbus/libsyncconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int monitoring_requires_synchronized_configuration();
|
||||
|
||||
gboolean init_gdbus_server(GBusType type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SYNC_DBUS_SERVER_H
|
|
@ -0,0 +1,8 @@
|
|||
#include "sync-dbus-server.h"
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
monitoring_requires_synchronized_configuration();
|
||||
init_gdbus_server(G_BUS_TYPE_SYSTEM);
|
||||
return 0;
|
||||
}
|
|
@ -49,7 +49,7 @@ int main(int argc, char *argv[])
|
|||
* 只有已连接切读过一次配置时才能接收到该信号
|
||||
* 接收信号需要开启主程序的消息循环
|
||||
*/
|
||||
// kdk_conf2_connect_signal(setting, "changed::int", (KCallBack)on_key_changed, NULL);
|
||||
// kdk_conf2_connect_signal(setting, "changed::int", on_key_changed, NULL);
|
||||
|
||||
char *schema_summary = kdk_conf2_get_schema_summary(setting);
|
||||
if (schema_summary)
|
||||
|
@ -171,39 +171,39 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/**********长整形读写**********/
|
||||
long l = kdk_conf2_get_default_int(setting, "long");
|
||||
long l = kdk_conf2_get_default_int64(setting, "long");
|
||||
printf("Long default value is %d\n", l);
|
||||
|
||||
l = kdk_conf2_get_int(setting, "long");
|
||||
l = kdk_conf2_get_int64(setting, "long");
|
||||
printf("Long value is %d\n", l);
|
||||
|
||||
success = kdk_conf2_set_int(setting, "long", l + 1);
|
||||
success = kdk_conf2_set_int64(setting, "long", l + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set long failed\n");
|
||||
}
|
||||
|
||||
/**********无符号整形读写**********/
|
||||
unsigned int u = kdk_conf2_get_default_int(setting, "uint");
|
||||
unsigned int u = kdk_conf2_get_default_uint(setting, "uint");
|
||||
printf("Uint default value is %d\n", u);
|
||||
|
||||
u = kdk_conf2_get_int(setting, "uint");
|
||||
u = kdk_conf2_get_uint(setting, "uint");
|
||||
printf("Uint value is %d\n", u);
|
||||
|
||||
success = kdk_conf2_set_int(setting, "uint", u + 1);
|
||||
success = kdk_conf2_set_uint(setting, "uint", u + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set uint failed\n");
|
||||
}
|
||||
|
||||
/**********无符号长整形读写**********/
|
||||
unsigned long t = kdk_conf2_get_default_int(setting, "ulong");
|
||||
unsigned long t = kdk_conf2_get_default_uint64(setting, "ulong");
|
||||
printf("Ulong default value is %d\n", t);
|
||||
|
||||
t = kdk_conf2_get_int(setting, "ulong");
|
||||
t = kdk_conf2_get_uint64(setting, "ulong");
|
||||
printf("Ulong value is %d\n", t);
|
||||
|
||||
success = kdk_conf2_set_int(setting, "ulong", t + 1);
|
||||
success = kdk_conf2_set_uint64(setting, "ulong", t + 1);
|
||||
if (0 == success)
|
||||
{
|
||||
printf("set ulong failed\n");
|
||||
|
@ -304,7 +304,7 @@ int main(int argc, char *argv[])
|
|||
int writable = kdk_conf2_is_writable(setting, "int");
|
||||
printf("Int is %s\n", writable ? "writable" : "not writable");
|
||||
|
||||
// kdk_conf2_connect_signal(setting, "reload", (KCallBack)on_reload, NULL);
|
||||
// kdk_conf2_connect_signal(setting, "reload", on_reload, NULL);
|
||||
kdk_conf2_reload();
|
||||
|
||||
char **schemas = kdk_conf2_list_schemas("test", NULL);
|
||||
|
|
|
@ -26,6 +26,14 @@ import re
|
|||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
import yaml
|
||||
import argparse
|
||||
|
||||
id_help = "指定一个gschema.xml的一个id,例如org.ukui.control-center。"\
|
||||
"工具会将这个id以及其子id(例如org.ukui.control-center.apt.prox)转为yaml格式,并生成yaml文件。"
|
||||
|
||||
version_help = "指定生成yaml文件的配置版本,如果不指定版本则默认版本为2.0.0.0-0k0.0"
|
||||
|
||||
path_help = "指定yaml文件的生成目录,如果不指定生成在${HOME}/yaml目录中"
|
||||
|
||||
def convert_one_file(data:dict, path:str, file:str):
|
||||
|
||||
|
@ -92,14 +100,24 @@ def convert_one_file(data:dict, path:str, file:str):
|
|||
print(f'{path}/{file} not exists')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = sys.argv[1]
|
||||
parser = argparse.ArgumentParser(description='这是一个将gschema.xml文件转化为yaml格式的程序, 例如: python3 src/conf2/tools/gschema_xml2yaml.py -i org.ukui.control-center -v 3.2.1.0-0k0.15 -p /home/kylin')
|
||||
parser.add_argument('--id', '-i', type=str, help=id_help)
|
||||
parser.add_argument('--version', '-v', type=str, help=version_help)
|
||||
parser.add_argument('--path', '-p', type=str, help=path_help)
|
||||
args = parser.parse_args()
|
||||
|
||||
app = args.id
|
||||
|
||||
version = '2.0.0-0k0.0'
|
||||
if 3 == len(sys.argv):
|
||||
version = sys.argv[2]
|
||||
if args.version:
|
||||
version = args.version
|
||||
|
||||
path = '/usr/share/glib-2.0/schemas'
|
||||
|
||||
if len(sys.argv) > 3:
|
||||
path = sys.argv[3]
|
||||
home = os.getenv('HOME')
|
||||
out_path = f'{home}/yaml'
|
||||
if args.path:
|
||||
out_path = args.path
|
||||
|
||||
organization = app.rsplit('.', 1)[0]
|
||||
|
||||
|
@ -122,8 +140,7 @@ if __name__ == '__main__':
|
|||
yaml_data = yaml.safe_dump(result, allow_unicode = True)
|
||||
|
||||
# 将YAML数据写入文件
|
||||
home = os.getenv('HOME')
|
||||
file = f"{home}/yaml/{app}.yaml"
|
||||
file = f"{out_path}/{app}.yaml"
|
||||
if not os.path.exists(os.path.dirname(file)):
|
||||
os.makedirs(os.path.dirname(file), exist_ok=True)
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/python3
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
override_dirs = ['/etc/kylin-config/industry']
|
||||
output_file = ''
|
||||
|
||||
# 每个问题类型声明一个列表存储对应的问题类型
|
||||
# 键值类型改变
|
||||
type_list = []
|
||||
# 键值权限改变
|
||||
permission_list = []
|
||||
# 取值范围改变
|
||||
range_list = []
|
||||
# 版本不在应用支持范围
|
||||
version_list = []
|
||||
|
||||
# 打印报告
|
||||
def print_err():
|
||||
with open(output_file, 'w') as file:
|
||||
if type_list:
|
||||
file.write('键值类型改变\n')
|
||||
file.write(' ' * 4 + '描述\n')
|
||||
file.write(' ' * 8 + '键值类型变化会导致应用读取数据是读不到数据或读到错误数据,导致应用运行结果异常\n')
|
||||
file.write(' ' * 4 + '如何修复\n')
|
||||
file.write(' ' * 8 + '联系应用调查原因,商讨修改方案\n')
|
||||
file.write(' ' * 4 + '问题上下文\n')
|
||||
for basic_file, override_file, path in type_list:
|
||||
file.write(' ' * 8 + f'应用文件:{basic_file} 目标文件:{override_file} 位置:{path}\n')
|
||||
if permission_list:
|
||||
file.write('键值权限改变\n')
|
||||
file.write(' ' * 4 + '描述\n')
|
||||
file.write(' ' * 8 + '键值权限改变可能会导致定制文件的内容无法覆盖应用文件的内容,导致定制内容不生效\n')
|
||||
file.write(' ' * 4 + '如何修复\n')
|
||||
file.write(' ' * 8 + '联系应用调查原因,商讨修改方案\n')
|
||||
file.write(' ' * 4 + '问题上下文\n')
|
||||
for basic_file, override_file, path in permission_list:
|
||||
file.write(' ' * 8 + f'应用文件:{basic_file} 目标文件:{override_file} 位置:{path}\n')
|
||||
if range_list:
|
||||
file.write('取值范围改变改变\n')
|
||||
file.write(' ' * 4 + '描述\n')
|
||||
file.write(' ' * 8 + '取值范围改变,可能会导致应用在读/写数据是读到/写入无意义的数据,导致应用运行出错或设置数据失败\n')
|
||||
file.write(' ' * 4 + '如何修复\n')
|
||||
file.write(' ' * 8 + '联系应用调查原因,商讨修改方案\n')
|
||||
file.write(' ' * 4 + '问题上下文\n')
|
||||
for basic_file, override_file, path in range_list:
|
||||
file.write(' ' * 8 + f'应用文件:{basic_file} 目标文件:{override_file} 位置:{path}\n')
|
||||
if version_list:
|
||||
file.write('版本不在应用规定范围\n')
|
||||
file.write(' ' * 4 + '描述\n')
|
||||
file.write(' ' * 8 + '如果版本不在应用指定支持的版本范围内无法确定配置应用读取的配置是否存在与该版本的配置内容中,可能会导致应用运行错误\n')
|
||||
file.write(' ' * 4 + '如何修复\n')
|
||||
file.write(' ' * 8 + '调查文件来源,如果可以删除建议删除,不能删除的话联系应用与定制包的负责人,商讨修改方案\n')
|
||||
file.write(' ' * 4 + '问题上下文\n')
|
||||
for basic_file, override_file, path in version_list:
|
||||
file.write(' ' * 8 + f'应用文件:{basic_file} 目标文件:{override_file} 位置:{path}\n')
|
||||
|
||||
# 查询枚举类型数据的枚举定义
|
||||
def _recursive_search(dictionary, key):
|
||||
if key in dictionary:
|
||||
return dictionary[key]
|
||||
else:
|
||||
for value in dictionary.values():
|
||||
if isinstance(value, dict):
|
||||
result = _recursive_search(value, key)
|
||||
if result is not None:
|
||||
return result
|
||||
return None
|
||||
|
||||
def _compare_versions(src, dest):
|
||||
src_nums = re.findall(r'\d+', src)
|
||||
dest_nums = re.findall(r'\d+', dest)
|
||||
lengh = len(src_nums) if len(src_nums) > len(dest_nums) else len(dest_nums)
|
||||
ret = -1 if len(src_nums) > len(dest_nums) else 1 if len(src_nums) < len(dest_nums) else 0
|
||||
for i in range(0, lengh):
|
||||
if dest_nums[i] > src_nums[i]:
|
||||
return 1
|
||||
if dest_nums[i] < src_nums[i]:
|
||||
return -1
|
||||
return ret
|
||||
|
||||
def _calculate_default_version(data:dict):
|
||||
versions = list(data.keys())
|
||||
if '_default_version' in versions:
|
||||
return data.get('_default_version')
|
||||
default_version = ''
|
||||
for version in versions:
|
||||
if default_version == '':
|
||||
default_version = version
|
||||
continue
|
||||
if 1 == _compare_versions(default_version, version):
|
||||
default_version = version
|
||||
return default_version
|
||||
|
||||
def check_value_type(basic_data:dict, override_data:dict, path:str, app, version, basic_file, override_file):
|
||||
basic_group = basic_data
|
||||
override_group = override_data
|
||||
for group in path.split('.'):
|
||||
basic_group = basic_group[group]
|
||||
override_group = override_group[group]
|
||||
result = []
|
||||
for key, value in override_group.items():
|
||||
if key in basic_group:
|
||||
if not isinstance(value, dict):
|
||||
continue
|
||||
basic_key_is_group = True if '_default' in next(iter(value.values())) else False
|
||||
override_key_is_group = True if '_default' in next(iter(value.values())) else False
|
||||
# 同名但是一个是组,一个是键
|
||||
if basic_key_is_group != override_key_is_group:
|
||||
result.append((basic_file, override_file, f'{app}/{version}/{path}/{key}'))
|
||||
else:
|
||||
# 组
|
||||
if basic_key_is_group and override_key_is_group:
|
||||
check_value_type(basic_data, override_data, f'{path}.{key}', app, version, basic_file, override_file)
|
||||
else:
|
||||
basic_key_type = basic_group[key]['_type']
|
||||
override_key_type = override_group[key]['_type']
|
||||
if basic_key_type != override_key_type:
|
||||
type_list.append((basic_file, override_file, f'{app}/{version}/{path}/{key}'))
|
||||
# 获取组的权限,未声明默认'public'
|
||||
basic_key_permission = basic_group.get('_permission', 'public')
|
||||
override_key_permission = override_group.get('_permission', 'public')
|
||||
# 读取键的权限,未声明则使用组权限
|
||||
basic_key_permission = basic_group[key].get('_permission', basic_key_permission)
|
||||
override_key_permission = override_group[key].get('_permission', override_key_permission)
|
||||
if basic_key_permission != override_key_permission:
|
||||
permission_list.append((basic_file, override_file, f'{app}/{version}/{path}/{key}'))
|
||||
|
||||
basic_key_range = basic_group[key].get('_range', '')
|
||||
override_key_range = override_group[key].get('_range', '')
|
||||
if basic_key_range and override_key_range:
|
||||
if basic_key_type == 'enum':
|
||||
basic_key_range = _recursive_search(basic_data, basic_key_range[1:])
|
||||
override_key_range = _recursive_search(override_data, override_key_range[1:])
|
||||
if basic_key_range != override_key_range:
|
||||
range_list.append((basic_file, override_file, f'{app}/{version}/{path}/{key}'))
|
||||
# elif basic_key_range == '' and override_key_range != '':
|
||||
# range_list.append((basic_file, override_file, f'{app}/{version}/{path}/{key}'))
|
||||
# elif basic_key_range != '' and override_key_range == '':
|
||||
# range_list.append((basic_file, override_file, f'{app}/{version}/{path}/{key}'))
|
||||
return result
|
||||
|
||||
# 检查组配置文件
|
||||
def check_group_config(basic_data, override_data, basic_file, override_file):
|
||||
for app, app_data in basic_data.items():
|
||||
for version, version_data in app_data.items():
|
||||
groups = set(override_data.keys())
|
||||
for group in groups:
|
||||
if group in version_data:
|
||||
if not isinstance(version_data[group], dict):
|
||||
continue
|
||||
check_value_type(version_data, override_data, group, app, version, basic_file, override_file)
|
||||
|
||||
# 检查应用配置文件
|
||||
def check_app_config(basic_data, override_data, basic_file, override_file):
|
||||
version_err = []
|
||||
for app, app_data in override_data.items():
|
||||
if app in basic_data:
|
||||
# 读取应用支持版本号区间
|
||||
min_version = ''
|
||||
max_version = ''
|
||||
if os.path.exists(f'/etc/kylin-config/compatibility/{app}-compatibility-settings.yaml'):
|
||||
with open(f'/etc/kylin-config/compatibility/{app}-compatibility-settings.yaml', 'r') as f:
|
||||
version_range = yaml.safe_load(f)
|
||||
min_version = version_range[app]['compatibility']['min_version']
|
||||
max_version = version_range[app]['compatibility']['max_version']
|
||||
versions = set(basic_data[app].keys()) | set(override_data[app].keys())
|
||||
for version in versions:
|
||||
if (version == '_default_version'):
|
||||
continue
|
||||
if min_version and max_version:
|
||||
if -1 == _compare_versions(version, min_version) or 1 == _compare_versions(version, max_version):
|
||||
version_list.append((basic_file, override_file, f'{app}/{version}'))
|
||||
else:
|
||||
# 定制文件版本是否比应用文件版本高 待定?
|
||||
pass
|
||||
if version in basic_data[app] and version in override_data[app]:
|
||||
for group in override_data[app][version]:
|
||||
if not isinstance(override_data[app][version][group], dict):
|
||||
continue
|
||||
check_value_type(basic_data[app][version], override_data[app][version], group, app, version, basic_file, override_file)
|
||||
|
||||
def check_one_app(basic_data, basic_file):
|
||||
for dir in override_dirs:
|
||||
for root, dirs, files in os.walk(dir):
|
||||
for file in files:
|
||||
override_file = f'{root}/{file}'
|
||||
with open(override_file, 'r') as f:
|
||||
override_data = yaml.safe_load(f)
|
||||
for value in override_data.values():
|
||||
is_group_file = True if '_default' in next(iter(value.values())) else False
|
||||
if is_group_file:
|
||||
check_group_config(basic_data, override_data, basic_file, override_file)
|
||||
else:
|
||||
check_app_config(basic_data, override_data, basic_file, override_file)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print("example: 111.py /home/xxx/output.txt")
|
||||
sys.exit()
|
||||
output_file = sys.argv[1]
|
||||
for root, dirs, files in os.walk('/etc/kylin-config/basic'):
|
||||
for file in files:
|
||||
basic_file = f'{root}/{file}'
|
||||
with open(basic_file, 'r') as f:
|
||||
basic_data = yaml.safe_load(f)
|
||||
check_one_app(basic_data, basic_file)
|
||||
print_err()
|
|
@ -9,6 +9,7 @@ import tkinter as tk
|
|||
import tkinter.ttk as ttk
|
||||
import tkinter.messagebox as msgbox
|
||||
import tkinter.filedialog as filedialog
|
||||
import tkinter.simpledialog as simpledialog
|
||||
import dbus
|
||||
from gi.repository import GLib
|
||||
|
||||
|
@ -25,14 +26,16 @@ def close_menu(event):
|
|||
download_menu.unpost()
|
||||
|
||||
def on_search():
|
||||
pack_list = root.pack_slaves()
|
||||
if view_frame in pack_list:
|
||||
text = search_button.cget('text')
|
||||
if text == 'search':
|
||||
search_button.config(text='cancel')
|
||||
view_frame.pack_forget()
|
||||
search_frame.pack(side='bottom', fill='both', expand=True)
|
||||
search_tree.delete(*search_tree.get_children())
|
||||
search_entry.config(state='normal')
|
||||
# search_entry.event_generate("<KeyRelease>")
|
||||
else:
|
||||
elif text == 'cancel':
|
||||
search_button.config(text='search')
|
||||
search_frame.pack_forget()
|
||||
view_frame.pack(side='bottom', fill='both', expand=True)
|
||||
items = tree.selection()
|
||||
|
@ -55,21 +58,60 @@ def on_search_entry_change(event):
|
|||
search_tree.insert('', 'end', text= key)
|
||||
|
||||
def on_download():
|
||||
class MultiSelectDialog(tk.simpledialog.Dialog):
|
||||
def body(self, master):
|
||||
self.results = []
|
||||
self.options = list(target_view.keys())
|
||||
self.vars = []
|
||||
for i, option in enumerate(self.options):
|
||||
var = tk.IntVar()
|
||||
checkbutton = tk.Checkbutton(master, text=option, variable=var)
|
||||
checkbutton.grid(row=i, sticky='w')
|
||||
self.vars.append(var)
|
||||
|
||||
select_all_button = tk.Button(master, text="全选", command=self.all_select)
|
||||
select_all_button.grid(row=len(self.options), column=0, sticky='w')
|
||||
|
||||
select_none_button = tk.Button(master, text="全不选", command=self.none_select)
|
||||
select_none_button.grid(row=len(self.options), column=1, sticky='w')
|
||||
|
||||
def apply(self):
|
||||
self.results = [option for var, option in zip(self.vars, self.options) if var.get() == 1]
|
||||
|
||||
def all_select(self):
|
||||
for var in self.vars:
|
||||
var.set(1)
|
||||
|
||||
def none_select(self):
|
||||
for var in self.vars:
|
||||
var.set(0)
|
||||
|
||||
global target_view
|
||||
path = filedialog.askdirectory(mustexist=True, title=' Choose a folder')
|
||||
if path:
|
||||
success = converter.editor_save(target_view, path)
|
||||
if success:
|
||||
msgbox.showinfo(message='Save successed')
|
||||
else:
|
||||
msgbox.showinfo(message='Save failed')
|
||||
dialog = MultiSelectDialog(root, title="Multi-Select Dialog")
|
||||
if dialog.results != []:
|
||||
path = filedialog.askdirectory(mustexist=True, title=' Choose a folder')
|
||||
if path:
|
||||
try:
|
||||
converter._value_override_default(target_view)
|
||||
for app in dialog.results:
|
||||
yaml_file_path = f'{path}/{app}.yaml'
|
||||
if os.path.exists(yaml_file_path):
|
||||
msgbox.askyesno(message=f'{yaml_file_path} is existed. Do you want to replace it')
|
||||
else:
|
||||
with open(yaml_file_path, 'w') as yaml_file:
|
||||
yaml_file.write(yaml.safe_dump({app:target_view[app]}, allow_unicode = True))
|
||||
msgbox.showinfo(message='Save successed')
|
||||
except Exception as e:
|
||||
msgbox.showinfo(message='Save failed')
|
||||
|
||||
def on_download_one():
|
||||
global target_view
|
||||
key = tree.item(right_select_item, 'text')
|
||||
app = tree.item(right_select_item, 'text')
|
||||
apps = []
|
||||
apps.append(app)
|
||||
path = filedialog.askdirectory(mustexist=True, title=' Choose a folder')
|
||||
if path:
|
||||
success = converter.editor_save({key:target_view[key]}, path)
|
||||
success = converter.editor_save(apps, target_view, path)
|
||||
if success:
|
||||
msgbox.showinfo(message='Save successed')
|
||||
else:
|
||||
|
@ -85,40 +127,80 @@ def on_set():
|
|||
|
||||
user = destination_file.split('/')[2]
|
||||
|
||||
key = id = value = ''
|
||||
key = id = value = permission = type = range = ''
|
||||
for widget in inner_frame.winfo_children():
|
||||
if isinstance(widget, tk.Text):
|
||||
if 'key' in widget.winfo_name:
|
||||
key = widget.get()
|
||||
if 'id' in widget.winfo_name:
|
||||
id = widget.get()
|
||||
if 'custom' in widget.winfo_name:
|
||||
value = widget.get()
|
||||
if 'key' == widget.winfo_name():
|
||||
key = widget.get(1.0, 'end')
|
||||
key = key.strip()
|
||||
if 'id' == widget.winfo_name():
|
||||
id = widget.get(1.0, 'end')
|
||||
id = id.strip()
|
||||
if 'type' == widget.winfo_name():
|
||||
type = widget.get(1.0, 'end')
|
||||
type = type.strip()
|
||||
if 'permission' == widget.winfo_name():
|
||||
permission = widget.get(1.0, 'end')
|
||||
permission = permission.strip()
|
||||
if 'range' == widget.winfo_name():
|
||||
range = widget.get(1.0, 'end')
|
||||
range = range.strip()
|
||||
if 'custom' == widget.winfo_name():
|
||||
value = widget.get(1.0, 'end')
|
||||
value = value.strip()
|
||||
|
||||
path = search_entry.get()
|
||||
version = path.split('/')[1]
|
||||
print(f'{user} {id} {version} {key} {value}')
|
||||
|
||||
# 类型检测
|
||||
try:
|
||||
if type != 'enum':
|
||||
variant_type = GLib.VariantType(type)
|
||||
variant = GLib.Variant.parse(variant_type, value)
|
||||
except Exception as e:
|
||||
msgbox.showinfo('unknown keyword')
|
||||
return
|
||||
|
||||
# 取值范围检测
|
||||
if type == 'enum' and value not in range:
|
||||
msgbox.showinfo(message='Out of range')
|
||||
return
|
||||
elif type != 'enum' and range != '':
|
||||
try:
|
||||
min = GLib.Variant.parse(variant_type, range.split(',')[0].strip())
|
||||
max = GLib.Variant.parse(variant_type, range.split(',')[1].strip())
|
||||
if variant.compare(min) < 0 or variant.compare(max) > 0:
|
||||
msgbox.showinfo(message='Out of range')
|
||||
return
|
||||
except Exception as e:
|
||||
msgbox.showinfo(message=e)
|
||||
return
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
obj = bus.get_object('com.kylin.kysdk.conf2', '/com/kylin/kysdk/conf2')
|
||||
interface = dbus.Interface(obj, 'com.kylin.kysdk.conf2')
|
||||
# success = interface.set(user, id, version, key, value)
|
||||
# if success:
|
||||
# global target_view
|
||||
# target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
|
||||
# msgbox.showinfo(message='Set successed')
|
||||
# else:
|
||||
# msgbox.showinfo(message='Set failed')
|
||||
obj_interface = dbus.Interface(obj, dbus_interface='com.kylin.kysdk.conf2')
|
||||
success = obj_interface.set(user, id, version, key, value)
|
||||
if success:
|
||||
global target_view
|
||||
target_view = converter._db2dict(f'{destination_file}/.config/kylin-config/user.db')
|
||||
msgbox.showinfo(message='Set successed')
|
||||
else:
|
||||
msgbox.showinfo(message='Set failed')
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def on_search_tree_select(event):
|
||||
items = search_tree.selection()
|
||||
text = search_tree.item(items[0], 'text')
|
||||
text = search_tree.item(items, 'text')
|
||||
if text == '':
|
||||
return
|
||||
tree.selection_set(search_list[text])
|
||||
tree.see(search_list[text])
|
||||
search_frame.pack_forget()
|
||||
view_frame.pack(side='bottom', fill='both', expand=True)
|
||||
search_button_text = search_button.cget('text')
|
||||
if search_button_text == 'cancel':
|
||||
search_button.config(text='search')
|
||||
|
||||
def on_tree_select(event):
|
||||
selected_item = tree.selection()
|
||||
|
@ -180,7 +262,7 @@ def on_tree_select(event):
|
|||
summary_label = tk.Label(inner_frame, text=f'摘要', anchor='w')
|
||||
summary_label.pack(side='top', fill='x')
|
||||
|
||||
summary_text = tk.Text(inner_frame, height=3, width=100, wrap='word')
|
||||
summary_text = tk.Text(inner_frame, height=3, width=100, wrap='word', name='summary')
|
||||
summary_text.insert('1.0', tmp.get('_summary'))
|
||||
summary_text.config(state='disabled')
|
||||
summary_text.pack(side='top', fill='x', expand=True)
|
||||
|
@ -189,7 +271,7 @@ def on_tree_select(event):
|
|||
decription_label = tk.Label(inner_frame, text=f'描述', anchor='w')
|
||||
decription_label.pack(side='top', fill='x')
|
||||
|
||||
decription_text = tk.Text(inner_frame, height=3, width=100, wrap='word')
|
||||
decription_text = tk.Text(inner_frame, height=3, width=100, wrap='word' ,name='description')
|
||||
decription_text.insert('1.0', tmp.get('_description'))
|
||||
decription_text.config(state='disabled')
|
||||
decription_text.pack(side='top', fill='x', expand=True)
|
||||
|
@ -198,11 +280,33 @@ def on_tree_select(event):
|
|||
permission_label = tk.Label(inner_frame, text=f'权限', anchor='w')
|
||||
permission_label.pack(side='top', fill='x')
|
||||
|
||||
permission_text = tk.Text(inner_frame, height=1, width=100, wrap='word')
|
||||
permission_text = tk.Text(inner_frame, height=1, width=100, wrap='word', name='permission')
|
||||
permission_text.insert('1.0', permission)
|
||||
permission_text.config(state='disabled')
|
||||
permission_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
if tmp.get('_range') is not None:
|
||||
decription_label = tk.Label(inner_frame, text=f'取值范围', anchor='w')
|
||||
decription_label.pack(side='top', fill='x')
|
||||
range = tmp.get('_range')
|
||||
if tmp.get('_type') == 'enum':
|
||||
if range.startswith('@'):
|
||||
path = search_entry.get()
|
||||
version_data = target_view[path.split('/')[0]][path.split('/')[1]]
|
||||
# _开头的应该是内部函数仅在类内部使用,但我实在懒得搬代码了
|
||||
element_list = converter._recursive_search(version_data, range[1:])
|
||||
value_list = []
|
||||
for element in element_list:
|
||||
value_list.append(element['_nick'])
|
||||
range = str(value_list)
|
||||
else:
|
||||
data = yaml.safe_load(range)
|
||||
range = str(list(data.keys()))
|
||||
decription_text = tk.Text(inner_frame, height=3, width=100, wrap='word' ,name='range')
|
||||
decription_text.insert('1.0', range)
|
||||
decription_text.config(state='disabled')
|
||||
decription_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
if '_default' in tmp:
|
||||
default_value = tmp['_default']
|
||||
if isinstance(default_value, bool):
|
||||
|
@ -216,16 +320,17 @@ def on_tree_select(event):
|
|||
default_text.config(state='disabled')
|
||||
default_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
custom_value = tmp.get('_value')
|
||||
if custom_value is None or custom_value == default_value:
|
||||
custom_value = '默认值'
|
||||
custom_label = tk.Label(inner_frame, text=f'当前值', anchor='w')
|
||||
custom_label.pack(side='top', fill='x')
|
||||
if combobox.get() == 'custom':
|
||||
custom_value = tmp.get('_value')
|
||||
if custom_value is None:
|
||||
custom_value = '默认值'
|
||||
custom_label = tk.Label(inner_frame, text=f'当前值', anchor='w')
|
||||
custom_label.pack(side='top', fill='x')
|
||||
|
||||
custom_text = tk.Text(inner_frame, height=5, width=100, wrap='word', name='custom')
|
||||
custom_text.insert('1.0', custom_value)
|
||||
custom_text.config(state='disabled')
|
||||
custom_text.pack(side='top', fill='x', expand=True)
|
||||
custom_text = tk.Text(inner_frame, height=5, width=100, wrap='word', name='custom')
|
||||
custom_text.insert('1.0', custom_value)
|
||||
custom_text.config(state='disabled')
|
||||
custom_text.pack(side='top', fill='x', expand=True)
|
||||
|
||||
if type != 'group' and permission == 'public' and combobox.get() == 'custom':
|
||||
custom_text.config(state='normal')
|
||||
|
@ -275,7 +380,7 @@ root.bind("<Button-1>", close_menu)
|
|||
|
||||
download_menu = tk.Menu(root, tearoff=0)
|
||||
download_menu.add_command(label="下载", command=on_download_one)
|
||||
download_menu.add_command(label="导入到其他目录", command=on_import_file)
|
||||
# download_menu.add_command(label="导入到其他目录", command=on_import_file)
|
||||
|
||||
search_list = {}
|
||||
|
||||
|
@ -302,19 +407,19 @@ search_entry = tk.Entry(button_frame, state='readonly')
|
|||
search_entry.bind("<KeyRelease>", on_search_entry_change)
|
||||
|
||||
# 搜索按钮
|
||||
# search_icon = tk.BitmapImage(data=search_icon_data)
|
||||
search_button = tk.Button(button_frame, text= 's', command=on_search, width=20)
|
||||
# search_icon = tk.PhotoImage('/etc/kylin-config/search.png')
|
||||
search_button = tk.Button(button_frame, text='search', command=on_search, width=20)
|
||||
|
||||
# 下载按钮
|
||||
# download_icon = tk.PhotoImage(file="download_icon.png")
|
||||
download_button = tk.Button(button_frame, text= 'd', command=on_download, width=20)
|
||||
# download_icon = tk.PhotoImage(file="/etc/kylin-config/download.png")
|
||||
download_button = tk.Button(button_frame, text='export', command=on_download, width=20)
|
||||
|
||||
# 视图选择列表
|
||||
with open('/etc/kylin-config/conf2.yaml', 'r') as file:
|
||||
configures = yaml.safe_load(file)
|
||||
options = configures['dirs']
|
||||
if os.path.exists(f'{destination_file}/.config/kylin-config/configs'):
|
||||
options.append('user')
|
||||
options.append('mutable')
|
||||
options.append('custom')
|
||||
options.reverse()
|
||||
|
||||
|
@ -354,16 +459,33 @@ right_frame.pack(side='right', fill='both', expand=True)
|
|||
# 创建一个Canvas
|
||||
canvas = tk.Canvas(right_frame)
|
||||
canvas.pack(side="left", fill="both", expand=True)
|
||||
|
||||
# 将Canvas的窗口设置为Frame
|
||||
inner_frame = tk.Frame(canvas)
|
||||
inner_frame.grid(row=0, column=0, sticky="nsew")
|
||||
canvas_window = canvas.create_window((0, 0), window=inner_frame, anchor="nw")
|
||||
canvas.config(scrollregion=canvas.bbox("all"))
|
||||
|
||||
right_scrollbar = ttk.Scrollbar(right_frame, orient="vertical", command=canvas.yview)
|
||||
right_scrollbar.pack(side="right", fill="y")
|
||||
canvas.configure(yscrollcommand=right_scrollbar.set)
|
||||
|
||||
# 将Canvas的窗口设置为Frame
|
||||
inner_frame = tk.Frame(canvas)
|
||||
|
||||
canvas_window = canvas.create_window((0, 0), window=inner_frame, anchor="nw")
|
||||
inner_frame.bind("<Configure>", lambda event: canvas.config(scrollregion=canvas.bbox("all")))
|
||||
# 控制滚动条滚动 Button-4是向上滚动, Button-5是向下滚动 event.num的数值代表按钮id
|
||||
def on_mouse_scroll(event):
|
||||
inner_height = inner_frame.winfo_height()
|
||||
canvas_height = canvas.winfo_height()
|
||||
# 内容长度是否需要滚动
|
||||
if inner_height > canvas_height:
|
||||
# 仅响应在canvas空间区域的滚轮事件
|
||||
if canvas.winfo_containing(event.x_root, event.y_root) == canvas:
|
||||
if event.num == 4:
|
||||
canvas.yview_scroll(-2, "units")
|
||||
elif event.num == 5:
|
||||
canvas.yview_scroll(2, "units")
|
||||
|
||||
canvas.bind_all("<Button-4>", on_mouse_scroll)
|
||||
canvas.bind_all("<Button-5>", on_mouse_scroll)
|
||||
|
||||
# 创建Treeview显示搜索匹配的路径
|
||||
search_tree = ttk.Treeview(search_frame, show='tree')
|
||||
search_tree.bind("<<TreeviewSelect>>", on_search_tree_select)
|
||||
|
@ -373,4 +495,4 @@ search_scrollbar = ttk.Scrollbar(search_frame, orient="vertical", command=search
|
|||
search_scrollbar.pack(side="right", fill="y")
|
||||
search_tree.configure(yscrollcommand=search_scrollbar.set)
|
||||
|
||||
root.mainloop()
|
||||
root.mainloop()
|
|
@ -18,6 +18,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
/*于2.5.1.0版本舍弃,专用python实现可视化工具*/
|
||||
|
||||
#include "../api/libkysettings.h"
|
||||
#include "../api/ksettingsschema.h"
|
||||
|
||||
|
@ -847,4 +850,4 @@ int main(int argc, char *argv[])
|
|||
|
||||
gtk_main();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ static void print_help()
|
|||
" writable Check if a key is writable\n"
|
||||
" monitor Watch for changes\n"
|
||||
// " monitor-reload Watch for realod\n"
|
||||
" reload Reload configuration file, retain user configuration"
|
||||
" save Save User config in target folder"
|
||||
"\n"
|
||||
"Use kconf2 help \"COMMAND\" to get detailed help.\n");
|
||||
|
@ -281,11 +282,11 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (0 == strcmp(argv[1], "list-schemas"))
|
||||
{
|
||||
if (argc < 3)
|
||||
{
|
||||
print_command("list-schemas");
|
||||
exit(0);
|
||||
}
|
||||
// if (argc < 3)
|
||||
// {
|
||||
// print_command("list-schemas");
|
||||
// exit(0);
|
||||
// }
|
||||
gboolean limit_app = FALSE, limit_version = FALSE;
|
||||
if (argc > 2)
|
||||
limit_app = TRUE;
|
||||
|
@ -643,4 +644,4 @@ int main(int argc, char *argv[])
|
|||
print_help();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue