📄 tree.c
字号:
/* * 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 = 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);#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. */ 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 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) 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 *search_tree_file(node, filename) 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}voidinit_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 + -