/* * Copyright (C) 2005 Kouji TAKAO * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "gpass/pack.h" #include "gpass/attribute.h" /*********************************************************** * * GPassAttributeType * ***********************************************************/ GType gpass_attribute_type_get_type(void) { static GType etype = 0; if (etype == 0) { static const GEnumValue values[] = { { GPASS_ATTRIBUTE_TYPE_INVALID, "GPASS_ATTRIBUTE_TYPE_INVALID", N_("Invalid") }, { GPASS_ATTRIBUTE_TYPE_INTEGER, "GPASS_ATTRIBUTE_TYPE_INTEGER", N_("Integer") }, { GPASS_ATTRIBUTE_TYPE_BOOLEAN, "GPASS_ATTRIBUTE_TYPE_BOOLEAN", N_("Boolean") }, { GPASS_ATTRIBUTE_TYPE_TIME, "GPASS_ATTRIBUTE_TYPE_TIME", N_("Time") }, { GPASS_ATTRIBUTE_TYPE_STRING, "GPASS_ATTRIBUTE_TYPE_STRING", N_("String") }, { GPASS_ATTRIBUTE_TYPE_TEXT, "GPASS_ATTRIBUTE_TYPE_TEXT", N_("Text") }, { GPASS_ATTRIBUTE_TYPE_PASSWORD, "GPASS_ATTRIBUTE_TYPE_PASSWORD", N_("Password") }, { GPASS_ATTRIBUTE_TYPE_URL, "GPASS_ATTRIBUTE_TYPE_URL", N_("Url") }, { GPASS_ATTRIBUTE_TYPE_ENTRY_TYPE, "GPASS_ATTRIBUTE_TYPE_ENTRY_TYPE", N_("Entry Type") }, { 0, NULL, NULL } }; etype = g_enum_register_static("GPassAttributeType", values); } return etype; } /*********************************************************** * * GPassAttribute * ***********************************************************/ static GObjectClass *parent_class = NULL; static void attribute_instance_init(GTypeInstance *instance, gpointer g_class) { GPassAttribute *self = GPASS_ATTRIBUTE(instance); self->type = GPASS_ATTRIBUTE_TYPE_INVALID; self->name = NULL; self->nick = NULL; self->blurb = NULL; self->value = g_new0(GValue, 1); } enum { PROP_0, PROP_TYPE, PROP_NAME, PROP_NICK, PROP_BLURB, }; static GType attribute_type_to_g_type(GPassAttributeType type) { GType g_type; switch (type) { case GPASS_ATTRIBUTE_TYPE_INTEGER: g_type = G_TYPE_INT; break; case GPASS_ATTRIBUTE_TYPE_BOOLEAN: g_type = G_TYPE_BOOLEAN; break; case GPASS_ATTRIBUTE_TYPE_TIME: g_type = G_TYPE_ULONG; break; case GPASS_ATTRIBUTE_TYPE_STRING: case GPASS_ATTRIBUTE_TYPE_TEXT: case GPASS_ATTRIBUTE_TYPE_PASSWORD: case GPASS_ATTRIBUTE_TYPE_URL: case GPASS_ATTRIBUTE_TYPE_ENTRY_TYPE: g_type = G_TYPE_STRING; break; default: g_type = G_TYPE_INVALID; } return g_type; } static void change_type(GPassAttribute *self, GPassAttributeType type) { GType g_type; self->type = type; g_type = attribute_type_to_g_type(self->type); g_value_init(self->value, g_type); } static void attribute_instance_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GPassAttribute *self = GPASS_ATTRIBUTE(object); GPassAttributeType type; switch (prop_id) { case PROP_TYPE: type = g_value_get_enum(value); if (self->type != type) { change_type(self, type); } break; case PROP_NAME: g_free(self->name); self->name = g_value_dup_string(value); break; case PROP_NICK: g_free(self->nick); self->nick = g_value_dup_string(value); break; case PROP_BLURB: g_free(self->blurb); self->blurb = g_value_dup_string(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void attribute_instance_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GPassAttribute *self = GPASS_ATTRIBUTE(object); switch (prop_id) { case PROP_TYPE: g_value_set_enum(value, self->type); break; case PROP_NAME: g_value_set_static_string(value, self->name); break; case PROP_NICK: g_value_set_static_string(value, self->nick); break; case PROP_BLURB: g_value_set_static_string(value, self->blurb); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void attribute_instance_finalize(GObject *object) { GPassAttribute *self = GPASS_ATTRIBUTE(object); g_free(self->name); g_free(self->nick); g_free(self->blurb); g_free(self->value); G_OBJECT_CLASS(parent_class)->finalize(object); } static void attribute_class_init(gpointer g_class, gpointer g_class_data) { GObjectClass *gobject_class = G_OBJECT_CLASS(g_class); parent_class = g_type_class_peek_parent(g_class); gobject_class->set_property = attribute_instance_set_property; gobject_class->get_property = attribute_instance_get_property; gobject_class->finalize = attribute_instance_finalize; g_object_class_install_property (gobject_class, PROP_TYPE, g_param_spec_enum("type", _("Type"), _("The type of attribute"), GPASS_TYPE_ATTRIBUTE_TYPE, GPASS_ATTRIBUTE_TYPE_INTEGER, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_NAME, g_param_spec_string("name", _("Name"), _("The name of attribute"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_NICK, g_param_spec_string("nick", _("Nickname"), _("The nickname of attribute"), NULL, G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_BLURB, g_param_spec_string("blurb", _("Blurb"), _("The blurb of attribute"), NULL, G_PARAM_READWRITE)); } GType gpass_attribute_get_type(void) { static GType type = 0; if (type == 0) { static const GTypeInfo info = { sizeof(GPassAttributeClass), NULL, NULL, attribute_class_init, NULL, NULL, sizeof(GPassAttribute), 0, attribute_instance_init }; type = g_type_register_static(G_TYPE_OBJECT, "GPassAttribute", &info, 0); } return type; } GError * gpass_attribute_set_valist(GPassAttribute *self, va_list ap) { gchar *error_message = NULL; G_VALUE_COLLECT(self->value, ap, 0, &error_message); if (error_message != NULL) { GError *error = NULL; g_set_error(&error, 0, 0, error_message); g_free(error_message); return error; } return NULL; } GError * gpass_attribute_set(GPassAttribute *self, ...) { va_list ap; GError *error; va_start(ap, self); error = gpass_attribute_set_valist(self, ap); va_end(ap); return error; } GError * gpass_attribute_get_valist(GPassAttribute *self, va_list ap) { gchar *error_message = NULL; G_VALUE_LCOPY(self->value, ap, 0, &error_message); if (error_message != NULL) { GError *error = NULL; g_set_error(&error, 0, 0, error_message); g_free(error_message); return error; } return NULL; } GError * gpass_attribute_get(GPassAttribute *self, ...) { va_list ap; GError *error; va_start(ap, self); error = gpass_attribute_get_valist(self, ap); va_end(ap); return error; } GError * gpass_attribute_dump(GPassAttribute *self, GString **buffer) { GError *error = NULL; switch (self->type) { case GPASS_ATTRIBUTE_TYPE_INTEGER: gpass_pack_number(g_value_get_int(self->value), buffer); break; case GPASS_ATTRIBUTE_TYPE_BOOLEAN: if (g_value_get_boolean(self->value)) { gpass_pack_number(1, buffer); } else { gpass_pack_number(0, buffer); } break; case GPASS_ATTRIBUTE_TYPE_TIME: gpass_pack_number((gint) g_value_get_ulong(self->value), buffer); break; case GPASS_ATTRIBUTE_TYPE_STRING: case GPASS_ATTRIBUTE_TYPE_TEXT: case GPASS_ATTRIBUTE_TYPE_PASSWORD: case GPASS_ATTRIBUTE_TYPE_URL: case GPASS_ATTRIBUTE_TYPE_ENTRY_TYPE: gpass_pack_string(g_value_get_string(self->value), buffer); break; default: g_set_error(&error, 0, 0, _("%s(%d) unsupported dumping"), self->name, self->type); } return error; } GError * gpass_attribute_load(GPassAttribute *self, const guchar *buffer, gsize buffer_len, gsize *read_len) { GError *error = NULL; gint val; GString *str; switch (self->type) { case GPASS_ATTRIBUTE_TYPE_INTEGER: error = gpass_unpack_number(buffer, buffer_len, &val, read_len); if (error == NULL) { g_value_set_int(self->value, val); } break; case GPASS_ATTRIBUTE_TYPE_BOOLEAN: error = gpass_unpack_number(buffer, buffer_len, &val, read_len); if (error == NULL) { g_value_set_boolean(self->value, val); } break; case GPASS_ATTRIBUTE_TYPE_TIME: error = gpass_unpack_number(buffer, buffer_len, &val, read_len); if (error == NULL) { g_value_set_ulong(self->value, (gulong) val); } break; case GPASS_ATTRIBUTE_TYPE_STRING: case GPASS_ATTRIBUTE_TYPE_TEXT: case GPASS_ATTRIBUTE_TYPE_PASSWORD: case GPASS_ATTRIBUTE_TYPE_URL: case GPASS_ATTRIBUTE_TYPE_ENTRY_TYPE: str = g_string_new(""); error = gpass_unpack_string(buffer, buffer_len, &str, read_len); if (error == NULL) { g_value_set_string(self->value, str->str); } g_string_free(str, TRUE); break; default: g_set_error(&error, 0, 0, _("%s(%d) unsupported dumping"), self->name, self->type); } return error; }