📄 multi.c
字号:
{ return NULL; } pri = (struct iso_primary_descriptor *)vdp; /* * Check the blocksize of the image to make sure it is compatible. */ if( (isonum_723 ((unsigned char *) pri->logical_block_size) != SECTOR_SIZE) || (isonum_723 ((unsigned char *) pri->volume_set_size) != 1) ) { return NULL; } /* * Get the location and size of the root directory. */ rootp = (struct iso_directory_record *) malloc(sizeof(struct iso_directory_record)); memcpy(rootp, pri->root_directory_record, sizeof(*rootp)); return rootp;}void FDECL3(merge_remaining_entries, struct directory *, this_dir, struct directory_entry **, pnt, int, n_orig){ int i; struct directory_entry * s_entry; unsigned int ttbl_extent = 0; unsigned int ttbl_index = 0; char whole_path[1024]; /* * Whatever is leftover in the list needs to get merged back * into the directory. */ for( i=0; i < n_orig; i++ ) { if( pnt[i] == NULL ) { continue; } if( pnt[i]->name != NULL && pnt[i]->whole_name == NULL) { /* * Set the name for this directory. */ strcpy(whole_path, this_dir->de_name); strcat(whole_path, SPATH_SEPARATOR); strcat(whole_path, pnt[i]->name); pnt[i]->whole_name = strdup(whole_path); } if( pnt[i]->name != NULL/* && strcmp(pnt[i]->name, "<translation table>") == 0 )*/ && strcmp(pnt[i]->name, trans_tbl) == 0 ) { ttbl_extent = isonum_733((unsigned char *) pnt[i]->isorec.extent); ttbl_index = i; continue; } /* * Skip directories for now - these need to be treated * differently. */ if( (pnt[i]->isorec.flags[0] & 2) != 0 ) { /* * FIXME - we need to insert this directory into the * tree, so that the path tables we generate will * be correct. */ if( (strcmp(pnt[i]->name, ".") == 0) || (strcmp(pnt[i]->name, "..") == 0) ) { free_directory_entry(pnt[i]); pnt[i] = NULL; continue; } else { merge_old_directory_into_tree(pnt[i], this_dir); } } pnt[i]->next = this_dir->contents; pnt[i]->filedir = this_dir; this_dir->contents = pnt[i]; pnt[i] = NULL; } /* * If we don't have an entry for the translation table, then * don't bother trying to copy the starting extent over. * Note that it is possible that if we are copying the entire * directory, the entry for the translation table will have already * been inserted into the linked list and removed from the old * entries list, in which case we want to leave the extent number * as it was before. */ if( ttbl_extent == 0 ) { return; } /* * Finally, check the directory we are creating to see whether * there are any new entries in it. If there are not, we can * reuse the same translation table. */ for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { /* * Don't care about '.' or '..'. They are never in the table * anyways. */ if( s_entry->name != NULL && strcmp(s_entry->name, ".") == 0 ) { continue; } if( s_entry->name != NULL && strcmp(s_entry->name, "..") == 0 ) { continue; }/* if( strcmp(s_entry->name, "<translation table>") == 0)*/ if( strcmp(s_entry->name, trans_tbl) == 0) { continue; } if( (s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0 ) { return; } } /* * Locate the translation table, and re-use the same extent. * It isn't clear that there should ever be one in there already * so for now we try and muddle through the best we can. */ for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) {/* if( strcmp(s_entry->name, "<translation table>") == 0)*/ if( strcmp(s_entry->name, trans_tbl) == 0) { fprintf(stderr,"Should never get here\n"); set_733(s_entry->isorec.extent, ttbl_extent); return; } } pnt[ttbl_index]->next = this_dir->contents; pnt[ttbl_index]->filedir = this_dir; this_dir->contents = pnt[ttbl_index]; pnt[ttbl_index] = NULL;}/* * Here we have a case of a directory that has completely disappeared from * the face of the earth on the tree we are mastering from. Go through and * merge it into the tree, as well as everything beneath it. * * Note that if a directory has been moved for some reason, this will * incorrectly pick it up and attempt to merge it back into the old * location. FIXME(eric). */static intFDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, struct directory *, parent){ struct directory_entry **contents = NULL; int i; int n_orig; struct directory * this_dir, *next_brother; char whole_path[1024]; this_dir = (struct directory *) e_malloc(sizeof(struct directory)); memset(this_dir, 0, sizeof(struct directory)); this_dir->next = NULL; this_dir->subdir = NULL; this_dir->self = dpnt; this_dir->contents = NULL; this_dir->size = 0; this_dir->extent = 0; this_dir->depth = parent->depth + 1; this_dir->parent = parent; if(!parent->subdir) parent->subdir = this_dir; else { next_brother = parent->subdir; while(next_brother->next) next_brother = next_brother->next; next_brother->next = this_dir; } /* * Set the name for this directory. */ strcpy(whole_path, parent->de_name); strcat(whole_path, SPATH_SEPARATOR); strcat(whole_path, dpnt->name); this_dir->de_name = strdup(whole_path); this_dir->whole_name = strdup(whole_path); /* * Now fill this directory using information from the previous * session. */ contents = read_merging_directory(&dpnt->isorec, &n_orig); /* * Start by simply copying the '.', '..' and non-directory * entries to this directory. Technically we could let * merge_remaining_entries handle this, but it gets rather confused * by the '.' and '..' entries. */ for(i=0; i < n_orig; i ++ ) { /* * We can always reuse the TRANS.TBL in this particular case. */ contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; if( ((contents[i]->isorec.flags[0] & 2) != 0) && (i >= 2) ) { continue; } /* * If we have a directory, don't reuse the extent number. */ if( (contents[i]->isorec.flags[0] & 2) != 0 ) { memset(contents[i]->isorec.extent, 0, 8); if( strcmp(contents[i]->name, ".") == 0 ) this_dir->dir_flags |= DIR_HAS_DOT; if( strcmp(contents[i]->name, "..") == 0 ) this_dir->dir_flags |= DIR_HAS_DOTDOT; } /* * Set the whole name for this file. */ strcpy(whole_path, this_dir->whole_name); strcat(whole_path, SPATH_SEPARATOR); strcat(whole_path, contents[i]->name); contents[i]->whole_name = strdup(whole_path); contents[i]->next = this_dir->contents; contents[i]->filedir = this_dir; this_dir->contents = contents[i]; contents[i] = NULL; } /* * Zero the extent number for ourselves. */ memset(dpnt->isorec.extent, 0, 8); /* * Anything that is left are other subdirectories that need to be merged. */ merge_remaining_entries(this_dir, contents, n_orig); free_mdinfo(contents, n_orig);#if 0 /* * This is no longer required. The post-scan sort will handle * all of this for us. */ sort_n_finish(this_dir);#endif return 0;}char * cdrecord_data = NULL;intFDECL1(get_session_start, int *, file_addr) { char * pnt;#ifdef CDRECORD_DETERMINES_FIRST_WRITABLE_ADDRESS /* * FIXME(eric). We need to coordinate with cdrecord to obtain * the parameters. For now, we assume we are writing the 2nd session, * so we start from the session that starts at 0. */ *file_addr = (16 << 11); /* * We need to coordinate with cdrecord to get the next writable address * from the device. Here is where we use it. */ session_start = last_extent = last_extent_written = cdrecord_result();#else if( cdrecord_data == NULL ) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Special parameters for cdrecord not specified with -C\n");#else fprintf(stderr,"Special parameters for cdrecord not specified with -C\n"); exit(1);#endif } /* * Next try and find the ',' in there which delimits the two numbers. */ pnt = strchr(cdrecord_data, ','); if( pnt == NULL ) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Malformed cdrecord parameters\n");#else fprintf(stderr, "Malformed cdrecord parameters\n"); exit(1);#endif } *pnt = '\0'; if (file_addr != NULL) { *file_addr = atol(cdrecord_data) * SECTOR_SIZE; } pnt++; session_start = last_extent = last_extent_written = atol(pnt); pnt--; *pnt = ',';#endif return 0;}/* * This function scans the directory tree, looking for files, and it makes * note of everything that is found. We also begin to construct the ISO9660 * directory entries, so that we can determine how large each directory is. */intFDECL2(merge_previous_session,struct directory *, this_dir, struct iso_directory_record *, mrootp){ struct directory_entry **orig_contents = NULL; struct directory_entry * odpnt = NULL; int n_orig; struct directory_entry * s_entry; int status, lstatus; struct stat statbuf, lstatbuf; int retcode; /* * Parse the same directory in the image that we are merging * for multisession stuff. */ orig_contents = read_merging_directory(mrootp, &n_orig); if( orig_contents == NULL ) { return 0; }/* Now we scan the directory itself, and look at what is inside of it. */ for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) { status = stat_filter(s_entry->whole_name, &statbuf); lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); /* * We always should create an entirely new directory tree whenever * we generate a new session, unless there were *no* changes whatsoever * to any of the directories, in which case it would be kind of pointless * to generate a new session. * * I believe it is possible to rigorously prove that any change anywhere * in the filesystem will force the entire tree to be regenerated * because the modified directory will get a new extent number. Since * each subdirectory of the changed directory has a '..' entry, all of * them will need to be rewritten too, and since the parent directory * of the modified directory will have an extent pointer to the directory * it too will need to be rewritten. Thus we will never be able to reuse * any directory information when writing new sessions. * * We still check the previous session so we can mark off the equivalent * entry in the list we got from the original disc, however. */ /* * The check_prev_session function looks for an identical entry in * the previous session. If we see it, then we copy the extent * number to s_entry, and cross it off the list. It returns 2 if it's a directory */ retcode = check_prev_session(orig_contents, n_orig, s_entry, &statbuf, &lstatbuf, &odpnt); if (retcode == -1) return (-1); if(retcode==2 && odpnt != NULL) { int dflag; if (strcmp(s_entry->name,".") != 0 && strcmp(s_entry->name,"..") != 0) { struct directory * child; /* * 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. */ child = find_or_create_directory(this_dir, s_entry->whole_name, s_entry, 1); dflag = merge_previous_session(child, &odpnt->isorec); if (dflag == -1) return (-1); free(odpnt); odpnt = NULL; } } } /* * Whatever is left over, are things which are no longer in the tree * on disk. We need to also merge these into the tree. */ merge_remaining_entries(this_dir, orig_contents, n_orig); free_mdinfo(orig_contents, n_orig); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -