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

📄 lib.c

📁 linux下自动mount各种即插即用设备的一个小程序源码 文件包含内容: /vold.h /vold.c /split.h /split.c /disktype-6/disktype.c
💻 C
字号:
/* * lib.c * Global utility functions. * * Copyright (c) 2003 Christoph Pfisterer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * 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. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE.  */#include "disktype.h"#include <stdarg.h>#define USE_BINARY_SEARCH 0#define DEBUG_SIZE 0#ifdef USE_IOCTL_LINUX#include <sys/ioctl.h>#include <linux/fs.h>#endif#ifdef USE_IOCTL_FREEBSD#include <sys/disklabel.h>#endif#ifdef USE_IOCTL_DARWIN#include <sys/ioctl.h>#include <sys/disk.h>#endif#if USE_BINARY_SEARCHint check_position(int f, U64 pos);#endifvoid dt_getfilesize(int f, SOURCE* s) {	off_t result;	if(s == NULL)		return;	/*	Determine the size using various methods. The first method that		works is used. */	/*	 * lseek() to the end:	 * Works on files. On some systems (Linux), this also works on devices.	 */	if (!s->size_known) {		result = lseek(f, 0, SEEK_END);#if DEBUG_SIZE		printf("Size: lseek returned %lld\n", result);#endif		if (result > 0) {			s->size_known = 1;			s->size = result;		}	}#ifdef USE_IOCTL_LINUX	/*	 * ioctl, Linux style:	 * Works on certain devices.	 */#ifdef BLKGETSIZE64#define u64 __u64   /* workaround for broken header file */	if (!s->size_known && s->type != DT_FILE) {		U64 devsize;		if (ioctl(f, BLKGETSIZE64, (void *)&devsize) >= 0) {			s->size_known = 1;			s->size = devsize;#if DEBUG_SIZE			printf("Size: Linux 64-bit ioctl reports %llu\n", s->size);#endif		}	}#undef u64#endif	if (!s->size_known && s->type != DT_FILE) {		U32 blockcount;		if (ioctl(f, BLKGETSIZE, (void *)&blockcount) >= 0) {			s->size_known = 1;			s->size = (U64)blockcount * 512;#if DEBUG_SIZE			printf("Size: Linux 32-bit ioctl reports %llu (%lu blocks)\n", s->size, blockcount);#endif		}	}#endif#ifdef USE_IOCTL_FREEBSD	/*	 * ioctl, FreeBSD style:	 * Works on partitioned hard disks or somthing like that.	 */	if (!s->size_known && s->type != DT_FILE) {		struct disklabel dl;		if (ioctl(f, DIOCGDINFO, &dl) >= 0) {			s->size_known = 1;			s->size = (U64) dl.d_ncylinders * dl.d_secpercyl * dl.d_secsize;			/* TODO: check this, it's the whole disk size... */#if DEBUG_SIZE			printf("Size: FreeBSD ioctl reports %llu\n", s->size);#endif		}	}#endif#ifdef USE_IOCTL_DARWIN	/*	 * ioctl, Darwin style:	 * Works on certain devices.	 */	if (!s->size_known && s->type != DT_FILE) {		U32 blocksize;		U64 blockcount;		if (ioctl(f, DKIOCGETBLOCKSIZE, (void *)&blocksize) >= 0) {			if (ioctl(f, DKIOCGETBLOCKCOUNT, (void *)&blockcount) >= 0) {				s->size_known = 1;				s->size = blockcount * blocksize;#if DEBUG_SIZE				printf("Size: Darwin ioctl reports %llu (%llu blocks of %lu bytes)\n",				       s->size, blockcount, blocksize);#endif			}		}	}#endif#if USE_BINARY_SEARCH	/*	 * binary search:	 * Works on anything that can seek, but is quite expensive.	 */	if (!s->size_known) {		U64 lower, upper, current;		/* TODO: check that the target can seek at all */#if DEBUG_SIZE		printf("Size: Doing a binary search\n");#endif		/* first, find an upper bound starting from a reasonable guess */		lower = 0;		upper = 1024 * 1024;  /* start with 1MB */		while (check_position(f, upper)) {			lower = upper;			upper <<= 2;		}		/* second, nail down the size between the lower and upper bounds */		while (upper > lower + 1) {			current = (lower + upper) >> 1;			if (check_position(f, current))				lower = current;			else				upper = current;		}		s->size_known = 1;		s->size = lower + 1;#if DEBUG_SIZE		printf("Size: Binary search reports %llu\n", s->size);#endif	}#endif	return;}/* * check if the given position is inside the file's size */#if USE_BINARY_SEARCHint check_position(int f, U64 pos) {	char buf[2];#if DEBUG_SIZE	printf("      Probing %llu\n", pos);#endif	if(lseek(f, pos, SEEK_SET) != pos)		return 0;	if (read(f, buf, 1) != 1)		return 0;	return 1;}#endif/* * endian-aware data access */U16 get_be_short(void *from) {	U8 *p = from;	return ((U16)(p[0]) << 8) +	       (U16)p[1];}U32 get_be_long(void *from) {	U8 *p = from;	return ((U32)(p[0]) << 24) +	       ((U32)(p[1]) << 16) +	       ((U32)(p[2]) << 8) +	       (U32)p[3];}U64 get_be_quad(void *from) {	U8 *p = from;	return ((U64)(p[0]) << 56) +	       ((U64)(p[1]) << 48) +	       ((U64)(p[2]) << 40) +	       ((U64)(p[3]) << 32) +	       ((U64)(p[4]) << 24) +	       ((U64)(p[5]) << 16) +	       ((U64)(p[6]) << 8) +	       (U64)p[7];}U16 get_le_short(void *from) {	U8 *p = from;	return ((U16)(p[1]) << 8) +	       (U16)p[0];}U32 get_le_long(void *from) {	U8 *p = from;	return ((U32)(p[3]) << 24) +	       ((U32)(p[2]) << 16) +	       ((U32)(p[1]) << 8) +	       (U32)p[0];}U64 get_le_quad(void *from) {	U8 *p = from;	return ((U64)(p[7]) << 56) +	       ((U64)(p[6]) << 48) +	       ((U64)(p[5]) << 40) +	       ((U64)(p[4]) << 32) +	       ((U64)(p[3]) << 24) +	       ((U64)(p[2]) << 16) +	       ((U64)(p[1]) << 8) +	       (U64)p[0];}U16 get_ve_short(int endianness, void *from) {	if (endianness)		return get_le_short(from);	else		return get_be_short(from);}U32 get_ve_long(int endianness, void *from) {	if (endianness)		return get_le_long(from);	else		return get_be_long(from);}U64 get_ve_quad(int endianness, void *from) {	if (endianness)		return get_le_quad(from);	else		return get_be_quad(from);}const char * get_ve_name(int endianness) {	if (endianness)		return _T("little-endian");	else		return _T("big-endian");}/* * more data access */void get_string(void *from, int len, char *to) {	if (len > 255)		len = 255;	memcpy(to, from, len);	to[len] = 0;}void get_pstring(void *from, char *to) {	int len = *(unsigned char *)from;	memcpy(to, (char *)from + 1, len);	to[len] = 0;}void get_padded_string(void *from, int len, char pad, char *to) {	int pos;	get_string(from, len, to);	for (pos = strlen(to) - 1; pos >= 0 && to[pos] == pad; pos--)		to[pos] = 0;}int find_memory(void *haystack, int haystack_len,                void *needle, int needle_len) {	int searchlen = haystack_len - needle_len + 1;	int pos = 0;	void *p;	while (pos < searchlen) {		p = memchr((char *)haystack + pos, *(unsigned char *)needle,		           searchlen - pos);		if (p == NULL)			return -1;		pos = (char *)p - (char *)haystack;		if (memcmp(p, needle, needle_len) == 0)			return pos;		pos++;	}	return -1;}/* * error functions */#ifdef DEBUGvoid debugmessage(char* function, int line, const char *msg, ...) {	va_list par;	char buf[4096];	va_start(par, msg);	vsnprintf(buf, 4096, msg, par);	va_end(par);	fprintf(stderr, "* DEBUG *:%s:%i: %s\n", function, line, buf);}#endifvoid error(const char *msg, ...) {	va_list par;	char buf[4096];	va_start(par, msg);	vsnprintf(buf, 4096, msg, par);	va_end(par);	fprintf(stderr, "*** ERROR ***: %s\n", buf);}void errore(const char *msg, ...) {	va_list par;	char buf[4096];	char* error;	va_start(par, msg);	vsnprintf(buf, 4096, msg, par);	va_end(par);	error = strerror(errno);	fprintf(stderr, "*** ERROR ***: %s: %s\n", buf, error);}void bailout(const char *msg, ...) {	va_list par;	char buf[4096];	va_start(par, msg);	vsnprintf(buf, 4096, msg, par);	va_end(par);	fprintf(stderr, "*** FATAL ***: %s\n", buf);	exit(1);}void bailoute(const char *msg, ...) {	va_list par;	char buf[4096];	char* error;	va_start(par, msg);	vsnprintf(buf, 4096, msg, par);	va_end(par);		error = strerror(errno);	fprintf(stderr, "*** FATAL ***: %s: %s\n", buf, error);	exit(1);}/* EOF */

⌨️ 快捷键说明

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