Destination directory patch

View: New views
16 Messages — Rating Filter:   Alert me  

Destination directory patch

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

   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 patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

--- 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 patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

--- 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 patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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
 


Parent Message unknown Re: Destination directory patch

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

   Hi,
 
> --- On Fri, 23/7/10, Sergey Poznyakoff <gray@...>
> wrote:
> > Yes, if the target directory is not absolute.

    Not just relative paths, it'll create problems whenever change_directory_option != directory_name.
 
  if (change_directory_option && !ISSLASH (directory_name[0]))
 
   - checking `change_directory_option' makes no difference here. In fact if change_directory_option is NULL, and directory_name[0] != '/', then this will fail, because directory_name is not an absolute path.
 
     {
       char *pwd = xgetcwd ();
 
       dirname_len += strlen (pwd) + 1;
       ds_init (&output_name, dirname_len + 2);
       strcpy (output_name.ds_string, pwd);
       strcat (output_name.ds_string, "/");
       strcat (output_name.ds_string, directory_name);
     }
   else
     {
       ds_init (&output_name, dirname_len > + 2);
       strcpy (output_name.ds_string, directory_name);
     }
 
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]
 
Also change_dir() could create problems if the input file paths are relative to the current directory.
 
 $ cpio -dD /tmp/dir1 -p /tmp/dir2 < ../input-file1 ./abc/input-file2 ...


Second, ./bootstrap and ./configure works but make still fails with
 
...
Making all in src
Making all in po
*** error: gettext infrastructure mismatch: using a
Makefile.in.in from gettext version 0.17 but the autoconf
macros are from gettext version 0.18
make[2]: *** [check-macro-version] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
 
hope that helps.
---
Regards
    -Prasad
PS: Please don't send me html/attachment/Fwd mails





Re: Re: Destination directory patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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 patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

--- 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

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

--- 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 patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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 patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

   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 patch

by Sergey Poznyakoff-2 :: Rate this Message:

| View Threaded | Show Only this Message

P 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

by P J P-2 :: Rate this Message:

| View Threaded | Show Only this Message

--- 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