/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2018 Red Hat, Inc. */ #include "src/core/nm-default-daemon.h" #include "nms-ifcfg-rh-storage.h" #include "nm-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "nm-connection.h" #include "nms-ifcfg-rh-plugin.h" /*****************************************************************************/ struct _NMSIfcfgRHStorageClass { NMSettingsStorageClass parent; }; G_DEFINE_TYPE(NMSIfcfgRHStorage, nms_ifcfg_rh_storage, NM_TYPE_SETTINGS_STORAGE) /*****************************************************************************/ gboolean nms_ifcfg_rh_storage_equal_type(const NMSIfcfgRHStorage *self_a, const NMSIfcfgRHStorage *self_b) { return (self_a == self_b) || (self_a && self_b && nm_streq0(nms_ifcfg_rh_storage_get_uuid_opt(self_a), nms_ifcfg_rh_storage_get_uuid_opt(self_b)) && nm_streq0(self_a->unmanaged_spec, self_b->unmanaged_spec) && nm_streq0(self_a->unrecognized_spec, self_b->unrecognized_spec)); } void nms_ifcfg_rh_storage_copy_content(NMSIfcfgRHStorage *dst, const NMSIfcfgRHStorage *src) { nm_assert(src != dst); nm_assert(src && dst); nm_assert(nms_ifcfg_rh_storage_equal_type(dst, src)); nm_assert(nms_ifcfg_rh_storage_get_filename(dst) && nm_streq(nms_ifcfg_rh_storage_get_filename(dst), nms_ifcfg_rh_storage_get_filename(src))); nm_g_object_ref_set(&dst->connection, src->connection); g_free(dst->unmanaged_spec); g_free(dst->unrecognized_spec); dst->unmanaged_spec = g_strdup(src->unmanaged_spec); dst->unrecognized_spec = g_strdup(src->unrecognized_spec); dst->stat_mtime = src->stat_mtime; } NMConnection * nms_ifcfg_rh_storage_steal_connection(NMSIfcfgRHStorage *self) { nm_assert(NMS_IS_IFCFG_RH_STORAGE(self)); return g_steal_pointer(&self->connection); } /*****************************************************************************/ static int cmp_fcn(const NMSIfcfgRHStorage *a, const NMSIfcfgRHStorage *b) { nm_assert(NMS_IS_IFCFG_RH_STORAGE(a)); nm_assert(NMS_IS_IFCFG_RH_STORAGE(b)); nm_assert(a != b); /* newer files are more important. */ NM_CMP_FIELD(a, b, stat_mtime.tv_sec); NM_CMP_FIELD(a, b, stat_mtime.tv_nsec); NM_CMP_DIRECT_STRCMP(nms_ifcfg_rh_storage_get_filename(a), nms_ifcfg_rh_storage_get_filename(b)); return 0; } /*****************************************************************************/ static void nms_ifcfg_rh_storage_init(NMSIfcfgRHStorage *self) {} static NMSIfcfgRHStorage * _storage_new(NMSIfcfgRHPlugin *plugin, const char *uuid, const char *filename) { nm_assert(NMS_IS_IFCFG_RH_PLUGIN(plugin)); nm_assert(!uuid || nm_utils_is_uuid(uuid)); nm_assert(filename && filename[0] == '/'); return g_object_new(NMS_TYPE_IFCFG_RH_STORAGE, NM_SETTINGS_STORAGE_PLUGIN, plugin, NM_SETTINGS_STORAGE_UUID, uuid, NM_SETTINGS_STORAGE_FILENAME, filename, NULL); } NMSIfcfgRHStorage * nms_ifcfg_rh_storage_new_connection(NMSIfcfgRHPlugin * plugin, const char * filename, NMConnection * connection_take, const struct timespec *mtime) { NMSIfcfgRHStorage *self; nm_assert(NM_IS_CONNECTION(connection_take)); nm_assert(_nm_connection_verify(connection_take, NULL) == NM_SETTING_VERIFY_SUCCESS); nmtst_connection_assert_unchanging(connection_take); self = _storage_new(plugin, nm_connection_get_uuid(connection_take), filename); self->connection = connection_take; if (mtime) self->stat_mtime = *mtime; return self; } NMSIfcfgRHStorage * nms_ifcfg_rh_storage_new_unhandled(NMSIfcfgRHPlugin *plugin, const char * filename, const char * unmanaged_spec, const char * unrecognized_spec) { NMSIfcfgRHStorage *self; nm_assert(unmanaged_spec || unrecognized_spec); self = _storage_new(plugin, NULL, filename); self->unmanaged_spec = g_strdup(unmanaged_spec); self->unrecognized_spec = g_strdup(unrecognized_spec); return self; } static void _storage_clear(NMSIfcfgRHStorage *self) { c_list_unlink(&self->parent._storage_lst); c_list_unlink(&self->parent._storage_by_uuid_lst); nm_clear_g_free(&self->unmanaged_spec); nm_clear_g_free(&self->unrecognized_spec); g_clear_object(&self->connection); } static void dispose(GObject *object) { NMSIfcfgRHStorage *self = NMS_IFCFG_RH_STORAGE(object); _storage_clear(self); G_OBJECT_CLASS(nms_ifcfg_rh_storage_parent_class)->dispose(object); } void nms_ifcfg_rh_storage_destroy(NMSIfcfgRHStorage *self) { _storage_clear(self); g_object_unref(self); } static void nms_ifcfg_rh_storage_class_init(NMSIfcfgRHStorageClass *klass) { GObjectClass * object_class = G_OBJECT_CLASS(klass); NMSettingsStorageClass *storage_class = NM_SETTINGS_STORAGE_CLASS(klass); object_class->dispose = dispose; storage_class->cmp_fcn = (int (*)(NMSettingsStorage *, NMSettingsStorage *)) cmp_fcn; }