diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2005-04-16 15:19:04 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2005-04-16 15:19:04 +0000 | 
| commit | 0467164fb3a90cddff16c52fc4172029f978497d (patch) | |
| tree | 965748868d42f43ff9d60d3fda8bdf297359ff74 | |
| parent | f1a83659170a8f324991061c9ed14f39393e7c10 (diff) | |
Store device names in the background
| -rw-r--r-- | hcid/hcid.h | 1 | ||||
| -rw-r--r-- | hcid/security.c | 4 | ||||
| -rw-r--r-- | hcid/storage.c | 178 | 
3 files changed, 180 insertions, 3 deletions
| diff --git a/hcid/hcid.h b/hcid/hcid.h index 845e3889..bcc43e4a 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -111,3 +111,4 @@ gboolean hcid_dbus_init(void);  #endif  int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); +int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); diff --git a/hcid/security.c b/hcid/security.c index f0bf12bd..92353373 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -193,6 +193,8 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr)  	key.time = time(0);  	save_link_key(&key); + +	write_link_key(sba, dba, evt->link_key, evt->key_type);  }  /* PIN code handling */ @@ -386,7 +388,7 @@ static void remote_name_information(int dev, bdaddr_t *sba, void *ptr)  	evt_remote_name_req_complete *evt = ptr;  	bdaddr_t *dba = &evt->bdaddr; -	if (!evt->status) +	if (evt->status)  		return;  	write_device_name(sba, dba, evt->name); 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;  } | 
