📄 tree.c
字号:
/* if the reloc_dir is hidden (empty), then return */ if (reloc_dir->dir_flags & INHIBIT_ISO9660_ENTRY) return; s_entry = reloc_dir->contents; s_entry = s_entry->next->next; /* Skip past . and .. */ for (; s_entry; s_entry = s_entry->next) { /* skip if it's hidden */ if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { continue; } d_entry = reloc_dir->subdir; while (d_entry) { if (d_entry->self == s_entry) break; d_entry = d_entry->next; }; if (!d_entry) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Unable to locate directory parent\n");#else fprintf(stderr, "Unable to locate directory parent\n"); exit(1);#endif }; if (s_entry->filedir != NULL && s_entry->parent_rec != NULL) { char *rr_attr; /* * First fix the PL pointer in the directory in the * rr_reloc dir */ s_entry1 = d_entry->contents->next;/* set_733((char *) s_entry1->rr_attributes +*//* s_entry1->total_rr_attr_size - 8,*//* s_entry->filedir->extent); */ /* * The line above won't work when entry was read from * the previous session, because if total_rr_attr_size * was odd when recording previous session, now we have * total_rr_attr_size off by 1 due to padding. * * So, just search for the attributes by name */ rr_attr = find_rr_attribute(s_entry1->rr_attributes, s_entry1->total_rr_attr_size, "PL"); if (rr_attr != NULL) set_733(rr_attr + 4, s_entry->filedir->extent); /* Now fix the CL pointer */ s_entry1 = s_entry->parent_rec;/* set_733((char *) s_entry1->rr_attributes +*//* s_entry1->total_rr_attr_size - 8, d_entry->extent); */ rr_attr = find_rr_attribute(s_entry1->rr_attributes, s_entry1->total_rr_attr_size, "CL"); if (rr_attr != NULL) set_733(rr_attr + 4, d_entry->extent); } s_entry->filedir = reloc_dir; /* Now we can fix this */ } /* * Next we need to modify the NLINK terms in the assorted root * directory records to account for the presence of the RR_MOVED * directory */ increment_nlink(root->self); increment_nlink(root->self->next); d_entry = root->subdir; while (d_entry) { increment_nlink(d_entry->contents->next); d_entry = d_entry->next; }; finish_cl_pl_for_prev_session();}/* * Function: scan_directory_tree * * Purpose: Walk through a directory on the local machine * filter those things we don't want to include * and build our representation of a dir. * * Notes: */intscan_directory_tree(this_dir, path, de) struct directory *this_dir; char *path; struct directory_entry *de;{ DIR *current_dir; char whole_path[PATH_MAX]; struct dirent *d_entry; struct directory *parent; int dflag; char *old_path; if (verbose > 1) { fprintf(stderr, "Scanning %s\n", path); }/*#define check_needed*/#ifdef check_needed /* * Trying to use this to avoid directory loops from hard links * or followed symlinks does not work. It would prevent us from * implementing merge directories. */ if (this_dir->dir_flags & DIR_WAS_SCANNED) { fprintf(stderr, "Already scanned directory %s\n", path); return (1); /* It's a directory */ }#endif this_dir->dir_flags |= DIR_WAS_SCANNED; errno = 0; /* Paranoia */ current_dir = opendir(path); d_entry = NULL; /* * Apparently NFS sometimes allows you to open the directory, but then * refuses to allow you to read the contents. Allow for this */ old_path = path; if (current_dir) { errno = 0; d_entry = readdir(current_dir); } if (!current_dir || !d_entry) { int ret = 1;#ifdef USE_LIBSCHILY errmsg("Unable to open directory %s\n", path);#else fprintf(stderr, "Unable to open directory %s\n", path);#endif if (errno == ENOTDIR) { de->isorec.flags[0] &= ~ISO_DIRECTORY;/* Mark as not a directory */ ret = 0; } if (current_dir) closedir(current_dir); return ret; }#ifdef ABORT_DEEP_ISO_ONLY if ((this_dir->depth > RR_relocation_depth) && !use_RockRidge) { errmsgno(EX_BAD, "Directories too deep for '%s' (%d) max is %d.\n", path, this_dir->depth, RR_relocation_depth); closedir(current_dir); return 1; }#endif parent = de->filedir; /* * Set up the struct for the current directory, and insert it into * the tree */#ifdef VMS vms_path_fixup(path);#endif /* * if entry for this sub-directory is hidden, then hide this directory */ if (de->de_flags & INHIBIT_ISO9660_ENTRY) this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; if (de->de_flags & INHIBIT_JOLIET_ENTRY) this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY;#ifdef SORTING /* set any sort weighting from it's own directory entry - if a * directory is given a weighting, then all the contents will use * this as the default weighting */ this_dir->sort = de->sort;#endif /* SORTING */ /* * Now we scan the directory itself, and look at what is inside of it. */ dflag = 0; while (1 == 1) { /* * The first time through, skip this, since we already asked * for the first entry when we opened the directory. */ if (dflag) d_entry = readdir(current_dir); dflag++; if (!d_entry) break; /* OK, got a valid entry */ /* If we do not want all files, then pitch the backups. */ if (!all_files) { if (strchr(d_entry->d_name, '~') || strchr(d_entry->d_name, '#') || rstr(d_entry->d_name, ".bak")) { if (verbose > 0) { fprintf(stderr, "Ignoring file %s\n", d_entry->d_name); } continue; } }#ifdef APPLE_HYB if (apple_both) { /* * exclude certain HFS type files/directories for the * time being */ if (hfs_exclude(d_entry->d_name)) continue; }#endif /* APPLE_HYB */ if (strlen(path) + strlen(d_entry->d_name) + 2 > sizeof(whole_path)) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Overflow of stat buffer\n");#else fprintf(stderr, "Overflow of stat buffer\n"); exit(1);#endif }; /* Generate the complete ASCII path for this file */ strcpy(whole_path, path);#ifndef VMS if (whole_path[strlen(whole_path) - 1] != '/') strcat(whole_path, "/");#endif strcat(whole_path, d_entry->d_name); /** Should we exclude this file ? */ if (matches(d_entry->d_name) || matches(whole_path)) { if (verbose > 1) { fprintf(stderr, "Excluded by match: %s\n", whole_path); } continue; } if (generate_tables && strcmp(d_entry->d_name, trans_tbl) == 0) { /* * Ignore this entry. We are going to be generating * new versions of these files, and we need to ignore * any originals that we might have found. */ if (verbose > 1) { fprintf(stderr, "Excluded: %s\n", whole_path); } continue; } /* * If we already have a '.' or a '..' entry, then don't insert * new ones. */ if (strcmp(d_entry->d_name, ".") == 0 && this_dir->dir_flags & DIR_HAS_DOT) { continue; } if (strcmp(d_entry->d_name, "..") == 0 && this_dir->dir_flags & DIR_HAS_DOTDOT) { continue; }#if 0 if (verbose > 1) fprintf(stderr, "%s\n", whole_path);#endif /* This actually adds the entry to the directory in question.*/#ifdef APPLE_HYB insert_file_entry(this_dir, whole_path, d_entry->d_name, 0);#else insert_file_entry(this_dir, whole_path, d_entry->d_name);#endif /* APPLE_HYB */ } closedir(current_dir);#ifdef APPLE_HYB /* * if we cached the HFS info stuff for this directory, then delete it */ if (this_dir->hfs_info) { del_hfs_info(this_dir->hfs_info); this_dir->hfs_info = 0; }#endif /* APPLE_HYB */ return 1;}/* * Function: insert_file_entry * * Purpose: Insert one entry into our directory node. * * Note: * This function inserts a single entry into the directory. It * is assumed that all filtering and decision making regarding what * we want to include has already been made, so the purpose of this * is to insert one entry (file, link, dir, etc), into this directory. * Note that if the entry is a dir (or if we are following links, * and the thing it points to is a dir), then we will scan those * trees before we return. */#ifdef APPLE_HYBintinsert_file_entry(this_dir, whole_path, short_name, have_rsrc) struct directory *this_dir; char *whole_path; char *short_name; int have_rsrc;#elseintinsert_file_entry(this_dir, whole_path, short_name) struct directory *this_dir; char *whole_path; char *short_name;#endif /* APPLE_HYB */{ struct stat statbuf, lstatbuf; struct directory_entry *s_entry, *s_entry1; int lstatus; int status; int deep_flag; int no_scandir = 0;#ifdef APPLE_HYB int x_hfs = 0; int htype = TYPE_NONE;#endif /* APPLE_HYB */ status = stat_filter(whole_path, &statbuf); lstatus = lstat_filter(whole_path, &lstatbuf); if ((status == -1) && (lstatus == -1)) { /* * This means that the file doesn't exist, or isn't accessible. * Sometimes this is because of NFS permissions problems. */#ifdef USE_LIBSCHILY errmsg("Non-existent or inaccessible: %s\n", whole_path);#else fprintf(stderr, "Non-existent or inaccessible: %s\n", whole_path);#endif return 0; } if (this_dir == root && strcmp(short_name, ".") == 0) root_statbuf = statbuf; /* Save this for later on */ /* We do this to make sure that the root entries are consistent */ if (this_dir == root && strcmp(short_name, "..") == 0) { statbuf = root_statbuf; lstatbuf = root_statbuf; } if (S_ISLNK(lstatbuf.st_mode)) { /* * Here we decide how to handle the symbolic links. Here we * handle the general case - if we are not following links or * there is an error, then we must change something. If RR * is in use, it is easy, we let RR describe the file. If * not, then we punt the file. */ if ((status || !follow_links)) { if (use_RockRidge) { status = 0; statbuf.st_size = (off_t)0; STAT_INODE(statbuf) = UNCACHED_INODE; statbuf.st_dev = (dev_t) UNCACHED_DEVICE; statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; } else { if (follow_links) {#ifdef USE_LIBSCHILY /* XXX errno may be wrong! */ errmsg("Unable to stat file %s - ignoring and continuing.\n", whole_path);#else fprintf(stderr, "Unable to stat file %s - ignoring and continuing.\n", whole_path);#endif } else {#ifdef USE_LIBSCHILY errmsgno(EX_BAD, "Symlink %s ignored - continuing.\n", whole_path);#else fprintf(stderr, "Symlink %s ignored - continuing.\n", whole_path);#endif return 0;/* Non Rock Ridge discs - ignore all symlinks */ } } } /* * Here we handle a different kind of case. Here we have a * symlink, but we want to follow symlinks. If we run across * a directory loop, then we need to pretend that we are not * following symlinks for this file. If this is the first * time we have seen this, then make this seem as if there was * no symlink there in the first place */ if (follow_links && S_ISDIR(statbuf.st_mode)) { if (strcmp(short_name, ".") && strcmp(short_name, "..")) { if (find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) { if (!use_RockRidge) { fprintf(stderr, "Already cached directory seen (%s)\n", whole_path); return 0; } lstatbuf = statbuf; /* * XXX when this line was active, * XXX mkisofs did not include all * XXX files if it was called with '-f' * XXX (follow symlinks). * XXX Now scan_directory_tree() * XXX checks if the directory has * XXX already been scanned via the * XXX DIR_WAS_SCANNED flag. *//* no_scandir = 1;*/ } else { lstatbuf = statbuf; add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); } } } /* * For non-directories, we just copy the stat information over * so we correctly include this file. */ if (follow_links && !S_ISDIR(statbuf.st_mode)) { lstatbuf = statbuf; } } /* * Add directories to the cache so that we don't waste space even if * we are supposed to be following symlinks. */ if (follow_links && strcmp(short_name, ".") && strcmp(short_name, "..") && S_ISDIR(statbuf.st_mode)) { add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); }#ifdef VMS if (!S_ISDIR(lstatbuf.st_mode) && (statbuf.st_fab_rfm != FAB$C_FIX && statbuf.st_fab_rfm != FAB$C_STMLF)) { fprintf(stderr, "Warning - file %s has an unsupported VMS record" " format (%d)\n", whole_path, statbuf.st_fab_rfm); }#endif if (S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK))) {#ifdef USE_LIBSCHILY errmsg("File %s is not readable - ignoring\n", whole_path);#else fprintf(stderr, "File %s is not readable (errno = %d) - ignoring\n", whole_path, errno);#endif return 0; } /* * >= is required by the large file summit standard. */ if (S_ISREG(lstatbuf.st_mode) && (lstatbuf.st_size >= (off_t)0x7FFFFFFF)) {#ifdef EOVERFLOW
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -