ArcCheck.pm revision 1.7
1# ex:ts=8 sw=4: 2# $OpenBSD: ArcCheck.pm,v 1.7 2007/05/25 12:19:24 espie Exp $ 3# 4# Copyright (c) 2005-2006 Marc Espie <espie@openbsd.org> 5# 6# Permission to use, copy, modify, and distribute this software for any 7# purpose with or without fee is hereby granted, provided that the above 8# copyright notice and this permission notice appear in all copies. 9# 10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 18# Supplementary code to handle archives in the package context. 19# Contrarily to GNU-tar, we do not change the archive format, but by 20# convention, the names LongName\d+ and LongLink\d correspond to names 21# too long to fit. The actual names reside in the PLIST, but the archive 22# is still a valid archive. 23# 24 25package OpenBSD::Ustar::Object; 26 27# match archive header name against PackingElement item 28sub check_name 29{ 30 my ($self, $item) = @_; 31 return 1 if $self->{name} eq $item->{name}; 32 if ($self->{name} =~ m/^LongName\d+$/) { 33 $self->{name} = $item->{name}; 34 return 1; 35 } 36 return 0; 37} 38 39# match archive header link name against actual link names 40sub check_linkname 41{ 42 my ($self, $linkname) = @_; 43 my $c = $self->{linkname}; 44 if ($self->isHardLink && defined $self->{cwd}) { 45 $c = $self->{cwd}.'/'.$c; 46 } 47 return 1 if $c eq $linkname; 48 if ($self->{linkname} =~ m/^Long(?:Link|Name)\d+$/) { 49 $self->{linkname} = $linkname; 50 if ($self->isHardLink && defined $self->{cwd}) { 51 $self->{linkname} =~ s|^$self->{cwd}/||; 52 } 53 return 1; 54 } 55 return 0; 56} 57 58use POSIX; 59 60sub verify_modes 61{ 62 my ($o, $item) = @_; 63 my $result = 1; 64 65 if (!defined $item->{owner} && !$o->isSymLink) { 66 if ($o->{uname} ne 'root' && $o->{uname} ne 'bin') { 67 print STDERR "Error: no \@owner for ", 68 $item->fullname, " (", $o->{uname}, ")\n"; 69 $result = 0; 70 } 71 } 72 if (!defined $item->{group} && !$o->isSymLink) { 73 if ($o->{gname} ne 'bin' && $o->{gname} ne 'wheel') { 74 print STDERR "Warning: no \@group for ", 75 $item->fullname, " (", $o->{gname}, ")\n"; 76 } 77 } 78 if (!defined $item->{mode} && $o->isFile) { 79 if (($o->{mode} & (S_ISUID | S_ISGID | S_IWOTH)) != 0) { 80 print STDERR "Error: weird mode for ", 81 $item->fullname, ": ", 82 sprintf("%4o", $o->{mode} & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID)), "\n"; 83 $result = 0; 84 } 85 } 86 return $result; 87} 88 89# copy long items, avoiding duplicate long names. 90sub copy_long 91{ 92 my ($self, $wrarc) = @_; 93 if ($self->{name} =~ m/^LongName(\d+)$/) { 94 $wrarc->{name_index} = $1 + 1; 95 } 96 if (length($self->{name}) > MAXFILENAME+MAXPREFIX+1) { 97 $wrarc->{name_index} = 0 if !defined $wrarc->{name_index}; 98 $entry->{name} = 'LongName'.$wrarc->{name_index}++; 99 } 100 $self->copy($wrarc); 101} 102 103package OpenBSD::Ustar; 104 105# prepare item and introduce long names where needed. 106sub prepare_long 107{ 108 my ($self, $item) = @_; 109 my $filename = $item->{name}; 110 my $entry = $self->prepare($filename); 111 if (!defined $entry->{uname}) { 112 die "No user name for ", $entry->{name}, " (uid ", $entry->{uid}, ")\n"; 113 } 114 if (!defined $entry->{gname}) { 115 die "No group name for ", $entry->{name}, " (gid ", $entry->{gid}. "\n"; 116 } 117 my ($prefix, $name) = split_name($entry->{name}); 118 if (length($name) > MAXFILENAME || length($prefix) > MAXPREFIX) { 119 $self->{name_index} = 0 if !defined $self->{name_index}; 120 $entry->{name} = 'LongName'.$self->{name_index}++; 121 } 122 if (length($entry->{linkname}) > MAXLINKNAME) { 123 $self->{linkname_index} = 0 if !defined $self->{linkname_index}; 124 $entry->{linkname} = 'LongLink'.$self->{linkname_index}++; 125 } 126 return $entry; 127} 128 1291; 130