1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
| | # Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# base class to ensures Xapian||SQLite files respect core.sharedRepository
# of git repos
package PublicInbox::Umask;
use v5.12;
use PublicInbox::OnDestroy;
use constant {
PERM_UMASK => 0,
OLD_PERM_GROUP => 1,
OLD_PERM_EVERYBODY => 2,
PERM_GROUP => 0660,
PERM_EVERYBODY => 0664,
};
sub _read_git_config_perm {
my ($self) = @_;
chomp(my $perm = $self->git->qx('config', 'core.sharedRepository'));
$perm;
}
sub _git_config_perm {
my $self = shift;
my $perm = scalar @_ ? $_[0] : _read_git_config_perm($self);
$perm //= '';
return PERM_UMASK if $perm eq '' || $perm eq 'umask';
return PERM_GROUP if $perm eq 'group';
return PERM_EVERYBODY if $perm =~ /\A(?:all|world|everybody)\z/;
return PERM_GROUP if ($perm =~ /\A(?:true|yes|on|1)\z/);
return PERM_UMASK if ($perm =~ /\A(?:false|no|off|0)\z/);
my $i = oct($perm);
return PERM_UMASK if $i == PERM_UMASK;
return PERM_GROUP if $i == OLD_PERM_GROUP;
return PERM_EVERYBODY if $i == OLD_PERM_EVERYBODY;
if (($i & 0600) != 0600) {
die "core.sharedRepository mode invalid: ".
sprintf('%.3o', $i) . "\nOwner must have permissions\n";
}
($i & 0666);
}
sub _umask_for {
my ($perm) = @_; # _git_config_perm return value
my $rv = $perm;
return umask if $rv == 0;
# set +x bit if +r or +w were set
$rv |= 0100 if ($rv & 0600);
$rv |= 0010 if ($rv & 0060);
$rv |= 0001 if ($rv & 0006);
(~$rv & 0777);
}
sub with_umask {
my ($self, $cb, @arg) = @_;
my $old = umask($self->{umask} //= umask_prepare($self));
my $restore = on_destroy \&CORE::umask, $old;
$cb ? $cb->(@arg) : $restore;
}
sub umask_prepare {
my ($self) = @_;
_umask_for(_git_config_perm($self));
}
1;
|