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

📄 write.c

📁 一款功能很强的光盘镜象制作工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	 sortlist[dcount+xcount-1]->next = NULL;	 *sort_dir = sortlist[0];       }     free(sortlist);     return sort_goof;}static int root_gen(){     init_fstatbuf();          root_record.length[0] = 1 + sizeof(struct iso_directory_record)	  - sizeof(root_record.name);     root_record.ext_attr_length[0] = 0;     set_733((char *) root_record.extent, root->extent);     set_733((char *) root_record.size, ROUND_UP(root->size));     iso9660_date(root_record.date, root_statbuf.st_mtime);     root_record.flags[0] = 2;     root_record.file_unit_size[0] = 0;     root_record.interleave[0] = 0;     set_723(root_record.volume_sequence_number, volume_sequence_number);     root_record.name_len[0] = 1;     return 0;}static void FDECL1(assign_file_addresses, struct directory *, dpnt){     struct directory * finddir;     struct directory_entry * s_entry;     struct file_hash *s_hash;     struct deferred_write * dwpnt;     char whole_path[1024];     char tempbuf[255];     char md5result[33];     while (dpnt)     {	  s_entry = dpnt->contents;	  for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next)	  {	       /*		* If we already have an  extent for this entry,		* then don't assign a new one.  It must have come		* from a previous session on the disc.  Note that		* we don't end up scheduling the thing for writing		* either.		*/	       if( isonum_733((unsigned char *) s_entry->isorec.extent) != 0 )	       {		    continue;	       }	       	       /* 		* This saves some space if there are symlinks present 		*/	       s_hash = find_hash(s_entry->dev, s_entry->inode);	       if(s_hash)	       {		    if(verbose > 2)		    {			 fprintf(stderr, "Cache hit for %s%s%s\n",s_entry->filedir->de_name, 				 SPATH_SEPARATOR, s_entry->name);		    }		    set_733((char *) s_entry->isorec.extent, s_hash->starting_block);		    set_733((char *) s_entry->isorec.size, s_hash->size);		    continue;	       }	       /*		* If this is for a directory that is not a . or a .. entry, 		* then look up the information for the entry.  We have already		* assigned extents for directories, so we just need to		* fill in the blanks here.		*/	       if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") && 		   s_entry->isorec.flags[0] == 2)	       {		    finddir = dpnt->subdir;		    while(1==1)		    {			 if(finddir->self == s_entry) break;			 finddir = finddir->next;			 if(!finddir) 			 {			      fprintf(stderr,"Fatal goof\n"); exit(1);			 }		    }		    set_733((char *) s_entry->isorec.extent, finddir->extent);		    s_entry->starting_block = finddir->extent;		    s_entry->size = ROUND_UP(finddir->size);		    total_dir_size += s_entry->size;		    add_hash(s_entry);		    set_733((char *) s_entry->isorec.size, ROUND_UP(finddir->size));		    continue;	       }	       /*		* If this is . or .., then look up the relevant info from the		* tables.		*/	       if(strcmp(s_entry->name,".") == 0) 	       {		    set_733((char *) s_entry->isorec.extent, dpnt->extent);		    		    /* 		     * Set these so that the hash table has the		     * correct information		     */		    s_entry->starting_block = dpnt->extent;		    s_entry->size = ROUND_UP(dpnt->size);		    		    add_hash(s_entry);		    s_entry->starting_block = dpnt->extent;		    set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->size));		    continue;	       }	       if(strcmp(s_entry->name,"..") == 0) 	       {		    if(dpnt == root)		    { 			 total_dir_size += root->size;		    }		    set_733((char *) s_entry->isorec.extent, dpnt->parent->extent);		    		    /* 		     * Set these so that the hash table has the		     * correct information		     */		    s_entry->starting_block = dpnt->parent->extent;		    s_entry->size = ROUND_UP(dpnt->parent->size);		    		    add_hash(s_entry);		    s_entry->starting_block = dpnt->parent->extent;		    set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->parent->size));		    continue;	       }            if (do_fileopt)            {               /* calc the MD5 hash value */               memset(md5result,0,33);               if (s_entry->size && MD5File(md5result,s_entry->whole_name))               {                  // md5 calc ok,  make hash key                      struct directory_entry *hash_result;                  sprintf(tempbuf,"%d%s",s_entry->size,md5result);                  hash_result = (struct directory_entry *)htInTable(md5_hash,tempbuf);                  if (!hash_result)                  {                     htAddToTable(md5_hash,tempbuf,(void *) s_entry);                  }                   else                  {                     // found a matching md5 hash! using the duplicate file                     set_733((char *) s_entry->isorec.extent, hash_result->starting_block);                     set_733((char *) s_entry->isorec.size, hash_result->size);                       continue;                                   }                }             }               	       /* 		* Some ordinary non-directory file.  Just schedule the		* file to be written.  This is all quite		* straightforward, just make a list and assign extents		* as we go.  Once we get through writing all of the		* directories, we should be ready write out these		* files		*/	       if(s_entry->size) 	       {		    dwpnt = (struct deferred_write *) 			 e_malloc(sizeof(struct deferred_write));		    if(dw_tail)		    {			 dw_tail->next = dwpnt;			 dw_tail = dwpnt;		    } 		    else 		    {			 dw_head = dwpnt;			 dw_tail = dwpnt;		    }		    if(s_entry->inode  ==  TABLE_INODE) 		    {			 dwpnt->table = s_entry->table;			 dwpnt->name = NULL;			 sprintf(whole_path,"%s%sTRANS.TBL",				 s_entry->filedir->whole_name, SPATH_SEPARATOR);		    } 		    else 		    {			 dwpnt->table = NULL;			 strcpy(whole_path, s_entry->whole_name);			 dwpnt->name = strdup(whole_path);		    }		    dwpnt->next = NULL;		    dwpnt->size = s_entry->size;		    dwpnt->extent = last_extent;		    set_733((char *) s_entry->isorec.extent, last_extent);		    s_entry->starting_block = last_extent;		    add_hash(s_entry);		    last_extent += ROUND_UP(s_entry->size) >> 11;		    if(verbose > 2)		    {			 fprintf(stderr,"%d %d %s\n", s_entry->starting_block,				 last_extent-1, whole_path);		    }#ifdef DBG_ISO		    if((ROUND_UP(s_entry->size) >> 11) > 500)		    {			 fprintf(stderr,"Warning: large file %s\n", whole_path);			 fprintf(stderr,"Starting block is %d\n", s_entry->starting_block);			 fprintf(stderr,"Reported file size is %d extents\n", s_entry->size);			 		    }#endif#ifdef	NOT_NEEDED	/* Never use this code if you like to create a DVD */		    if(last_extent > (800000000 >> 11)) 		    { 			 /*			  * More than 800Mb? Punt 			  */			 fprintf(stderr,"Extent overflow processing file %s\n", whole_path);			 fprintf(stderr,"Starting block is %d\n", s_entry->starting_block);			 fprintf(stderr,"Reported file size is %d extents\n", s_entry->size);			 exit(1);		    }#endif		    continue;	       }	       /*		* This is for zero-length files.  If we leave the extent 0,		* then we get screwed, because many readers simply drop files		* that have an extent of zero.  Thus we leave the size 0,		* and just assign the extent number.		*/	       set_733((char *) s_entry->isorec.extent, last_extent);	  }	  if(dpnt->subdir) 	  {	       assign_file_addresses(dpnt->subdir);	  }	  dpnt = dpnt->next;     }} /* assign_file_addresses(... */static void FDECL1(free_one_directory, struct directory *, dpnt){     struct directory_entry		* s_entry;     struct directory_entry		* s_entry_d;          s_entry = dpnt->contents;     while(s_entry)      {	 s_entry_d = s_entry;	 s_entry = s_entry->next;	 	 if( s_entry_d->name != NULL )	 {	     free (s_entry_d->name);	 }	 if( s_entry_d->whole_name != NULL )	 {	     free (s_entry_d->whole_name);	 }	 free (s_entry_d);     }     dpnt->contents = NULL;} /* free_one_directory(... */static void FDECL1(free_directories, struct directory *, dpnt){  while (dpnt)    {      free_one_directory(dpnt);      if(dpnt->subdir) free_directories(dpnt->subdir);      dpnt = dpnt->next;    }}void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile){     unsigned int			  ce_address = 0;     char				* ce_buffer;     unsigned int			  ce_index = 0;     unsigned int			  ce_size;     unsigned int			  dir_index;     char				* directory_buffer;     int				  new_reclen;     struct directory_entry		* s_entry;     struct directory_entry		* s_entry_d;     unsigned int			  total_size;          total_size = (dpnt->size + (SECTOR_SIZE - 1)) &  ~(SECTOR_SIZE - 1);     directory_buffer = (char *) e_malloc(total_size);     memset(directory_buffer, 0, total_size);     dir_index = 0;          ce_size = (dpnt->ce_bytes + (SECTOR_SIZE - 1)) &  ~(SECTOR_SIZE - 1);     ce_buffer = NULL;          if(ce_size)      {	  ce_buffer = (char *) e_malloc(ce_size);	  memset(ce_buffer, 0, ce_size);	  	  ce_index = 0;	  	  /*	   * Absolute byte address of CE entries for this directory 	   */	  ce_address = last_extent_written + (total_size >> 11);	  ce_address = ce_address << 11;     }          s_entry = dpnt->contents;     while(s_entry)      {	  /* skip if it's hidden */	  if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) {	    s_entry = s_entry->next;	    continue;	  }	  /* 	   * We do not allow directory entries to cross sector boundaries.  	   * Simply pad, and then start the next entry at the next sector 	   */	  new_reclen = s_entry->isorec.length[0];	  if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE )	  {	       dir_index = (dir_index + (SECTOR_SIZE - 1)) & 		    ~(SECTOR_SIZE - 1);	  }	  memcpy(directory_buffer + dir_index, &s_entry->isorec, 		 sizeof(struct iso_directory_record) -		 sizeof(s_entry->isorec.name) + s_entry->isorec.name_len[0]);	  dir_index += sizeof(struct iso_directory_record) - 	       sizeof (s_entry->isorec.name)+ s_entry->isorec.name_len[0];	  /*	   * Add the Rock Ridge attributes, if present 	   */	  if(s_entry->rr_attr_size)	  {	       if(dir_index & 1)	       {		    directory_buffer[dir_index++] = 0;	       }	       /* 		* If the RR attributes were too long, then write the		* CE records, as required.		*/	       if(s_entry->rr_attr_size != s_entry->total_rr_attr_size) 	       {		    unsigned char * pnt;		    int len, nbytes;		    		    /* 		     * Go through the entire record and fix up the CE entries		     * so that the extent and offset are correct 		     */		    		    pnt = s_entry->rr_attributes;		    len = s_entry->total_rr_attr_size;		    while(len > 3)		    {#ifdef DEBUG			 if (!ce_size)			 {			      fprintf(stderr,"Warning: ce_index(%d) && ce_address(%d) not initialized\n",				      ce_index, ce_address);			 }#endif			 			 if(pnt[0] == 'C' && pnt[1] == 'E') 			 {			      nbytes = get_733( (char *) pnt+20);			      			      if((ce_index & (SECTOR_SIZE - 1)) + nbytes >=				 SECTOR_SIZE) 			      {				   ce_index = ROUND_UP(ce_index);			      }			      			      set_733( (char *) pnt+4, 				       (ce_address + ce_index) >> 11);			      set_733( (char *) pnt+12, 				       (ce_address + ce_index) & (SECTOR_SIZE - 1));			      			      			      /* 			       * Now store the block in the ce buffer 			       */			      memcpy(ce_buffer + ce_index, 				     pnt + pnt[2], nbytes);			      ce_index += nbytes;			      if(ce_index & 1) 			      {				   ce_index++;			      }			 }			 len -= pnt[2];			 pnt += pnt[2];		    }		    	       }	       rockridge_size += s_entry->total_rr_attr_size;	       memcpy(directory_buffer + dir_index, s_entry->rr_attributes, 		      s_entry->rr_attr_size);	       dir_index += s_entry->rr_attr_size;	  }	  if(dir_index & 1)	  {	       directory_buffer[dir_index++] = 0;	  }	  	  s_entry_d = s_entry;	  s_entry = s_entry->next;	  	  /*	   * Joliet doesn't use the Rock Ridge attributes, so we free it here.	   */	  if (s_entry_d->rr_attributes) 	    {	      free(s_entry_d->rr_attributes);	      s_entry_d->rr_attributes = NULL;	    }     }     if(dpnt->size != dir_index)     {	  fprintf(stderr,"Unexpected directory length %d %d %s\n",dpnt->size, 	    dir_index, dpnt->de_name);     }     xfwrite(directory_buffer, 1, total_size, outfile);     last_extent_written += total_size >> 11;     free(directory_buffer);     if(ce_size)     {	  if(ce_index != dpnt->ce_bytes)	  {	       fprintf(stderr,"Continuation entry record length mismatch (%d %d).\n",		       ce_index, dpnt->ce_bytes);	  }	  xfwrite(ce_buffer, 1, ce_size, outfile);	  last_extent_written += ce_size >> 11;	  free(ce_buffer);     }     } /* generate_one_directory(... */static void FDECL1(build_pathlist, struct directory *, node){     struct directory * dpnt;          dpnt = node;          while (dpnt)     {	/* skip if it's hidden */	if( (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0 )	  pathlist[dpnt->path_index] = dpnt;	if(dpnt->subdir) build_pathlist(dpnt->subdir);	dpnt = dpnt->next;     }} /* build_pathlist(... */static int FDECL2(compare_paths, void const *, r, void const *, l) {  struct directory const *ll = *(struct directory * const *)l;  struct directory const *rr = *(struct directory * const *)r;  if (rr->parent->path_index < ll->parent->path_index)  {       return -1;  }  if (rr->parent->path_index > ll->parent->path_index)   {       return 1;  }

⌨️ 快捷键说明

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