JSON: include a signature header
[girocco/readme.git] / toolbox / perlcpio.pl
blobc1bd2817124d3b8d0947e0d8e6e88a04d636d6da
1 #!/usr/bin/env perl
3 # perlcpio.pl - write ASCII cpio archive
5 # Copyright (C) 2020 Kyle J. McKay.
6 # All rights reserved.
8 # Permission to use, copy, modify, and distribute this software for any
9 # purpose with or without fee is hereby granted, provided that the above
10 # copyright notice and this permission notice appear in all copies.
12 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 # Version 1.0.0
22 use strict;
23 use warnings;
24 use bytes;
26 use File::Basename qw(basename);
27 use Getopt::Long;
28 use Pod::Usage;
29 BEGIN {
30 eval 'require Pod::Text::Termcap; 1;' and
31 @Pod::Usage::ISA = (qw( Pod::Text::Termcap ));
33 my $hascrc32;
34 BEGIN { $hascrc32 = eval 'use Compress::Zlib qw(crc32); 1;' }
35 my $me = basename($0);
36 close(DATA) if fileno(DATA);
38 exit(&main(@ARGV)||0);
40 my $die_nl; BEGIN { $die_nl = 0 }
41 sub dodie {
42 my $msg = join(" ", @_);
43 substr($msg, -1, 1) eq "\n" or $msg .= "\n";
44 $die_nl and $msg = "\n" . $msg;
45 $die_nl = 0;
46 die $msg;
48 sub dowarn {
49 my $msg = join(" ", @_);
50 substr($msg, -1, 1) eq "\n" and substr($msg, -1, 1) = "";
51 $die_nl and $msg = "\n" . $msg;
52 !$die_nl and $msg .= "\n";
53 print STDERR $msg;
55 sub dofn {
56 my $msg = join(" ", @_);
57 substr($msg, -1, 1) eq "\n" and substr($msg, -1, 1) = "";
58 if ($die_nl) {
59 print STDERR "\n", $msg;
60 } else {
61 $die_nl = 1;
62 print STDERR $msg;
65 sub donefn {
66 my $msg = join(" ", @_);
67 $msg eq "" || substr($msg, -1, 1) eq "\n" or $msg .= "\n";
68 $die_nl and $msg = "\n" . $msg;
69 $die_nl = 0;
70 print STDERR $msg;
73 my (
74 $opt_0, $opt_a, $opt_b, $opt_c, $opt_e, $opt_G, $opt_g, $opt_k, $opt_q,
75 $opt_r, $opt_U, $opt_u, $opt_v, $opt_w, $opt_z
78 my $totalbyteswritten; BEGIN { $totalbyteswritten = 0 }
79 my $crc32; BEGIN { $crc32 = undef }
80 my $ugid_mask; BEGIN { $ugid_mask = 0177777 }
82 sub is_uint18 {
83 my $opt = '-'.$_[0];
84 $_[1] =~ /^[0-9]+$/ or die "$opt requires an unsigned integer argument\n";
85 my $uint18 = 0 + $_[1];
86 0 <= $uint18 && $uint18 <= 0777777 or die "$opt value must be in range 0..262143\n";
87 return $uint18;
90 sub main {
91 local *ARGV = \@_;
92 select((select(STDERR),$|=1)[0]); # just in case
93 Getopt::Long::Configure('bundling');
94 GetOptions(
95 'h' => sub {pod2usage(-verbose => 0, -exitval => 0)},
96 'help' => sub {pod2usage(-verbose => 2, -exitval => 0)},
97 '0' => \$opt_0,
98 'a' => \$opt_a,
99 'b' => \$opt_b,
100 'c' => \$opt_c,
101 'e' => \$opt_e,
102 'G=s' => sub {$opt_G = is_uint18(@_)},
103 'g=s' => sub {$opt_g = is_uint18(@_)},
104 'k' => \$opt_k,
105 'q|quiet' => \$opt_q,
106 'r' => \$opt_r,
107 'U=s' => sub {$opt_U = is_uint18(@_)},
108 'u=s' => sub {$opt_u = is_uint18(@_)},
109 'v' => \$opt_v,
110 'w' => \$opt_w,
111 'z' => \$opt_z,
112 ) && !@ARGV or pod2usage(-verbose => 0, -exitval => 2);
113 $opt_w and $ugid_mask = 0777777;
114 $opt_c && $opt_a and
115 pod2usage(-msg => "$me: error: '-a' and '-c' may not be used together",
116 -verbose => 0, -exitval => 2);
117 $opt_b && $opt_r and
118 pod2usage(-msg => "$me: error: '-b' and '-r' may not be used together",
119 -verbose => 0, -exitval => 2);
120 $opt_c && !$hascrc32 and
121 die("$me: error: required Compress::Zlib module not found (needed for '-c')\n");
123 binmode(STDIN);
124 binmode(STDOUT);
126 $opt_0 and $/ = "\0";
127 while (my $line = <STDIN>) {
128 chomp $line;
129 $line =~ /\000/ and
130 die "$me: error: NUL encountered in file name, did you forget the '-0'?\n";
131 process_filename($line);
134 process_trailer() unless $opt_a;
136 return 0;
139 my @filetypes; BEGIN { @filetypes = (
140 0, # 0000000
141 1, # 0010000 FIFO
142 1, # 0020000 Char dev
143 0, # 0030000
144 1, # 0040000 Dir
145 0, # 0050000
146 1, # 0060000 Blk dev
147 0, # 0070000
148 1, # 0100000 File
149 0, # 0110000 Reserved (C_ISCTG)
150 1, # 0120000 Sym link
151 0, # 0130000
152 1, # 0140000 Socket
153 0, # 0150000
154 0, # 0160000
155 0, # 0170000
158 my $filenum; { $filenum = 0 }
159 my %hardlinks; { %hardlinks = () }
161 # NOTE: 077777777777 == 8589934591
162 # On a 32-bit system both bitand (&) and sprintf (%o) are
163 # limited to 32 bits. The result of this next bitand (&)
164 # will be 4294967295 on a 32-bit system, NOT 8589934591
165 my $maxfsize; BEGIN { $maxfsize = 8589934591 & 8589934591 }
167 sub nextfilenum($) {
168 ++$filenum;
169 $filenum <= 68719476735 or # 0777777777777 is 68719476735
170 die "$me: error: $_[0] counter overflowed 68719476735 limit\n";
171 return $filenum;
174 sub process_filename {
175 my $fn = shift;
176 if (length($fn) >= 0777777) { # need to leave one for the NUL
177 die "$me: error: pathname too long (>262142 chars): $fn\n" unless $opt_k;
178 warn "$me: warning: pathname too long (>262142 chars), skipping: $fn\n" unless $opt_q;
179 return; # skip it
181 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
182 $atime,$mtime,$ctime,$blksize,$blocks);
184 no warnings 'newline';
185 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
186 $atime,$mtime,$ctime,$blksize,$blocks) = lstat($fn);
188 if (!defined($mtime)) {
189 die "$me: error: could not lstat \"@{[vis($fn)]}\": $!\n" unless $opt_k;
190 warn "$me: warning: could not lstat \"@{[vis($fn)]}\", skipping: $!\n" unless $opt_q;
191 return; # skip it
193 if (($mode & ~07777) == 0100000) {
194 no warnings 'newline';
196 # There is, conceivably, a miniscule window after the lstat
197 # where a regular file could be replaced with something else
198 # that we then open here. There are various possible
199 # scenarios. The only one we currently handle is when what
200 # we successfully opened is not a regular file and the open
201 # succeeded (in which case we just close the handle).
203 open FILEDATA, '<', $fn or do {
204 die "$me: error: unable to read-only open \"$fn\": $!\n" unless $opt_k;
205 warn "$me: error: unable to read-only open \"$fn\", skipping: $!\n" unless $opt_q;
206 return; # skip it
208 binmode(FILEDATA);
209 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
210 $atime,$mtime,$ctime,$blksize,$blocks) = stat(FILEDATA);
211 defined($mtime) or do {
212 die "$me: error: could not stat read-only opened \"@{[vis($fn)]}\": $!\n" unless $opt_k;
213 warn "$me: error: could not stat read-only opened \"@{[vis($fn)]}\", skipping: $!\n" unless $opt_q;
214 close(FILEDATA);
215 return; # skip it
217 close(FILEDATA) if ($mode & ~07777) != 0100000; # it changed out from under us
219 my $ftype = $mode & ~07777;
220 my $data = undef;
221 if ($ftype == 0120000) {
222 $size <= $maxfsize or
223 die "$me: error: symlink size too large ($size > $maxfsize): $fn\n";
224 defined($data = readlink($fn)) or do {
225 die "$me: error: unable to read symlink \"$fn\": $!\n" unless $opt_k;
226 warn "$me: warning: unable to read symlink \"$fn\", skipping: $!\n" unless $opt_q;
227 return; # skip it
229 length($data) == $size or do {
230 die "$me: error: unable to correctly read symlink: \"$fn\"\n" unless $opt_k;
231 warn "$me: warning: unable to correctly read symlink: \"$fn\", skipping\n" unless $opt_q;
232 return; # skip it
234 $rdev = 0;
235 $nlink = 1;
236 } elsif ($ftype == 0100000) {
237 # leaving $data undef means write the contents of the file
238 $size <= $maxfsize or
239 die "$me: error: file size too large ($size > $maxfsize): $fn\n";
240 $rdev = 0;
241 } elsif ($ftype == 0040000) {
242 $nlink = 2 if $opt_e;
243 $rdev = 0;
244 $data = ""; # no data for directories
245 } else {
246 die "$me: error: unrecognizable file mode type for \"$fn\": " .
247 sprintf("0%06o\n", $ftype) if
248 $ftype != ($ftype & 0170000) || !$filetypes[$ftype >> 12];
249 $data = ""; # no data to write
251 $opt_z && $ftype != 0100000 and $dev = $ino = 0;
252 if (!$opt_z || $ftype == 0100000) {
253 if ($opt_b) {
254 nextfilenum("hard link breakage");
255 $dev = $filenum >> 18;
256 $ino = $filenum & 0777777;
257 $nlink = 1 if $ftype == 0100000;
258 } elsif ($opt_r) {
259 ($ino & 0777777) == $ino or do {
260 die "$me: error: st_ino value (@{[sprintf('0x%X',$ino)]}) outside 18-bit limit: $fn\n" unless $opt_k;
261 warn "$me: warning: st_ino value (@{[sprintf('0x%X',$ino)]}) outside 18-bit limit, truncated: $fn\n" unless $opt_q;
263 ($dev & 0777777) == $dev or do {
264 die "$me: error: st_dev value (@{[sprintf('0x%X',$dev)]}) outside 18-bit limit: $fn\n" unless $opt_k;
265 warn "$me: warning: st_dev value (@{[sprintf('0x%X',$dev)]}) outside 18-bit limit, truncated: $fn\n" unless $opt_q;
267 } else {
268 if ($ftype != 0100000 || $nlink <= 1) {
269 nextfilenum("unique file counter");
270 $dev = $filenum >> 18;
271 $ino = $filenum & 0777777;
272 $nlink = 1 if $ftype == 0100000;
273 } else {
274 my $key = '' . $dev . ',' . $ino;
275 if (!exists($hardlinks{$key})) {
276 nextfilenum("unique file counter");
277 $dev = $filenum >> 18;
278 $ino = $filenum & 0777777;
279 $hardlinks{$key} = [ $filenum, $size ];
280 } else {
281 my ($hlfnum, $hlsize) = @{$hardlinks{$key}};
282 if ($size == $hlsize) {
283 $dev = $hlfnum >> 18;
284 $ino = $hlfnum & 0777777;
285 } else {
286 die "$me: error: hard-linked file size ($size) does not match original ($hlsize) for: $fn\n" unless $opt_k;
287 warn "$me: warn: hard-linked file size ($size) does not match original ($hlsize), breaking hard-link for: $fn\n" unless $opt_q;
288 $nlink = 1;
289 nextfilenum("unique file counter");
290 $dev = $filenum >> 18;
291 $ino = $filenum & 0777777;
297 defined($data) and $size = length($data);
298 $mtime = $maxfsize if $mtime > $maxfsize;
299 $mtime = 0 if $mtime < 0;
300 $nlink = 07777777 if $nlink > 07777777;
301 if (defined($opt_U)) {
302 $uid = $opt_U;
303 } else {
304 $uid = defined($opt_u) ? $opt_u : ($uid & $ugid_mask)
305 if ($uid & $ugid_mask) != $uid;
307 if (defined($opt_G)) {
308 $gid = $opt_G;
309 } else {
310 $gid = defined($opt_g) ? $opt_g : ($gid & $ugid_mask)
311 if ($gid & $ugid_mask) != $gid;
313 my $hdr = sprintf("070707%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o%s\0",
314 ($dev & 0777777), ($ino & 0777777), ($mode & 0777777),
315 ($uid & 0777777), ($gid & 0777777), $nlink,
316 ($rdev & 0777777), $mtime, (length($fn) + 1), $size, $fn);
317 dofn($fn) if $opt_v;
318 writeall($hdr) or
319 dodie "$me: error: writeall failed writing cpio file header: $!\n";
320 $crc32 = crc32($hdr, $crc32) if $opt_c;
321 $totalbyteswritten += length($hdr);
322 if (defined($data) && $data ne "") {
323 writeall($data) or
324 dodie "$me: error: writeall failed writing cpio file data: $!\n";
325 $crc32 = crc32($data, $crc32) if $opt_c;
326 } elsif (!defined($data)) {
327 # we already "grabbed" a hold of the file's data earlier by opening FILEDATA
328 # to make sure that it couldn't disappear on us after writing the "cpio Header"
329 my $fsize = 0;
330 my $bytes;
331 do {
332 my $buf = '';
333 $bytes = sysread(FILEDATA, $buf, 32768);
334 defined($bytes) or
335 dodie "$me: error: error reading \"$fn\": $!\n";
336 $bytes == 0 || writeall($buf) or
337 dodie "$me: error: writeall failed writing file data: $!\n";
338 $crc32 = crc32($buf, $crc32) if $opt_c && $bytes;
339 $fsize += $bytes;
340 } while ($bytes != 0);
341 close FILEDATA;
342 $size == $fsize or
343 dodie "$me: error: file stat size $size != actual data size $fsize for: $fn\n";
345 $totalbyteswritten += $size;
346 donefn if $opt_v;
347 return 1;
350 sub writeall {
351 my $offset = 0;
352 my $towrite = length($_[0]);
353 while ($towrite) {
354 my $bytes = syswrite(STDOUT, $_[0], $towrite, $offset);
355 defined($bytes) or return 0;
356 last if $bytes == 0;
357 $offset += $bytes;
358 $towrite -= $bytes;
360 !$towrite or die "$me: error: EOF encountered writing STDOUT\n";
361 return 1;
364 sub vis {
365 my $s = shift;
366 $s =~ s/\n/\\n/gs;
367 $s =~ s/\0/\\000/gs;
368 return $s;
371 sub process_trailer {
372 my $hdr = sprintf("070707%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o%s\0",
373 0, 0, 0, 0, 0, 1, 0, 0, 11, 0, "TRAILER!!!");
374 $totalbyteswritten += length($hdr);
375 if ($opt_c) {
376 my $llen = '';
377 my $size = $totalbyteswritten;
378 while ($size) {
379 $llen .= pack('C', $size & 0xff);
380 $size = int($size / 256);
382 $hdr .= $llen;
383 $crc32 = crc32($hdr, $crc32);
384 $crc32 ^= 0xffffffff;
385 for (my $i = 4; $i; --$i) {
386 $hdr .= pack('C', $crc32 & 0xff);
387 $crc32 >>= 8;
389 $totalbyteswritten += length($llen) + 4;
391 my $needtowrite = 512 * int(($totalbyteswritten + 511) / 512);
392 $hdr .= pack('C', 0) x ($needtowrite - $totalbyteswritten) if
393 $needtowrite > $totalbyteswritten;
394 writeall($hdr) or
395 die "$me: error: writeall failed writing cpio file trailer: $!\n";
396 return 1;
399 __DATA__
401 =head1 NAME
403 perlcpio.pl - write ASCII cpio archive
405 =head1 SYNOPSIS
407 B<perlcpio.pl> [options] > I<< <cpio-output-file> >>
409 Options:
410 -h show short usage help
411 --help show long detailed help
412 -0 use \0 instead of \n reading input
413 -a omit trailer from output
414 -b break all hard links in output
415 -c append checksum to end
416 -e empty directory link count
417 -G <gid> always set c_gid value to <gid>
418 -g <gid> set c_gid value to <gid> on overflow
419 -k keep going (when possible) after errors
420 -q quiet all non-fatal messages
421 -r record raw st_dev and st_ino values
422 -U <uid> always set c_uid value to <uid>
423 -u <uid> set c_uid value to <uid> on overflow
424 -v be verbose while writing archive
425 -w allow wider st_uid and st_gid values
426 -z zero non-file st_dev and st_ino values
428 =head1 DESCRIPTION
430 B<perlcpio.pl> reads a list of file names from standard input and then
431 writes one "POSIX.1-2001 IEEE Std 1003.1-2001 SUSv3 cpio Interchange Format"
432 "cpio Header" followed by the contents of the file for each file name read
433 from standard input.
435 The blocking size is fixed at 512 bytes (the minimum allowed).
437 Essentially B<perlcpio.pl> is the equivalent of this command:
439 pax -wd -b 512 -x cpio
441 However, uid and gid values are truncated to 16-bits rather than producing
442 an error.
444 =head1 OPTIONS
446 =over
448 =item B<-a>
450 Leave the output "appendable" by omitting the trailer and any needed
451 following zero padding. May I<NOT> be used together with B<-c>.
453 =item B<-b>
455 Break all hard links in the output stream. In other words, the
456 "c_nlink" field will be forced to 1 for files and no two files will
457 share the same pair of "c_dev" and "c_ino" values in the output.
459 Even if two files are hard-linked to one another and that hard
460 linkage is recorded properly in a cpio archive (option B<-b> was
461 I<NOT> used), the entire file's data will be I<duplicated> in the
462 archive for each hard link!
464 It is only during extraction that an attempt will be made to re-create
465 the hard linkages (which may, or may not, succeed) and eliminate
466 the redundancy at that time. The archive will always remain bloated
467 with multiple copies of the duplicated data!
469 Best to archive symbolic links instead of hard links when feasible
470 to reduce unnecessary bloating of the size of the output archive.
472 The B<-b> option is not compatible with the B<-r> option.
474 =item B<-c>
476 Append the minimum number of bytes needed to represent the little-endian
477 length of the data written up through the NUL byte in the "TRAILER!!!"
478 string and then the appropriate 32-bit CRC value plus zero padding up to
479 the next 512-byte boundary.
481 When such a file is passed through zlib's crc32 checksum routine, the output
482 (if the file remains uncorrupted) is always 0xffffffff.
484 This option may I<NOT> be used together with B<-a>.
486 =item B<-e>
488 Make the "c_nlink" count of all directories in the output "empty".
489 In other words, make it have the value 2. (For the "." and ".."
490 entries of an empty directory.)
492 This can be useful when the number of entries in a directory being
493 archived changes but the actual contents being written to the archive
494 do not.
496 =item B<-G> I<< <gid> >>
498 Force all items in the output archive to have "c_gid" set to I<< <gid> >>.
499 The given I<< <gid> >> value must be in the range 0..0777777 (262143).
501 Always overrides any B<-g> option.
503 =item B<-g> I<< <gid> >>
505 Instead of truncating "st_gid" values that would overflow, substitute
506 I<< <gid> >> instead. That means than any "st_gid" value less than 0
507 or greater than 65535 (withOUT B<-w>) or 262143 (WITH B<-w>) will be
508 replaced with I<< <gid> >> in the "c_gid" field of the item in the
509 output archive.
511 This option only affects values that would otherwise be truncated, any
512 "st_gid" values that would not be truncated are left unchanged by this
513 option.
515 =item B<-k>
517 Normally certain kinds of errors immediately abort production of an
518 output archive (leaving the partial result quite possibly unusable).
520 With B<-k>, certain errors are turned into warnings by performing an
521 action that allows the archival process to continue. In particular:
523 =over
525 =item hard-linked file size mismatch
527 When NEITHER B<-r> NOR B<-b> is in effect, if a file to be archived
528 with a hard link to an earlier file in the archive has a different
529 size than that earlier file it's hard-linked to, a fatal error would
530 normally occur and abort the archival process. With B<-k> the
531 hard-link is broken for the size-mismatched file and archiving
532 continues with a warning (but see B<-q>).
534 =item raw (B<-r>) mode value outside 18-bit limit
536 Normally when B<-r> is in effect, any "st_dev" or "st_ino" value
537 that does not fit into 18 bits causes an abort of the archival
538 process. With B<-k> the value will be truncated with a warning and
539 archiving continues (but see B<-q>).
541 =item file not found or file/symlink unreadable
543 Normally a file not found error immediately aborts the archival
544 process. With B<-k>, the file will be skipped instead (with a
545 warning, but see B<-q>). Similarly for a symlink that cannot be
546 read or a file that cannot be opened for read access.
548 Note that it is not possible to keep going when a read error occurs
549 while copying file data into the archive nor when the file data
550 copied into the archive is a different length than the original
551 stat of that file. (The "cpio Header" will have already been written
552 by then and it cannot just be taken back in order to skip the file.)
554 =back
556 =item B<-q>
558 Quiet non-fatal error messages. Any warning message that is not fatal
559 will be suppressed with this option.
561 If B<-k> is also in effect, the messages that would have been fatal
562 errors without B<-k> are suppressed as well.
564 =item B<-r>
566 Record raw "st_dev" and "st_ino" values in the output archive. A
567 failure will occur if either value does not fit in 18 bits.
569 The default (if neither the B<-b> nor the B<-r> option is given)
570 is to re-map the "st_dev" and "st_ino" values to new values in order
571 to preserve hard links while avoiding any overflow that might result
572 in an unintentional collision with other files.
574 The B<-r> option is not compatible with the B<-b> option.
576 =item B<-U> I<< <uid> >>
578 Force all items in the output archive to have "c_uid" set to I<< <uid> >>.
579 The given I<< <uid> >> value must be in the range 0..0777777 (262143).
581 Always overrides any B<-u> option.
583 =item B<-u> I<< <uid> >>
585 Instead of truncating "st_uid" values that would overflow, substitute
586 I<< <uid> >> instead. That means than any "st_uid" value less than 0
587 or greater than 65535 (withOUT B<-w>) or 262143 (WITH B<-w>) will be
588 replaced with I<< <uid> >> in the "c_uid" field of the item in the
589 output archive.
591 This option only affects values that would otherwise be truncated, any
592 "st_uid" values that would not be truncated are left unchanged by this
593 option.
595 =item B<-v>
597 Write each filename to STDERR as its entry is being written to
598 STDOUT.
600 =item B<-w>
602 Normally the "st_uid" and "st_gid" values are truncated to 16 bits.
603 With B<-w> they will be truncated to fit which means 18 bits instead
604 of 16 bits.
606 =item B<-z>
608 Write a 0 value for the "c_dev" and "c_ino" values of all but regular
609 files.
611 =back
613 =head1 DETAILS
615 The generated output consists of the following for each input file:
617 +-------------+------/.../------+
618 | cpio Header | file data bytes |
619 +-------------+------/.../------+
621 followed by the trailer and zero or more zero pad bytes:
623 +--------------+-------/.../-------+
624 | cpio Trailer | zero byte padding | <-- 512-byte boundary
625 +--------------+-------/.../-------+
627 The "cpio Trailer" is just a "cpio Header" with all fields set to
628 ASCII "0"s except:
630 c_magic "070707" (usual c_magic value)
631 c_nlink "000001" (1 link)
632 c_namesize "000013" (length 11)
633 c_name "TRAILER!!!\0"
635 The "cpio Header" has the following format:
637 c_magic 6 ASCII 6-byte string "070707"
638 c_dev 6 ASCII octal value of st_dev
639 c_ino 6 ASCII octal value of st_ino
640 c_mode 6 ASCII octal value of st_mode (see below)
641 c_uid 6 ASCII octal value of st_uid
642 c_gid 6 ASCII octal value of st_gid
643 c_nlink 6 ASCII octal value of st_nlink
644 c_rdev 6 ASCII octal value of st_rdev
645 c_mtime 11 ASCII octal UNIX epoch seconds st_mtime
646 c_namesize 6 ASCII octal length (including NUL) of c_name
647 c_filesize 11 ASCII octal length of c_filedata
648 c_name c_namesize NUL-terminated pathname string
649 c_filedata c_filesize file or symlink data
651 For the C<c_mode> field, the least-significant 12 BITS (least-significant
652 4 octal digits) have the following meanings (in any bit-or'd combination):
654 004000 Set uid
655 002000 Set gid
656 001000 The "sticky"/"text" bit
658 000400 Readable by owner
659 000200 Writable by owner
660 000100 Executable by owner
662 000040 Readable by group
663 000020 Writable by group
664 000010 Executable by group
666 000004 Readable by other
667 000002 Writable by other
668 000001 Executable by other
670 The most-significant 6 BITS (most-significant 2 octal digits) have these
671 defined meanings exclusively and MUST NOT be combined (i.e. bit or'd together),
672 but may be bit-or'd with any combination of the least-significant 12 BITS above:
674 0010000 FIFO / named pipe (i.e. "mkfifo")
675 0020000 Character special device
676 0040000 Directory
677 0060000 Block special device
678 0100000 Regular file
679 0110000 Reserved (C_ISCTG)
680 0120000 Symbolic link
681 0140000 Socket (e.g. "socket(AF_UNIX,SOCK_STREAM,0)")
683 Any other value for the most-significant 2 octal digits has undefined behavior
684 (except, of course, in the "TRAILER!!!" where all ASCII "0"s are expected for
685 the c_mode field.)
687 =head1 LIMITATIONS
689 The `pax` option `-P` (physical) is always in effect. In other words,
690 symbolic links are I<NEVER> followed. (The `-P` option is the default
691 for the `pax` utility.)
693 If there are more than 68719476735 items in the archive, using option B<-b>
694 will result in a failure when the 68719476736th item is encountered.
696 When not using option B<-b> or option B<-r>, a failure will occur
697 when the 68719476736th unique (i.e. not a hard-link of an already
698 seen file) item is encountered. Additionally, memory will be used
699 for an internal hard-link hash table that keeps track of all regular
700 files with an st_nlink value greater than 1 which will only be a
701 problem if there are an absurdly large number of hard-linked files!
703 The "st_rdev" value is always stored as 0 for regular files, directories
704 and symbolic links. Otherwise it's always truncated. Systems that use
705 a 32-bit value for "st_rdev" and store the major device number in the
706 high-order 8 bits will always record a truncated (and therefore useless)
707 "c_rdev" value unless the major device number happens to be 0.
709 The "st_nlink" value will be pinned to 0777777 if it exceeds that value.
710 But symbolic links always have their "c_nlink" value set to 1.
712 The "st_uid" and "st_gid" values are always truncated to 16 bits (default)
713 or 18 bits (with B<-w>). But they can be overridden (B<-U> and/or B<-G>)
714 or substituted only when they overflow (B<-u> and/or B<-g>).
716 When storing subsequent copies of a hard-linked file and neither
717 option B<-b> nor option B<-r> has been used, while there is a fatal
718 error if the any of the subsequent copies of a hard-linked file
719 differ in size, there's no detection of differing modification times or
720 actual content.
722 Negative values for st_mtime are forced to 0.
724 Values for st_mtime > 077777777777 (037777777777 for 32-bit platforms)
725 are pinned to 077777777777 (037777777777 for 32-bit platforms).
727 The maximum supported file size is 077777777777 (037777777777 for 32-bit
728 platforms) in other words 8GiB - 1 (4GiB - 1 for 32-bit platforms) bytes.
730 Some 32-bit platform consumers of values in the range 020000000000 -
731 037777777777 may misbehave unless they are fully prepared to handle
732 values in that range. This is especially true for the "c_mtime" field
733 when consumed by 32-bit platforms and may also apply to the "c_filesize"
734 field as well.
736 While an unsigned 31-bit number (0 .. 0x7FFFFFFF) can represent dates in
737 the range 1970-01-01T00:00:00Z .. 2038-01-19T03:14:07Z, an unsigned 32-bit
738 number can represent dates through 2106-02-07T06:28:15Z and an unsigned
739 33-bit number can represent dates through 2242-03-16T12:56:31Z.
741 If perl's "lstat" function returns the correct positive value for dates
742 after 2038-01-19T03:14:07Z then 32-bit perl platforms will correctly
743 store cpio "c_mtime" values through 2106-02-07T06:28:15Z and 64-bit
744 perl platforms will correctly store through 2242-03-16T12:56:31Z.
746 However, "st_mtime" values less than 0 (i.e. before 1970-01-01T00:00:00Z)
747 are always stored as 0 (meaning 1970-01-01T00:00:00Z).
748 Note that some platforms may interpret a "0" "st_mtime" value on a file as
749 meaning that it does not have a last modified timestamp available.
751 =head1 SEE ALSO
753 =over
755 =item POSIX.1-2001 IEEE Std 1003.1-2001 SUSv3 cpio Interchange Format
757 =item L<https://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html#tag_04_100_13_07>
759 =back
761 =head1 COPYRIGHT AND LICENSE
763 =over
765 =item Copyright (C) 2020 Kyle J. McKay
767 =item All rights reserved.
769 =back
771 Permission to use, copy, modify, and distribute this software for any
772 purpose with or without fee is hereby granted, provided that the above
773 copyright notice and this permission notice appear in all copies.
775 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
776 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
777 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
778 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
779 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
780 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
781 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
783 =cut