VlockPlugin: add virtual open method
[vlock.git] / src / plugin.c
blob8fe337f7b5d0589327bf9caec0edc413afbf77b0
1 /* plugin.c -- generic plugin routines for vlock,
2 * the VT locking program for linux
4 * This program is copyright (C) 2007 Frank Benkstein, and is free
5 * software which is freely distributable under the terms of the
6 * GNU General Public License version 2, included as the file COPYING in this
7 * distribution. It is NOT public domain software, and any
8 * redistribution not permitted by the GNU General Public License is
9 * expressly forbidden without prior written permission from
10 * the author.
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
18 #include <glib.h>
20 #include "plugin.h"
21 #include "util.h"
23 /* Allocate a new plugin struct. */
24 struct plugin *new_plugin(const char *name, struct plugin_type *type)
26 struct plugin *p = malloc(sizeof *p);
27 char *last_slash;
29 if (p == NULL)
30 return NULL;
32 /* For security plugin names must not contain a slash. */
33 last_slash = strrchr(name, '/');
35 if (last_slash != NULL)
36 name = last_slash+1;
38 p->name = strdup(name);
40 if (p->name == NULL) {
41 free(p);
42 return NULL;
45 p->context = NULL;
46 p->save_disabled = false;
48 for (size_t i = 0; i < nr_dependencies; i++)
49 p->dependencies[i] = NULL;
51 p->type = type;
53 if (p->type->init(p)) {
54 return p;
55 } else {
56 destroy_plugin(p);
57 return NULL;
61 /* Destroy the given plugin. */
62 void destroy_plugin(struct plugin *p)
64 /* Call destroy method. */
65 p->type->destroy(p);
67 /* Destroy dependency lists. */
68 for (size_t i = 0; i < nr_dependencies; i++) {
69 while (p->dependencies[i] != NULL) {
70 free(p->dependencies[i]->data);
71 p->dependencies[i] = g_list_delete_link(p->dependencies[i], p->dependencies[i]);
75 free(p->name);
76 free(p);
79 bool call_hook(struct plugin *p, const char *hook_name)
81 return p->type->call_hook(p, hook_name);
84 GQuark vlock_plugin_error_quark(void)
86 return g_quark_from_static_string("vlock-plugin-error-quark");
89 G_DEFINE_TYPE(VlockPlugin, vlock_plugin, G_TYPE_OBJECT)
91 /* Initialize plugin to default values. */
92 static void vlock_plugin_init(VlockPlugin *self)
94 self->name = NULL;
97 /* Create new plugin object. */
98 static GObject *vlock_plugin_constructor(
99 GType gtype,
100 guint n_properties,
101 GObjectConstructParam *properties)
103 GObjectClass *parent_class = G_OBJECT_CLASS(vlock_plugin_parent_class);
104 GObject *object = parent_class->constructor(gtype, n_properties, properties);
105 VlockPlugin *self = VLOCK_PLUGIN(object);
107 g_return_val_if_fail(self->name != NULL, NULL);
109 return object;
112 /* Destroy plugin object. */
113 static void vlock_plugin_finalize(GObject *object)
115 VlockPlugin *self = VLOCK_PLUGIN(object);
116 g_free(self->name);
117 self->name = NULL;
119 G_OBJECT_CLASS(vlock_plugin_parent_class)->finalize(object);
122 /* Properties. */
123 enum {
124 PROP_VLOCK_PLUGIN_0,
125 PROP_VLOCK_PLUGIN_NAME
128 /* Set properties. */
129 static void vlock_plugin_set_property(
130 GObject *object,
131 guint property_id,
132 const GValue *value,
133 GParamSpec *pspec)
135 VlockPlugin *self = VLOCK_PLUGIN(object);
137 switch (property_id)
139 case PROP_VLOCK_PLUGIN_NAME:
140 g_free(self->name);
141 self->name = g_value_dup_string(value);
142 break;
143 default:
144 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
145 break;
149 /* Get properties. */
150 static void vlock_plugin_get_property(
151 GObject *object,
152 guint property_id,
153 GValue *value,
154 GParamSpec *pspec)
156 VlockPlugin *self = VLOCK_PLUGIN(object);
158 switch (property_id)
160 case PROP_VLOCK_PLUGIN_NAME:
161 g_value_set_string(value, self->name);
162 break;
163 default:
164 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
165 break;
169 /* Initialize plugin class. */
170 static void vlock_plugin_class_init(VlockPluginClass *klass)
172 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
173 GParamSpec *vlock_plugin_param_spec;
175 /* Virtual methods. */
176 klass->open = NULL;
178 /* Install overridden methods. */
179 gobject_class->constructor = vlock_plugin_constructor;
180 gobject_class->finalize = vlock_plugin_finalize;
181 gobject_class->set_property = vlock_plugin_set_property;
182 gobject_class->get_property = vlock_plugin_get_property;
184 /* Install properties. */
185 vlock_plugin_param_spec = g_param_spec_string(
186 "name",
187 "plugin name",
188 "Set the plugin's name",
189 NULL,
190 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE
193 g_object_class_install_property(
194 gobject_class,
195 PROP_VLOCK_PLUGIN_NAME,
196 vlock_plugin_param_spec
200 bool vlock_plugin_open(VlockPlugin *self, GError **error)
202 VlockPluginClass *klass = VLOCK_PLUGIN_GET_CLASS(self);
203 g_assert(klass->open != NULL);
204 return klass->open(self, error);