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

📄 dun.c

📁 Bluezan implementation of the Bluetooth&#8482 wireless standards specifications for Linux. The code
💻 C
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2004  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: dun.c,v 1.3 2004/04/28 13:40:58 holtmann Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <syslog.h>#include <dirent.h>#include <ctype.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/poll.h>#include <sys/socket.h>#include <sys/wait.h>#include <netinet/in.h>#include <bluetooth/bluetooth.h>#include <bluetooth/rfcomm.h>#include "dund.h"#include "lib.h"#define PROC_BASE  "/proc"static int for_each_port(int (*func)(struct rfcomm_dev_info *, unsigned long), unsigned long arg){	struct rfcomm_dev_list_req *dl;	struct rfcomm_dev_info *di;	long r = 0;	int  sk, i;	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);	if (sk < 0 ) {		perror("Can't open RFCOMM control socket");		exit(1);	}	dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di));	if (!dl) {		perror("Can't allocate request memory");		close(sk);		exit(1);	}	dl->dev_num = RFCOMM_MAX_DEV;	di = dl->dev_info;	if (ioctl(sk, RFCOMMGETDEVLIST, (void *) dl) < 0) {		perror("Can't get device list");		exit(1);	}	for (i = 0; i < dl->dev_num; i++) {		r = func(di + i, arg);		if (r) break;	}	close(sk);	return r;}static int uses_rfcomm(char *path, char *dev){	struct dirent *de;	DIR   *dir;	dir = opendir(path);	if (!dir)		return 0;	chdir(path);	while ((de = readdir(dir)) != NULL) {		char link[PATH_MAX + 1];		int  len = readlink(de->d_name, link, sizeof(link));		if (len > 0) {			link[len] = 0;			if (strstr(link, dev))				return 1;		}	}	closedir(dir);	return 0;}static int find_pppd(int id, pid_t *pid){	struct dirent *de;	char  path[PATH_MAX + 1];	char  dev[10];	int   empty = 1;	DIR   *dir;	dir = opendir(PROC_BASE);	if (!dir) {		perror(PROC_BASE);		return -1;	}	sprintf(dev, "rfcomm%d", id);	*pid = 0;	while ((de = readdir(dir)) != NULL) {		empty = 0;		if (isdigit(de->d_name[0])) {			sprintf(path, "%s/%s/fd", PROC_BASE, de->d_name);			if (uses_rfcomm(path, dev)) {				*pid = atoi(de->d_name);				break;			}		}	}	closedir(dir);	if (empty)		fprintf(stderr, "%s is empty (not mounted ?)\n", PROC_BASE);	return *pid != 0;}static int dun_exec(char *tty, char *prog, char **args){	int pid = fork();	int fd;		switch (pid) {	case -1:		return -1;	case 0:		break;	default:		return pid;	}	setsid();	/* Close all FDs */	for (fd=3; fd < 20; fd++)		close(fd);	execvp(prog, args);	exit(1);}static int dun_create_tty(int sk, char *tty, int size){	struct sockaddr_rc sa;	struct stat st;	int id, alen, try = 3;	struct rfcomm_dev_req req = {		flags:   (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP),		dev_id:  -1	};	alen = sizeof(sa);	if (getpeername(sk, (struct sockaddr *) &sa, &alen) < 0)		return -1;	bacpy(&req.dst, &sa.rc_bdaddr);	alen = sizeof(sa);	if (getsockname(sk, (struct sockaddr *) &sa, &alen) < 0)		return -1;	bacpy(&req.src, &sa.rc_bdaddr);	req.channel = sa.rc_channel;	id = ioctl(sk, RFCOMMCREATEDEV, &req);	if (id < 0)		return id;	snprintf(tty, size, "/dev/rfcomm%d", id);	while (stat(tty, &st) < 0) {		snprintf(tty, size, "/dev/bluetooth/rfcomm/%d", id);		if (stat(tty, &st) < 0) {			snprintf(tty, size, "/dev/rfcomm%d", id);			if (try--) {				sleep(1);				continue;			}			memset(&req, 0, sizeof(req));			req.dev_id = id;			ioctl(sk, RFCOMMRELEASEDEV, &req);			return -1;		}	}	return id;}int dun_init(void){	return 0;}int dun_cleanup(void){	return 0;}static int show_conn(struct rfcomm_dev_info *di, unsigned long arg){	pid_t pid;		if (di->state == BT_CONNECTED &&		(di->flags & (1<<RFCOMM_REUSE_DLC)) &&		(di->flags & (1<<RFCOMM_TTY_ATTACHED)) &&		(di->flags & (1<<RFCOMM_RELEASE_ONHUP))) {		if (find_pppd(di->id, &pid)) {			char dst[18];			ba2str(&di->dst, dst);			printf("rfcomm%d: %s channel %d pppd pid %d\n",					di->id, dst, di->channel, pid);		}	}	return 0;}static int kill_conn(struct rfcomm_dev_info *di, unsigned long arg){	bdaddr_t *dst = (bdaddr_t *) arg;	pid_t pid;	if (di->state == BT_CONNECTED &&		(di->flags & (1<<RFCOMM_REUSE_DLC)) &&		(di->flags & (1<<RFCOMM_TTY_ATTACHED)) &&		(di->flags & (1<<RFCOMM_RELEASE_ONHUP))) {		if (dst && bacmp(&di->dst, dst))			return 0;		if (find_pppd(di->id, &pid)) {			if (kill(pid, SIGINT) < 0)				perror("Kill");			if (!dst)				return 0;			return 1;		}	}	return 0;}int dun_show_connections(void){	for_each_port(show_conn, 0);	return 0;}int dun_kill_connection(uint8_t *dst){	for_each_port(kill_conn, (unsigned long) dst);	return 0;}int dun_kill_all_connections(void){	for_each_port(kill_conn, 0);	return 0;}int dun_open_connection(int sk, char *pppd, char **args, int wait){	char tty[100];	int  pid;	if (dun_create_tty(sk, tty, sizeof(tty) - 1) < 0) {		syslog(LOG_ERR, "RFCOMM TTY creation failed. %s(%d)", strerror(errno), errno);		return -1;	}	args[0] = "pppd";	args[1] = tty;	args[2] = "nodetach";	pid = dun_exec(tty, pppd, args);	if (pid < 0) {		syslog(LOG_ERR, "Exec failed. %s(%d)", strerror(errno), errno);		return -1;	}	if (wait) {		int status;		waitpid(pid, &status, 0);		/* FIXME: Check for waitpid errors */	}	return 0;}

⌨️ 快捷键说明

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