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

📄 filesys.c.bak

📁 linux文件系统试验 一、实验目的 学习有关linux文件管理程序如何组织的知识
💻 BAK
字号:
/* here we only deal with 8 byte file name length */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <ctype.h>#include "filesys.h"#define DEBUG#define RevByte(low,high) ((high) << 8 | (low))#define RevWord(lowest,lower,higher,highest) ((highest) << 24 | (higher) << 16 | (lower) << 8 | lowest)struct BootDescriptor_t bdptor;struct Entry *curdir = NULL;int fd;unsigned char fatbuf[0x1200];void ScanBootSector(){  unsigned char buf[SECTOR_SIZE];	 /* Attention to type  */  int ret,i;  if ((ret = read(fd,buf,SECTOR_SIZE)) < 0)    perror("read boot sector failed");    for (i = 0; i <= 10; i++)    bdptor.Oem_name[i] = buf[i+0x03];  bdptor.Oem_name[i] = '\0';  bdptor.BytesPerSector   = RevByte(buf[0x0b],buf[0x0c]);  bdptor.SectorsPerCluster= buf[0x0d];  bdptor.ReservedSectors  = RevByte(buf[0x0e],buf[0x0f]);  bdptor.FATs             = buf[0x10];  bdptor.RootDirEntries   = RevByte(buf[0x11],buf[0x12]);  bdptor.LogicSectors     = RevByte(buf[0x13],buf[0x14]);  bdptor.MediaType        = buf[0x15];  bdptor.SectorsPerFAT    = RevByte(buf[0x16],buf[0x17]);  bdptor.SectorsPerTrack  = RevByte(buf[0x18],buf[0x19]);  bdptor.Heads            = RevByte(buf[0x1a],buf[0x1b]);  bdptor.HiddenSectors    = RevByte(buf[0x1c],buf[0x1d]);#ifdef DEBUG  printf("Oem_name \t\t%s\n"	 "BytesPerSecotr \t\t%d\n"	 "SectorsPerCluster \t%d\n"	 "ReservedSectors \t%d\n"	 "FATs \t\t\t%d\n"	 "RootDirEntries \t\t%d\n"	 "LogicSectors \t\t%d\n"	 "MediaType \t\t%x\n"	 "SectorsPerFAT \t\t%d\n"	 "SectorsPerTrack \t%d\n"	 "Heads \t\t\t%d\n"	 "HiddenSectors \t\t%d\n",	 bdptor.Oem_name,	 bdptor.BytesPerSector,	 bdptor.SectorsPerCluster,	 bdptor.ReservedSectors,	 bdptor.FATs,	 bdptor.RootDirEntries,	 bdptor.LogicSectors,	 bdptor.MediaType,	 bdptor.SectorsPerFAT,	 bdptor.SectorsPerTrack,	 bdptor.Heads,	 bdptor.HiddenSectors);#endif}void findDate(unsigned short *year,	      unsigned short *month,	      unsigned short *day,	      unsigned char info[2]){  int date;    date = RevByte(info[0],info[1]);  *year = ((date & MASK_YEAR) >> 9) + 1980;  *month = (date & MASK_MONTH) >> 5;  *day = (date & MASK_DAY);}void findTime(unsigned short *hour,	      unsigned short *min,	      unsigned short *sec,	      unsigned char info[2]){  int time;    time = RevByte(info[0],info[1]);    //  printf("time %x\n",time);  *hour = (time & MASK_HOUR) >> 11;  *min = (time &  MASK_MIN) >> 5;  *sec = (time & MASK_SEC) * 2;}/* bug for fix */void FileNameFormat_old(unsigned char *name){  unsigned char *q,*k,filename[12];  q = name;  k = name;    while (*q != ' ')    q++;  *q = '\0';  strcpy(filename,k);  /* name */  *q = ' ';  strcat(filename,".");  while (*q == ' ')    q++;  k = q;  strcat(filename,k);  /* extension */  strcpy(name,filename);}void FileNameFormat(unsigned char *name){  unsigned char *p;  /* stripp the traling space */  p = name + strlen(name) - 1;  while (*p == ' ')    p--;  p++;  *p = '\0';}/*  * Function : scan root dir entry */void ScanRootEntry(){  struct Entry entry;  int ret,offset;  if ((ret = lseek(fd,ROOTDIR_OFFSET,SEEK_SET)) < 0)    perror("lseek ROOTDIR_OFFSET failed");  offset = ROOTDIR_OFFSET;  while (offset < DATA_OFFSET) {    ret = GetEntry(&entry);    offset += abs(ret);    if (ret > 0) {      printf("%12s\t"	     "%d:%d:%d\t "	     "%d:%d:%d\t "	     "%d\t "	     "%d\t\t "	     "%s\n",	     entry.short_name,	     entry.year, entry.month, entry.day,	     entry.hour, entry.min, entry.sec,	     entry.size,	     entry.FirstCluster,	     (entry.subdir) ? "dir" : "file");    }  }}/* Argument : entry, Type : struct Entry * * Return   : offset for success, -count for fail or no entry * Function : get entry from cluster or root dir * Comment  : One Entry maybe 32,64,96 Bytes */int GetEntry(struct Entry *pentry){  int ret,i;  int count = 0;  unsigned char buf[DIR_ENTRY_SIZE],info[2];  /* read 32 Bytes */  if ((ret = read(fd,buf,DIR_ENTRY_SIZE)) < 0)    perror("read entry failed");  count += ret;  if (buf[0] == 0xe5 || buf[0] == 0x00) /* not used or deleted entry */    return -1*count;  else {    while (buf[11] == 0x0f) {	      /* long file name entry, skip it */      if ((ret = read(fd,buf,DIR_ENTRY_SIZE)) < 0)	perror("read root dir failed");      count += ret;    }    /* valid entry */    for (i = 0; i <= 10; i++)      pentry->short_name[i] = buf[i];    pentry->short_name[i] = '\0';    FileNameFormat(pentry->short_name);    info[0] = buf[22];    info[1] = buf[23];    findTime(&(pentry->hour),&(pentry->min),&(pentry->sec),info);    info[0] = buf[24];    info[1] = buf[25];    findDate(&(pentry->year),&(pentry->month),&(pentry->day),info);    pentry->FirstCluster = RevByte(buf[26],buf[27]);    pentry->size = RevWord(buf[28],buf[29],buf[30],buf[31]);    pentry->readonly = (buf[11] & ATTR_READONLY) ? 1 : 0;    pentry->hidden   = (buf[11] & ATTR_HIDDEN)   ? 1 : 0;    pentry->system   = (buf[11] & ATTR_SYSTEM)   ? 1 : 0;    pentry->vlabel   = (buf[11] & ATTR_VLABEL)   ? 1 : 0;    pentry->subdir   = (buf[11] & ATTR_SUBDIR)   ? 1 : 0;    pentry->archive  = (buf[11] & ATTR_ARCHIVE)  ? 1 : 0;    return count;  }}/*  * Function : list current dir contents * Return   : 1 for success, -1 for fail  */int fd_ls(){  int ret,offset,cluster_addr;  struct Entry entry;  /* Header */  printf("\tname\tdate\t\t time\t\tsector\tsize\t\tattr\n");  if (curdir == NULL) {       /* print root dir */    ScanRootEntry(fd);  } else {        /* subdir start address,here only read one sector,ignore fat */    cluster_addr = DATA_OFFSET + (curdir->FirstCluster - 2) * SECTOR_SIZE;    if ((ret = lseek(fd,cluster_addr,SEEK_SET)) < 0)      perror("lseek cluster_addr failed");        offset = cluster_addr;    while (offset < cluster_addr + SECTOR_SIZE) {      ret = GetEntry(&entry);      offset += abs(ret);      if (ret > 0) {	printf("%12s\t"	       "%d:%d:%d\t "	       "%d:%d:%d\t "	       "%d\t "	       "%d\t\t"	       "%s\n",	       entry.short_name,	       entry.year, entry.month, entry.day,	       entry.hour, entry.min, entry.sec,	       entry.size,	       entry.FirstCluster,	       (entry.subdir) ? "dir" : "file");      }    }  }  return 0;}/* Argument : entryname, Type : char * *          : pentry, Type : struct Entry* *          : mode, Type : int, mode=1 for dir; mode=0 for file * Return   : offset( >0 ) if success or -1 if failed * Function : scan current dir for the entry, file or dir */int ScanEntry(char *entryname,struct Entry *pentry,int mode){  int ret,offset,i;  int cluster_addr;  char uppername[80];  for (i = 0; i < strlen(entryname); i++)    uppername[i] = toupper(entryname[i]);  uppername[i] = '\0';  if (curdir == NULL) {    /* scan in root dir */    if ((ret = lseek(fd,ROOTDIR_OFFSET,SEEK_SET)) < 0)      perror("lseek ROOTDIR_OFFSET failed");        offset = ROOTDIR_OFFSET;    while (offset < DATA_OFFSET) {      ret = GetEntry(pentry);      offset += abs(ret);      if (pentry->subdir == mode && !strcmp(pentry->short_name,uppername))	return offset;    }    /* no entry for entryname */    return -1;  } else {    /* scan in non-root dir , bug cd .. not support */    cluster_addr = DATA_OFFSET + (curdir->FirstCluster - 2) * SECTOR_SIZE;    if ((ret = lseek(fd,cluster_addr,SEEK_SET)) < 0)      perror("lseek cluster_addr failed");    offset = cluster_addr;    while (offset < cluster_addr + SECTOR_SIZE) {      ret = GetEntry(pentry);      offset += abs(ret);      if (pentry->subdir == mode && !strcmp(pentry->short_name,uppername))	  	return offset;    }    /* no entry for entryname */    return -1;  }}/* Argument : dir, Type char * * Return   : 1 if success, or -1 if failed * Function : change dir to parent dir or subdir * e.g "cd .." or "cd subdir", full path not support  */int fd_cd(char *dir){  struct Entry *pentry;  int ret;  if (!strcmp(dir,"."))         /* cd . */    return 1;  if (!strcmp(dir,"..") && curdir == NULL)    return 1;  pentry = (struct Entry*)malloc(sizeof(struct Entry));  /* scan current dir for the name of parent dir */  ret = ScanEntry(dir,pentry,1);  if (ret < 0) {    printf("no such dir\n");    free(pentry);    return -1;  }  free(curdir);  curdir = pentry;#ifdef DEBUG/*   printf("%12s\t" *//* 	 "%d:%d:%d\t " *//* 	 "%d:%d:%d\t " *//* 	 "%d\t " *//* 	 "%d\t\t " *//* 	 "%s\n", *//* 	 pentry->short_name, *//* 	 pentry->year, pentry->month, pentry->day, *//* 	 pentry->hour, pentry->min, pentry->sec, *//* 	 pentry->size, *//* 	 pentry->FirstCluster, *//* 	 (pentry->subdir) ? "dir" : "file"); */  #endif  return 1;}/* Argument : prev, Type unsigned short, previous cluster number * Return   : next cluster  * Function : get next cluster in fat  */unsigned short GetFatCluster(unsigned short prev){  unsigned short next,fatentry;  int index;    index = prev * 1.5;  fatentry = RevByte(fatbuf[index],fatbuf[index+1]);  if (prev % 2 == 1)    next = fatentry >> 4;  else    next = fatentry & 0x0fff;  return next;}/* Argument : cluster, Type unsigned short, cluster number * Return   : void * Function : clear the cluster in fat */void ClearFatCluster(unsigned short cluster){  int index;  index = cluster * 1.5;    if (cluster % 2 == 1) {    fatbuf[index] &= 0x0f;    fatbuf[index+1] &= 0x00;  } else {    fatbuf[index] &= 0x00;    fatbuf[index+1] &= 0xf0;  }}/* Argument : filename, Type char * * Return   : 1 if success, or -1 if failed * Function : remove a file in current dir */int fd_rm(char *filename){  struct Entry *pentry;  int ret;  unsigned char c;  unsigned short seed,next;  pentry = (struct Entry*)malloc(sizeof(struct Entry));  /* scan current dir for the name of file */  ret = ScanEntry(filename,pentry,0);  if (ret < 0) {    printf("no such file\n");    free(pentry);    return -1;  }  /* clear fat entry */  seed = pentry->FirstCluster;  while ((next = GetFatCluster(seed)) != 0x0fff) {    seed = next;    ClearFatCluster(next);  }  ClearFatCluster(pentry->FirstCluster);  /* clear dir entry */  c = 0xe5;  if (lseek(fd,ret-0x40,SEEK_SET) < 0)    perror("lseek fd_rm failed");  if (write(fd,&c,1) < 0)    perror("write failed");  if (lseek(fd,ret-0x20,SEEK_SET) < 0)    perror("lseek fd_rm failed");  if (write(fd,&c,1) < 0)    perror("write failed");  free(pentry);  /* write to fat */  if (WriteFat() < 0)      exit(1);  return 1;}int WriteFat(){  if (lseek(fd,FAT_ONE_OFFSET,SEEK_SET) < 0) {    perror("lseek failed");    return -1;  }  if (write(fd,fatbuf,0x1200) < 0) {    perror("read failed");    return -1;  }  if (lseek(fd,FAT_TWO_OFFSET,SEEK_SET) < 0) {    perror("lseek failed");    return -1;  }  if (write(fd,fatbuf,0x1200) < 0) {    perror("read failed");    return -1;  }  return 1;}int ReadFat(){  if (lseek(fd,FAT_ONE_OFFSET,SEEK_SET) < 0) {    perror("lseek failed");    return -1;  }  if (read(fd,fatbuf,0x1200) < 0) {    perror("read failed");    return -1;  }  return 1;}  int main(){  if ((fd = open(DEVNAME,O_RDWR)) < 0)    perror("open failed");  if (ReadFat() < 0)     exit(1);  /* test zero */  //  ScanBootSector();  //  ScanRootEntry();  /* test one */  //  fd_cd("xxx");  /* test two */  //  fd_ls();  /* test three */  //fd_rm("filesys");  close(fd);  free(curdir);  return 0;}

⌨️ 快捷键说明

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