storage: add save/load functionality

Prints can now be saved to disk (but you currently must classify which
finger they are) and you can load them later.

Added 2 simple example programs to demonstrate this.
This commit is contained in:
Daniel Drake
2007-10-16 14:23:30 +01:00
parent 3b8f8c195c
commit 680142f268
6 changed files with 429 additions and 4 deletions

View File

@@ -18,12 +18,55 @@
*/
#include <config.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <glib.h>
#include "fp_internal.h"
#define DIR_PERMS 0700
/* FIXME: should free this during library shutdown */
static char *base_store = NULL;
static void storage_setup(void)
{
const char *homedir;
homedir = g_getenv("HOME");
if (!homedir)
homedir = g_get_home_dir();
if (!homedir)
return;
base_store = g_build_filename(homedir, ".fprint/prints", NULL);
g_mkdir_with_parents(base_store, DIR_PERMS);
/* FIXME handle failure */
}
static const char *finger_code_to_str(enum fp_finger finger)
{
const char *names[] = {
[LEFT_THUMB] = "lthu",
[LEFT_INDEX] = "lind",
[LEFT_MIDDLE] = "lmid",
[LEFT_RING] = "lrin",
[LEFT_LITTLE] = "llit",
[RIGHT_THUMB] = "rthu",
[RIGHT_INDEX] = "rind",
[RIGHT_MIDDLE] = "rmid",
[RIGHT_RING] = "rrin",
[RIGHT_LITTLE] = "rlit",
};
if (finger < LEFT_THUMB || finger > RIGHT_LITTLE)
return NULL;
return names[finger];
}
struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
{
struct fp_print_data *data = g_malloc(sizeof(*data) + length);
@@ -33,6 +76,82 @@ struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
return data;
}
API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
enum fp_finger finger)
{
GError *err = NULL;
char *path;
char *dirpath;
const char *fingerstr = finger_code_to_str(finger);
int r;
if (!fingerstr)
return -EINVAL;
if (!base_store)
storage_setup();
fp_dbg("save %s print from %s", fingerstr, data->driver_name);
dirpath = g_build_filename(base_store, data->driver_name, NULL);
r = g_mkdir_with_parents(dirpath, DIR_PERMS);
if (r < 0) {
fp_err("couldn't create storage directory");
g_free(dirpath);
return r;
}
path = g_build_filename(dirpath, fingerstr, NULL);
fp_dbg("saving to %s", path);
g_file_set_contents(path, data->buffer, data->length, &err);
g_free(dirpath);
g_free(path);
if (err) {
r = err->code;
fp_err("%s save failed: %s", fingerstr, err->message);
g_error_free(err);
return r;
}
return 0;
}
API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
enum fp_finger finger, struct fp_print_data **data)
{
const char *fingerstr = finger_code_to_str(finger);
gchar *path;
gsize length;
gchar *contents;
GError *err = NULL;
struct fp_print_data *fdata;
if (!fingerstr)
return -EINVAL;
if (!base_store)
storage_setup();
path = g_build_filename(base_store, dev->drv->name, fingerstr, NULL);
fp_dbg("from %s", path);
g_file_get_contents(path, &contents, &length, &err);
g_free(path);
if (err) {
int r = err->code;
fp_err("%s load failed: %s", fingerstr, err->message);
g_error_free(err);
if (r == G_FILE_ERROR_NOENT)
return -ENOENT;
else
return r;
}
fdata = fpi_print_data_new(dev, length);
memcpy(fdata->buffer, contents, length);
g_free(contents);
*data = fdata;
return 0;
}
API_EXPORTED void fp_print_data_free(struct fp_print_data *data)
{
g_free(data);