| Index: src/storage.c
|
| diff --git a/src/storage.c b/src/storage.c
|
| index 4eea5a84e304670137909d7ecadf29b59e1e2040..81f517acc34a4e3613edaa777a97c233beae085d 100644
|
| --- a/src/storage.c
|
| +++ b/src/storage.c
|
| @@ -23,6 +23,7 @@
|
| #include <config.h>
|
| #endif
|
|
|
| +#include <stdio.h>
|
| #include <unistd.h>
|
|
|
| #include "connman.h"
|
| @@ -71,39 +72,86 @@ void connman_storage_unregister(struct connman_storage *storage)
|
| }
|
|
|
| void __connman_storage_set_encrypted_value(GKeyFile *keyfile,
|
| - const char *profile_name, const char *section, const char *key,
|
| - const char *value)
|
| + const char *section, const char *key, const char *value)
|
| {
|
| - char *cryptvalue = __connman_crypto_encrypt_keyvalue(
|
| - profile_name, key, value);
|
| + char *cryptvalue = __connman_crypto_encrypt_keyvalue(key, value);
|
| g_key_file_set_string(keyfile, section, key, cryptvalue);
|
| g_free(cryptvalue);
|
| }
|
|
|
| char *__connman_storage_get_encrypted_value(GKeyFile *keyfile,
|
| - const char *profile_name, const char *section, const char *key)
|
| + const char *section, const char *key)
|
| {
|
| - char *ciphertext = g_key_file_get_string(keyfile, section, key, NULL);
|
| + char *ciphertext, *plaintext;
|
| +
|
| + ciphertext = g_key_file_get_string(keyfile, section, key, NULL);
|
| if (ciphertext == NULL)
|
| return NULL;
|
|
|
| - char *plaintext = __connman_crypto_decrypt_keyvalue(
|
| - profile_name, key, ciphertext);
|
| + plaintext = __connman_crypto_decrypt_keyvalue(key, ciphertext);
|
| g_free(ciphertext);
|
|
|
| return plaintext;
|
| }
|
|
|
| -GKeyFile *__connman_storage_open(const char *ident)
|
| +static const char *__getpath(const struct connman_storage_ident *ident)
|
| +{
|
| + static char path[80];
|
| +
|
| + if (ident->user != NULL) {
|
| + /* TODO(sleffler) worth using getpwnam & co? */
|
| + /* TODO(sleffler) at least use #define */
|
| + snprintf(path, sizeof(path), STORAGE_HOMEDIR "/%s.profile",
|
| + ident->user, ident->ident);
|
| + } else {
|
| + snprintf(path, sizeof(path), STORAGEDIR "/%s.profile",
|
| + ident->ident);
|
| + }
|
| + return path;
|
| +}
|
| +
|
| +static char *getpath(const struct connman_storage_ident *ident)
|
| +{
|
| + if (ident->user != NULL) {
|
| + /* TODO(sleffler) worth using getpwnam & co? */
|
| + /* TODO(sleffler) at least use #define */
|
| + return g_strdup_printf(STORAGE_HOMEDIR "/%s.profile",
|
| + ident->user, ident->ident);
|
| + } else {
|
| + return g_strdup_printf(STORAGEDIR "/%s.profile", ident->ident);
|
| + }
|
| +}
|
| +
|
| +gboolean __connman_storage_exists(const struct connman_storage_ident *ident)
|
| +{
|
| + gchar *pathname, *data = NULL;
|
| + gboolean result;
|
| + gsize length;
|
| +
|
| + _DBG_STORAGE("ident %s", __getpath(ident));
|
| +
|
| + pathname = getpath(ident);
|
| + if (pathname == NULL)
|
| + return FALSE;
|
| +
|
| + result = g_file_get_contents(pathname, &data, &length, NULL);
|
| +
|
| + g_free(pathname);
|
| + g_free(data);
|
| +
|
| + return result;
|
| +}
|
| +
|
| +GKeyFile *__connman_storage_open(const struct connman_storage_ident *ident)
|
| {
|
| GKeyFile *keyfile;
|
| gchar *pathname, *data = NULL;
|
| gboolean result;
|
| gsize length;
|
|
|
| - _DBG_STORAGE("ident %s", ident);
|
| + _DBG_STORAGE("ident %s", __getpath(ident));
|
|
|
| - pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
|
| + pathname = getpath(ident);
|
| if (pathname == NULL)
|
| return NULL;
|
|
|
| @@ -127,27 +175,29 @@ done:
|
| return keyfile;
|
| }
|
|
|
| -void __connman_storage_close(const char *ident,
|
| +void __connman_storage_close(const struct connman_storage_ident *ident,
|
| GKeyFile *keyfile, gboolean save)
|
| {
|
| gchar *pathname, *data = NULL;
|
| gsize length = 0;
|
|
|
| - _DBG_STORAGE("ident %s keyfile %p save %d", ident, keyfile, save);
|
| + _DBG_STORAGE("ident %s keyfile %p save %d", __getpath(ident),
|
| + keyfile, save);
|
|
|
| if (save == FALSE) {
|
| g_key_file_free(keyfile);
|
| return;
|
| }
|
|
|
| - pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
|
| + pathname = getpath(ident);
|
| if (pathname == NULL)
|
| return;
|
|
|
| data = g_key_file_to_data(keyfile, &length, NULL);
|
|
|
| if (g_file_set_contents(pathname, data, length, NULL) == FALSE)
|
| - connman_error("Failed to store information");
|
| + connman_error("%s: failed to store data for %s:%s",
|
| + __func__, ident->user, ident->ident);
|
|
|
| g_free(data);
|
|
|
| @@ -156,18 +206,20 @@ void __connman_storage_close(const char *ident,
|
| g_key_file_free(keyfile);
|
| }
|
|
|
| -void __connman_storage_delete(const char *ident)
|
| +void __connman_storage_delete(const struct connman_storage_ident *ident)
|
| {
|
| gchar *pathname;
|
|
|
| - _DBG_STORAGE("ident %s", ident);
|
| + _DBG_STORAGE("ident %s", __getpath(ident));
|
|
|
| - pathname = g_strdup_printf("%s/%s.profile", STORAGEDIR, ident);
|
| + pathname = getpath(ident);
|
| if (pathname == NULL)
|
| return;
|
|
|
| if (unlink(pathname) < 0)
|
| connman_error("Failed to remove %s", pathname);
|
| +
|
| + g_free(pathname);
|
| }
|
|
|
| int __connman_storage_init_profile(void)
|
| @@ -224,7 +276,36 @@ int __connman_storage_save_profile(struct connman_profile *profile)
|
| return -ENOENT;
|
| }
|
|
|
| -int __connman_storage_load_service(struct connman_service *service)
|
| +/*
|
| + * Load/Save object support. Walk the list of registered
|
| + * storage implementors until we find one that has a handler
|
| + * for the object type. The storage implementor template
|
| + * has per-object types (apparently) but these are not used
|
| + * at the moment.
|
| + */
|
| +#define DOLOAD(func, arg, profile_ident) do { \
|
| + int err; \
|
| + GKeyFile *keyfile = __connman_storage_open(profile_ident); \
|
| + if (keyfile == NULL) \
|
| + return -ENXIO; \
|
| + err = func(arg, keyfile); \
|
| + __connman_storage_close(profile_ident, keyfile, FALSE); \
|
| + return err; \
|
| +} while (0)
|
| +
|
| +#define DOSAVE(func, arg, profile_ident) do { \
|
| + int err; \
|
| + GKeyFile *keyfile = __connman_storage_open(profile_ident); \
|
| + if (keyfile == NULL) \
|
| + return -ENXIO; \
|
| + err = func(arg, keyfile); \
|
| + /* NB: always write-back for compatibility */ \
|
| + __connman_storage_close(profile_ident, keyfile, TRUE); \
|
| + return err; \
|
| +} while (0)
|
| +
|
| +int __connman_storage_load_service(struct connman_service *service,
|
| + const struct connman_storage_ident *profile_ident)
|
| {
|
| GSList *list;
|
|
|
| @@ -233,16 +314,14 @@ int __connman_storage_load_service(struct connman_service *service)
|
| for (list = storage_list; list; list = list->next) {
|
| struct connman_storage *storage = list->data;
|
|
|
| - if (storage->service_load) {
|
| - if (storage->service_load(service) == 0)
|
| - return 0;
|
| - }
|
| + if (storage->service_load)
|
| + DOLOAD(storage->service_load, service, profile_ident);
|
| }
|
| -
|
| return -ENOENT;
|
| }
|
|
|
| -int __connman_storage_save_service(struct connman_service *service)
|
| +int __connman_storage_save_service(struct connman_service *service,
|
| + const struct connman_storage_ident *profile_ident)
|
| {
|
| GSList *list;
|
|
|
| @@ -251,16 +330,14 @@ int __connman_storage_save_service(struct connman_service *service)
|
| for (list = storage_list; list; list = list->next) {
|
| struct connman_storage *storage = list->data;
|
|
|
| - if (storage->service_save) {
|
| - if (storage->service_save(service) == 0)
|
| - return 0;
|
| - }
|
| + if (storage->service_save)
|
| + DOSAVE(storage->service_save, service, profile_ident);
|
| }
|
| -
|
| return -ENOENT;
|
| }
|
|
|
| -int __connman_storage_load_device(struct connman_device *device)
|
| +int __connman_storage_load_device(struct connman_device *device,
|
| + const struct connman_storage_ident *profile_ident)
|
| {
|
| GSList *list;
|
|
|
| @@ -269,16 +346,14 @@ int __connman_storage_load_device(struct connman_device *device)
|
| for (list = storage_list; list; list = list->next) {
|
| struct connman_storage *storage = list->data;
|
|
|
| - if (storage->device_load) {
|
| - if (storage->device_load(device) == 0)
|
| - return 0;
|
| - }
|
| + if (storage->device_load)
|
| + DOLOAD(storage->device_load, device, profile_ident);
|
| }
|
| -
|
| return -ENOENT;
|
| }
|
|
|
| -int __connman_storage_save_device(struct connman_device *device)
|
| +int __connman_storage_save_device(struct connman_device *device,
|
| + const struct connman_storage_ident *profile_ident)
|
| {
|
| GSList *list;
|
|
|
| @@ -287,16 +362,14 @@ int __connman_storage_save_device(struct connman_device *device)
|
| for (list = storage_list; list; list = list->next) {
|
| struct connman_storage *storage = list->data;
|
|
|
| - if (storage->device_save) {
|
| - if (storage->device_save(device) == 0)
|
| - return 0;
|
| - }
|
| + if (storage->device_save)
|
| + DOSAVE(storage->device_save, device, profile_ident);
|
| }
|
| -
|
| return -ENOENT;
|
| }
|
|
|
| -int __connman_storage_load_ipconfig(struct connman_ipconfig *ipconfig)
|
| +int __connman_storage_load_ipconfig(struct connman_ipconfig *ipconfig,
|
| + const struct connman_storage_ident *profile_ident)
|
| {
|
| GSList *list;
|
|
|
| @@ -305,16 +378,14 @@ int __connman_storage_load_ipconfig(struct connman_ipconfig *ipconfig)
|
| for (list = storage_list; list; list = list->next) {
|
| struct connman_storage *storage = list->data;
|
|
|
| - if (storage->ipconfig_load) {
|
| - if (storage->ipconfig_load(ipconfig) == 0)
|
| - return 0;
|
| - }
|
| + if (storage->ipconfig_load)
|
| + DOLOAD(storage->ipconfig_load, ipconfig, profile_ident);
|
| }
|
| -
|
| return -ENOENT;
|
| }
|
|
|
| -int __connman_storage_save_ipconfig(const struct connman_ipconfig *ipconfig)
|
| +int __connman_storage_save_ipconfig(const struct connman_ipconfig *ipconfig,
|
| + const struct connman_storage_ident *profile_ident)
|
| {
|
| GSList *list;
|
|
|
| @@ -323,12 +394,9 @@ int __connman_storage_save_ipconfig(const struct connman_ipconfig *ipconfig)
|
| for (list = storage_list; list; list = list->next) {
|
| struct connman_storage *storage = list->data;
|
|
|
| - if (storage->ipconfig_save) {
|
| - if (storage->ipconfig_save(ipconfig) == 0)
|
| - return 0;
|
| - }
|
| + if (storage->ipconfig_save)
|
| + DOSAVE(storage->ipconfig_save, ipconfig, profile_ident);
|
| }
|
| -
|
| return -ENOENT;
|
| }
|
|
|
|
|