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

📄 multi.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    {      return NULL;    }  pri = (struct iso_primary_descriptor *)vdp;  /*   * Check the blocksize of the image to make sure it is compatible.   */  if(    (isonum_723 ((unsigned char *) pri->logical_block_size) != SECTOR_SIZE)      || (isonum_723 ((unsigned char *) pri->volume_set_size) != 1) )    {      return NULL;    }  /*   * Get the location and size of the root directory.   */  rootp = (struct iso_directory_record *)     malloc(sizeof(struct iso_directory_record));  memcpy(rootp, pri->root_directory_record, sizeof(*rootp));  return rootp;}void FDECL3(merge_remaining_entries, struct directory *, this_dir,	    struct directory_entry **, pnt,	    int, n_orig){  int i;  struct directory_entry * s_entry;  unsigned int ttbl_extent = 0;  unsigned int ttbl_index  = 0;  char whole_path[1024];  /*   * Whatever is leftover in the list needs to get merged back   * into the directory.   */  for( i=0; i < n_orig; i++ )    {      if( pnt[i] == NULL )	{	  continue;	}            if( pnt[i]->name != NULL && pnt[i]->whole_name == NULL)       {         /*          * Set the name for this directory.          */         strcpy(whole_path, this_dir->de_name);         strcat(whole_path, SPATH_SEPARATOR);         strcat(whole_path, pnt[i]->name);         pnt[i]->whole_name = strdup(whole_path);       }      if( pnt[i]->name != NULL/*	  && strcmp(pnt[i]->name, "<translation table>") == 0 )*/	  && strcmp(pnt[i]->name, trans_tbl) == 0 )	{	  ttbl_extent = isonum_733((unsigned char *) pnt[i]->isorec.extent);	  ttbl_index = i;	  continue;	}      /*       * Skip directories for now - these need to be treated       * differently.       */      if( (pnt[i]->isorec.flags[0] & 2) != 0 )	{	  /*	   * FIXME - we need to insert this directory into the	   * tree, so that the path tables we generate will	   * be correct.	   */	  if(    (strcmp(pnt[i]->name, ".") == 0)	      || (strcmp(pnt[i]->name, "..") == 0) )	    {	      free_directory_entry(pnt[i]);	      pnt[i] = NULL;	      continue;	    }	  else	    {	      merge_old_directory_into_tree(pnt[i], this_dir);	    }	}      pnt[i]->next = this_dir->contents;      pnt[i]->filedir = this_dir;      this_dir->contents = pnt[i];      pnt[i] = NULL;    }    /*   * If we don't have an entry for the translation table, then   * don't bother trying to copy the starting extent over.   * Note that it is possible that if we are copying the entire   * directory, the entry for the translation table will have already   * been inserted into the linked list and removed from the old   * entries list, in which case we want to leave the extent number   * as it was before.   */  if( ttbl_extent == 0 )    {      return;    }  /*   * Finally, check the directory we are creating to see whether   * there are any new entries in it.  If there are not, we can   * reuse the same translation table.   */  for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)    {      /*       * Don't care about '.' or '..'.  They are never in the table       * anyways.       */      if( s_entry->name != NULL && strcmp(s_entry->name, ".") == 0 )	{	  continue;	}      if( s_entry->name != NULL && strcmp(s_entry->name, "..") == 0 )	{	  continue;	}/*      if( strcmp(s_entry->name, "<translation table>") == 0)*/      if( strcmp(s_entry->name, trans_tbl) == 0)	{	  continue;	}      if( (s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0 )	{	  return;	}    }  /*   * Locate the translation table, and re-use the same extent.   * It isn't clear that there should ever be one in there already   * so for now we try and muddle through the best we can.   */  for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)    {/*      if( strcmp(s_entry->name, "<translation table>") == 0)*/      if( strcmp(s_entry->name, trans_tbl) == 0)	{	  fprintf(stderr,"Should never get here\n");	  set_733(s_entry->isorec.extent, ttbl_extent);	  return;	}    }  pnt[ttbl_index]->next = this_dir->contents;  pnt[ttbl_index]->filedir = this_dir;  this_dir->contents = pnt[ttbl_index];  pnt[ttbl_index] = NULL;}/* * Here we have a case of a directory that has completely disappeared from * the face of the earth on the tree we are mastering from.  Go through and * merge it into the tree, as well as everything beneath it. * * Note that if a directory has been moved for some reason, this will * incorrectly pick it up and attempt to merge it back into the old * location.  FIXME(eric). */static intFDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt,        struct directory *, parent){  struct directory_entry	**contents = NULL;  int				  i;  int				  n_orig;  struct directory		* this_dir, *next_brother;  char				  whole_path[1024];  this_dir = (struct directory *) e_malloc(sizeof(struct directory));  memset(this_dir, 0, sizeof(struct directory));  this_dir->next = NULL;  this_dir->subdir = NULL;  this_dir->self = dpnt;  this_dir->contents = NULL;  this_dir->size = 0;  this_dir->extent = 0;  this_dir->depth = parent->depth + 1;  this_dir->parent = parent;  if(!parent->subdir)    parent->subdir = this_dir;  else {    next_brother = parent->subdir;    while(next_brother->next) next_brother = next_brother->next;    next_brother->next = this_dir;  }  /*   * Set the name for this directory.   */  strcpy(whole_path, parent->de_name);  strcat(whole_path, SPATH_SEPARATOR);  strcat(whole_path, dpnt->name);  this_dir->de_name = strdup(whole_path);  this_dir->whole_name = strdup(whole_path);  /*   * Now fill this directory using information from the previous   * session.   */  contents = read_merging_directory(&dpnt->isorec, &n_orig);  /*   * Start by simply copying the '.', '..' and non-directory   * entries to this directory.  Technically we could let   * merge_remaining_entries handle this, but it gets rather confused   * by the '.' and '..' entries.   */  for(i=0; i < n_orig; i ++ )    {      /*       * We can always reuse the TRANS.TBL in this particular case.       */      contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;	      if(    ((contents[i]->isorec.flags[0] & 2) != 0)	  && (i >= 2) )	{	  continue;	}      /*       * If we have a directory, don't reuse the extent number.       */      if( (contents[i]->isorec.flags[0] & 2) != 0 )	{	  memset(contents[i]->isorec.extent, 0, 8);	  if( strcmp(contents[i]->name, ".") == 0 )	      this_dir->dir_flags |= DIR_HAS_DOT;	  if( strcmp(contents[i]->name, "..") == 0 )	      this_dir->dir_flags |= DIR_HAS_DOTDOT;	}      /*       * Set the whole name for this file.       */      strcpy(whole_path, this_dir->whole_name);      strcat(whole_path, SPATH_SEPARATOR);      strcat(whole_path, contents[i]->name);      contents[i]->whole_name = strdup(whole_path);      contents[i]->next = this_dir->contents;      contents[i]->filedir = this_dir;      this_dir->contents = contents[i];      contents[i] = NULL;    }  /*   * Zero the extent number for ourselves.   */  memset(dpnt->isorec.extent, 0, 8);  /*   * Anything that is left are other subdirectories that need to be merged.   */  merge_remaining_entries(this_dir, contents, n_orig);  free_mdinfo(contents, n_orig);#if 0  /*   * This is no longer required.  The post-scan sort will handle   * all of this for us.   */  sort_n_finish(this_dir);#endif  return 0;}char * cdrecord_data = NULL;intFDECL1(get_session_start, int *, file_addr) {  char * pnt;#ifdef CDRECORD_DETERMINES_FIRST_WRITABLE_ADDRESS  /*   * FIXME(eric).  We need to coordinate with cdrecord to obtain   * the parameters.  For now, we assume we are writing the 2nd session,   * so we start from the session that starts at 0.   */  *file_addr = (16 << 11);  /*   * We need to coordinate with cdrecord to get the next writable address   * from the device.  Here is where we use it.   */  session_start = last_extent = last_extent_written = cdrecord_result();#else  if( cdrecord_data == NULL )    {#ifdef	USE_LIBSCHILY      comerrno(EX_BAD, "Special parameters for cdrecord not specified with -C\n");#else      fprintf(stderr,"Special parameters for cdrecord not specified with -C\n");      exit(1);#endif    }  /*   * Next try and find the ',' in there which delimits the two numbers.   */  pnt = strchr(cdrecord_data, ',');  if( pnt == NULL )    {#ifdef	USE_LIBSCHILY      comerrno(EX_BAD, "Malformed cdrecord parameters\n");#else      fprintf(stderr, "Malformed cdrecord parameters\n");      exit(1);#endif    }  *pnt = '\0';  if (file_addr != NULL) {    *file_addr = atol(cdrecord_data) * SECTOR_SIZE;  }  pnt++;  session_start = last_extent = last_extent_written = atol(pnt);  pnt--;  *pnt = ',';#endif  return 0;}/* * This function scans the directory tree, looking for files, and it makes * note of everything that is found.  We also begin to construct the ISO9660 * directory entries, so that we can determine how large each directory is. */intFDECL2(merge_previous_session,struct directory *, this_dir,       struct iso_directory_record *, mrootp){  struct directory_entry	**orig_contents = NULL;  struct directory_entry        * odpnt = NULL;  int				  n_orig;  struct directory_entry	* s_entry;  int				  status, lstatus;  struct stat			  statbuf, lstatbuf;  int 				  retcode;  /*   * Parse the same directory in the image that we are merging   * for multisession stuff.   */  orig_contents = read_merging_directory(mrootp, &n_orig);  if( orig_contents == NULL )    {      return 0;    }/* Now we scan the directory itself, and look at what is inside of it. */  for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next)    {      status  =  stat_filter(s_entry->whole_name, &statbuf);      lstatus = lstat_filter(s_entry->whole_name, &lstatbuf);      /*       * We always should create an entirely new directory tree whenever       * we generate a new session, unless there were *no* changes whatsoever       * to any of the directories, in which case it would be kind of pointless       * to generate a new session.       *       * I believe it is possible to rigorously prove that any change anywhere       * in the filesystem will force the entire tree to be regenerated       * because the modified directory will get a new extent number.  Since       * each subdirectory of the changed directory has a '..' entry, all of       * them will need to be rewritten too, and since the parent directory       * of the modified directory will have an extent pointer to the directory       * it too will need to be rewritten.  Thus we will never be able to reuse       * any directory information when writing new sessions.       *       * We still check the previous session so we can mark off the equivalent       * entry in the list we got from the original disc, however.       */      /*       * The check_prev_session function looks for an identical entry in       * the previous session.  If we see it, then we copy the extent       * number to s_entry, and cross it off the list. It returns 2 if it's a directory       */      retcode = check_prev_session(orig_contents, n_orig, s_entry,			 &statbuf, &lstatbuf, &odpnt);      if (retcode == -1)	return (-1);      if(retcode==2 && odpnt != NULL)	{	  int dflag;	  if (strcmp(s_entry->name,".") != 0 && strcmp(s_entry->name,"..") != 0)	    {	      struct directory * child;		/*		 * XXX It seems that the tree that has been read from the		 * XXX previous session does not carry whole_name entries.		 * XXX We provide a hack in multi.c:find_or_create_directory()		 * XXX that should be removed when a reasonable method could		 * XXX be found.		 */	      child = find_or_create_directory(this_dir, 					       s_entry->whole_name, 					       s_entry, 1);	      dflag = merge_previous_session(child, 					     &odpnt->isorec);	      if (dflag == -1)		return (-1);	      free(odpnt);	      odpnt = NULL;	    }	}    }    /*   * Whatever is left over, are things which are no longer in the tree   * on disk.  We need to also merge these into the tree.   */   merge_remaining_entries(this_dir, orig_contents, n_orig);   free_mdinfo(orig_contents, n_orig);    return 1;}

⌨️ 快捷键说明

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