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

📄 main.c

📁 一个有关挂载U盘
💻 C
字号:
#include <limits.h>
#include "comm_msg_handle.h"
#include "utility.h"

/*
 *2008-10-27 modify Ver 0.1.0 -> Ver 0.1.1
 *修改SD卡开机无法识别bug
 *
 *2008-10-10 Create Ver 0.1.0
 *
 */

#define Version "AutoDetect Ver0.1.1"

#define MAX_ITEM_NUM 8
#define MAX_PARTITION_NUM 32

#define ULLONG_MAX (~0ULL)

typedef struct ProcStruct
{
	int major;							//主设备号
	int minor;		  				//次设备号
	char name[32];         	//设备名
	char type;              //类型
	char Status;            //状态
} ProcItem;

typedef struct ProcPartition
{
	int major;							//主设备号
	int minor;		  				//次设备号
	char name[32];         	//设备名
} PartitionItem;

static int g_item_count = 0;
static ProcItem g_proc_item[MAX_ITEM_NUM];

static int g_partition_count = 0;
static PartitionItem g_partition_item[MAX_PARTITION_NUM];

extern int InitMsg(void);

static unsigned long long ret_ERANGE(void)
{
	errno = ERANGE; /* this ain't as small as it looks (on glibc) */
	return ULLONG_MAX;
}

static unsigned long long handle_errors(unsigned long long v, char **endp, char *endptr)
{
	if (endp) *endp = endptr;

	/* Check for the weird "feature":
	 * a "-" string is apparently a valid "number" for strto[u]l[l]!
	 * It returns zero and errno is 0! :( */
	if (endptr[-1] == '-')
		return ret_ERANGE();

	/* errno is already set to ERANGE by strtoXXX if value overflowed */
	if (endptr[0]) {
		/* "1234abcg" or out-of-range? */
		if (isalnum(endptr[0]) || errno)
			return ret_ERANGE();
		/* good number, just suspicious terminator */
		errno = EINVAL;
	}
	
	return v;
}

static unsigned bb_strtou(const char *arg, char **endp, int base)
{
	unsigned long v;
	char *endptr;

	if (!isalnum(arg[0])) return ret_ERANGE();
	errno = 0;
	v = strtoul(arg, &endptr, base);
	if (v > UINT_MAX) return ret_ERANGE();
	return handle_errors(v, endp, endptr);
}

static unsigned long long bb_strtoull(const char *arg, char **endp, int base)
{
	unsigned long long v;
	char *endptr;

	/* strtoul("  -4200000000") returns 94967296, errno 0 (!) */
	/* I don't think that this is right. Preventing this... */
	if (!isalnum(arg[0])) return ret_ERANGE();

	/* not 100% correct for lib func, but convenient for the caller */
	errno = 0;
	v = strtoull(arg, &endptr, base);
	return handle_errors(v, endp, endptr);
}

static char* strchrnul(const char *s, char c)
{
	while (*s && *s != c) ++s;
	
	return (char*)s;
}

static char *skip_whitespace(const char *s)
{
	/* NB: isspace('\0') returns 0 */
	while (isspace(*s)) ++s;

	return (char *) s;
}

static void init_partition_item( void )
{
	int i;
	
	g_partition_count = 0;
	for( i = 0; i < MAX_PARTITION_NUM; i++ ) {
		g_partition_item[i].major = 0;
    g_partition_item[i].minor = 0;
		memset( g_partition_item[i].name, 0x00, sizeof(g_partition_item[i].name) );
	}
  
	return ;
}

static void get_proc_partitions(void)
{
	char line[128];
	int major, minor;
	unsigned long long sz;
	FILE *procpt;
	char *chptr;

  init_partition_item();
  if( !( procpt = fopen( "/proc/partitions", "r" ) ) ) 
		return ;
  /*
  # cat /proc/partitions
  major minor  #blocks  name
  
     8     0  293036184 sda
     8     1    6835626 sda1
     8     2          1 sda2
     8     5     979933 sda5
     8     6   15623181 sda6
     8     7   97659103 sda7
     8     8  171935631 sda8
  */
	fseek(procpt, 0, SEEK_SET);

	while (fgets(line, sizeof(line), procpt)) {
		/* The original version of this code used sscanf, but
		   diet's sscanf is quite limited */
		chptr = line;
		if (*chptr != ' ') continue;
		chptr = skip_whitespace(chptr);

		major = bb_strtou(chptr, &chptr, 0);
		if (major < 0) continue;
		chptr = skip_whitespace(chptr);

		minor = bb_strtou(chptr, &chptr, 0);
		if (minor < 0) continue;
		chptr = skip_whitespace(chptr);

		sz = bb_strtoull(chptr, &chptr, 0);
		if ((long long)sz == -1LL) continue;
		chptr = skip_whitespace(chptr);

		/* skip extended partitions (heuristic: size 1) */
		if (sz == 1)
			continue;

		*strchrnul(chptr, '\n') = '\0';
		/* now chptr => device name */
		g_partition_item[g_partition_count].major = major;
    g_partition_item[g_partition_count].minor = minor;
		strcpy( g_partition_item[g_partition_count].name, chptr );
		g_partition_count++;
	#if 0	
		//printf( "major:%d minor:%d size:%llu name:'%s'\n", major, minor, sz, chptr );
		if( g_item_count > 0 ) {
			for( i = 0; i < g_item_count; i++ ) {
				if( (g_proc_item[i].major == major) && (g_proc_item[i].minor) && \
					  ((strcmp(g_proc_item[i].name, chptr) == 0)) && (g_proc_item[i].Status == 0x00) ) {					
					printf( "Find dev: %02x %s\n", g_proc_item[i].type, g_proc_item[i].name );
					
          g_proc_item[i].Status = 0x01;
					memset( Data, 0x00, sizeof(Data) );
					len = 1 + strlen(g_proc_item[i].name);
					Data[0] = g_proc_item[i].type;
					strcpy( Data + 1, g_proc_item[i].name ); 
					SendGTKAutoDetectMsg( Data, len );  	
				}
			}
		}
	#endif
	}

	fclose(procpt);
	
	return ;
}

static void init_proc_item( void )
{
	int i;
	
	for( i = 0; i < MAX_ITEM_NUM; i++ ) {
		g_proc_item[i].major = 0;
    g_proc_item[i].minor = 0;
    g_proc_item[i].type = 0x00;
    g_proc_item[i].Status = 0x00;
		memset( g_proc_item[i].name, 0x00, sizeof(g_proc_item[i].name) );
	}
	
	g_item_count = 0;
	//mmc
	g_proc_item[g_item_count].major = 179;
  g_proc_item[g_item_count].minor = 1;
  g_proc_item[g_item_count].type = 0x01;
  strcpy( g_proc_item[g_item_count].name, "mmcblk0p1" );
  g_item_count++;
	//usb
  g_proc_item[g_item_count].major = 180;
  g_proc_item[g_item_count].minor = 1;
  g_proc_item[g_item_count].type = 0x02;
  strcpy( g_proc_item[g_item_count].name, "uba1" );
  g_item_count++;
  
	return ;
}

static int find_partition_item( int index )
{
	int i = -1;
	
	if( g_partition_count > 0 ) {
		for( i = 0; i < g_partition_count; i++ ) {
			if( (g_partition_item[i].major == g_proc_item[index].major) && \
				  (g_partition_item[i].minor == g_proc_item[index].minor) && \
				  ((strcmp(g_partition_item[i].name, g_proc_item[index].name) == 0)) ) {
				 return 0; 	
			}
		}
	}
	
	return i;
}

static int IsExistFile( const char *filename )
{
	int ret;
	
	if ( access( filename, F_OK ) == 0 ) {
		ret = 1;
	} else {
		ret = 0;
	}
	
	return ret;
}

int main( int argc, char *argv[] )
{
	int ret, i, len;
	char Data[128];
	
	printf( "%s\n", Version );
	
	ret = InitMsg();
	if( ret != 0 ) {
		printf( "AutoDetect: (LYS) Init Error\n");
		return -1;
	}
	
	init_proc_item();
	while( 1 ) 
	{
		get_proc_partitions();
		if( g_item_count > 0 ) {
			for( i = 0; i < g_item_count; i++ ) {
				ret = find_partition_item( i );
				if( ret == 0 )
				{
					//检测到,已插入
					if( (g_proc_item[i].Status == 0x00) ) {
						char buf[32], cmd[64];
						
						memset(buf, 0x00, sizeof(buf) );
						sprintf(buf, "/dev/%s", g_proc_item[i].name);
						//判断设备是否存在
						if (IsExistFile(buf) == 0) {
						  memset(cmd, 0x00, sizeof(cmd) );
						  sprintf(cmd, "mknod %s b %d %d", \
						    buf, g_proc_item[i].major, g_proc_item[i].minor);
						  system(cmd);
						  //"mknod /dev/mmcblk0p1 b 179 1"
						}
						
						//发送消息
						g_proc_item[i].Status = 0x01;
				    memset( Data, 0x00, sizeof(Data) );
				    len = 2 + strlen(g_proc_item[i].name);
				    Data[0] = DEV_IN;
				    Data[1] = g_proc_item[i].type;
				    strcpy( Data + 2, g_proc_item[i].name ); 
				    SendGTKAutoDetectMsg( Data, len );
					}
				} else {						
					//未检测到,已拔出
					if( (g_proc_item[i].Status == 0x01) ) {
						//发送消息
						g_proc_item[i].Status = 0x00;
				    memset( Data, 0x00, sizeof(Data) );
				    len = 2 + strlen(g_proc_item[i].name);
				    Data[0] = DEV_OUT;
				    Data[1] = g_proc_item[i].type;
				    strcpy( Data + 2, g_proc_item[i].name ); 
				    SendGTKAutoDetectMsg( Data, len );
					}
				}	
			}
		}
		sleep( 1 );
	}
  
	return 0;
}

⌨️ 快捷键说明

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