#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mount.h>
#include <unistd.h>
#include <pthread.h>
//setMsg
#define TRUE 1
#define FALSE 0
/*
下面是我根据网上一篇文章的思路整理的来的,以及测试验证通过,将其中的打印换成标准的C打印就可以直接拿来跑。
目前只是验证了U盘,没有进行硬盘测试,以及一些异常测试。但是证明整个通道是OK的。该代码的作用是:在机顶盒上
检测有USB的插拔,即可通知到应用,这个不难办到,关键是插拔之后应用还要能够访问U盘目录,所以就要进行手动的
mount 和umount操作。
*/
#define FILE_DEV_CHECK "/proc/scsi/scsi" //用来检测设备数和类型
#define FILE_MOUNT_CHECK "/proc/mounts" //用来检测设备是否被mount
#define FILE_DISC_PARTS_CHECK "/proc/partitions" //用来检测设备的分区情况
#define FILE_DEV_PART_TEMPL "/dev/scsi/host%d/bus0/target0/lun0/" //具体的设备
#define USB_CDROM_MP "/opt/cdrom"
#define USB_DISK_MP "/opt/d"
#define FILE_DEV_STATU_TEMPL "/proc/scsi/usb-storage-%d/%d" //用来检测某一设备是否在插入状态
#define MAX_NAME_LEN 64
#define MAX_PART_NUM 6 //最多运行6个分区
#define KK_FS_OK 1
#define KK_FS_FAIL 0
typedef struct s_scsi_usb_dev
{
int type; /*1 cdrom 2 disk */
int index; /*like host0 host1*/
char file_statu[MAX_NAME_LEN]; /*like "/proc/scsi/usb-storage-%d/%d"*/
char devfile_parts[MAX_PART_NUM][MAX_NAME_LEN]; /*存储每个分区的设备文件*/
char mount_path[MAX_PART_NUM][MAX_NAME_LEN]; /*与上面对应的mount点*/
int part_num; //4分区数
struct s_scsi_usb_dev *next_dev; //4指向下一个设备
} SCSI_USB_DEV;
static SCSI_USB_DEV *f_first_dev = NULL;
static int insert = FALSE;
static int find_attached = FALSE;
static int is_manual_umount = 1;
static void CLEAR_DEV(void);
static int CHECK_PARTS(SCSI_USB_DEV *dev);
static int ADD_DEV(SCSI_USB_DEV *dev);
static int INIT_DEV(SCSI_USB_DEV *dev, int index, char *type);
static int check_mount(SCSI_USB_DEV *dev);
static int do_mount(SCSI_USB_DEV *dev);
static int do_umount(SCSI_USB_DEV *dev);
static int process_dev(SCSI_USB_DEV *dev);
static int find_device(void);
//device opt function
static int ADD_DEV(SCSI_USB_DEV *dev)
{
if(f_first_dev)
{
dev->next_dev = f_first_dev;
f_first_dev = dev;
}
else
{
f_first_dev = dev;
dev->next_dev = NULL;
}
return KK_FS_OK;
}
static int INIT_DEV(SCSI_USB_DEV *dev, int index, char *type)
{
dev->index = index;
sprintf(dev->file_statu, FILE_DEV_STATU_TEMPL, index, index);
if (!strncmp(type, "CD-ROM", 6))//cd-rom
{
}
else//usb disk
{
dev->type = 2;
dev->part_num = CHECK_PARTS(dev);
}
return KK_FS_OK;
}
/*
* 如果在/proc/scsi/scsi/中发现的设备是usb-storage,则进一步在/proc/partitions/中分析其所
* 包含几个分区,并将其记录下来dev->devfile_parts,mount路径也一并设置dev->mount_path
* 例如发现一个U盘,仅仅有一个分区,系统将其挂载在/dev/sda1/下,则可以将其mount路径设置成
* 用户可以访问的/tmp/usb/disk0/part0/下
*/
static int CHECK_PARTS(SCSI_USB_DEV *dev)
{
int len = 0;
int part_num = 0;
char buf[1024] = {0}; //1024 is enough for save information of FILE partitions
char hoststr[16] = {0};
char *delim="\n";
char *line = NULL;
char *strtok_tmp_ptr = NULL;
char *seek = NULL;
char *seek_sd = NULL; //USED FOR DEVICE MOUNTED ON SD*
char *seek_hd = NULL; //USED FOR DEVICE MOUNTED ON HD*
char *part_blocks = NULL;
FILE *fd = NULL;
fd = fopen(FILE_DISC_PARTS_CHECK, "r"); //直接操作open打开系统文件
if(fd != NULL)
{
// printf("[%s]open file %s success\n",__FUNCTION__,FILE_DISC_PARTS_CHECK);
len = fread(buf, 1, sizeof(buf), fd);
fclose(fd);
if(len > 0)
{
line = strtok_r(buf, delim, &strtok_tmp_ptr);//以"\n"结束符来截断字符串
while(line)
{
seek_sd = strstr(line, "sd");//成功找到sd后指针seek指向s, seek_sd[0] = 's', seek_sd[1] = 'd'
// seek_hd = strstr(line, "hd");//成功找到hd后指针seek指向h, seek_hd[0] = 'h', seek_hd[1] = 'd'
if (seek_sd)
{
if(seek_sd[2] >= 'a' && seek_sd[2] <= 'z')
{
if(seek_sd[3] >= '1' && seek_sd[3] < '9')
{
printf("[%s]find device %s\n",seek_sd);
sprintf(dev->devfile_parts[part_num],"/dev/%s", seek_sd);
sprintf(dev->mount_path[part_num], USB_DISK_MP"/disk%d/part%d",dev->index, part_num);
part_num ++;
if (part_num == MAX_PART_NUM)
{
break;//too many parts ignore
}
}
}
}
/* if (seek_hd)
{
if(seek_hd[2] >= 'a' && seek_hd[2] <= 'z')
{
if(seek_hd[3] >= '1' && seek_hd[3] < '9')
{
// printf("[%s]find device %s\n",seek_sd);
sprintf(dev->devfile_parts[part_num],"/dev/%s", seek_hd);
sprintf(dev->mount_path[part_num], USB_DISK_MP"/disk%d/part%d",dev->index, part_num);
part_num ++;
if (part_num == MAX_PART_NUM)
{
break;//too many parts ignore
}
}
}
}*/
line = strtok_r(NULL, delim, &strtok_tmp_ptr);
}
}
}
else
{
perror(FILE_DISC_PARTS_CHECK);
}
return part_num;
}
/*
* 线程扫描时会不停的调用该接口去清除之前获取的设备信息
*/
static void CLEAR_DEV(void)
{
SCSI_USB_DEV *cur_dev = f_first_dev;
SCSI_USB_DEV *tmp_dev;
while (cur_dev)
{
tmp_dev = cur_dev;
cur_dev = cur_dev->next_dev;
free(tmp_dev);
}
f_first_dev = NULL;
}
/*
* 打开"/proc/scsi/scsi" 里面会有如下信息,该接口通过轮询Host: scsi去查找有无插上设备
* 以及轮询Type 去查询设备类型
* Attached devices:
*
* Host: scsi0 Channel: 00 Id: 00 Lun: 00
* Vendor: BENQ Model: DVD-ROM 16X Rev: A.DD
* Type: CD-ROM ANSI SCSI revision: 02
*
* Host: scsi1 Channel: 00 Id: 00 Lun: 00
* Vendor: FUJITSU Model: MHT2040AH Rev: 0000
* Type: Direct-Access ANSI SCSI revision: 02
*
*
*/
static int find_device()
{
FILE *fd = NULL;
int len = 0;
int dev_num = 0;
char buf[1024] = {0};
char *seek = NULL;
SCSI_USB_DEV *new_dev = NULL;
//clear exist device
CLEAR_DEV();
//add new device
fd = fopen(FILE_DEV_CHECK, "r");//直接操作open系统文件/proc/scsi/scsi
if(fd > 0)
{
/*
* 如果没有任何设备接入,那么/proc/scsi/scsi中仅仅包含下列字符 "Attached devices:"
* 文件长度为18。所以下面以20个字符来做判断。
*/
len = fread(buf, 1, sizeof(buf), fd);
fclose(fd);
if(len < 20 && find_attached == TRUE)
{
find_attached = FALSE;
// KK_ERROR("Device removed......\n");
// KKFS_Callback(KK_FS_DISK_REMOVED);
return KK_FS_OK;
}
if (len > 0)
{
/*
* 如果文件打开成功,而且长度大于20,表示里面是有设备记录的,如果find_attached标志之前是FALSE
* 表示有新的动作:设备插入系统
*/
if(len > 20 && find_attached == FALSE)
{
find_attached = TRUE;
// KK_ERROR("Device Inserted......\n");
// KKFS_Callback(KK_FS_DISK_INSERT);
}
seek = buf;
while(seek && ((strlen(seek)) > 0))//jacky
{
seek = strstr(seek, "Host: scsi");//从seek 中查找"Host: scsi"的第一次出现,返回第一次出现的位置
if(seek && (seek[0] == 'H'))
{
seek += strlen( "Host: scsi");
seek = strstr(seek, "Type:");
if(seek && (seek[0] == 'T'))
{
seek += strlen("Type:");
while(*seek == ' ')
{
seek++;
}
new_dev = malloc(sizeof(SCSI_USB_DEV));
INIT_DEV(new_dev, dev_num, seek);
ADD_DEV(new_dev);
dev_num ++;
}
}
}
// KK_INFO("dev_num = %d\n", dev_num);
}
}
else
{
perror(FILE_DEV_CHECK);
}
return dev_num;
}
static int check_mount(SCSI_USB_DEV *dev)
{
FILE *fd = NULL;
int len = 0;
int i = 0;
char buf[1024] = {0};
char *seek = NULL;
fd = fopen(FILE_MOUNT_CHECK, "r");
if(fd > 0)
{
// KK_INFO("[%s]open file %s success\n",__FUNCTION__, FILE_MOUNT_CHECK);
len = fread(buf, 1, sizeof(buf), fd);
fclose(fd);
if (len > 0)
{
buf[len] = '\0';
if(dev->type == 2) {
seek = strstr(buf, dev->devfile_parts[0]);
if (seek != NULL)
{
return KK_FS_OK;/*have one part mounted return 1*/
}
}
}
}
else
{
perror(FILE_MOUNT_CHECK);
}
return KK_FS_FAIL;
}
static int check_attach(SCSI_USB_DEV * dev)
{//检测设备是否连接
//linux中只要设备被插入过就会记住该设备
//只能通过Attached来判断是否连接
char buf[512];
int fd;
int len;
char * seek;
fd = open(dev->file_statu, O_RDONLY);
if( fd > 0 )
{
len = read(fd, buf, sizeof(buf));
close(fd);
if ( len > 0 )
{
seek = strstr(buf, "Attached:");
if (seek)
{
seek += strlen( "Attached:");
while(*seek == ' ') seek++;
return *seek=='Y';
}
}
}
else
{
perror(dev->file_statu);
}
return 0;
}
//mount format: # mount -t vfat /dev/sda1 /1
/*
* # cat /proc/mounts
* rootfs / rootfs rw 0 0
* proc /proc proc rw 0 0
* devpts /dev/pts devpts rw,mode=600 0 0
* sysfs /sys sysfs rw 0 0
* /dev/mtdblock3 /usr/sbin/zoran squashfs ro 0 0
* /dev/sda1 /tmp/usbdisk/disk0/part0 vfat rw,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1 0 0
* /dev/sdb1 /tmp/usbdisk/disk0/part0 vfat rw,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1 0 0
* /dev/sdc1 /tmp/usbdisk/disk0/part0 vfat rw,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1 0 0
*/
static int do_mount(SCSI_USB_DEV *dev)
{
int i = 0;
int is_vcd = 0;
int mount_ok = 0;
char fstype[10] = {0};
char tmpdir[50] = {0};
char check_cmd[50] = {0};
char mount_data[30] = {0};
char mount_cmd[64] = {0};
unsigned long mountflags = 0;
/*
* CD-ROM这里可以不去考虑,不论其完善与否,可以作为扩展放在这里
*/
if(dev->type == 1 && is_manual_umount == 0)
{
}
else if (dev->type == 2)
{
sprintf(tmpdir, USB_DISK_MP"/disk%d", dev->index);
mkdir(tmpdir, 0777);
strcpy(fstype, "vfat");
mountflags= 0xc0ed0000;
strcpy(mount_data,"codepage=936,iocharset=gb2312");
mkdir(dev->mount_path[0], 0777);
sprintf(mount_cmd, "mount -t vfat %s %s", dev->devfile_parts[0], dev->mount_path[0]);
system(mount_cmd);
}
else
{
return KK_FS_FAIL;
}
return KK_FS_OK;
}
static int do_umount(SCSI_USB_DEV *dev)
{
int i = 0;
char tmpdir[50] = {0};
char mount_cmd[40];
if (dev->type == 1)//cdrom
{
}
else if(dev->type == 2)//usb-storage
{
sprintf(mount_cmd,"umount -l %s",dev->mount_path[0]);
printf("%s\n",mount_cmd);
i= system(mount_cmd);
remove(dev->mount_path[0]);
}
sprintf(tmpdir, USB_DISK_MP"/disk%d", dev->index);
remove(tmpdir);
return KK_FS_OK;
}
static int process_dev(SCSI_USB_DEV * dev)
{
if( check_attach(dev)){
if (check_mount(dev) == KK_FS_FAIL)//检测设备是否mount上
{
do_mount(dev);
//printf(" check_mountKK_FS_FAIL \n");
}
// else
//printf("check_mount KK_FS_OK \n");
}
else
{
if (check_mount(dev) == KK_FS_OK){
printf("icheck_mount unmount \n");
do_umount(dev);
}
}
return KK_FS_OK;
}
int usb_main()
{
SCSI_USB_DEV *cur_dev = NULL;
mkdir(USB_DISK_MP, 0777);
mkdir(USB_CDROM_MP, 0777);
while(1)
{
find_device();//查找设备 初始化设备列表
cur_dev = f_first_dev;
while(cur_dev)
{
process_dev(cur_dev);//对每个设备进行处理
cur_dev = cur_dev->next_dev;
}
sleep(3); // 3秒钟检测一次
}
}
#include <stdlib.h>
#include <error.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mount.h>
#include <unistd.h>
#include <pthread.h>
//setMsg
#define TRUE 1
#define FALSE 0
/*
下面是我根据网上一篇文章的思路整理的来的,以及测试验证通过,将其中的打印换成标准的C打印就可以直接拿来跑。
目前只是验证了U盘,没有进行硬盘测试,以及一些异常测试。但是证明整个通道是OK的。该代码的作用是:在机顶盒上
检测有USB的插拔,即可通知到应用,这个不难办到,关键是插拔之后应用还要能够访问U盘目录,所以就要进行手动的
mount 和umount操作。
*/
#define FILE_DEV_CHECK "/proc/scsi/scsi" //用来检测设备数和类型
#define FILE_MOUNT_CHECK "/proc/mounts" //用来检测设备是否被mount
#define FILE_DISC_PARTS_CHECK "/proc/partitions" //用来检测设备的分区情况
#define FILE_DEV_PART_TEMPL "/dev/scsi/host%d/bus0/target0/lun0/" //具体的设备
#define USB_CDROM_MP "/opt/cdrom"
#define USB_DISK_MP "/opt/d"
#define FILE_DEV_STATU_TEMPL "/proc/scsi/usb-storage-%d/%d" //用来检测某一设备是否在插入状态
#define MAX_NAME_LEN 64
#define MAX_PART_NUM 6 //最多运行6个分区
#define KK_FS_OK 1
#define KK_FS_FAIL 0
typedef struct s_scsi_usb_dev
{
int type; /*1 cdrom 2 disk */
int index; /*like host0 host1*/
char file_statu[MAX_NAME_LEN]; /*like "/proc/scsi/usb-storage-%d/%d"*/
char devfile_parts[MAX_PART_NUM][MAX_NAME_LEN]; /*存储每个分区的设备文件*/
char mount_path[MAX_PART_NUM][MAX_NAME_LEN]; /*与上面对应的mount点*/
int part_num; //4分区数
struct s_scsi_usb_dev *next_dev; //4指向下一个设备
} SCSI_USB_DEV;
static SCSI_USB_DEV *f_first_dev = NULL;
static int insert = FALSE;
static int find_attached = FALSE;
static int is_manual_umount = 1;
static void CLEAR_DEV(void);
static int CHECK_PARTS(SCSI_USB_DEV *dev);
static int ADD_DEV(SCSI_USB_DEV *dev);
static int INIT_DEV(SCSI_USB_DEV *dev, int index, char *type);
static int check_mount(SCSI_USB_DEV *dev);
static int do_mount(SCSI_USB_DEV *dev);
static int do_umount(SCSI_USB_DEV *dev);
static int process_dev(SCSI_USB_DEV *dev);
static int find_device(void);
//device opt function
static int ADD_DEV(SCSI_USB_DEV *dev)
{
if(f_first_dev)
{
dev->next_dev = f_first_dev;
f_first_dev = dev;
}
else
{
f_first_dev = dev;
dev->next_dev = NULL;
}
return KK_FS_OK;
}
static int INIT_DEV(SCSI_USB_DEV *dev, int index, char *type)
{
dev->index = index;
sprintf(dev->file_statu, FILE_DEV_STATU_TEMPL, index, index);
if (!strncmp(type, "CD-ROM", 6))//cd-rom
{
}
else//usb disk
{
dev->type = 2;
dev->part_num = CHECK_PARTS(dev);
}
return KK_FS_OK;
}
/*
* 如果在/proc/scsi/scsi/中发现的设备是usb-storage,则进一步在/proc/partitions/中分析其所
* 包含几个分区,并将其记录下来dev->devfile_parts,mount路径也一并设置dev->mount_path
* 例如发现一个U盘,仅仅有一个分区,系统将其挂载在/dev/sda1/下,则可以将其mount路径设置成
* 用户可以访问的/tmp/usb/disk0/part0/下
*/
static int CHECK_PARTS(SCSI_USB_DEV *dev)
{
int len = 0;
int part_num = 0;
char buf[1024] = {0}; //1024 is enough for save information of FILE partitions
char hoststr[16] = {0};
char *delim="\n";
char *line = NULL;
char *strtok_tmp_ptr = NULL;
char *seek = NULL;
char *seek_sd = NULL; //USED FOR DEVICE MOUNTED ON SD*
char *seek_hd = NULL; //USED FOR DEVICE MOUNTED ON HD*
char *part_blocks = NULL;
FILE *fd = NULL;
fd = fopen(FILE_DISC_PARTS_CHECK, "r"); //直接操作open打开系统文件
if(fd != NULL)
{
// printf("[%s]open file %s success\n",__FUNCTION__,FILE_DISC_PARTS_CHECK);
len = fread(buf, 1, sizeof(buf), fd);
fclose(fd);
if(len > 0)
{
line = strtok_r(buf, delim, &strtok_tmp_ptr);//以"\n"结束符来截断字符串
while(line)
{
seek_sd = strstr(line, "sd");//成功找到sd后指针seek指向s, seek_sd[0] = 's', seek_sd[1] = 'd'
// seek_hd = strstr(line, "hd");//成功找到hd后指针seek指向h, seek_hd[0] = 'h', seek_hd[1] = 'd'
if (seek_sd)
{
if(seek_sd[2] >= 'a' && seek_sd[2] <= 'z')
{
if(seek_sd[3] >= '1' && seek_sd[3] < '9')
{
printf("[%s]find device %s\n",seek_sd);
sprintf(dev->devfile_parts[part_num],"/dev/%s", seek_sd);
sprintf(dev->mount_path[part_num], USB_DISK_MP"/disk%d/part%d",dev->index, part_num);
part_num ++;
if (part_num == MAX_PART_NUM)
{
break;//too many parts ignore
}
}
}
}
/* if (seek_hd)
{
if(seek_hd[2] >= 'a' && seek_hd[2] <= 'z')
{
if(seek_hd[3] >= '1' && seek_hd[3] < '9')
{
// printf("[%s]find device %s\n",seek_sd);
sprintf(dev->devfile_parts[part_num],"/dev/%s", seek_hd);
sprintf(dev->mount_path[part_num], USB_DISK_MP"/disk%d/part%d",dev->index, part_num);
part_num ++;
if (part_num == MAX_PART_NUM)
{
break;//too many parts ignore
}
}
}
}*/
line = strtok_r(NULL, delim, &strtok_tmp_ptr);
}
}
}
else
{
perror(FILE_DISC_PARTS_CHECK);
}
return part_num;
}
/*
* 线程扫描时会不停的调用该接口去清除之前获取的设备信息
*/
static void CLEAR_DEV(void)
{
SCSI_USB_DEV *cur_dev = f_first_dev;
SCSI_USB_DEV *tmp_dev;
while (cur_dev)
{
tmp_dev = cur_dev;
cur_dev = cur_dev->next_dev;
free(tmp_dev);
}
f_first_dev = NULL;
}
/*
* 打开"/proc/scsi/scsi" 里面会有如下信息,该接口通过轮询Host: scsi去查找有无插上设备
* 以及轮询Type 去查询设备类型
* Attached devices:
*
* Host: scsi0 Channel: 00 Id: 00 Lun: 00
* Vendor: BENQ Model: DVD-ROM 16X Rev: A.DD
* Type: CD-ROM ANSI SCSI revision: 02
*
* Host: scsi1 Channel: 00 Id: 00 Lun: 00
* Vendor: FUJITSU Model: MHT2040AH Rev: 0000
* Type: Direct-Access ANSI SCSI revision: 02
*
*
*/
static int find_device()
{
FILE *fd = NULL;
int len = 0;
int dev_num = 0;
char buf[1024] = {0};
char *seek = NULL;
SCSI_USB_DEV *new_dev = NULL;
//clear exist device
CLEAR_DEV();
//add new device
fd = fopen(FILE_DEV_CHECK, "r");//直接操作open系统文件/proc/scsi/scsi
if(fd > 0)
{
/*
* 如果没有任何设备接入,那么/proc/scsi/scsi中仅仅包含下列字符 "Attached devices:"
* 文件长度为18。所以下面以20个字符来做判断。
*/
len = fread(buf, 1, sizeof(buf), fd);
fclose(fd);
if(len < 20 && find_attached == TRUE)
{
find_attached = FALSE;
// KK_ERROR("Device removed......\n");
// KKFS_Callback(KK_FS_DISK_REMOVED);
return KK_FS_OK;
}
if (len > 0)
{
/*
* 如果文件打开成功,而且长度大于20,表示里面是有设备记录的,如果find_attached标志之前是FALSE
* 表示有新的动作:设备插入系统
*/
if(len > 20 && find_attached == FALSE)
{
find_attached = TRUE;
// KK_ERROR("Device Inserted......\n");
// KKFS_Callback(KK_FS_DISK_INSERT);
}
seek = buf;
while(seek && ((strlen(seek)) > 0))//jacky
{
seek = strstr(seek, "Host: scsi");//从seek 中查找"Host: scsi"的第一次出现,返回第一次出现的位置
if(seek && (seek[0] == 'H'))
{
seek += strlen( "Host: scsi");
seek = strstr(seek, "Type:");
if(seek && (seek[0] == 'T'))
{
seek += strlen("Type:");
while(*seek == ' ')
{
seek++;
}
new_dev = malloc(sizeof(SCSI_USB_DEV));
INIT_DEV(new_dev, dev_num, seek);
ADD_DEV(new_dev);
dev_num ++;
}
}
}
// KK_INFO("dev_num = %d\n", dev_num);
}
}
else
{
perror(FILE_DEV_CHECK);
}
return dev_num;
}
static int check_mount(SCSI_USB_DEV *dev)
{
FILE *fd = NULL;
int len = 0;
int i = 0;
char buf[1024] = {0};
char *seek = NULL;
fd = fopen(FILE_MOUNT_CHECK, "r");
if(fd > 0)
{
// KK_INFO("[%s]open file %s success\n",__FUNCTION__, FILE_MOUNT_CHECK);
len = fread(buf, 1, sizeof(buf), fd);
fclose(fd);
if (len > 0)
{
buf[len] = '\0';
if(dev->type == 2) {
seek = strstr(buf, dev->devfile_parts[0]);
if (seek != NULL)
{
return KK_FS_OK;/*have one part mounted return 1*/
}
}
}
}
else
{
perror(FILE_MOUNT_CHECK);
}
return KK_FS_FAIL;
}
static int check_attach(SCSI_USB_DEV * dev)
{//检测设备是否连接
//linux中只要设备被插入过就会记住该设备
//只能通过Attached来判断是否连接
char buf[512];
int fd;
int len;
char * seek;
fd = open(dev->file_statu, O_RDONLY);
if( fd > 0 )
{
len = read(fd, buf, sizeof(buf));
close(fd);
if ( len > 0 )
{
seek = strstr(buf, "Attached:");
if (seek)
{
seek += strlen( "Attached:");
while(*seek == ' ') seek++;
return *seek=='Y';
}
}
}
else
{
perror(dev->file_statu);
}
return 0;
}
//mount format: # mount -t vfat /dev/sda1 /1
/*
* # cat /proc/mounts
* rootfs / rootfs rw 0 0
* proc /proc proc rw 0 0
* devpts /dev/pts devpts rw,mode=600 0 0
* sysfs /sys sysfs rw 0 0
* /dev/mtdblock3 /usr/sbin/zoran squashfs ro 0 0
* /dev/sda1 /tmp/usbdisk/disk0/part0 vfat rw,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1 0 0
* /dev/sdb1 /tmp/usbdisk/disk0/part0 vfat rw,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1 0 0
* /dev/sdc1 /tmp/usbdisk/disk0/part0 vfat rw,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1 0 0
*/
static int do_mount(SCSI_USB_DEV *dev)
{
int i = 0;
int is_vcd = 0;
int mount_ok = 0;
char fstype[10] = {0};
char tmpdir[50] = {0};
char check_cmd[50] = {0};
char mount_data[30] = {0};
char mount_cmd[64] = {0};
unsigned long mountflags = 0;
/*
* CD-ROM这里可以不去考虑,不论其完善与否,可以作为扩展放在这里
*/
if(dev->type == 1 && is_manual_umount == 0)
{
}
else if (dev->type == 2)
{
sprintf(tmpdir, USB_DISK_MP"/disk%d", dev->index);
mkdir(tmpdir, 0777);
strcpy(fstype, "vfat");
mountflags= 0xc0ed0000;
strcpy(mount_data,"codepage=936,iocharset=gb2312");
mkdir(dev->mount_path[0], 0777);
sprintf(mount_cmd, "mount -t vfat %s %s", dev->devfile_parts[0], dev->mount_path[0]);
system(mount_cmd);
}
else
{
return KK_FS_FAIL;
}
return KK_FS_OK;
}
static int do_umount(SCSI_USB_DEV *dev)
{
int i = 0;
char tmpdir[50] = {0};
char mount_cmd[40];
if (dev->type == 1)//cdrom
{
}
else if(dev->type == 2)//usb-storage
{
sprintf(mount_cmd,"umount -l %s",dev->mount_path[0]);
printf("%s\n",mount_cmd);
i= system(mount_cmd);
remove(dev->mount_path[0]);
}
sprintf(tmpdir, USB_DISK_MP"/disk%d", dev->index);
remove(tmpdir);
return KK_FS_OK;
}
static int process_dev(SCSI_USB_DEV * dev)
{
if( check_attach(dev)){
if (check_mount(dev) == KK_FS_FAIL)//检测设备是否mount上
{
do_mount(dev);
//printf(" check_mountKK_FS_FAIL \n");
}
// else
//printf("check_mount KK_FS_OK \n");
}
else
{
if (check_mount(dev) == KK_FS_OK){
printf("icheck_mount unmount \n");
do_umount(dev);
}
}
return KK_FS_OK;
}
int usb_main()
{
SCSI_USB_DEV *cur_dev = NULL;
mkdir(USB_DISK_MP, 0777);
mkdir(USB_CDROM_MP, 0777);
while(1)
{
find_device();//查找设备 初始化设备列表
cur_dev = f_first_dev;
while(cur_dev)
{
process_dev(cur_dev);//对每个设备进行处理
cur_dev = cur_dev->next_dev;
}
sleep(3); // 3秒钟检测一次
}
}
要注意的一个地方是: sprintf(mount_cmd,"umount -l %s",dev->mount_path[0]);
加个-l 好用!!!如果你的系统中加入了samba,没有-l会出现:device is busy错误!