📄 tree.c
字号:
} 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 (¤t_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 + -