|
View:
New views
16 Messages
—
Rating Filter:
Alert me
|
|
|
Destination directory patch Hi,
Please have a look at the patch below; It adds a new -D <DIR> option to cpio-2.11, where <DIR> is a destination directory for copy-in mode. See: http://pjp.dgplug.org/tools/cpio-2.11-destination-dir.patch Files changed: cpio-2.11/src/copyin.c: new function: prefix_directory_name(*file_hdr) cpio-2.11/src/extern.h: new constant: int destination_dir_flag; cpio-2.11/src/global.c: new constant: int destination_dir_flag = false; cpio-2.11/src/main.c: new option -D <DIR> Now the command works well, $ rpm2cpio bash-3.2-24.el5.x86_64.rpm | ./cpio -imdD bash I hope you find it useful. Do let me know if it needs any more changes. Thank you. --- Regards -Prasad PS: Please don't send me html/attachment/Fwd mails |
|
|
Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> Please have a look at the patch below; Thanks. It unnecessarily complicates the operation by allocating new filename for each archive member. Besides, it provides the -D option only for copy-in, whereas it can be useful in other modes too. I have implemented it another way. Attached is a patch. Regards, Sergey From cbc3c156df244df3985374da4cb1b7c83f163d6d Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff <gray@...> Date: Thu, 22 Jul 2010 11:34:56 +0300 Subject: [PATCH] Provide a tar-like --directory (-D) option. * src/copyin.c (process_copy_in): Call change_dir. * src/copyout.c (process_copy_out): Likewise. * src/copypass.c (process_copy_pass): Likewise. * src/extern.h (change_directory_option): New extern. (change_dir): New proto. * src/global.c (change_directory_option): New global. * src/main.c (options): New option --directory. (parse_opt): Handle the --directory option. * src/util.c (change_dir): New proto. * doc/cpio.texi: Document the --directory option. --- doc/cpio.texi | 32 ++++++++++++++++++++++++++++++++ src/copyin.c | 2 ++ src/copyout.c | 2 ++ src/copypass.c | 2 ++ src/extern.h | 2 ++ src/global.c | 2 ++ src/main.c | 7 +++++++ src/util.c | 18 ++++++++++++++++++ 8 files changed, 67 insertions(+), 0 deletions(-) diff --git a/doc/cpio.texi b/doc/cpio.texi index 1af808a..bcece3c 100644 --- a/doc/cpio.texi +++ b/doc/cpio.texi @@ -342,6 +342,38 @@ Set the I/O block size to @var{io-size} bytes. @itemx --make-directories Create leading directories where needed. +@item -D @var{dir} +@item --directory=@var{dir} +Change to the directory @var{dir} before starting the operation. This +can be used, for example, to extract an archive contents in a +different directory: + +@example +$ cpio -i -D /usr/local < archive +@end example + +@noindent +or to copy-pass files from one directory to another: + +@example +$ cpio -D /usr/bin -p /usr/local/bin < filelist +@end example + + The @option{-D} option does not affect file names supplied as +arguments to another command line options, such as @option{-F} +or @option{-E}. For example, the following invocation: + +@example +cpio -D /tmp/foo -d -i -F arc +@end example + +@noindent +instructs @command{cpio} to open the archive file @file{arc} in +the current working directory, then change to the directory +@file{/tmp/foo} and extract files to that directory. If +@file{/tmp/foo} does not exist, it will be created first (the +@option{-d} option) and then changed to. + @item -E @var{file} @itemx --pattern-file=@var{file} Read additional patterns specifying filenames to extract or list from diff --git a/src/copyin.c b/src/copyin.c index ac921e1..e1be4e2 100644 --- a/src/copyin.c +++ b/src/copyin.c @@ -1338,6 +1338,8 @@ process_copy_in () } output_is_seekable = true; + change_dir (); + /* While there is more input in the collection, process the input. */ while (!done) { diff --git a/src/copyout.c b/src/copyout.c index 7e6b624..e9849ff 100644 --- a/src/copyout.c +++ b/src/copyout.c @@ -625,6 +625,8 @@ process_copy_out () output_is_seekable = S_ISREG (file_stat.st_mode); } + change_dir (); + if (append_flag) { process_copy_in (); diff --git a/src/copypass.c b/src/copypass.c index d249a31..1fcc8b3 100644 --- a/src/copypass.c +++ b/src/copypass.c @@ -75,6 +75,8 @@ process_copy_pass () output_name.ds_string[dirname_len] = '/'; output_is_seekable = true; + change_dir (); + /* Copy files with names read from stdin. */ while (ds_fgetstr (stdin, &input_name, name_end) != NULL) { diff --git a/src/extern.h b/src/extern.h index 4f94d40..c25a6ef 100644 --- a/src/extern.h +++ b/src/extern.h @@ -97,6 +97,7 @@ extern char input_is_seekable; extern char output_is_seekable; extern int (*xstat) (); extern void (*copy_function) (); +extern char *change_directory_option; /* copyin.c */ @@ -200,6 +201,7 @@ void cpio_to_stat (struct stat *st, struct cpio_file_stat *hdr); void cpio_safer_name_suffix (char *name, bool link_target, bool absolute_names, bool strip_leading_dots); int cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir); +void change_dir (void); /* FIXME: These two defines should be defined in paxutils */ #define LG_8 3 diff --git a/src/global.c b/src/global.c index cff9720..29e7afc 100644 --- a/src/global.c +++ b/src/global.c @@ -193,3 +193,5 @@ int (*xstat) (); /* Which copy operation to perform. (-i, -o, -p) */ void (*copy_function) () = 0; + +char *change_directory_option; diff --git a/src/main.c b/src/main.c index ba1b969..4c1c033 100644 --- a/src/main.c +++ b/src/main.c @@ -108,6 +108,9 @@ static struct argp_option options[] = { {"file", 'F', N_("[[USER@]HOST:]FILE-NAME"), 0, N_("Use this FILE-NAME instead of standard input or output. Optional USER and HOST specify the user and host names in case of a remote archive"), GRID+1 }, + {"directory", 'D', N_("DIR"), 0, + N_("Change to directory DIR"), GRID+1 }, + {"force-local", FORCE_LOCAL_OPTION, 0, 0, N_("Archive file is local, even if its name contains colons"), GRID+1 }, {"format", 'H', N_("FORMAT"), 0, @@ -325,6 +328,10 @@ parse_opt (int key, char *arg, struct argp_state *state) create_dir_flag = true; break; + case 'D': + change_directory_option = arg; + break; + case 'f': /* Only copy files not matching patterns. */ copy_matching_files = false; break; diff --git a/src/util.c b/src/util.c index 00953d5..0faccbc 100644 --- a/src/util.c +++ b/src/util.c @@ -1618,3 +1618,21 @@ cpio_create_dir (struct cpio_file_stat *file_hdr, int existing_dir) return 0; } +void +change_dir () +{ + if (change_directory_option && chdir (change_directory_option)) + { + if (errno == ENOENT && create_dir_flag) + { + if (make_path (change_directory_option, -1, -1, + (warn_option & CPIO_WARN_INTERDIR) ? + _("Creating directory `%s'") : NULL)) + exit (PAXEXIT_FAILURE); + if (chdir (change_directory_option) == 0) + return; + } + error (PAXEXIT_FAILURE, errno, + _("cannot change to directory `%s'"), change_directory_option); + } +} -- 1.6.0.3 |
|
|
Re: Destination directory patch--- On Thu, 22/7/10, Sergey Poznyakoff <gray@...> wrote:
> Thanks. It unnecessarily complicates the operation by allocating new > filename for each archive member. Besides, it provides the > -D option only for copy-in, whereas it can be useful in other modes > too. I thought changing directory might not be a good option for it might break things in other places while reading/writing files. > I have implemented it another way. Attached is a patch. That's cool. Good to see that you've also documented the same. So has it been pushed to upstream? Another problem I faced was, the git clone does not build on F12. After bootstrap, the configure fails to create the Makefile for absence of the Make.rules file in the top directory. Thank you. --- Regards -Prasad PS: Please don't send me html/attachment/Fwd mails |
|
|
Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> So has it been pushed to upstream? Yes, it has. > After bootstrap, the configure fails to create the Makefile for > absence of the Make.rules file in the top directory. I've pushed a fix (3ac72b91f6). Regards, Sergey |
|
|
Re: Destination directory patch--- On Thu, 22/7/10, Sergey Poznyakoff <gray@...> wrote:
> Yes, it has. I think change_dir() could create problems in copy-pass mode. Because in src/copypass.c output_name.ds_string = directory_name + '/' + input_name.ds_string where directory_name = argv[index] in src/main.c, which could be different from change_directory_option. > > After bootstrap, the configure fails to create the > Makefile for > > absence of the Make.rules file in the top directory. > > I've pushed a fix (3ac72b91f6). I git cloned it today, it still has enough glitches. Make fails with $ make Making all in doc Making all in headers Making all in gnu Making all in lib make[3]: *** No rule to make target `exit.o', needed by `libpax.a'. Stop. make[2]: *** [all] Error 2 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2 After bootstrap, rmt directory and rmt/Makefile.in did not exist, I think configure failed for that. Let me know if this is right 1. $ git clone git://git.savannah.gnu.org/cpio.git cpio 2. $ cd cpio 3. $ ./bootstrap 4. $ ./configure 5. $ make Thanks. --- Regards -Prasad PS: Please don't send me html/attachment/Fwd mails |
|
|
Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> I think change_dir() could create problems in copy-pass > mode. Because in src/copypass.c Yes, if the target directory is not absolute. Fixed by commit 6377e0dfec. > I git cloned it today, it still has enough glitches. Make fails with Strange, I tried a fresh checkout and it worked for me. > make[3]: *** No rule to make target `exit.o', needed by `libpax.a'. Stop. [..] > After bootstrap, rmt directory and rmt/Makefile.in did not exist Both indicate that paxutils files were not copied. Regards, Sergey |
|
|
|
|
|
Re: Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> - checking `change_directory_option' makes no difference here. No, it does. When it is not set, cpio operates the way it did before. > fact if change_directory_option is NULL, and directory_name[0] != > '/', then this will fail, because directory_name is not an > absolute path. It is not required to be absolute. > In either case, output_name.ds_string starts with the directory_name, > which could be different from change_directory_option, because in > src/main.c directory_name = argv[index] Yes, it is intended. > Also change_dir() could create problems if the input file paths are > relative to the current directory. That's the question of creating proper file lists. It is not not related to cpio proper. Regards, Sergey |
|
|
Re: Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> Makefile.in.in from gettext version 0.17 but the autoconf > macros are from gettext version 0.18 You'll have to downgrade to gnulib e01b458f404. Regards, Sergey |
|
|
Re: Re: Destination directory patch--- On Fri, 23/7/10, Sergey Poznyakoff <gray@...> wrote:
> No, it does. When it is not set, cpio operates the > way it did before. I think even when `change_directory_option' is set, cpio operates the way it did before because the output_name.ds_sting starts with directory_name. > It is not required to be absolute. Yeah, but if change_directory_option is NULL, directory_name will be treated like an absolute path, even if if it is not absolute. > Yes, it is intended. It is intended that `change_directory_option' and `directory_name' have different values? --- Regards -Prasad PS: Please don't send me html/attachment/Fwd mails |
|
|
Re: Re: Destination directory patch--- On Fri, 23/7/10, Sergey Poznyakoff <gray@...> wrote:
> You'll have to downgrade to gnulib e01b458f404. Could you do $ make dist in the git repo and pass me the .tar.bz2 file of the latest changes? May be that'll build on my machine. Thanks. --- Regards -Prasad PS: Please don't send me html/attachment/Fwd mails |
|
|
Re: Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> It is intended that `change_directory_option' and `directory_name' > have different values? Yes, of course. They *must* have different values, otherwise -D is of no use. Looks like you did not understand its semantics. The change_directory_option supplies *source directory* and the directory_name gives *destination directory*. As an example, consider this: cpio -D /usr -p /usr/local < filelist (it is supposed that filelist contains names relative to /usr, of course). Regards, Sergey |
|
|
Re: Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> Could you [...] pass me the .tar.bz2 file of the latest changes? ftp://download.gnu.org.ua/pub/alpha/cpio/cpio-2.11.90.tar.bz2 |
|
|
Re: Re: Destination directory patch Hi, thanks for the tar file, it built properly.
--- On Sat, 24/7/10, Sergey Poznyakoff <gray@...> wrote: > Yes, of course. They *must* have different values, > otherwise -D is of no use. Looks like you did not understand its > semantics. The change_directory_option supplies *source directory* and > the directory_name gives *destination directory*. As an > example, consider this: That doesn't sound good. It's confusing. > cpio -D /usr -p /usr/local < filelist > > (it is supposed that filelist contains names relative to > /usr, of course). Here, the redirection will be done by the shell, so the paths in the file-list should either be absolute or relative to the current directory. Otherwise shell will say - No such file or directory. 1. While creating a cpio archive, the input/output files are redirected by the shell, there is no point in changing to any source directory. 2. While extraction it helps because files are extracted to the current working directory of the process. Which means -D <DIR> is a destination directory, rather than a source directory. 3. In copy-pass mode again, input files are redirected by the shell, and as per your semantics destination directory is given by directory_name, which renders -D <DIR> useless. I think the semantics needs some re-thinking. --- Regards -Prasad PS: Please don't send me html/attachment/Fwd mails |
|
|
Re: Re: Destination directory patchP J P <pj.pandit@...> ha escrit:
> That doesn't sound good. It's confusing. It's no more confusing than `cp source dest'. > Here, the redirection will be done by the shell, I'm not sure what you mean by redirection. > so the paths in the file-list should Once again: cpio makes no assumptions about the contents of the input file list. If it is wrong, than it is wrong. It is the user's responsibility to prepare appropriate and well-formed file lists. Regards, Sergey |
|
|
Re: Re: Destination directory patch--- On Sat, 24/7/10, Sergey Poznyakoff <gray@...> wrote:
> I'm not sure what you mean by redirection. Hmmn...my bad, for some reason I thought the files mentioned on the command-line are archived, whereas those files are suppose to provide appropriate file-paths to be archived. Thanks. --- Regards -Prasad PS: Please don't send me html/attachment/Fwd mails |
| Free embeddable forum powered by Nabble | Forum Help |