📄 multi.c
字号:
* Set this information so that we correctly cache previous * session bits of information. */ (*pnt)->inode = (*pnt)->starting_block; (*pnt)->dev = PREV_SESS_DEV; (*pnt)->rr_attributes = NULL; (*pnt)->rr_attr_size = 0; (*pnt)->total_rr_attr_size = 0; (*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY; /* * Check for and parse any RR attributes for the file. * All we are really looking for here is the original name * of the file. */ rlen = idr->length[0] & 0xff; cpnt = (unsigned char *) idr; rlen -= offsetof(struct iso_directory_record, name[0]); cpnt += offsetof(struct iso_directory_record, name[0]); rlen -= idr->name_len[0]; cpnt += idr->name_len[0]; if((idr->name_len[0] & 1) == 0){ cpnt++; rlen--; }; if (no_rr) rlen = 0; if( rlen != 0 ) { (*pnt)->total_rr_attr_size = (*pnt)->rr_attr_size = rlen; (*pnt)->rr_attributes = e_malloc(rlen); memcpy((*pnt)->rr_attributes, cpnt, rlen); seen_rockridge = 1; } /* * Now zero out the remainder of the name field. */ cpnt = (unsigned char *)(*pnt)->isorec.name; cpnt += idr->name_len[0]; memset(cpnt, 0, sizeof((*pnt)->isorec.name) - idr->name_len[0]); if (parse_rr((*pnt)->rr_attributes, rlen, *pnt) == -1) {#ifdef USE_LIBSCHILY comerrno(EX_BAD, "Cannot parse Rock Ridge attributes for '%s'.\n", idr->name);#else fprintf(stderr, "Cannot parse Rock Ridge attributes for '%s'.\n", idr->name); exit(1);#endif } if( ((*pnt)->isorec.name_len[0] == 1) && ( ((*pnt)->isorec.name[0] == 0) /* "." entry */ || ((*pnt)->isorec.name[0] == 1)) ) /* ".." entry */ { if( (*pnt)->name != NULL ) { free((*pnt)->name); } if( (*pnt)->whole_name != NULL ) { free((*pnt)->whole_name); } if( (*pnt)->isorec.name[0] == 0 ) { (*pnt)->name = strdup("."); } else { (*pnt)->name = strdup(".."); } }#ifdef DEBUG fprintf(stderr, "got DE name: %s\n", (*pnt)->name);#endif if( strncmp(idr->name, trans_tbl, strlen(trans_tbl)) == 0) { if( (*pnt)->name != NULL ) { free((*pnt)->name); } if( (*pnt)->whole_name != NULL ) { free((*pnt)->whole_name); }/* (*pnt)->name = strdup("<translation table>");*/ (*pnt)->name = strdup(trans_tbl); tt_extent = isonum_733((unsigned char *)idr->extent); tt_size = isonum_733((unsigned char *)idr->size); if (tt_extent == 0) tt_size = 0; } pnt++; i += idr->length[0]; } /* * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it * to get the filenames of the files. Also, save the table info, just * in case we need to use it. * * The entries look something like: * F ISODUMP.;1 isodump */ if( tt_extent != 0 && tt_size != 0 ) { nbytes = roundup(tt_size, SECTOR_SIZE); tt_buf = (unsigned char *) e_malloc(nbytes); readsecs(tt_extent, tt_buf, nbytes / SECTOR_SIZE); /* * Loop through the file, examine each entry, and attempt to * attach it to the correct entry. */ cpnt = tt_buf; cpnt1 = tt_buf; while( cpnt - tt_buf < tt_size ) { /* * Skip to a line terminator, or end of the file. */ while( (cpnt1 - tt_buf < tt_size) && (*cpnt1 != '\n') && (*cpnt1 != '\0') ) { cpnt1++; } /* * Zero terminate this particular line. */ if (cpnt1 - tt_buf < tt_size) { *cpnt1 = '\0'; } /* * Now dig through the actual directories, and * try and find the attachment for this particular * filename. */ for(pnt = rtn, i = 0; i <*nent; i++, pnt++) { rlen = isonum_711((*pnt)->isorec.name_len); /* * If this filename is so long that it would * extend past the end of the file, it cannot * be the one we want. */ if( cpnt + 2 + rlen - tt_buf >= tt_size) { continue; } /* * Now actually compare the name, and make sure that * the character at the end is a ' '. */ if( strncmp((char *) cpnt + 2, (*pnt)->isorec.name, rlen) == 0 && cpnt[2+rlen] == ' ') { /* * This is a keeper. Now determine the correct table * entry that we will use on the new image. */ if( strlen((char*)cpnt) > 33) { (*pnt)->table = e_malloc(strlen((char*)cpnt) - 33); sprintf((*pnt)->table, "%c\t%s\n", *cpnt, cpnt+37); } if( !(*pnt)->got_rr_name ) { if ((*pnt)->name != NULL) { free((*pnt)->name); } (*pnt)->name = strdup((char *) cpnt+37); } break; } } cpnt = cpnt1 + 1; cpnt1 = cpnt; } free(tt_buf); } else if( !seen_rockridge && !warning_given ) { /* * Warn the user that iso (8.3) names were used because neither * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were found. */ fprintf(stderr,"Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) \n"); fprintf(stderr,"name translations were found on previous session.\n"); fprintf(stderr,"ISO (8.3) file names have been used instead.\n"); warning_given = 1; } if( dirbuff != NULL ) { free(dirbuff); } return rtn;} /* read_merging_directory *//* * Free any associated data related to the structures. */int FDECL2(free_mdinfo, struct directory_entry ** , ptr, int, len ){ int i; struct directory_entry **p; p = ptr; for(i=0; i<len; i++, p++) { /* * If the tree-handling code decided that it needed an entry, * it will have removed it from the list. Thus we must allow * for null pointers here. */ if( *p == NULL ) { continue; } free_directory_entry(*p); } free(ptr); return 0;}static voidFDECL1(free_directory_entry, struct directory_entry *, dirp){ if(dirp->name != NULL) free(dirp->name); if(dirp->whole_name != NULL) free(dirp->whole_name); if(dirp->rr_attributes != NULL) free(dirp->rr_attributes); if(dirp->table != NULL) free(dirp->table); free(dirp);}/* * Search the list to see if we have any entries from the previous * session that match this entry. If so, copy the extent number * over so we don't bother to write it out to the new session. */intFDECL6(check_prev_session, struct directory_entry ** , ptr, int, len, struct directory_entry *, curr_entry, struct stat *, statbuf, struct stat *, lstatbuf, struct directory_entry **, odpnt){ int i; int rr; int retcode = 0; /* Default not found */ for( i=0; i < len; i++ ) { if( ptr[i] == NULL ) /* Used or empty entry skip */ { continue; }#if 0 if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 && ptr[i]->name[0] == '\0' ) { continue; } if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 && ptr[i]->name[0] == 1) { continue; }#else if( ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0 ) { continue; } if( ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0 ) { continue; }#endif if( ptr[i]->name != NULL && strcmp(ptr[i]->name, curr_entry->name) != 0 ) /* Not the same name continue */ { continue; } /* * It's a directory so we must always merge it * with the new session. * Never ever reuse directory extents. See comments in * tree.c for an explaination of why this must be the case. */ if( (curr_entry->isorec.flags[0] & 2) != 0 ) { retcode = 2; /* Flag directory case */ goto found_it; } /* * We know that the files have the same name. If they also have * the same file type (i.e. file, dir, block, etc), then we * can safely reuse the TRANS.TBL entry for this file. * The check_rr_dates function will do this for us. * * Verify that the file type and dates are consistent. * If not, we probably have a different file, and we need * to write it out again. */ retcode = 1; /* We found a non directory */ if (ptr[i]->rr_attributes != NULL) { if ((rr = check_rr_dates(ptr[i], curr_entry, statbuf, lstatbuf)) == -1) return (-1); if (rr==0) { /* Different files */ goto found_it; } } /* * Verify size and timestamp. If rock ridge is in use, we need * to compare dates from RR too. Directories are special, we * calculate their size later. */ if (ptr[i]->size != curr_entry->size ) { /* Different files */ goto found_it; } if( memcmp(ptr[i]->isorec.date, curr_entry->isorec.date,7) != 0 ) { /* Different files */ goto found_it; } /* * We found it and we can reuse the extent */ memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8); curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; goto found_it; } return retcode;found_it: if( odpnt != NULL ) { *odpnt = ptr[i]; } else { free(ptr[i]); } ptr[i] = NULL; return retcode;}/* * open_merge_image: Open an existing image. */int FDECL1(open_merge_image, char *, path){#ifndef USE_SCG in_image = fopen(path, "rb"); if( in_image == NULL ) { return -1; }#else in_image = fopen(path, "rb"); if( in_image == NULL ) { if (scsidev_open(path) < 0) return -1; }#endif return 0;}/* * merge_isofs: Scan an existing image, and return a pointer * to the root directory for this image. */struct iso_directory_record * FDECL1(merge_isofs, char *, path){ char buffer[SECTOR_SIZE]; int file_addr; int i; struct iso_primary_descriptor * pri = NULL; struct iso_directory_record * rootp; struct iso_volume_descriptor * vdp; /* * Start by searching for the volume header. * Ultimately, we need to search for volume headers in multiple places * because we might be starting with a multisession image. * FIXME(eric). */ get_session_start(&file_addr); for(i = 0; i< 100; i++) { if (readsecs(file_addr/SECTOR_SIZE, buffer, sizeof(buffer)/SECTOR_SIZE) != sizeof(buffer)) {#ifdef USE_LIBSCHILY comerr(" Read error on old image %s\n", path);#else fprintf(stderr," Read error on old image %s\n", path); exit(10);#endif } vdp = (struct iso_volume_descriptor *)buffer; if( (strncmp(vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) && (isonum_711((unsigned char *) vdp->type) == ISO_VD_PRIMARY) ) { break; } file_addr += SECTOR_SIZE; } if( i == 100 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -