4

From the info cpio page:

If you wanted to archive an entire directory tree, the find command can provide the file list to cpio:

 % find . -print -depth | cpio -ov > tree.cpio

The '-depth' option forces 'find' to print of the entries in a directory before printing the directory itself. This limits the effects of restrictive directory permissions by printing the directory entries in a directory before the directory name itself.

What does this last part mean? How does printing the directory entries in a directory before the directory name itself limit the effects of restrictive directory permissions?

2 Answers 2

2

Most cpio implementations are dumb and do not manage directory permissions while unpacking archives.

If a directory has no write access and the cpio archive is in the usual order from find, the directory would be first in the cpio archive and unpacked first from the cpio archive. When such a "readonly" directory has been unpacked and given it's permissions, it has no permissions to put files into when later the directory content is seen in the archive and going to be unpacked.

  • one solution for this cpio problem is to create archives where the content of a directory comes first and the related directory comes after the content. This causes cpio to create the missing directory (if called with -d to create missing directories) with default permissions, extract the files inside from the archive and later, when the directory is seen in the archive, set the permissions to "readonly".

  • another solution is to extract the archive with a dumb cpio implementation as root, since root is permitted to create files even inside a readonly directory.

  • the third solution is to use a modern cpio implementation like the cpio emulation inside star. star remembers the directory permissions from the archive, but creates the directory with intermediate write permissions first. The remembered real directory permissions are set delayed by star, after the files in the archive have been extracted into the directory with intermediate write permission.

6
  • 2
    Note that GNU cpio, bsdtar, cpio on BSDs (well, I've only tested FreeBSD) don't have the problem either, I suppose it's mostly about traditional SysV derived Unices like Solaris (and busybox), not most. Jul 3, 2018 at 6:00
  • The idea for the solution is from the real BSD tar (not the one you may know) from 1985 but originally for mtimes only. Star implemented it in 1988 for times and GNU tar in the mid 1990s AFAIR. The current BSD implementations are based on libarchive that seem to be OK. GNU cpio was unmaintained since 1995 and is typically not on Linux. What did you check? BTW: README.otherbugs from the star distro for a list of funny bugs.
    – schily
    Jul 3, 2018 at 6:46
  • not sure what you mean about GNU cpio, git.savannah.gnu.org/cgit/cpio.git looks maintained to me and is definitely available on GNU/Linux OSes and the one that is installed on most of the systems I use (probably installed by default). Jul 3, 2018 at 7:07
  • GNU cpio was dead for many years because the maintainer was attacked by RMS. Looking at the git still does not show a high development activity. As an example: `star' had approx. one edit every two days sustained during the past 20 years. The 16 years before, it was a bit less. BTW: the directory stack feature has been added in 2004 to GNU cpio.
    – schily
    Jul 3, 2018 at 9:08
  • The ChangeLog shows activity throughout the years. cpio is an archaic format, the main reason it's still installed on Linux systems (and it being available in busybox) is that it's used for the initramfs. There's no reason there be much development on it other than make sure it still compiles on newer systems and address bugs and security vulnerabilities. Jul 3, 2018 at 9:32
1

The OSX (and therefore BSD) version of the find man page states the following:

 -d      Cause find to perform a depth-first traversal, i.e., directories 
         are visited in post-order and all entries in a directory will 
         be acted on before the directory itself.  By default, find visits 
         directories in pre-order, i.e., before their contents.  Note, 
         the default is not a breadth-first traversal.

         This option is equivalent to the -depth primary of IEEE Std 
         1003.1-2001 (``POSIX.1'').  The -d option can be useful when find 
         is used with cpio(1) to process files that are contained in 
         directories with unusual permissions.  It ensures that you have 
         write permission while you are placing files in a directory, 
         then sets the directory's permissions as the last thing.

The last sentence explains why, somewhat better???

The purpose of the -depth switch is to force find to go deep in every directory it finds until it hits the "leaf nodes", which it will then print.

NOTE: The -depth forces sub-directories to be processed before their parents.

By utilizing the -depth switch, you're guaranteeing that find will not get tripped up when carrying parent directories forward to the cpio command which may be overly restrictive, and not allow for lower level directories to get created due to your userid not being allowed full read/execute privileges.

  • -depth option (really a criterion that is always true) forces the output to be depth-first - that is, files first and then the directories containing them. This helps when the directories have restrictive permissions, and restoring the directory first could prevent the files from restoring at all (and would change the time stamp on the directory in any case). Normally, find returns the directory first, before any of the files in that directory.

References

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .