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

📄 isoread.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * isoread.c * * isoread reads a file system in ISO9660 or HIGH SIERRA format from * a given device. * * Apr 5 1995     Michel R. Prevenier  */#include <ctype.h>#include <errno.h>#include <limits.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <time.h>#include <sys/times.h>#include <unistd.h>/*              *  definitions used by the ISO9660 and HIGH SIERRA file system */#define ISO9660_ID	"CD001"#define HIGH_SIERRA_ID	"CDROM"#define BLOCK_SIZE	2048#define BLOCK_SHIFT	11/* Fields in a ISO9660 volume descriptor */struct iso9660_descriptor{  char type[1];		  char id[5];			  char version[1];		  char reserved1[1];		  char system_id[32];		  char volume_id[32];		  char reserved2[8];		  char volume_size[8];	  char reserved3[32];		  char volume_set_size[4];	  char volume_seq_nr[4];  char block_size[4];	  char path_table_size[8];	  char type_l_path_table[4];	  char opt_type_l_path_table[4];	  char type_m_path_table[4];	  char opt_type_m_path_table[4];	  char root_dir_entry[34];  char vol_set_id[128];	  char publ_id[128];  char prep_id[128];	  char appl_id[128];	  char copyright_file_id[37];	  char abstract_file_id[37];	  char bibl_file_id[37];  char creation_date[17];	  char mod_date[17];	  char exp_date[17];	  char eff_date[17];	  char file_struc_version[1];  char reserved4[1];		  char appl_data[512];	  char reserved5[653];			};/* Fields in a High Sierra volume descriptor */struct high_sierra_descriptor{  char reserved1[8];  char type[1];	  char id[5];		  char version[1];	  char reserved2[1];	  char system_id[32];  char volume_id[32];  char reserved3[8];	  char volume_size[8];	  char reserved4[32];  char vol_set_size[4];  char volume_seq_nr[4];	  char block_size[4];	  char path_table_size[8];  char type_l_path_table[4];  char reserved5[28];		  char root_dir_entry[34];};/* Fields in a directory entry */struct dir_entry {  char length[1];	  char ext_attr_length[1];  char first_block[8];  char size[8];	  char date[7];  char flags[1];	  char file_unit_size[1];  char interleave[1];  char volume_seq_nr[4];	  char name_length[1];  char name[1];};#define STDOUT		stdout#define STDERR		stderr#define NULL_DIR	(struct dir_entry *) 0#define MAX_NAME_LENGTH	255#define MAX_PATH_LENGTH	1024#define NR_OF_CHARS	13 #define NR_OF_BLANKS	2#define NR_OF_COLS	(80 / (NR_OF_CHARS + NR_OF_BLANKS))/* This macro always returns a lower case character */#define LOWER_CASE(CHR) (CHR >= 'A' && CHR <= 'Z' ? CHR | 0x20 : CHR) /* Macro's for determining . , .. and normal directory entries */#define IS_DOT(PTR) (PTR->name_length[0] == 1 && PTR->name[0] == 0 ? 1 : 0)#define IS_DOT_DOT(PTR) (PTR->name_length[0] == 1 && PTR->name[0] == 1 ? 1 : 0)#define IS_DIR(PTR) (PTR->flags[-High_Sierra] & 2 ? 1 : 0)_PROTOTYPE (int main, (int argc, char **argv));_PROTOTYPE (int iso_cmp, (char *name, struct dir_entry *dir_ptr, int dir_flag));_PROTOTYPE (void list_dir, (struct dir_entry *dir_ptr));_PROTOTYPE (void list_file, (struct dir_entry *dir_ptr));_PROTOTYPE (struct dir_entry *look_up, (char *name));_PROTOTYPE (void recurse_dir, (char *path, struct dir_entry *dir_ptr));_PROTOTYPE (void read_device, (long offset, int nr_of_bytes, char *buffer));_PROTOTYPE (int valid_fs, (void) );               _PROTOTYPE (void usage, (void) );               _PROTOTYPE (void print_date, (char *date));_PROTOTYPE (void print_dir_date, (char *date));_PROTOTYPE (void iso_info, (struct iso9660_descriptor *vol_desc));_PROTOTYPE (void hs_info, (struct high_sierra_descriptor *vol_desc));_PROTOTYPE (int iso_711, (char *c));_PROTOTYPE (int iso_712, (char *c));_PROTOTYPE (int iso_721, (char *c));_PROTOTYPE (int iso_722, (char *c));_PROTOTYPE (int iso_723, (char *c));_PROTOTYPE (long iso_731, (char *c));_PROTOTYPE (long iso_732, (char *c));_PROTOTYPE (long iso_733, (char *c));char Buffer[BLOCK_SIZE];	            /* buffer to hold read data */int Device;				    /* global file descriptor */struct iso9660_descriptor *Iso_Vol_Desc;    /* iso9660 volume descriptor */struct high_sierra_descriptor *Hs_Vol_Desc; /* high sierra volume descriptor */int High_Sierra = 0;                        /* 1 = high sierra format */int Iso9660 = 0;                            /* 1 = iso9660 format *//* This comes in handy when printing the date */char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";/* Flags displaying what to do  */int Read_File = 0;      /* 1 = Read file */int Read_Dir = 0;	/* 1 = Read directory entry */int Read_Info = 0;      /* 1 = Read volume descriptor */int Recurse = 0;        /* 1 = Recursively descend directories */int Verbose = 0;        /* 1 = Print all info on directories */int iso_cmp(name, dir_ptr, dir_flag)char *name;struct dir_entry *dir_ptr;int dir_flag;{  int i;  /* First match the filename */  for (i = 0; (i < strlen(name) && i < iso_711(dir_ptr->name_length)); i++)  {    if (dir_ptr->name[i] == ';') break;    if (name[i] != LOWER_CASE(dir_ptr->name[i])) return 1;  }  /* The filename is ok, now look at the file type */  if (dir_flag && !IS_DIR(dir_ptr)) return 1;  /* File type not correct */  return 0; }void usage(){  if (Read_Dir)   fprintf (STDERR, "Usage: isodir [-lr] inputfile [dir]\n");  else if (Read_Info)   fprintf (STDERR, "Usage: isoinfo inputfile\n");  else   fprintf (STDERR, "Usage: isoread inputfile file\n");  exit(1);}int main(argc, argv)int argc;char **argv;{  struct dir_entry *entry;  char path[MAX_PATH_LENGTH];  char *input_file;  char *basename;  char *file_name;  int i,j;  /* Read arguments */  basename = argv[0];  while (*argv[0] != '\0')     if (*argv[0]++ == '/') basename = argv[0];  if (strcmp(basename,"isodir") == 0) Read_Dir = 1;  else if (strcmp(basename,"isoinfo") == 0) Read_Info = 1;  else Read_File = 1;  if ((argc > 5 && Read_Dir) || (argc > 2 && Read_Info) ||     (argc > 3 && Read_File)) usage();  i = 1;  while (i < argc && argv[i][0] == '-')  {    char *opt = argv[i++] + 1;    if (opt[0] == '-' && opt[1] == '\0') break;    while (*opt != '\0')    {      if (!Read_Dir) usage();      switch (*opt++)      {	case 'r':	Recurse = 1; break;  	case 'l':	Verbose = 1; break;	default:	usage();      }    }  }  if (i >= argc) usage();  input_file = argv[i++];  if (Read_File)  {    if (i >= argc) usage();    file_name = argv[i++];  }  if (Read_Dir)  {    file_name = "/";    if (i < argc)    {      file_name = argv[i++];    }  }  if (i < argc) usage();    if (Read_File || Read_Dir)  {    for (i=0; file_name[i] != '\0'; i++)       path[i] = LOWER_CASE(file_name[i]);    path[i] = '\0';  }   /* Open file system (file or device) */  if ((Device = open(input_file, O_RDONLY)) < 0)   {    fprintf (STDERR, "cannot open %s\n", input_file);    exit(-1);  }    if (!valid_fs())  {    fprintf (STDERR, "File system not in ISO9660 or HIGH SIERRA format \n");    exit(-1);  }    if (Read_Info)  {    if (Iso9660)       iso_info(Iso_Vol_Desc);    else       hs_info(Hs_Vol_Desc);    exit(1);  }  /* Lookup file */  if ((entry = look_up(path)) != NULL_DIR)  {    if (Read_Dir)      if (Recurse) recurse_dir(path,entry);      else list_dir(entry);    else      list_file(entry);  }  else  {    if (Read_Dir)      fprintf (STDERR, "Directory");    else      fprintf (STDERR, "File");    fprintf (STDERR, " %s not found\n", path);    exit(-1);  }}struct dir_entry *look_up(path)char *path;{  /* Lookup a file name */  struct dir_entry *dir_ptr;  long block;  int nr_of_blocks;  int offset;  char name[MAX_NAME_LENGTH + 1];  int name_index = 0;  int last_in_path = 0;  int found;  int i,j;  /* Get the right dir entry structure */  if (Iso9660)    dir_ptr = (struct dir_entry *) Iso_Vol_Desc->root_dir_entry;    else    dir_ptr = (struct dir_entry *) Hs_Vol_Desc->root_dir_entry;    /* If we look for the root we already have the right entry */  if (path[0] == '/')    if (strlen(path) == 1) return dir_ptr;    else name_index = 1; /* first name in path */  /* Keep searching for the path elements until all are found */  while (!last_in_path)  {    /* Get next name in path */     for (i = name_index; i < strlen(path); i++)    {      if (path[i] == '/') break;      name[i - name_index] = path[i];    }    last_in_path =            (i == strlen(path) || (i == strlen(path) - 1 && path[i] == '/'));    name[i-name_index] = '\0';    name_index = i + 1;       /* Get block of next directory */    block = iso_733(dir_ptr->first_block) + iso_711(dir_ptr->ext_attr_length);    nr_of_blocks = (int) (iso_733(dir_ptr->size) >> BLOCK_SHIFT);    /* Search for file in dir entry */    found = 0;    for (j=0; j < nr_of_blocks && !found; j++)     {      /* Read a directory block */      read_device(block*BLOCK_SIZE, BLOCK_SIZE, Buffer);      dir_ptr = (struct dir_entry *) Buffer;      offset = 0;      /* Compare with all entries in this block */      while (iso_711(dir_ptr->length) > 0 && offset < BLOCK_SIZE)      {        if (iso_cmp(name, dir_ptr,            (Read_Dir || (!Read_Dir && !last_in_path))) == 0)         {          found = 1;          break;        }        /* Next entry */        offset += iso_711(dir_ptr->length);        dir_ptr = (struct dir_entry *) (Buffer + offset);      }    }    if (!found) return NULL_DIR;   /* path element not found */   }  return dir_ptr;}  void recurse_dir(path, dir_ptr)char *path;struct dir_entry *dir_ptr;{  /* Recursively descend all directories starting with dir_ptr */  char tmp_buffer[BLOCK_SIZE];

⌨️ 快捷键说明

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