summaryrefslogtreecommitdiffstats
path: root/hcid/storage.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-04-16 15:19:04 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-04-16 15:19:04 +0000
commit0467164fb3a90cddff16c52fc4172029f978497d (patch)
tree965748868d42f43ff9d60d3fda8bdf297359ff74 /hcid/storage.c
parentf1a83659170a8f324991061c9ed14f39393e7c10 (diff)
Store device names in the background
Diffstat (limited to 'hcid/storage.c')
-rw-r--r--hcid/storage.c178
1 files changed, 176 insertions, 2 deletions
diff --git a/hcid/storage.c b/hcid/storage.c
index cd04b254..a025e674 100644
--- a/hcid/storage.c
+++ b/hcid/storage.c
@@ -34,15 +34,189 @@
#include <stdio.h>
#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <syslog.h>
+#include <sys/file.h>
+#include <sys/stat.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include "hcid.h"
-#define DEVPATH "/etc/bluetooth/devices"
+#define DEVPATH "/var/cache/bluetooth/"
+
+struct name_list {
+ bdaddr_t bdaddr;
+ char name[249];
+ struct name_list *next;
+};
+
+static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr, const char *name)
+{
+ struct name_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));
+ return list;
+ }
+ temp = temp->next;
+ }
+
+ temp = malloc(sizeof(*temp));
+ if (!temp)
+ return list;
+
+ memset(temp, 0, sizeof(*temp));
+
+ bacpy(&temp->bdaddr, bdaddr);
+ memcpy(temp->name, name, sizeof(temp->name));
+ temp->next = NULL;
+
+ if (!list)
+ return temp;
+
+ while (last->next)
+ last = last->next;
+
+ last->next = temp;
+
+ return list;
+}
+
+static struct name_list *name_free(struct name_list *list)
+{
+ struct name_list *temp = list;
+
+ if (!list)
+ return NULL;
+
+ while (list->next) {
+ temp = list;
+ list = list->next;
+ free(temp);
+ }
+
+ return NULL;
+}
+
+#define name_foreach(list, entry) \
+ for (entry = list; entry; entry = entry->next)
+
+static int create_dirs(const char *filename, mode_t mode)
+{
+ struct stat st;
+ char dir[PATH_MAX + 1], *prev, *next;
+ int err;
+
+ err = stat(filename, &st);
+ if (!err && S_ISREG(st.st_mode))
+ return 0;
+
+ memset(dir, 0, PATH_MAX + 1);
+ strcat(dir, "/");
+
+ prev = strchr(filename, '/');
+
+ while (prev) {
+ next = strchr(prev + 1, '/');
+ if (!next)
+ break;
+
+ if (next - prev == 1) {
+ prev = next;
+ continue;
+ }
+
+ strncat(dir, prev + 1, next - prev);
+ mkdir(dir, mode);
+
+ prev = next;
+ }
+
+ return 0;
+}
int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name)
{
- return -EIO;
+ struct name_list *temp, *list = NULL;
+ mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+ mode_t mask = S_IWGRP | S_IWOTH;
+ char filename[PATH_MAX + 1];
+ char addr[18], str[249], *buf, *ptr;
+ bdaddr_t bdaddr;
+ struct stat st;
+ int fd, pos, err = 0;
+
+ ba2str(local, addr);
+ snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr);
+
+ umask(mask);
+ create_dirs(filename, mode);
+
+ fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd < 0)
+ return -errno;
+
+ if (flock(fd, LOCK_EX) < 0) {
+ err = -errno;
+ goto close;
+ }
+
+ 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 = name_add(list, &bdaddr, str);
+ ptr += pos;
+ };
+
+ lseek(fd, 0, SEEK_SET);
+ ftruncate(fd, 0);
+ }
+
+ list = name_add(list, peer, name);
+ if (!list) {
+ err = -EIO;
+ goto unlock;
+ }
+
+ name_foreach(list, temp) {
+ ba2str(&temp->bdaddr, addr);
+ snprintf(buf, 200, "%s %s\n", addr, temp->name);
+ write(fd, buf, strlen(buf));
+ }
+
+unlock:
+ flock(fd, LOCK_UN);
+
+close:
+ close(fd);
+ name_free(list);
+ return err;
+}
+
+int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type)
+{
+ return 0;
}