On Mon, 2003-07-21 at 19:07, Patrick Ohly wrote: > Hello everyone, > > I have updated the patch that adds -root and -old-root > to mkisofs. It is now based on cdrtools 2.01a16,
I have updated the patch again to apply cleanly against 2.01a26pre. Patching the man page and a function prototype caused conflicts while the rest applied still fine. -- Bye, Patrick Ohly -- [EMAIL PROTECTED] [EMAIL PROTECTED] (MakeCD related mails) http://home.pages.de/~ohly/ http://makecd.core.de/ (MakeCD home page)
diff -r -c cdrtools-2.01a26pre/mkisofs/mkisofs.8 cdrtools-2.01a26pre-patched/mkisofs/mkisofs.8 *** cdrtools-2.01a26pre/mkisofs/mkisofs.8 Mon Dec 29 14:34:17 2003 --- cdrtools-2.01a26pre-patched/mkisofs/mkisofs.8 Sun Feb 15 17:08:58 2004 *************** *** 480,485 **** --- 480,534 ---- .I \-graft\-points has been specified. .TP + .BI \-root " dir + Moves all files and directories into + .I dir + in the image. This is essentially the + same as using + .B -graft-points + and adding + .I dir + in front of every pathspec, but is easier to use. + + .I dir + may actually be several levels deep. It is + created with the same permissions as other graft points. + .TP + .BI \-old-root " dir + This option is necessary when writing a multisession + image and the previous (or even older) session was written with + .BI -root " dir. + Using a directory name not found in the previous session + causes + .B mkisofs + to abort with an error. + + Without this option, + .B mkisofs + would not be able to find unmodified files and would + be forced to write their data into the image once more. + + .B \-root + and + .B \-old-root + are meant to be used together to do incremental backups. + The initial session would e.g. use: + mkisofs \-root backup_1 <dirs>. + The next incremental backup with mkisofs \-root backup_2 + \-old-root backup_1 <dirs> + would take another snapshot of these directories. The first + snapshot would be found in backup_1, the second one in + backup_2, but only modified or new files need to be written + into the second session. + + Without these options, new files would be added and old ones would be + preserved. But old ones would be overwritten if the file was + modified. Recovering the files by copying the whole directory back + from CD would also restore files that were deleted + intentionally. Accessing several older versions of a file requires + support by the operating system to choose which sessions are to be + mounted. + .TP .BI \-hide " glob Hide .I glob diff -r -c cdrtools-2.01a26pre/mkisofs/mkisofs.c cdrtools-2.01a26pre-patched/mkisofs/mkisofs.c *** cdrtools-2.01a26pre/mkisofs/mkisofs.c Wed Jan 7 00:23:46 2004 --- cdrtools-2.01a26pre-patched/mkisofs/mkisofs.c Sun Feb 15 17:10:08 2004 *************** *** 420,425 **** --- 420,428 ---- #define OPTION_HFS_BLESS 2040 #define OPTION_HFS_PARMS 2041 + #define OPTION_RELOC_ROOT 2042 + #define OPTION_RELOC_OLD_ROOT 2043 + #endif /* APPLE_HYB */ static int save_pname = 0; *************** *** 481,486 **** --- 484,493 ---- ONE_DASH}, {{"graft-points", no_argument, NULL, OPTION_USE_GRAFT}, '\0', NULL, "Allow to use graft points for filenames", ONE_DASH}, + {{"root", required_argument, NULL, OPTION_RELOC_ROOT}, + '\0', "DIR", "Set root directory for all new files and directories", ONE_DASH}, + {{"old-root", required_argument, NULL, OPTION_RELOC_OLD_ROOT}, + '\0', "DIR", "Set root directory in previous session that is searched for files", ONE_DASH}, {{"help", no_argument, NULL, OPTION_HELP}, '\0', NULL, "Print option help", ONE_DASH}, {{"hide", required_argument, NULL, OPTION_I_HIDE}, *************** *** 1145,1150 **** --- 1152,1159 ---- #endif struct stat statbuf; char *merge_image = NULL; + char *reloc_root = NULL; + char *reloc_old_root = NULL; struct iso_directory_record *mrootp = NULL; struct output_fragment *opnt; int longind; *************** *** 1521,1526 **** --- 1530,1541 ---- case 'M': merge_image = optarg; break; + case OPTION_RELOC_ROOT: + reloc_root = optarg; + break; + case OPTION_RELOC_OLD_ROOT: + reloc_old_root = optarg; + break; case 'N': omit_version_number++; warn_violate++; *************** *** 2647,2652 **** --- 2662,2673 ---- memset(&de, 0, sizeof (de)); + /* + * PO: + * Isn't root NULL at this time anyway? + * I think it is created by the first call to + * find_or_create_directory() below. + */ de.filedir = root; /* We need this to bootstrap */ if (cdrecord_data != NULL && merge_image == NULL) { *************** *** 2764,2776 **** short_name = NULL; ! if (node != NULL) { char *pnt; char *xpnt; ! *node = '\0'; ! escstrcpy(graft_point, arg); ! *node = '='; /* * Remove unwanted "./" & "/" sequences from start... --- 2785,2812 ---- short_name = NULL; ! if (node != NULL || reloc_root) { char *pnt; char *xpnt; + size_t len; + + /* insert -root prefix */ + if (reloc_root != NULL) { + strcpy(graft_point, reloc_root); + len = strlen(graft_point); + if (graft_point[len] != '/' ) { + graft_point[len] = '/'; + len++; + } + } else { + len = 0; + } ! if (node) { ! *node = '\0'; ! escstrcpy(graft_point + len, arg); ! *node = '='; ! } /* * Remove unwanted "./" & "/" sequences from start... *************** *** 2785,2791 **** strcpy(graft_point, xpnt); } while (xpnt > graft_point); ! node = escstrcpy(nodename, ++node); graft_dir = root; xpnt = graft_point; --- 2821,2831 ---- strcpy(graft_point, xpnt); } while (xpnt > graft_point); ! if (node) { ! node = escstrcpy(nodename, ++node); ! } else { ! node = arg; ! } graft_dir = root; xpnt = graft_point; *************** *** 2945,2951 **** * side, since we may need to create some additional directories. */ if (merge_image != NULL) { ! if (merge_previous_session(root, mrootp) < 0) { #ifdef USE_LIBSCHILY comerrno(EX_BAD, "Cannot merge previous session.\n"); #else --- 2985,2992 ---- * side, since we may need to create some additional directories. */ if (merge_image != NULL) { ! if (merge_previous_session(root, mrootp, ! reloc_root, reloc_old_root) < 0) { #ifdef USE_LIBSCHILY comerrno(EX_BAD, "Cannot merge previous session.\n"); #else diff -r -c cdrtools-2.01a26pre/mkisofs/mkisofs.h cdrtools-2.01a26pre-patched/mkisofs/mkisofs.h *** cdrtools-2.01a26pre/mkisofs/mkisofs.h Sun Dec 28 14:38:51 2003 --- cdrtools-2.01a26pre-patched/mkisofs/mkisofs.h Sun Feb 15 17:02:57 2004 *************** *** 496,502 **** struct directory_entry * dpnt)); extern int rr_flags __PR((struct iso_directory_record *idr)); extern int merge_previous_session __PR((struct directory *, ! struct iso_directory_record *)); extern int get_session_start __PR((int *)); /* joliet.c */ --- 496,502 ---- struct directory_entry * dpnt)); extern int rr_flags __PR((struct iso_directory_record *idr)); extern int merge_previous_session __PR((struct directory *, ! struct iso_directory_record *, char *, char *)); extern int get_session_start __PR((int *)); /* joliet.c */ diff -r -c cdrtools-2.01a26pre/mkisofs/multi.c cdrtools-2.01a26pre-patched/mkisofs/multi.c *** cdrtools-2.01a26pre/mkisofs/multi.c Wed Apr 30 00:18:10 2003 --- cdrtools-2.01a26pre-patched/mkisofs/multi.c Sun Feb 15 17:02:57 2004 *************** *** 1530,1538 **** * directory entries, so that we can determine how large each directory is. */ int ! merge_previous_session(this_dir, mrootp) struct directory *this_dir; struct iso_directory_record *mrootp; { struct directory_entry **orig_contents = NULL; struct directory_entry *odpnt = NULL; --- 1530,1540 ---- * directory entries, so that we can determine how large each directory is. */ int ! merge_previous_session(this_dir, mrootp, reloc_root, reloc_old_root) struct directory *this_dir; struct iso_directory_record *mrootp; + char *reloc_root; + char *reloc_old_root; { struct directory_entry **orig_contents = NULL; struct directory_entry *odpnt = NULL; *************** *** 1544,1558 **** --- 1546,1677 ---- lstatbuf; int retcode; + /* skip leading slash */ + while (reloc_old_root && reloc_old_root[0] == PATH_SEPARATOR) { + reloc_old_root++; + } + while (reloc_root && reloc_root[0] == PATH_SEPARATOR) { + reloc_root++; + } + /* * 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) { + if (reloc_old_root) { + #ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Reading old session failed, cannot execute -old-root.\n"); + #else + fprintf(stderr, "Reading old session failed, cannot execute -old-root.\n"); + #endif + return (-1); + } return (0); } + if (reloc_old_root && reloc_old_root[0]) { + struct directory_entry **new_orig_contents = orig_contents; + int new_n_orig = n_orig; + + /* decend until we reach the original root */ + while (reloc_old_root[0]) { + int i; + char *next; + int last; + + for (next = reloc_old_root; *next && *next != PATH_SEPARATOR; next++); + if (*next) { + last = 0; + *next = 0; + next++; + } else { + last = 1; + } + while (*next == PATH_SEPARATOR) { + next++; + } + + for (i = 0; i < new_n_orig; i++) { + struct iso_directory_record subroot; + + if (new_orig_contents[i]->name != NULL + && strcmp(new_orig_contents[i]->name, reloc_old_root) != 0) { + /* Not the same name continue */ + continue; + } + /* + * enter directory, free old one only if not the top level, + * which is still needed + */ + subroot = new_orig_contents[i]->isorec; + if (new_orig_contents != orig_contents) { + free_mdinfo(new_orig_contents, new_n_orig); + } + new_orig_contents = read_merging_directory(&subroot, &new_n_orig); + + if (!new_orig_contents) { + #ifdef USE_LIBSCHILY + comerrno(EX_BAD, "Reading directory %s in old session failed, cannot execute -old-root.\n", reloc_old_root ); + #else + fprintf(stderr, "Reading directory %s in old session failed, cannot execute -old-root.\n", reloc_old_root ); + #endif + return (-1); + } + + i = -1; + break; + } + + if (i == new_n_orig) { + #ifdef USE_LIBSCHILY + comerrno(EX_BAD, "-old-root (sub)directory %s not found in old session.\n", reloc_old_root ); + #else + fprintf(stderr, "-old-root (sub)directory %s not found in old session.\n", reloc_old_root ); + #endif + return (-1); + } + + /* restore string, proceed to next sub directory */ + if (!last) { + reloc_old_root[strlen(reloc_old_root)] = PATH_SEPARATOR; + } + reloc_old_root = next; + } + + /* + * preserve the old session, skipping those dirs/files that are found again + * in the new root + */ + 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); + + /* check_prev_session() will search for s_entry and remove it from + orig_contents if found */ + retcode = check_prev_session(orig_contents, n_orig, s_entry, + &statbuf, &lstatbuf, NULL); + if (retcode == -1) + return (-1); + } + merge_remaining_entries(this_dir, orig_contents, n_orig); + + /* use new directory */ + free_mdinfo(orig_contents, n_orig); + orig_contents = new_orig_contents; + n_orig = new_n_orig; + + if (reloc_root && reloc_root[0]) { + /* also decend into new root before searching for files */ + this_dir = find_or_create_directory(this_dir, reloc_root, NULL, TRUE); + if (!this_dir) { + return (-1); + } + } + } + + /* * Now we scan the directory itself, and look at what is inside of it. */ *************** *** 1613,1619 **** s_entry->whole_name, s_entry, 1); dflag = merge_previous_session(child, ! &odpnt->isorec); if (dflag == -1) { return (-1); } --- 1732,1739 ---- s_entry->whole_name, s_entry, 1); dflag = merge_previous_session(child, ! &odpnt->isorec, ! NULL, reloc_old_root ); if (dflag == -1) { return (-1); } *************** *** 1623,1633 **** } } ! /* ! * 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); } --- 1743,1755 ---- } } ! if (!reloc_old_root) { ! /* ! * 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); }