📄 tree.c
字号:
nchar = -1;#endif symlink_buff[nchar < 0 ? 0 : nchar] = 0; sprintf(buffer, "L\t%s\t%s\n", s_entry->name, symlink_buff); break;#endif#ifdef S_IFSOCK case S_IFSOCK: sprintf(buffer, "S\t%s\n", s_entry->name); break;#endif case S_IFREG: default: sprintf(buffer, "F\t%s\n", s_entry->name); break; }; s_entry->table = strdup(buffer); } 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 */#ifdef APPLE_HYB /* if the file is HFS excluded, then we don't have an hfs_ent */ if (apple_both && !have_rsrc && s_entry->hfs_ent) { if (S_ISREG(lstatbuf.st_mode)) { /* it's a regular file */ /* fill in the rest of the HFS entry */ get_hfs_info(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, 0); /* print details about the HFS file */ if (verbose > 2) print_hfs_info(s_entry); /* * copy the new ISO9660 name to the rsrc fork * - if it exists */ if (s_entry->assoc) strcpy(s_entry->assoc->isorec.name, s_entry->isorec.name); /* * we can't handle hard links in the hybrid case, so we * "uncache" the file. The downside to this is that * hard linked files are added to the output image * more than once (we've already done this for rsrc * files) */ if (apple_hyb) { s_entry->inode = UNCACHED_INODE; s_entry->dev = (dev_t) UNCACHED_DEVICE; } } else if (!(s_entry->isorec.flags[0] & ISO_DIRECTORY)) { /* not a directory .. */ /* * no mac equivalent, so ignore - have to be careful * here, the hfs_ent may be also be for a relocated * directory */ if (s_entry->hfs_ent && !(s_entry->de_flags & RELOCATED_DIRECTORY)) free(s_entry->hfs_ent); s_entry->hfs_ent = NULL; } /* * if the rsrc size is zero, then we don't need the entry, so * we might as well delete it - this will only happen if we * didn't know the rsrc size from the rsrc file size */ if (s_entry->assoc && s_entry->assoc->size == 0) delete_rsrc_ent(s_entry); } if (apple_ext && s_entry->assoc) { /* need Apple extensions for the resource fork as well */ generate_rock_ridge_attributes(whole_path, short_name, s_entry->assoc, &statbuf, &lstatbuf, deep_flag); } /* leave out resource fork for the time being */ if (use_RockRidge && !have_rsrc) {#else if (use_RockRidge) {#endif /* APPLE_HYB */ generate_rock_ridge_attributes(whole_path, short_name, s_entry, &statbuf, &lstatbuf, deep_flag); } return 1;}voidgenerate_iso9660_directories(node, outfile) 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 *find_or_create_directory(parent, path, de, flag) 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] = ISO_DIRECTORY; 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 = new_dir_mode | S_IFDIR; fstatbuf.st_nlink = 2; generate_rock_ridge_attributes("", (char *) pnt, de, &fstatbuf, &fstatbuf, 0); } iso9660_date(de->isorec.date, fstatbuf.st_mtime);#ifdef APPLE_HYB if (apple_both) { /* give the directory an HFS entry */ hfsdirent *hfs_ent; hfs_ent = (hfsdirent *) e_malloc(sizeof(hfsdirent)); /* fill in the defaults */ memset(hfs_ent, 0, sizeof(hfsdirent)); hfs_ent->crdate = fstatbuf.st_ctime; hfs_ent->mddate = fstatbuf.st_mtime; de->hfs_ent = hfs_ent; /* get the Mac directory name */ get_hfs_dir((char *) path, (char *) pnt, de); }#endif /* APPLE_HYB */ } /* * 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;#ifdef APPLE_HYB dpnt->hfs_ent = de->hfs_ent;#endif /* APPLE_HYB */ 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. */ if (parent == NULL || parent->whole_name[0] == '\0') sts = -1; else sts = stat_filter(parent->whole_name, &xstatbuf); if (debug && parent) { error("stat parent->whole_name: '%s' -> %d.\n", parent->whole_name, sts); } 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) { /* * XXX to prevent this, we would need to add * XXX support for RR directory relocation * XXX to find_or_create_directory() */#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 voiddelete_directory(parent, child) 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;#ifdef APPLE_HYB if (apple_both && child->hfs_ent) free(child->hfs_ent);#endif /* APPLE_HYB */ 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;}intsort_tree(node) 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;}voiddump_tree(node) 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; }}voidupdate_nlink_field(node) 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) u
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -