Zero out fprint_data fields on allocation
[libfprint.git] / libfprint / data.c
blob6eba48ce630a4fc4e29e7dc61f812734971550c8
1 /*
2 * Fingerprint data handling and storage
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <config.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
27 #include <glib.h>
29 #include "fp_internal.h"
31 #define DIR_PERMS 0700
33 /* FIXME: should free this during library shutdown */
34 static char *base_store = NULL;
36 static void storage_setup(void)
38 const char *homedir;
40 homedir = g_getenv("HOME");
41 if (!homedir)
42 homedir = g_get_home_dir();
43 if (!homedir)
44 return;
46 base_store = g_build_filename(homedir, ".fprint/prints", NULL);
47 g_mkdir_with_parents(base_store, DIR_PERMS);
48 /* FIXME handle failure */
51 static const char *finger_code_to_str(enum fp_finger finger)
53 const char *names[] = {
54 [LEFT_THUMB] = "lthu",
55 [LEFT_INDEX] = "lind",
56 [LEFT_MIDDLE] = "lmid",
57 [LEFT_RING] = "lrin",
58 [LEFT_LITTLE] = "llit",
59 [RIGHT_THUMB] = "rthu",
60 [RIGHT_INDEX] = "rind",
61 [RIGHT_MIDDLE] = "rmid",
62 [RIGHT_RING] = "rrin",
63 [RIGHT_LITTLE] = "rlit",
65 if (finger < LEFT_THUMB || finger > RIGHT_LITTLE)
66 return NULL;
67 return names[finger];
70 struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length)
72 struct fp_print_data *data = g_malloc(sizeof(*data) + length);
73 memset(data, 0, sizeof(*data));
74 fp_dbg("length=%zd", length);
75 data->driver_name = dev->drv->name;
76 data->length = length;
77 return data;
80 API_EXPORTED int fp_print_data_save(struct fp_print_data *data,
81 enum fp_finger finger)
83 GError *err = NULL;
84 char *path;
85 char *dirpath;
86 const char *fingerstr = finger_code_to_str(finger);
87 int r;
89 if (!fingerstr)
90 return -EINVAL;
92 if (!base_store)
93 storage_setup();
95 fp_dbg("save %s print from %s", fingerstr, data->driver_name);
96 dirpath = g_build_filename(base_store, data->driver_name, NULL);
97 r = g_mkdir_with_parents(dirpath, DIR_PERMS);
98 if (r < 0) {
99 fp_err("couldn't create storage directory");
100 g_free(dirpath);
101 return r;
104 path = g_build_filename(dirpath, fingerstr, NULL);
105 fp_dbg("saving to %s", path);
106 g_file_set_contents(path, data->buffer, data->length, &err);
107 g_free(dirpath);
108 g_free(path);
109 if (err) {
110 r = err->code;
111 fp_err("%s save failed: %s", fingerstr, err->message);
112 g_error_free(err);
113 return r;
116 return 0;
119 API_EXPORTED int fp_print_data_load(struct fp_dev *dev,
120 enum fp_finger finger, struct fp_print_data **data)
122 const char *fingerstr = finger_code_to_str(finger);
123 gchar *path;
124 gsize length;
125 gchar *contents;
126 GError *err = NULL;
127 struct fp_print_data *fdata;
129 if (!fingerstr)
130 return -EINVAL;
132 if (!base_store)
133 storage_setup();
135 path = g_build_filename(base_store, dev->drv->name, fingerstr, NULL);
136 fp_dbg("from %s", path);
137 g_file_get_contents(path, &contents, &length, &err);
138 g_free(path);
139 if (err) {
140 int r = err->code;
141 fp_err("%s load failed: %s", fingerstr, err->message);
142 g_error_free(err);
143 /* FIXME interpret more error codes */
144 if (r == G_FILE_ERROR_NOENT)
145 return -ENOENT;
146 else
147 return r;
150 fdata = fpi_print_data_new(dev, length);
151 memcpy(fdata->buffer, contents, length);
152 g_free(contents);
153 *data = fdata;
154 return 0;
157 API_EXPORTED void fp_print_data_free(struct fp_print_data *data)
159 g_free(data);
162 int fpi_print_data_compatible(struct fp_dev *dev, struct fp_print_data *data)
164 return strcmp(dev->drv->name, data->driver_name) == 0;