📄 tree.c
字号:
#else fprintf(stderr, "Unable to sort directory %s\n", this_dir->whole_name); exit(1);#endif } /* * If we are filling out a TRANS.TBL, generate the entries that will * go in the thing. */ if(table) { count = 0; for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){ if(s_entry == table) continue; if(!s_entry->table) continue; if(strcmp(s_entry->name, ".") == 0 || strcmp(s_entry->name, "..") == 0) continue; if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; /* * Warning: we cannot use the return value of sprintf because * old BSD based sprintf() implementations will return * a pointer to the result instead of a count. */ sprintf(table->table + count, "%c %-34s%s", s_entry->table[0], s_entry->isorec.name, s_entry->table+1); count += strlen(table->table + count); free(s_entry->table); /* for a memory file, set s_entry->table to the correct data - which is stored in s_entry->whole_name */ if (s_entry->de_flags & MEMORY_FILE) { s_entry->table = s_entry->whole_name; s_entry->whole_name = NULL; } else { s_entry->table = NULL; } } if(count != tablesize) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Translation table size mismatch %d %d\n", count, tablesize);#else fprintf(stderr,"Translation table size mismatch %d %d\n", count, tablesize); exit(1);#endif } } /* * Now go through the directory and figure out how large this one will be. * Do not split a directory entry across a sector boundary */ s_entry = this_dir->contents; this_dir->ce_bytes = 0; while(s_entry) { /* skip if it's hidden */ if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { s_entry = s_entry->next; continue; } new_reclen = s_entry->isorec.length[0]; if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); this_dir->size += new_reclen; /* See if continuation entries were used on disc */ if(use_RockRidge && s_entry->rr_attr_size != s_entry->total_rr_attr_size) { unsigned char * pnt; int len; int nbytes; pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; /* * We make sure that each continuation entry record is not * split across sectors, but each file could in theory have more * than one CE, so we scan through and figure out what we need. */ while(len > 3) { if(pnt[0] == 'C' && pnt[1] == 'E') { nbytes = get_733((char *) pnt+20); if((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= SECTOR_SIZE) this_dir->ce_bytes = ROUND_UP(this_dir->ce_bytes); /* Now store the block in the ce buffer */ this_dir->ce_bytes += nbytes; if(this_dir->ce_bytes & 1) this_dir->ce_bytes++; } len -= pnt[2]; pnt += pnt[2]; } } s_entry = s_entry->next; } return status;}static void generate_reloc_directory(){ time_t current_time; struct directory_entry *s_entry; /* Create an entry for our internal tree */ time (¤t_time); reloc_dir = (struct directory *) e_malloc(sizeof(struct directory)); memset(reloc_dir, 0, sizeof(struct directory)); reloc_dir->parent = root; reloc_dir->next = root->subdir; root->subdir = reloc_dir; reloc_dir->depth = 1; if (hide_rr_moved) { reloc_dir->whole_name = strdup("./.rr_moved"); reloc_dir->de_name = strdup(".rr_moved"); } else { reloc_dir->whole_name = strdup("./rr_moved"); reloc_dir->de_name = strdup("rr_moved"); } reloc_dir->extent = 0; /* Now create an actual directory entry */ s_entry = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); memset(s_entry, 0, sizeof(struct directory_entry)); s_entry->next = root->contents; reloc_dir->self = s_entry; /* * The rr_moved entry will not appear in the Joliet tree. */ reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; /* * Hiding RR_MOVED seems not to be possible..... */#ifdef HIDE_RR reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; s_entry->de_flags |= INHIBIT_ISO9660_ENTRY;#endif root->contents = s_entry; root->contents->name = strdup(reloc_dir->de_name); root->contents->filedir = root; root->contents->isorec.flags[0] = 2; root->contents->priority = 32768; iso9660_date(root->contents->isorec.date, current_time); root->contents->inode = UNCACHED_INODE; root->contents->dev = (dev_t) UNCACHED_DEVICE; set_723(root->contents->isorec.volume_sequence_number, volume_sequence_number); iso9660_file_length (reloc_dir->de_name, root->contents, 1); init_fstatbuf(); if(use_RockRidge) { fstatbuf.st_mode = 0555 | S_IFDIR; fstatbuf.st_nlink = 2; generate_rock_ridge_attributes("", hide_rr_moved?".rr_moved":"rr_moved", s_entry, &fstatbuf, &fstatbuf, 0); }; /* Now create the . and .. entries in rr_moved */ /* Now create an actual directory entry */ attach_dot_entries(reloc_dir, &root_statbuf);}/* * Function: attach_dot_entries * * Purpose: Create . and .. entries for a new directory. * * Notes: Only used for artificial directories that * we are creating. */static void FDECL2(attach_dot_entries, struct directory *, dirnode, struct stat *, parent_stat){ struct directory_entry *s_entry; struct directory_entry *orig_contents; int deep_flag = 0; init_fstatbuf(); orig_contents = dirnode->contents; if( (dirnode->dir_flags & DIR_HAS_DOTDOT) == 0 ) { s_entry = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); memcpy(s_entry, dirnode->self, sizeof(struct directory_entry)); s_entry->name = strdup(".."); s_entry->whole_name = NULL; s_entry->isorec.name_len[0] = 1; s_entry->isorec.flags[0] = 2; /* Mark as a directory */ iso9660_file_length ("..", s_entry, 1); iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); set_733(s_entry->isorec.size,SECTOR_SIZE); memset(s_entry->isorec.extent, 0, 8); s_entry->filedir = dirnode->parent; dirnode->contents = s_entry; dirnode->contents->next = orig_contents; orig_contents = s_entry; if(use_RockRidge) { if( parent_stat == NULL ) { parent_stat = &fstatbuf; } generate_rock_ridge_attributes("", "..", s_entry, parent_stat, parent_stat, 0); } dirnode->dir_flags |= DIR_HAS_DOTDOT; } if( (dirnode->dir_flags & DIR_HAS_DOT) == 0 ) { s_entry = (struct directory_entry *) e_malloc(sizeof (struct directory_entry)); memcpy(s_entry, dirnode->self, sizeof(struct directory_entry)); s_entry->name = strdup("."); s_entry->whole_name = NULL; s_entry->isorec.name_len[0] = 1; s_entry->isorec.flags[0] = 2; /* Mark as a directory */ iso9660_file_length (".", s_entry, 1); iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); set_733(s_entry->isorec.size,SECTOR_SIZE); memset(s_entry->isorec.extent, 0, 8); s_entry->filedir = dirnode; dirnode->contents = s_entry; dirnode->contents->next = orig_contents; if(use_RockRidge) { fstatbuf.st_mode = 0555 | S_IFDIR; fstatbuf.st_nlink = 2; if( dirnode == root ) { deep_flag |= NEED_CE | NEED_SP; /* For extension record */ } generate_rock_ridge_attributes("", ".", s_entry, &fstatbuf, &fstatbuf, deep_flag); } dirnode->dir_flags |= DIR_HAS_DOT; }}static void FDECL2(update_nlink, struct directory_entry *, s_entry, int, value){ unsigned char * pnt; int len; pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; while(len) { if(pnt[0] == 'P' && pnt[1] == 'X') { set_733((char *) pnt+12, value); break; } len -= pnt[2]; pnt += pnt[2]; }}static void FDECL1(increment_nlink, struct directory_entry *, s_entry){ unsigned char * pnt; int len, nlink; pnt = s_entry->rr_attributes; len = s_entry->total_rr_attr_size; while(len) { if(pnt[0] == 'P' && pnt[1] == 'X') { nlink = get_733((char *) pnt+12); set_733((char *) pnt+12, nlink+1); break; } len -= pnt[2]; pnt += pnt[2]; }}void finish_cl_pl_entries(){ struct directory_entry *s_entry, *s_entry1; struct directory * d_entry; /* 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 }; /* 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); /* 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); 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; };}/* * 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: */intFDECL3(scan_directory_tree,struct directory *, this_dir, char *, path, struct directory_entry *, de){ DIR * current_dir; char whole_path[1024]; struct dirent * d_entry; struct directory * parent; int dflag; char * old_path; if (verbose > 1) { fprintf(stderr, "Scanning %s\n", path); } 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) 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] &= ~2; /* 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; /* * 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; } } 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -