⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage.c

📁 Bluezan implementation of the Bluetooth&#8482 wireless standards specifications for Linux. The code
💻 C
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2000-2001  Qualcomm Incorporated *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2005  Marcel Holtmann <marcel@holtmann.org> * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation; * *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. *  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY *  CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *  ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,  *  COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS  *  SOFTWARE IS DISCLAIMED. * * *  $Id: storage.c,v 1.20 2005/07/03 10:44:52 holtmann Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <errno.h>#include <ctype.h>#include <fcntl.h>#include <unistd.h>#include <malloc.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/param.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include "textfile.h"#include "hcid.h"struct list {	bdaddr_t bdaddr;	unsigned char *data;	size_t size;	struct list *next;};static struct list *list_add(struct list *list, const bdaddr_t *bdaddr,				const unsigned char *data, const size_t size){	struct list *temp = list, *last = list;	if (!bacmp(bdaddr, BDADDR_ANY))		return list;	while (temp) {		if (!bacmp(&temp->bdaddr, bdaddr)) {			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;	}	temp = malloc(sizeof(*temp));	if (!temp)		return list;	memset(temp, 0, sizeof(*temp));	bacpy(&temp->bdaddr, bdaddr);	temp->data = malloc(size);	if (temp->data) {		memcpy(temp->data, data, size);		temp->size = size;	} else		temp->size = 0;	temp->next = NULL;	if (!list)		return temp;	while (last->next)		last = last->next;	last->next = temp;	return list;}static struct list *list_free(struct list *list){	struct list *temp = list;	if (!list)		return NULL;	while (list->next) {		temp = list;		list = list->next;		if (temp->data)			free(temp->data);		free(temp);	}	return NULL;}#define list_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){	char filename[PATH_MAX + 1], addr[18], str[249];	int i;	memset(str, 0, sizeof(str));	strncpy(str, name, 248);	for (i = 0; i < 248 && str[i]; i++)		if (!isprint(str[i]))			str[i] = '.';	ba2str(local, addr);	snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr);	ba2str(peer, addr);	return textfile_put(filename, addr, str);}int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name){	char filename[PATH_MAX + 1], addr[18], *str;	ba2str(local, addr);	snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr);	ba2str(peer, addr);	str = textfile_get(filename, addr);	if (!str)		return -ENOENT;	memset(name, 0, 249);	strncpy(name, str, 248);	return 0;}int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver){	struct list *temp, *list = NULL;	char filename[PATH_MAX + 1], addr[18], str[16], *buf, *ptr;	bdaddr_t bdaddr;	struct stat st;	int fd, pos, err = 0;	ba2str(local, addr);	snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr);	umask(S_IWGRP | S_IWOTH);	create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);	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 + 100);	if (!buf) {		err = -ENOMEM;		goto unlock;	}	if (st.st_size > 0) {		read(fd, buf, st.st_size);		ptr = buf;		memset(str, 0, sizeof(str));		while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) {			str2ba(addr, &bdaddr);			str[sizeof(str) - 1] = '\0';			list = list_add(list, &bdaddr, str, sizeof(str));			memset(str, 0, sizeof(str));			ptr += pos;			if (ptr - buf >= st.st_size)				break;		};		lseek(fd, 0, SEEK_SET);		ftruncate(fd, 0);	}	memset(str, 0, sizeof(str));	sprintf(str, "%d %d %d", manufacturer, lmp_ver, lmp_subver);	list = list_add(list, peer, str, sizeof(str));	if (!list) {		err = -EIO;		goto unlock;	}	list_foreach(list, temp) {		ba2str(&temp->bdaddr, addr);		if (temp->data && temp->size > 0) {			memset(buf, 0, 100);			snprintf(buf, 99, "%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 write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *features){	struct list *temp, *list = NULL;	char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr;	bdaddr_t bdaddr;	struct stat st;	int i, fd, pos, err = 0;	ba2str(local, addr);	snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr);	umask(S_IWGRP | S_IWOTH);	create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);	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 + 100);	if (!buf) {		err = -ENOMEM;		goto unlock;	}	if (st.st_size > 0) {		read(fd, buf, st.st_size);		ptr = buf;		memset(str, 0, sizeof(str));		while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) {			str2ba(addr, &bdaddr);			str[sizeof(str) - 1] = '\0';			list = list_add(list, &bdaddr, str, sizeof(str));			memset(str, 0, sizeof(str));			ptr += pos;			if (ptr - buf >= st.st_size)				break;		};		lseek(fd, 0, SEEK_SET);		ftruncate(fd, 0);	}	memset(str, 0, sizeof(str));	for (i = 0; i < 8; i++)		sprintf(str + (i * 2), "%2.2X", features[i]);	list = list_add(list, peer, str, sizeof(str));	if (!list) {		err = -EIO;		goto unlock;	}	list_foreach(list, temp) {		ba2str(&temp->bdaddr, addr);		if (temp->data && temp->size > 0) {			memset(buf, 0, 100);			snprintf(buf, 99, "%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 write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type){	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", STORAGEDIR, addr);	umask(S_IWGRP | S_IWOTH);	create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);	fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);	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 + 100);	if (!buf) {		err = -ENOMEM;		goto unlock;	}	if (st.st_size > 0) {		read(fd, buf, st.st_size);		ptr = buf;		memset(str, 0, sizeof(str));		while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) {			str2ba(addr, &bdaddr);			str[sizeof(str) - 1] = '\0';			list = list_add(list, &bdaddr, str, sizeof(str));			memset(str, 0, sizeof(str));			ptr += pos;			if (ptr - buf >= st.st_size)				break;		};		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, sizeof(str));	if (!list) {		err = -EIO;		goto unlock;	}	list_foreach(list, temp) {		ba2str(&temp->bdaddr, addr);		if (temp->data && temp->size > 0) {			memset(buf, 0, 100);			snprintf(buf, 99, "%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){	char filename[PATH_MAX + 1], addr[18], str[35], tmp[3], *buf, *ptr;	bdaddr_t bdaddr;	struct stat st;	int i, fd, pos, err = -ENOENT;	ba2str(local, addr);	snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr);	fd = open(filename, O_RDONLY);	if (fd < 0)		return -errno;	if (flock(fd, LOCK_SH) < 0) {		err = -errno;		goto close;	}	if (fstat(fd, &st) < 0) {		err = -errno;		goto unlock;	}	buf = malloc(st.st_size);	if (!buf) {		err = -ENOMEM;		goto unlock;	}	if (st.st_size > 0) {		read(fd, buf, st.st_size);		ptr = buf;		memset(str, 0, sizeof(str));		while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) {			str2ba(addr, &bdaddr);			str[sizeof(str) - 1] = '\0';			if (!bacmp(&bdaddr, peer)) {				memset(tmp, 0, sizeof(tmp));				for (i = 0; i < 16; i++) {					memcpy(tmp, str + (i * 2), 2);					key[i] = (uint8_t) strtol(tmp, NULL, 16);				}				err = 0;				break;			}			memset(str, 0, sizeof(str));			ptr += pos;			if (ptr - buf >= st.st_size)				break;		};	}unlock:	flock(fd, LOCK_UN);close:	close(fd);	return err;}int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin){	char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr;	bdaddr_t bdaddr;	struct stat st;	int fd, pos, err = -ENOENT;	ba2str(local, addr);	snprintf(filename, PATH_MAX, "%s/%s/pincodes", STORAGEDIR, addr);	fd = open(filename, O_RDONLY);	if (fd < 0)		return -errno;	if (flock(fd, LOCK_SH) < 0) {		err = -errno;		goto close;	}	if (fstat(fd, &st) < 0) {		err = -errno;		goto unlock;	}	buf = malloc(st.st_size);	if (!buf) {		err = -ENOMEM;		goto unlock;	}	if (st.st_size > 0) {		read(fd, buf, st.st_size);		ptr = buf;		memset(str, 0, sizeof(str));		while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) {			str2ba(addr, &bdaddr);			str[sizeof(str) - 1] = '\0';			if (!bacmp(&bdaddr, peer)) {				strncpy(pin, str, 16);				err = strlen(pin);				break;			}			memset(str, 0, sizeof(str));			ptr += pos;			if (ptr - buf >= st.st_size)				break;		};	}unlock:	flock(fd, LOCK_UN);close:	close(fd);	return err;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -