summaryrefslogtreecommitdiffstats
path: root/hcid
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-04-16 22:07:39 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-04-16 22:07:39 +0000
commit76bc6f44a3d1eecf610d9191dfb443a66a8e9db6 (patch)
tree02b0d5a1abe0974b68b11e4ab1e26a2a171c906e /hcid
parentcdb1b911f93c49ab242b674f8f2a0e0a0b28d4d6 (diff)
Add link key storage function
Diffstat (limited to 'hcid')
-rw-r--r--hcid/storage.c114
1 files changed, 94 insertions, 20 deletions
diff --git a/hcid/storage.c b/hcid/storage.c
index 05e006c2..0932e2ef 100644
--- a/hcid/storage.c
+++ b/hcid/storage.c
@@ -48,22 +48,33 @@
#define DEVPATH "/var/lib/bluetooth/"
-struct name_list {
+struct list {
bdaddr_t bdaddr;
- char name[249];
- struct name_list *next;
+ unsigned char *data;
+ size_t size;
+ struct list *next;
};
-static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr, const char *name)
+static struct list *list_add(struct list *list, const bdaddr_t *bdaddr,
+ const unsigned char *data, const size_t size)
{
- struct name_list *temp = list, *last = list;
+ struct list *temp = list, *last = list;
if (!bacmp(bdaddr, BDADDR_ANY))
return list;
while (temp) {
if (!bacmp(&temp->bdaddr, bdaddr)) {
- memcpy(temp->name, name, sizeof(temp->name));
+ if (temp->data)
+ free(temp->data);
+
+ temp->data = malloc(size);
+ if (temp->data) {
+ memcpy(temp->data, data, size);
+ temp->size = size;
+ } else
+ temp->size = 0;
+
return list;
}
temp = temp->next;
@@ -76,7 +87,13 @@ static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr
memset(temp, 0, sizeof(*temp));
bacpy(&temp->bdaddr, bdaddr);
- memcpy(temp->name, name, sizeof(temp->name));
+ temp->data = malloc(size);
+ if (temp->data) {
+ memcpy(temp->data, data, size);
+ temp->size = size;
+ } else
+ temp->size = 0;
+
temp->next = NULL;
if (!list)
@@ -90,9 +107,9 @@ static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr
return list;
}
-static struct name_list *name_free(struct name_list *list)
+static struct list *list_free(struct list *list)
{
- struct name_list *temp = list;
+ struct list *temp = list;
if (!list)
return NULL;
@@ -100,13 +117,15 @@ static struct name_list *name_free(struct name_list *list)
while (list->next) {
temp = list;
list = list->next;
+ if (temp->data)
+ free(temp->data);
free(temp);
}
return NULL;
}
-#define name_foreach(list, entry) \
+#define list_foreach(list, entry) \
for (entry = list; entry; entry = entry->next)
static int create_dirs(const char *filename, mode_t mode)
@@ -145,7 +164,7 @@ static int create_dirs(const char *filename, mode_t mode)
int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name)
{
- struct name_list *temp, *list = NULL;
+ struct list *temp, *list = NULL;
char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr;
bdaddr_t bdaddr;
struct stat st;
@@ -184,7 +203,7 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n
while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) {
str2ba(addr, &bdaddr);
- list = name_add(list, &bdaddr, str);
+ list = list_add(list, &bdaddr, str, strlen(str) + 1);
ptr += pos;
};
@@ -192,15 +211,15 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n
ftruncate(fd, 0);
}
- list = name_add(list, peer, name);
+ list = list_add(list, peer, name, strlen(name) + 1);
if (!list) {
err = -EIO;
goto unlock;
}
- name_foreach(list, temp) {
+ list_foreach(list, temp) {
ba2str(&temp->bdaddr, addr);
- snprintf(buf, 200, "%s %s\n", addr, temp->name);
+ snprintf(buf, 200, "%s %s\n", addr, temp->data);
write(fd, buf, strlen(buf));
}
@@ -209,14 +228,17 @@ unlock:
close:
close(fd);
- name_free(list);
+ list_free(list);
return err;
}
int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type)
{
- char filename[PATH_MAX + 1], addr[18];
- int fd;
+ struct list *temp, *list = NULL;
+ char filename[PATH_MAX + 1], addr[18], str[35], *buf, *ptr;
+ bdaddr_t bdaddr;
+ struct stat st;
+ int i, fd, pos, err = 0;
ba2str(local, addr);
snprintf(filename, PATH_MAX, "%s/%s/linkkeys", DEVPATH, addr);
@@ -228,9 +250,61 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c
if (fd < 0)
return -errno;
- close(fd);
+ if (flock(fd, LOCK_EX) < 0) {
+ err = -errno;
+ goto close;
+ }
- return 0;
+ if (fstat(fd, &st) < 0) {
+ err = -errno;
+ goto unlock;
+ }
+
+ buf = malloc(st.st_size + 200);
+ if (!buf) {
+ err = -ENOMEM;
+ goto unlock;
+ }
+
+ if (st.st_size > 0) {
+ read(fd, buf, st.st_size);
+
+ ptr = buf;
+
+ while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) {
+ str2ba(addr, &bdaddr);
+ list = list_add(list, &bdaddr, str, strlen(str) + 1);
+ ptr += pos;
+ };
+
+ lseek(fd, 0, SEEK_SET);
+ ftruncate(fd, 0);
+ }
+
+ memset(str, 0, sizeof(str));
+ for (i = 0; i < 16; i++)
+ sprintf(str + (i * 2), "%2.2X", key[i]);
+ sprintf(str + 32, " %d", type);
+
+ list = list_add(list, peer, str, strlen(str) + 1);
+ if (!list) {
+ err = -EIO;
+ goto unlock;
+ }
+
+ list_foreach(list, temp) {
+ ba2str(&temp->bdaddr, addr);
+ snprintf(buf, 200, "%s %s\n", addr, temp->data);
+ write(fd, buf, strlen(buf));
+ }
+
+unlock:
+ flock(fd, LOCK_UN);
+
+close:
+ close(fd);
+ list_free(list);
+ return err;
}
int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key)