📄 tree.c
字号:
errno = EOVERFLOW;#else errno = EFBIG;#endif#ifdef USE_LIBSCHILY errmsg("File %s is too large - ignoring\n", whole_path);#else fprintf(stderr, "File %s is too large (errno = %d) - ignoring\n", whole_path, errno);#endif return 0; } /* * Add this so that we can detect directory loops with hard links. * If we are set up to follow symlinks, then we skip this checking. */ if (!follow_links && S_ISDIR(lstatbuf.st_mode) && strcmp(short_name, ".") && strcmp(short_name, "..")) { if (find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) {#ifdef USE_LIBSCHILY/* comerrno(EX_BAD,*//* "Directory loop - fatal goof (%s %lx %lu).\n",*/ errmsgno(EX_BAD, "Warning: Directory loop (%s dev: %lx ino: %lu).\n", whole_path, (unsigned long) statbuf.st_dev, (unsigned long) STAT_INODE(statbuf));#else/* fprintf(stderr,*//* "Directory loop - fatal goof (%s %lx %lu).\n",*/ fprintf(stderr, "Warning: Directory loop (%s dev: %lx ino: %lu).\n", whole_path, (unsigned long) statbuf.st_dev, (unsigned long) STAT_INODE(statbuf));#endif } add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); } if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) && !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) && !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) && !S_ISDIR(lstatbuf.st_mode)) { fprintf(stderr, "Unknown file type (%s) %s - ignoring and continuing.\n", filetype((int) lstatbuf.st_mode), whole_path); return 0; } /* Who knows what trash this is - ignore and continue */ if (status) {#ifdef USE_LIBSCHILY 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 return 0; } /* * Check to see if we have already seen this directory node. If so, * then we don't create a new entry for it, but we do want to recurse * beneath it and add any new files we do find. */ if (S_ISDIR(statbuf.st_mode)) { int dflag; for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { if (strcmp(s_entry->name, short_name) == 0) { break; } } if (s_entry != NULL && strcmp(short_name, ".") && strcmp(short_name, "..")) { struct directory *child; if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) { for (s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) { if (strcmp(s_entry->name, short_name) == 0) { break; } } child = find_or_create_directory(reloc_dir, whole_path, s_entry, 1); } else { child = find_or_create_directory(this_dir, whole_path, s_entry, 1); /* * If unable to scan directory, mark this as a * non-directory */ }/* if (no_scandir)*/ if (0) dflag = 1; else dflag = scan_directory_tree(child, whole_path, s_entry); if (!dflag) { lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; } return 0; } }#ifdef APPLE_HYB /* Should we exclude this HFS file ? - only works with -hfs */ if (!have_rsrc && apple_hyb && strcmp(short_name, ".") && strcmp(short_name, "..")) { if ((x_hfs = (hfs_matches(short_name) || hfs_matches(whole_path))) == 1) { if (verbose > 1) { fprintf(stderr, "Hidden from HFS tree: %s\n", whole_path); } } } /* * check we are a file, using Apple extensions and have a .resource * part and not excluded */ if (S_ISREG(lstatbuf.st_mode) && !have_rsrc && apple_both && !x_hfs) { char rsrc_path[PATH_MAX]; /* rsrc fork filename */ /* construct the resource full path */ htype = get_hfs_rname(whole_path, short_name, rsrc_path); /* check we can read the resouce fork */ if (htype) { struct stat rstatbuf, rlstatbuf; /* some further checks on the file */ status = stat_filter(rsrc_path, &rstatbuf); lstatus = lstat_filter(rsrc_path, &rlstatbuf);/* if (!status && !lstatus && S_ISREG(rlstatbuf.st_mode)*//* && rlstatbuf.st_size > (off_t)0) { */ if (!status && !lstatus && S_ISREG(rstatbuf.st_mode) && rstatbuf.st_size > (off_t)0) { /* * have a resource file - insert it into the * current directory but flag that we have a * resource fork */ insert_file_entry(this_dir, rsrc_path, short_name, htype); } } }#endif /* APPLE_HYB */ s_entry = (struct directory_entry *) e_malloc(sizeof(struct directory_entry)); /* memset the whole struct, not just the isorec.extent part JCP */ memset(s_entry, 0, sizeof(struct directory_entry)); s_entry->next = this_dir->contents;/* memset(s_entry->isorec.extent, 0, 8); */ this_dir->contents = s_entry; deep_flag = 0; s_entry->table = NULL; s_entry->name = strdup(short_name); s_entry->whole_name = strdup(whole_path); s_entry->de_flags = 0; /* * If the current directory is hidden, then hide all it's members * otherwise check if this entry needs to be hidden as well */ if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; } else if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") != 0) { if (i_matches(short_name) || i_matches(whole_path)) { if (verbose > 1) { fprintf(stderr, "Hidden from ISO9660 tree: %s\n", whole_path); } s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; } if (h_matches(short_name) || h_matches(whole_path)) { if (verbose > 1) { fprintf(stderr, "Hidden ISO9660 attribute: %s\n", whole_path); } s_entry->de_flags |= HIDDEN_FILE; } } if (this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; } else if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") != 0) { if (j_matches(short_name) || j_matches(whole_path)) { if (verbose > 1) { fprintf(stderr, "Hidden from Joliet tree: %s\n", whole_path); } s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; } }#ifdef SORTING /* inherit any sort weight from parent directory */ s_entry->sort = this_dir->sort;#ifdef DVD_VIDEO /* * No use at all to do a sort if we don't make a dvd video/audio */ /* * Assign special weights to VIDEO_TS and AUDIO_TS files. * This can't be done with sort_matches for two reasons: * first, we need to match against the destination (DVD) * path rather than the source path, and second, there are * about 2400 different file names to check, each needing * a different priority, and adding that many patterns to * sort_matches would slow things to a crawl. */ if (dvd_video) { s_entry->sort = assign_dvd_weights(s_entry->name, this_dir, s_entry->sort); /* turn on sorting if necessary, regardless of cmd-line options */ if (s_entry->sort != this_dir->sort) do_sort++; }#endif /* see if this entry should have a new weighting */ if (do_sort && strcmp(short_name,".") != 0 && strcmp(short_name,"..") != 0) { s_entry->sort = sort_matches(whole_path, s_entry->sort); }#endif /* SORTING */ s_entry->filedir = this_dir; s_entry->isorec.flags[0] = ISO_FILE; if (s_entry->de_flags & HIDDEN_FILE) s_entry->isorec.flags[0] |= ISO_EXISTENCE; s_entry->isorec.ext_attr_length[0] = 0; iso9660_date(s_entry->isorec.date, statbuf.st_mtime); s_entry->isorec.file_unit_size[0] = 0; s_entry->isorec.interleave[0] = 0;#ifdef APPLE_HYB if (apple_both && !x_hfs) { s_entry->hfs_ent = NULL; s_entry->assoc = NULL; s_entry->hfs_off = (off_t)0; s_entry->hfs_type = htype; if (have_rsrc) { s_entry->isorec.flags[0] |= ISO_ASSOCIATED;/* associated (rsrc) file */ /* set the type of HFS file */ s_entry->hfs_type = have_rsrc; /* * don't want the rsrc file to be included in any * Joliet tree */ s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; } else if (s_entry->next) { /* * if previous entry is an associated file, * then "link" it to this file i.e. we have a * data/resource pair */ if (s_entry->next->isorec.flags[0] & ISO_ASSOCIATED) { s_entry->assoc = s_entry->next; /* share the same HFS parameters */ s_entry->hfs_ent = s_entry->next->hfs_ent; s_entry->hfs_type = s_entry->next->hfs_type; } } /* allocate HFS entry if required */ if (apple_both && strcmp(short_name, ".") && strcmp(short_name, "..")) { if (!s_entry->hfs_ent) { hfsdirent *hfs_ent; hfs_ent = (hfsdirent *) e_malloc(sizeof(hfsdirent)); /* fill in the defaults */ memset(hfs_ent, 0, sizeof(hfsdirent)); s_entry->hfs_ent = hfs_ent; } /* * the resource fork is processed first, but the * data fork's time info is used in preference * i.e. time info is set from the resource fork * initially, then it is set from the data fork */ if (have_rsrc) { /* set rsrc size */ s_entry->hfs_ent->u.file.rsize = lstatbuf.st_size; /* * this will be overwritten - but might as * well set it here ... */ s_entry->hfs_ent->crdate = lstatbuf.st_ctime; s_entry->hfs_ent->mddate = lstatbuf.st_mtime; } else { /* set data size */ s_entry->hfs_ent->u.file.dsize = lstatbuf.st_size; s_entry->hfs_ent->crdate = lstatbuf.st_ctime; s_entry->hfs_ent->mddate = lstatbuf.st_mtime; } } }#endif /* APPLE_HYB */ if (strcmp(short_name, ".") == 0) { this_dir->dir_flags |= DIR_HAS_DOT; } if (strcmp(short_name, "..") == 0) { this_dir->dir_flags |= DIR_HAS_DOTDOT; } if (this_dir->parent && this_dir->parent == reloc_dir && strcmp(short_name, "..") == 0) { s_entry->inode = UNCACHED_INODE; s_entry->dev = (dev_t) UNCACHED_DEVICE; deep_flag = NEED_PL; } else#ifdef APPLE_HYB if (have_rsrc) { /* don't want rsrc files to be cached */ s_entry->inode = UNCACHED_INODE; s_entry->dev = (dev_t) UNCACHED_DEVICE; } else#endif /* APPLE_HYB */ { s_entry->inode = STAT_INODE(statbuf); s_entry->dev = statbuf.st_dev; } set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); iso9660_file_length(short_name, s_entry, S_ISDIR(statbuf.st_mode)); s_entry->rr_attr_size = 0; s_entry->total_rr_attr_size = 0; s_entry->rr_attributes = NULL; /* Directories are assigned sizes later on */ if (!S_ISDIR(statbuf.st_mode)) { if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode) || S_ISLNK(lstatbuf.st_mode)) { s_entry->size = (off_t)0; statbuf.st_size = (off_t)0; } else { s_entry->size = statbuf.st_size; } set_733((char *) s_entry->isorec.size, statbuf.st_size); } else { s_entry->isorec.flags[0] |= ISO_DIRECTORY; }#ifdef APPLE_HYB /* if the directory is HFS excluded, then we don't have an hfs_ent */ if (apple_both && s_entry->hfs_ent && (s_entry->isorec.flags[0] & ISO_DIRECTORY)) { /* get the Mac directory name */ get_hfs_dir(whole_path, short_name, s_entry); /* if required, set ISO directory name from HFS name */ if (use_mac_name) iso9660_file_length(s_entry->hfs_ent->name, s_entry, 1); }#endif /* APPLE_HYB */ if (strcmp(short_name, ".") != 0 && strcmp(short_name, "..") != 0 && S_ISDIR(statbuf.st_mode) && this_dir->depth > RR_relocation_depth) { struct directory *child; if (!reloc_dir) generate_reloc_directory(); /* * Replicate the entry for this directory. The old one will * stay where it is, and it will be neutered so that it no * longer looks like a directory. The new one will look like * a directory, and it will be put in the reloc_dir. */ s_entry1 = (struct directory_entry *) e_malloc(sizeof(struct directory_entry)); memcpy(s_entry1, s_entry, sizeof(struct directory_entry)); s_entry1->table = NULL; s_entry1->name = strdup(this_dir->contents->name); s_entry1->whole_name = strdup(this_dir->contents->whole_name); s_entry1->next = reloc_dir->contents; reloc_dir->contents = s_entry1; s_entry1->priority = 32768; s_entry1->parent_rec = this_dir->contents; set_723(s_entry1->isorec.volume_sequence_number, volume_sequence_number); deep_flag = NEED_RE; if (use_RockRidge) { generate_rock_ridge_attributes(whole_path, short_name, s_entry1, &statbuf, &lstatbuf, deep_flag); } deep_flag = 0; /* * We need to set this temporarily so that the parent to this * is correctly determined. */ s_entry1->filedir = reloc_dir; child = find_or_create_directory(reloc_dir, whole_path, s_entry1, 0);/* if (!no_scandir)*/ if (!0) scan_directory_tree(child, whole_path, s_entry1); s_entry1->filedir = this_dir; statbuf.st_size = (off_t)0; statbuf.st_mode &= 0777; set_733((char *) s_entry->isorec.size, 0); s_entry->size = 0; s_entry->isorec.flags[0] = ISO_FILE; s_entry->inode = UNCACHED_INODE; s_entry->de_flags |= RELOCATED_DIRECTORY; deep_flag = NEED_CL; } if (generate_tables && strcmp(s_entry->name, ".") != 0 && strcmp(s_entry->name, "..") != 0) { char buffer[SECTOR_SIZE]; int nchar; switch (lstatbuf.st_mode & S_IFMT) { case S_IFDIR: sprintf(buffer, "D\t%s\n", s_entry->name); break;/* * extra for WIN32 - if it doesn't have the major/minor defined, then * S_IFBLK and S_IFCHR type files are unlikely to exist anyway ... * code similar to that in rock.c */#if 0/* * Use the device handling code from <device.h> */#ifndef major#define major(dev) (sizeof(dev_t) <= 2 ? ((dev) >> 8) : \ (sizeof(dev_t) <= 4 ? (((dev) >> 8) >> 8) : \ (((dev) >> 16) >> 16)))#define minor(dev) (sizeof(dev_t) <= 2 ? (dev) & 0xff : \ (sizeof(dev_t) <= 4 ? (dev) & 0xffff : \ (dev) & 0xffffffff))#endif#endif#ifdef S_IFBLK case S_IFBLK: sprintf(buffer, "B\t%s\t%lu %lu\n", s_entry->name, (unsigned long) major(statbuf.st_rdev), (unsigned long) minor(statbuf.st_rdev)); break;#endif#ifdef S_IFIFO case S_IFIFO: sprintf(buffer, "P\t%s\n", s_entry->name); break;#endif#ifdef S_IFCHR case S_IFCHR: sprintf(buffer, "C\t%s\t%lu %lu\n", s_entry->name, (unsigned long) major(statbuf.st_rdev), (unsigned long) minor(statbuf.st_rdev)); break;#endif#ifdef S_IFLNK case S_IFLNK:#ifdef HAVE_READLINK nchar = readlink(whole_path, (char *) symlink_buff, sizeof(symlink_buff)-1);#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -