sub slice_dir_port {
my ($self,$slice) = @_;
- my ( undef, $dir, $port, undef ) = getgrnam($slice) || die "getgrnam $slice: $!";
+ my ( undef, $dir, $port, undef ) = getgrnam($slice);
+ die "getgrnam $slice: $!" if $!;
warn "# slice_dir_port $slice = $dir $port\n";
return ( $dir, $port );
}
while(<$fh>) {
my ( $login, $passwd, $uid, $gid, $email, $dir, $shell ) = split(/:/,$_);
$max_uid = $uid if $uid > $max_uid;
- $found = $uid if $email eq $new_email;
+ $found = $login if $email eq $new_email;
}
close($fh);
open(my $fh, '>>', $self->{passwd});
print $fh "u$max_uid:$new_passwd:$max_uid:$port:$new_email:$dir:/bin/true\n";
close($fh);
- $found = $max_uid;
+ $found = "u$max_uid";
mkdir $dir;
chown $max_uid, $port, $dir;
sub mkbasepath {
my ($self,$path,$opts) = @_;
+ cluck "ERROR: mkbasepath called without opts, so user is root!" unless $opts;
+ if ( $ENV{DEBUG} ) {
+ warn "# mkbasepath $path ",dump($opts);
+ $opts->{verbose} ||= 1;
+ }
$path =~ s{/[^/]+$}{};
- make_path $path unless -d $path;
+ if ( ! -d $path ) {
+ make_path $path, $opts;
+ }
}
sub user_dir {
- my ( $self,$user, $dir ) = @_;
+ my ( $self, $user, $dir ) = @_;
$user = $self->user_info($user) unless ref $user eq 'HASH';
my $path;
if ( exists $user->{dir} ) {
sub usage {
my ( $self, $user ) = @_;
$user = $self->user_info($user) unless ref $user eq 'HASH';
+
+ my $usage_path = $user->{dir} . '/.meta/files.usage';
+ $self->mkbasepath( $usage_path, { uid => $user->{uid} } );
+ if ( ! -e $usage_path ) {
+ warn "# usage $usage_path missing";
+ $self->list_files($user);
+ }
+
+ open(my $fh, '<', $usage_path);
+ my $size = <$fh>;
+ chomp $size;
+
+ warn "# usage $user->{login} $size bytes\n";
+ return $size;
+
+=for slow and broken
+
my $path = $self->user_dir( $user => 'usage');
my $sum;
open(my $fh, '<', $path);
$sum->{_quota} = $quota;
warn "## usage ",dump($user, $sum), $/;
return $sum;
+
+=cut
+
}
sub send_file {
$self->append( $t, 'recv', $size, $f->{uid}, $t_path );
$self->append_meta('md5sum', $t, $md5 => $t_path ) if $md5; # md5sum for received files! FIXME -- cross-slice md5
$self->refresh_file_list( $t );
+ } else {
+ warn "ERROR: send_file $f_full -> $t_full: $!";
}
return $size;
$self->mkbasepath( $t_full, { uid => $user->{uid}, gid => $user->{gid} } );
my $ok = rename $f_full, $t_full;
+ $self->refresh_file_list( $user );
+
my $md5 = $self->md5_get($t_full);
if ( ! $md5 ) {
warn "ERROR: no md5sum for $from";
$self->append_meta('md5sum', $user, 'rename' => $from );
$self->append_meta('md5sum', $user, $md5 => $from );
- $self->refresh_file_list( $user );
-
return $ok;
}
$user = $self->user_info($user) unless ref $user eq 'HASH';
my $full_path = "$user->{dir}/$path";
- return -s $full_path;
+ my $size = -s $full_path;
+ warn "# file_size $full_path = $size bytes\n";
+ return $size;
+}
+
+sub list_files {
+ my ( $self, $user, $path ) = @_;
+
+ $user =~ s{/+$}{} && warn "cleanup list_files arg [$user]";
+
+ $user = $self->user_info($user) unless ref $user eq 'HASH';
+
+ die "no dir for ",dump($user) unless exists $user->{dir};
+
+ my $files = $user->{dir} . '/.meta/files';
+ $self->mkbasepath( $files, { uid => $user->{uid} } );
+ if ( -e $files && -s $files > 0 && -e "$files.usage") {
+ local $/ = undef;
+ open(my $fh, '<', $files);
+ my $list = <$fh>;
+ close($fh);
+ warn "# list_files $user->{login} from cache ", length($list), " bytes\n";
+ return $list;
+ }
+
+ my $dir = $user->{dir};
+ open(my $pipe, '-|', qq|find -L $dir -printf "%y %s %p\n"|);
+ open(my $fh, '>', "$files.new");
+ my $total_usage = 0;
+ my $list_txt;
+ while(<$pipe>) {
+ chomp;
+ my ( $type, $size, $name ) = split(/\s/, $_, 3);
+ $name =~ s{$dir}{./};
+ $name =~ s{//+}{/}g;
+ my $line = "$type $size $name\n";
+ print $fh $line;
+ $list_txt .= $line;
+ $total_usage += $size;
+ }
+ close($pipe);
+ close($fh);
+ rename "$files.new", $files;
+
+ open(my $usage, '>', "$files.usage.new");
+ print $usage $total_usage;
+ close($usage);
+ rename "$files.usage.new", "$files.usage";
+
+ warn "# list_files $dir usage: $total_usage\n";
+
+ return $list_txt;
}
sub refresh_file_list {
my $full_path = "$user->{dir}/.meta/files";
if ( -e $full_path ) {
warn "## refresh_file_list $full_path";
- unlink $full_path;
+ unlink $full_path || warn "unlink $full_path: $!";
+ } else {
+ warn "## refresh_file_list $full_path missing";
}
+
+ unlink "$full_path.usage" if -e "$full_path.usage";
}
1;