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