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

📄 tree.c

📁 刻录光盘的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    if(S_ISDIR(statbuf.st_mode))    {      int dflag;      if (strcmp(short_name,".") != 0 && strcmp(short_name,"..") != 0) 	{	  struct directory * child;	  	  child = find_or_create_directory(this_dir, whole_path, 					   s_entry, 1);	  if (no_scandir) dflag = 1; else	  dflag = scan_directory_tree(child, whole_path, s_entry);	  	  if(!dflag)	    {	      lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG;	      if( child->contents == NULL )		{		  delete_directory(this_dir, child);		}	    }	}      /* If unable to scan directory, mark this as a non-directory */    }    if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".")  == 0)    {      deep_flag |= NEED_CE | NEED_SP;  /* For extension record */    }    /* Now figure out how much room this file will take in the     directory */    if(use_RockRidge)     {      generate_rock_ridge_attributes(whole_path,				     short_name, s_entry,				     &statbuf, &lstatbuf, deep_flag);          }    return 1;}void FDECL2(generate_iso9660_directories, struct directory *, node, FILE*, outfile){  struct directory * dpnt;  dpnt = node;  while (dpnt){    if( dpnt->extent > session_start )      {	generate_one_directory(dpnt, outfile);      }    if(dpnt->subdir) generate_iso9660_directories(dpnt->subdir, outfile);    dpnt = dpnt->next;  }}/* * Function:	find_or_create_directory * * Purpose:	Locate a directory entry in the tree, create if needed. * * Arguments:	parent & de are never NULL at the same time. */struct directory * FDECL4(find_or_create_directory, struct directory *, parent,			  const char *, path,			  struct directory_entry *, de, int, flag){  struct directory		* dpnt;  struct directory_entry	* orig_de;  struct directory		* next_brother;  const char                    * cpnt;  const char			* pnt;  orig_de = de;	/*	 * 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.	 */	if (path == NULL) {		error("Warning: missing whole name for: '%s'\n", de->name);		path = de->name;	}  pnt = strrchr(path, PATH_SEPARATOR);  if( pnt == NULL )    {      pnt = path;    }  else    {      pnt++;    }  if( parent != NULL )    {      dpnt = parent->subdir;      while (dpnt)	{	  /*	   * Weird hack time - if there are two directories by the	   * same name in the reloc_dir, they are not treated as the	   * same thing unless the entire path matches completely.	   */	  if( flag && strcmp(dpnt->de_name, pnt) == 0 )	    {	      return dpnt;	    }	  dpnt = dpnt->next;	}    }  /*   * We don't know if we have a valid directory entry for this one   * yet.  If not, we need to create one.   */  if( de == NULL )    {      de = (struct directory_entry *) 	e_malloc(sizeof (struct directory_entry));      memset(de, 0, sizeof(struct directory_entry));      de->next            = parent->contents;      parent->contents    = de;      de->name            = strdup(pnt);      de->whole_name      = strdup(path);      de->filedir         = parent;      de->isorec.flags[0] = 2;      de->priority        = 32768;      de->inode           = UNCACHED_INODE;      de->dev             = (dev_t) UNCACHED_DEVICE;      set_723(de->isorec.volume_sequence_number, volume_sequence_number);      iso9660_file_length (pnt, de, 1);      init_fstatbuf();      /*       * It doesn't exist for real, so we cannot add any Rock Ridge.       */      if(use_RockRidge)	{	  fstatbuf.st_mode = 0555 | S_IFDIR;	  fstatbuf.st_nlink = 2;	  generate_rock_ridge_attributes("",					 (char *) pnt, de,					 &fstatbuf, 					 &fstatbuf, 0);	}      iso9660_date(de->isorec.date, fstatbuf.st_mtime);    }  /*   * If we don't have a directory for this one yet, then allocate it   * now, and patch it into the tree in the appropriate place.   */  dpnt             = (struct directory *) e_malloc(sizeof(struct directory));  memset(dpnt, 0, sizeof(struct directory));  dpnt->next       = NULL;  dpnt->subdir     = NULL;  dpnt->self       = de;  dpnt->contents   = NULL;  dpnt->whole_name = strdup(path);  cpnt             = strrchr(path, PATH_SEPARATOR);  if(cpnt)    cpnt++;  else    cpnt = path;  dpnt->de_name    = strdup(cpnt);  dpnt->size       = 0;  dpnt->extent     = 0;  dpnt->jextent    = 0;  dpnt->jsize      = 0;  if( orig_de == NULL )    {      struct stat xstatbuf;      int sts;      /*       * Now add a . and .. entry in the directory itself.       * This is a little tricky - if the real directory       * exists, we need to stat it first.  Otherwise, we       * use the fictitious fstatbuf which points to the time       * at which mkisofs was started.       */      sts = stat_filter(parent->whole_name, &xstatbuf);      if( sts == 0 )	{	  attach_dot_entries(dpnt, &xstatbuf);	}      else	{	  attach_dot_entries(dpnt, &fstatbuf);	}    }  if(!parent || parent == root)    {      if (!root) 	{	  root = dpnt;  /* First time through for root directory only */	  root->depth = 0;	  root->parent = root;	} else {	  dpnt->depth = 1;	  if(!root->subdir)	    {	      root->subdir = dpnt;	    }	  else 	    {	      next_brother = root->subdir;	      while(next_brother->next) next_brother = next_brother->next;	      next_brother->next = dpnt;	    }	  dpnt->parent = parent;	}    }   else     {      /* Come through here for  normal traversal of  tree */#ifdef DEBUG      fprintf(stderr,"%s(%d) ", path, dpnt->depth);#endif      if(parent->depth >  RR_relocation_depth) 	{#ifdef	USE_LIBSCHILY	  comerrno(EX_BAD, "Directories too deep for '%s' (%d) max is %d.\n",				path, parent->depth, RR_relocation_depth);#else	  fprintf(stderr,"Directories too deep for '%s' (%d) max is %d.\n",				path, parent->depth, RR_relocation_depth);	  exit(1);#endif	}            dpnt->parent = parent;       dpnt->depth = parent->depth + 1;            if(!parent->subdir)	{	  parent->subdir = dpnt;	}      else 	{	  next_brother = parent->subdir;	  while(next_brother->next) next_brother = next_brother->next;	  next_brother->next = dpnt;	}    }  return dpnt;}/* * Function:	delete_directory * * Purpose:	Locate a directory entry in the tree, create if needed. * * Arguments: */static void FDECL2(delete_directory, struct directory *, parent, struct directory *, child){  struct directory		* tdir;  if( child->contents != NULL )    {#ifdef	USE_LIBSCHILY      comerrno(EX_BAD, "Unable to delete non-empty directory\n");#else      fprintf(stderr, "Unable to delete non-empty directory\n");      exit(1);#endif    }  free(child->whole_name);  child->whole_name = NULL;  free(child->de_name);  child->de_name = NULL;  if( parent->subdir == child )    {      parent->subdir = child->next;    }  else    {      for( tdir = parent->subdir; tdir->next != NULL; tdir = tdir->next )	{	  if( tdir->next == child )	    {	      tdir->next = child->next;	      break;	    }	}      if( tdir == NULL )	{#ifdef	USE_LIBSCHILY	  comerrno(EX_BAD, "Unable to locate child directory in parent list\n");#else	  fprintf(stderr, "Unable to locate child directory in parent list\n");	  exit(1);#endif	}    }  free(child);  return;}int FDECL1(sort_tree, struct directory *, node){  struct directory * dpnt;  int ret = 0;  dpnt = node;  while (dpnt){    ret = sort_n_finish(dpnt);    if( ret )      {	break;      }        if(dpnt->subdir) sort_tree(dpnt->subdir);    dpnt = dpnt->next;  }  return ret;}void FDECL1(dump_tree, struct directory *, node){  struct directory * dpnt;  dpnt = node;  while (dpnt){    fprintf(stderr,"%4d %5d %s\n",dpnt->extent, dpnt->size, dpnt->de_name);    if(dpnt->subdir) dump_tree(dpnt->subdir);    dpnt = dpnt->next;  }}void FDECL1(update_nlink_field, struct directory *, node){    struct directory		* dpnt;    struct directory		* xpnt;    struct directory_entry	* s_entry;    int				  i;    dpnt = node;        while (dpnt)    {	if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) {	    dpnt = dpnt->next;	    continue;	}	/*	 * First, count up the number of subdirectories this guy has.	 */        for(i=0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next)            if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0)                i++;	/*	 * Next check to see if we have any relocated directories	 * in this directory.   The nlink field will include these	 * as real directories when they are properly relocated.	 *	 * In the non-rockridge disk, the relocated entries appear	 * as zero length files.	 */	for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next)	{		if( (s_entry->de_flags  & RELOCATED_DIRECTORY) != 0 &&			(s_entry->de_flags  & INHIBIT_ISO9660_ENTRY) == 0)		{			i++;		}	}	/*	 * Now update the field in the Rock Ridge entry.	 */	update_nlink(dpnt->self, i + 2);	/*	 * Update the '.' entry for this directory.	 */	update_nlink(dpnt->contents, i + 2);	/*	 * Update all of the '..' entries that point to this guy.	 */	for(xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next)	    update_nlink(xpnt->contents->next, i + 2);	if(dpnt->subdir) update_nlink_field(dpnt->subdir);	dpnt = dpnt->next;    }}/* * something quick and dirty to locate a file given a path * recursively walks down path in filename until it finds the * directory entry for the desired file  */struct directory_entry * FDECL2(search_tree_file, struct directory *, 				node,char *, filename){  struct directory_entry * depnt;  struct directory	 * dpnt;  char			 * p1;  char			 * rest;  char			 * subdir;  /*   * strip off next directory name from filename    */  subdir = strdup(filename);  if( (p1=strchr(subdir, '/')) == subdir )    {      fprintf(stderr,"call to search_tree_file with an absolute path, stripping\n");      fprintf(stderr,"initial path separator. Hope this was intended...\n");      memmove(subdir, subdir+1, strlen(subdir)-1);      p1 = strchr(subdir, '/');    }  /*   * do we need to find a subdirectory    */  if (p1)     {      *p1 = '\0';#ifdef DEBUG_TORITO      fprintf(stderr,"Looking for subdir called %s\n",p1); #endif      rest = p1+1;#ifdef DEBUG_TORITO      fprintf(stderr,"Remainder of path name is now %s\n", rest); #endif            dpnt = node->subdir;     while( dpnt )       {#ifdef DEBUG_TORITO	 fprintf(stderr,"%4d %5d %s\n", dpnt->extent, dpnt->size, 		 dpnt->de_name); #endif	 if (!strcmp(subdir, dpnt->de_name)) 	   {#ifdef DEBUG_TORITO	     fprintf(stderr,"Calling next level with filename = %s", rest); #endif	     return(search_tree_file( dpnt, rest ));	   }	 dpnt = dpnt->next;       }           /* if we got here means we couldnt find the subdir */     return (NULL);    }      else     {      /*        * look for a normal file now        */      depnt = node->contents;      while (depnt)	{#ifdef DEBUG_TORITO	  fprintf(stderr,"%4d %5d %s\n",depnt->isorec.extent, 		  depnt->size, depnt->name); #endif	  if (!strcmp(filename, depnt->name)) 	    {#ifdef DEBUG_TORITO	      fprintf(stderr,"Found our file %s", filename); #endif	      return(depnt);	    }	  depnt = depnt->next;	}      /*        * if we got here means we couldnt find the subdir        */      return (NULL);    }#ifdef	ERIC_FUN  fprintf(stderr,"We cant get here in search_tree_file :-/ \n");#endif}void init_fstatbuf(){  time_t		    current_time;  if(fstatbuf.st_ctime == 0)    {      time (&current_time);      if( rationalize )	{	  fstatbuf.st_uid = 0;	  fstatbuf.st_gid = 0;	}      else	{	  fstatbuf.st_uid = getuid();	  fstatbuf.st_gid = getgid();	}      fstatbuf.st_ctime = current_time;      fstatbuf.st_mtime = current_time;      fstatbuf.st_atime = current_time;    }}

⌨️ 快捷键说明

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