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

📄 btutils.c

📁 Affix - Bluetooth Protocol Stack for Linux has been developed at Nokia Research Center in Helsinki
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Affix - Bluetooth Protocol Stack for Linux   Copyright (C) 2001 Nokia Corporation   Dmitry Kasatkin <dmitry.kasatkin@nokia.com>   Based on the from Pontus Fuchs <pontus.fuchs@tactel.se>   Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.      This program is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the   Free Software Foundation; either version 2 of the License, or (at your   option) any later version.   This program is distributed in the hope that it will be useful, but   WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   General Public License for more details.   You should have received a copy of the GNU General Public License along   with this program; if not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*//*   $Id: btutils.c,v 1.39 2003/02/18 13:39:11 kds Exp $   utility functions for Affix   Fixes:    		Dmitry Kasatkin*/#include <affix/config.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/file.h>#include <signal.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <string.h>#include <dirent.h>#include <unistd.h>#include <errno.h>#include <time.h>/* pidof */#include <sys/wait.h>#include <dirent.h>#include <stdint.h>#include <affix/btcore.h>#include <affix/utils.h>/* Info about a process. */typedef struct _proc_{	char *fullname;	/* Name as found out from argv[0] */	char *basename;	/* Only the part after the last / */	char *statname;	/* the statname without braces    */	ino_t ino;		/* Inode number			  */	dev_t dev;		/* Device it is on		  */	pid_t pid;		/* Process ID.			  */	int sid;		/* Session ID.			  */	struct _proc_ *next;	/* Pointer to next struct. 	  */} PROC;/* pid queue */typedef struct _pidq_ {	struct _pidq_ *front;	struct _pidq_ *next;	struct _pidq_ *rear;	PROC		*proc;} PIDQ;/* List of processes. */static PROC *plist = NULL;/* Did we stop a number of processes? */static int scripts_too = 0;//// Get some file-info. (size and lastmod)//int get_fileinfo(const char *name, char *lastmod){	struct stat stats;	struct tm *tm;		stat(name, &stats);	tm = gmtime(&stats.st_mtime);	snprintf(lastmod, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ",			tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,			tm->tm_hour, tm->tm_min, tm->tm_sec);	return (int) stats.st_size;}//// Read a file and alloc a buffer for it//uint8_t* easy_readfile(const char *filename, int *file_size){	int actual;	int fd;	uint8_t *buf;	fd = open(filename, O_RDONLY, 0);	if (fd == -1) {		return NULL;	}	*file_size = get_filesize(filename);	DBPRT("name=%s, size=%d\n", filename, *file_size);	if(! (buf = malloc(*file_size)) ) {		return NULL;	}	actual = read(fd, buf, *file_size);	close(fd); 	*file_size = actual;	return buf;}/* *	Read the proc filesystem. */static int readproc(void){	DIR *dir;	struct dirent *d;	char path[256];	char buf[256];	char *s, *q;	FILE *fp;	int pid, f;	PROC *p, *n;	struct stat st;	int c;	/* Open the /proc directory. */	if ((dir = opendir("/proc")) == NULL) {		BTERROR("cannot opendir(/proc)");		return -1;	}	/* Free the already existing process list. */	for (p = plist; p; p = n) {		n = p->next;		if (p->fullname)			free(p->fullname);		if (p->statname)			free(p->statname);		free(p);	}	plist = NULL;	/* Walk through the directory. */	while ((d = readdir(dir)) != NULL) {		/* See if this is a process */		if ((pid = atoi(d->d_name)) == 0) continue;		/* Get a PROC struct . */		p = (PROC *)malloc(sizeof(PROC));		memset(p, 0, sizeof(PROC));		/* Open the status file. */		snprintf(path, sizeof(path), "/proc/%s/stat", d->d_name);		/* Read SID & statname from it. */		if ((fp = fopen(path, "r")) != NULL) {			buf[0] = 0;			fgets(buf, 256, fp);			/* See if name starts with '(' */			s = buf;			while (*s != ' ') s++;			s++;			if (*s == '(') {				/* Read program name. */				q = strrchr(buf, ')');				if (q == NULL) {					p->sid = 0;					BTERROR("can't get program name from %s\n", path);					free(p);					continue;				}				s++;			} else {				q = s;				while (*q != ' ') q++;			}			*q++ = 0;			while (*q == ' ') q++;			p->statname = strdup(s);			/* This could be replaced by getsid(pid) */			if (sscanf(q, "%*c %*d %*d %d", &p->sid) != 1) {				p->sid = 0;				BTERROR("can't read sid from %s\n",						path);				free(p);				continue;			}			fclose(fp);		} else {			/* Process disappeared.. */			free(p);			continue;		}		/* Now read argv[0] */		snprintf(path, sizeof(path), "/proc/%s/cmdline", d->d_name);		if ((fp = fopen(path, "r")) != NULL) {			f = 0;			while(f < 127 && (c = fgetc(fp)) != EOF && c)				buf[f++] = c;			buf[f++] = 0;			fclose(fp);			/* Store the name into malloced memory. */			p->fullname = strdup(buf);			/* Get a pointer to the basename. */			if ((p->basename = strrchr(p->fullname, '/')) != NULL)				p->basename++;			else				p->basename = p->fullname;		} else {			/* Process disappeared.. */			free(p);			continue;		}		/* Try to stat the executable. */		snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);		if (stat(path, &st) == 0) {			p->dev = st.st_dev;			p->ino = st.st_ino;		}		/* Link it into the list. */		p->next = plist;		plist = p;		p->pid = pid;	}	closedir(dir);	/* Done. */	return 0;}static inline PIDQ *init_pid_q(PIDQ *q){	q->front =  q->next = q->rear = NULL;	q->proc = NULL;	return q;}static inline int empty_q(PIDQ *q){	return (q->front == NULL);}static inline int add_pid_to_q(PIDQ *q, PROC *p){	PIDQ *tmp;	tmp = (PIDQ *)malloc(sizeof(PIDQ));	tmp->proc = p;	tmp->next = NULL;	if (empty_q(q)) {		q->front = tmp;		q->rear  = tmp;	} else {		q->rear->next = tmp;		q->rear = tmp;	}	return 0;}static inline PROC *get_next_from_pid_q(PIDQ *q){	PROC *p;	PIDQ *tmp = q->front;	if (!empty_q(q)) {		p = q->front->proc;		q->front = tmp->next;		free(tmp);		return p;	}	return NULL;}/* Try to get the process ID of a given process. */static PIDQ *pidof(char *prog){	struct stat st;	int dostat = 0;	PROC *p;	PIDQ *q;	char *s;	int foundone = 0;	int ok = 0;	/* Try to stat the executable. */	if (prog[0] == '/' && stat(prog, &st) == 0) dostat++;	/* Get basename of program. */	if ((s = strrchr(prog, '/')) == NULL)		s = prog;	else		s++;	q = (PIDQ *)malloc(sizeof(PIDQ));	q = init_pid_q(q);	/* First try to find a match based on dev/ino pair. */	if (dostat) {		for (p = plist; p; p = p->next) {			if (p->dev == st.st_dev && p->ino == st.st_ino) {				add_pid_to_q(q, p);				foundone++;			}		}	}	/* If we didn't find a match based on dev/ino, try the name. */	if (!foundone) {		for (p = plist; p; p = p->next) {			ok = 0;			ok += (strcmp(p->fullname, prog) == 0);			ok += (strcmp(p->basename, s) == 0);			if (p->fullname[0] == 0 ||					strchr(p->fullname, ' ') ||					scripts_too)				ok += (strcmp(p->statname, s) == 0);			if (ok) add_pid_to_q(q, p);		}	}	return q;}#define PIDOF_OMITSZ	5/* *	Pidof functionality. */int affix_pidof(char *name, int flags, pid_t pid){	PROC *p;	PIDQ *q;	int i,oind;	pid_t opid[PIDOF_OMITSZ], spid = 0;	for (oind = PIDOF_OMITSZ-1; oind > 0; oind--)		opid[oind] = 0;	if (flags&PIDOF_SCRIPTS)		scripts_too++;	if (flags&PIDOF_OMIT) {		opid[oind] = pid;		oind++;	}	if (flags&PIDOF_POMIT) {		opid[oind] = getppid();		oind++;	}	/* Print out process-ID's one by one. */	readproc();	if ((q = pidof(name)) != NULL) {		spid = 0;		while ((p = get_next_from_pid_q(q))) {			if (flags & PIDOF_OMIT) {				for (i = 0; i < oind; i++)					if (opid[i] == p->pid)						break;				/*				 *	On a match, continue with				 *	the for loop above.				 */				if (i < oind)					continue;			}			if (flags & PIDOF_SINGLE) {				if (spid)					continue;				else					spid = p->pid;			}		}	}	return spid;}#define isblank(c) (c == ' ' || c == '\t')char *xml_element(char **buf, char **attr){	char	*start = *buf, *next;	// find first <	start = strchr(start, '<');	if (start == NULL)		return NULL;	start++;	// find last >	next = strchr(start, '>');	if (next == NULL) {		// broken		return NULL;	}	*next = '\0';	next++;	*buf = next;	// get first later of the element	while (isblank(*start) && *start != '\0')		start++;	next = start+1;	while (!isblank(*next) && *next != '\0')		next++;		*next = '\0';	*attr = next+1;	// check for "/"	next = *buf-1;	while (*next == '\0' || isblank(*next))		next--;	if (*next == '/')		*next = '\0';	return start;}char *xml_attribute(char **buf, char **value){	char *start = *buf, *next;	int flag = 0;	//find attr name	while (isblank(*start) && *start != '\0')		start++;		if (*start == '\0')		return NULL;	next = start+1;		//find end	while (!isblank(*next) && *next != '=' && *next != '\0')		next++;	if (*next == '=')		flag = 1;		*next = '\0';	next++;		if (flag == 0) {		next = strchr(next, '=');		if (next == NULL)			return NULL;		next++;	}		next = strchr(next, '"');	if (next == NULL)		return NULL;	*value = next+1;	next = strchr(next+1, '"');	if (next == NULL)		return NULL;	*next = '\0';	*buf = next+1;		return start;}int rmkdir(char *new_dir, int mode){	size_t i = 0;	DBPRT("new_dir: %s\n", new_dir);		if (new_dir == NULL || new_dir[0] == '\0')		return -1;	if (access(new_dir, R_OK|X_OK) == 0)		return 0;		if (new_dir[0] == '/')		i++;		for (; new_dir[i] != '\0'; i++) {		if (new_dir[i] == '/') {			char tmpdir[PATH_MAX + 1];			strncpy (tmpdir, new_dir, i);			tmpdir[i] = '\0';			if ((mkdir(tmpdir, mode) == -1) && (errno != EEXIST))				return -1;		}		}	if (mkdir(new_dir, mode) == -1 && errno != EEXIST)		return -1;	return 0;}/* speed stuff */int get_speed(int size, struct timeval *tv_start, struct timeval *tv_end,		long int *rsec, long int *rusec, double *speed){	long int	sec, usec;	sec = tv_end->tv_sec - tv_start->tv_sec;	usec = (1000000 * sec) + tv_end->tv_usec - tv_start->tv_usec;	*rsec = usec/1000000;	*rusec = (usec - (*rsec * 1000000))/10000;	*speed = (double)(size)/((double)(*rsec) + (double)(*rusec)/100);	return 0;}/* Mapping */char *val2str(struct affix_tupla *map, int value){	for (;map; map++) {		if (map->value == value)			return map->str;	}	return "";}int str2val(struct affix_tupla *map, char *str, unsigned int *val){	char			*fp, *tmp;	struct affix_tupla	*m;	int			found;	if (!str || !(str = strdup(str)))		return 0;	*val = 0;	found = 1;	for (fp = strtok_r(str, ", ", &tmp); fp; fp = strtok_r(NULL, ", ", &tmp)) {		//printf("arg: [%s]\n", fp);		for (m = map; m->match || (found = 0); m++) {			if (strcasecmp(fp, m->match) == 0) {				*val = m->value;				free(str);				return 1;			}		}		if (!found) {			free(str);			return 0;		}	}	free(str);	return 0;}int str2mask(struct affix_tupla *map, char *str, unsigned int *mask){	char			*fp, *tmp;	struct affix_tupla	*m;	int			found;	if (!str || !(str = strdup(str)))		return 0;	*mask = 0;	found = 1;	for (fp = strtok_r(str, ", ", &tmp); fp; fp = strtok_r(NULL, ", ", &tmp)) {		//printf("arg: [%s]\n", fp);		for (m = map; m->match || (found = 0); m++) {			if (strcasecmp(fp, m->match) == 0) {				*mask |= m->value;				break;			}		}		if (!found) {			free(str);			return 0;		}	}	free(str);	return 1;}int mask2str(struct affix_tupla *map, char *str, unsigned int mask){	int			i = 0;	struct affix_tupla	*m;	str[0] = '\0';	for (m = map; m->match; m++) {		if (m->value & mask)			i += sprintf(str + i, "%s ", m->match);	}	if (i)		str[i-1] = '\0';	return 0;}int mask2str_comma(struct affix_tupla *map, char *str, unsigned int mask){	int			i = 0;	struct affix_tupla	*m;	str[0] = '\0';	for (m = map; m->match; m++) {		if (m->value & mask)			i += sprintf(str + i, "%s, ", m->match);	}	if (i)		str[i-2] = '\0';	return 0;}int str2cod(char *str, uint32_t *cod){	struct affix_tupla	*map;	int			found = 1;	char			*arg, *tmp;	if (!str || !(str = strdup(str)))		return -1;	/* get Major */	arg = strtok_r(str, ", ", &tmp);	if (arg == NULL) {		free(str);		return -1;	}	*cod = 0;	for (map = codMajorClassMnemonic; map->match || (found=0); map++) {		if (strncasecmp(map->match, arg, 3) == 0) {			*cod |= map->value;			break;		}	}	if (!found){		free(str);		return -1;	}	/* get minor */	arg = strtok_r(NULL, ", ", &tmp);	if (arg == NULL) {		free(str);		return -1;	}	switch (*cod & HCI_COD_MAJOR) {		case HCI_COD_COMPUTER:			for (map = codMinorComputerMnemonic; map->match || (found=0); map++) {

⌨️ 快捷键说明

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