persistent property store - first try
Joe Shaw
joeshaw at novell.com
Thu Jun 10 15:29:55 PDT 2004
On Fri, 2004-06-11 at 00:06 +0200, Kay Sievers wrote:
> I've added a persistence attribute to the property and added a 3 line
> hack to hald_dbus to test it. All properties set through the libhal-api
> are persistent at the moment.
Nice! I think the hack is fine until we determine which properties
exactly to persist.
> Thanks for your comments, Joe. It's my first contact with glib, so I
> really appreciate it.
Happy to help.
One more comment, I missed it in my first email... :P
> --- /dev/null 2004-02-23 22:02:56.000000000 +0100
> +++ hal.kay/hal/hald/pstore.c 2004-06-10 22:01:28.883678048 +0200
> @@ -0,0 +1,368 @@
> +/***************************************************************************
> + * CVSID: $Id: $
> + *
> + * pstore.c : persistent property store on disk
> + *
> + * Copyright (C) 2004 Kay Sievers, <kay.sievers at vrfy.org>
> + *
> + * Licensed under the Academic Free License version 2.0
> + *
> + * 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 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 <config.h>
> +#endif
> +
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <time.h>
> +#include <sys/stat.h>
> +#include <glib.h>
> +
> +#include "logger.h"
> +#include "pstore.h"
> +
> +#define PSTR "String:"
> +#define PINT32 "Int32:"
> +#define PBOOL "Bool:"
> +#define PDOUBLE "Double:"
> +#define UDI_STRIP "/org/freedesktop/Hal"
> +
> +static char *pstore_uuid = NULL;
> +
> +struct _HalPStore {
> + char *path;
> + char *uuid;
> +};
> +
> +/** Create relative or absolute path.
> + *
> + */
> +static int
> +create_path(const char *path)
> +{
> + char *p;
> + char *pos;
> + struct stat stats;
> +
> + if (stat (path, &stats) == 0)
> + return 0;
> +
> + p = g_strdup (path);
> + pos = strrchr (p, '/');
> + if (pos != NULL && pos != p) {
> + pos[0] = '\0';
> + create_path (p);
> + }
> + g_free (p);
> +
> + return mkdir(path, 0755);
> +}
> +
> +/** Return absolute filename with simplified udi string.
> + *
> + */
> +static char
> +*build_path (HalPStore *pstore,
> + const char *udi, const char *file)
> +{
> + char *path;
> + const char *udi_s;
> +
> + udi_s = udi;
> + /* strip namespace part of udi string */
> + if (udi != NULL &&
> + g_ascii_strncasecmp(udi, UDI_STRIP, sizeof(UDI_STRIP)-1) == 0)
> + udi_s = &udi[sizeof(UDI_STRIP)-1];
> +
> + path = g_build_filename (G_DIR_SEPARATOR_S,
> + pstore->path, pstore->uuid,
> + udi_s, file, NULL);
> +
> + return path;
> +}
> +
> +/** Init pstore system by reading or generating our uuid.
> + *
> + */
> +void
> +hal_pstore_init (const char *path)
> +{
> + char *file;
> + char *uuid;
> + char hostname[HOST_NAME_MAX];
> + char *p;
> + GIOChannel *io;
> + GError *error = NULL;
> + int written;
> +
> + file = g_build_filename (G_DIR_SEPARATOR_S,
> + path, "uuid", NULL);
> + g_file_get_contents (file, &uuid, NULL, NULL);
> +
> + if (uuid == NULL) {
> + /* create new uuid and save it to disk */
> + gethostname (hostname, HOST_NAME_MAX);
> + uuid = g_strdup_printf ("%s-%lx", hostname, time(NULL));
> +
> + p = g_build_path (G_DIR_SEPARATOR_S,
> + path, NULL);
> + create_path(p);
> + g_free(p);
> +
> + io = g_io_channel_new_file (file, "w", &error);
> + if (error != NULL) {
> + HAL_WARNING (("error creating file %s", error->message));
> + g_error_free (error);
> + goto exit;
> + }
> + g_io_channel_write_chars (io, uuid, -1, &written, &error);
> + g_io_channel_shutdown (io, TRUE, NULL);
> + if (error != NULL) {
> + HAL_WARNING (("error writing to file %s", error->message));
> + g_error_free (error);
> + goto exit;
> + }
> + }
> +
> + HAL_DEBUG (("uuid is %s", uuid));
> + pstore_uuid = uuid;
> +
> +exit:
> + g_free (file);
> +}
> +
> +
> +/** Open pstore on the given location.
> + *
> + */
> +HalPStore
> +*hal_pstore_open (const char *path)
> +{
> + HalPStore *pstore;
> + char *p;
> +
> + pstore = g_new0 (HalPStore, 1);
> +
> + pstore->path = g_strdup (path);
> +
> + pstore->uuid = pstore_uuid;
> +
> + p = g_build_path (G_DIR_SEPARATOR_S,
> + pstore->path, pstore->uuid, NULL);
> + create_path(p);
> + g_free(p);
> +
> + HAL_DEBUG (("opened pstore at %s/%s/", pstore->path, pstore->uuid));
> +
> + return pstore;
> +}
> +
> +/** Turn around the OPEN sign, in the store's entrance :)
> + *
> + */
> +void
> +hal_pstore_close (HalPStore *pstore)
> +{
> + g_free (pstore->path);
> + g_free (pstore->uuid);
> + g_free (pstore);
> +}
Are you sure you want to free pstore->uuid here? If you do, pstore_uuid
will be garbage if you try to call hal_pstore_open() without first
calling hal_pstore_init(). You probably want to either g_strdup() it in
hal_store_open() or not free it at all (and declare it const in the
struct definition).
On a related note, you might want to check in hal_pstore_open() that
hal_pstore_init() is called first. Or just make hal_pstore_init()
static and have hal_pstore_open() lazily call it.
Other than that, it looks pretty good to me. Hopefully David can find
the time to also look it over and give it the OK.
Thanks,
Joe
_______________________________________________
hal mailing list
hal at freedesktop.org
http://freedesktop.org/mailman/listinfo/hal
More information about the Hal
mailing list