create sent/received logs
[cloudstore.git] / lib / CloudStore / API.pm
1 package CloudStore::API;
2 use warnings;
3 use strict;
4 use autodie;
5
6 use File::Path qw(make_path);
7 use Data::Dump qw(dump);
8
9 sub new {
10         my $class = shift;
11         my $self = {@_};
12         bless $self, $class;
13
14         $self->{passwd} ||= '/var/lib/extrausers/passwd';
15         $self->{PORT}   ||= $ENV{PORT}  || die "no PORT in env";
16         $self->{SLICE}  ||= $ENV{SLICE} || die "no SLICE in env";
17
18         return $self;
19 }
20
21 sub user_info {
22         my ($self,$login) = @_;
23
24         my @n = qw/ login passwd uid gid quota comment gecos dir shell expire /;
25         my @p = $login =~ m/^\d+$/ ? getpwuid $login : getpwnam $login;
26         die "$login: $!" if $!;
27         my $user;
28         $user->{$_} = shift @p foreach @n;
29         return $user;
30 }
31
32 sub create_user {
33         my ( $self, $new_email, $new_passwd, $new_quota ) = @_;
34
35         my $max_uid = 0;
36         my $found = 0;
37
38         open(my $fh, '<', $self->{passwd});
39         while(<$fh>) {
40                 my ( $login, $passwd, $uid, $gid, $email, $dir, $shell ) = split(/:/,$_);
41                 $max_uid = $uid if $uid > $max_uid;
42                 $found = $uid if $email eq $new_email;
43         }
44         close($fh);
45
46         if ( ! $found ) {
47                 $max_uid++;
48                 my $dir = "$self->{SLICE}/$max_uid";
49                 warn "# create_user $new_email $new_quota = $max_uid $dir";
50                 open(my $fh, '>>', $self->{passwd});
51                 print $fh "u$max_uid:$new_passwd:$max_uid:$self->{PORT}:$new_email:$dir:/bin/true\n";
52                 close($fh);
53                 $found = $max_uid;
54
55                 mkdir $dir;
56                 chown $max_uid, $self->{PORT}, $dir;
57         }
58
59         return $found;
60 }
61
62 sub mkbasepath {
63         my ($path,$opts) = @_;
64         $path =~ s{/[^/]+$}{};
65         make_path $path unless -d $path;
66 }
67
68 sub append {
69         my $self = shift @_;
70         my $user = shift @_;
71         my $path;
72         $user = $self->user_info($user) unless ref $user eq 'HASH';
73         if ( exists $user->{dir} ) {
74                 $path = $user->{dir} . '/.log';
75         } else {
76                 die "no dir in ", dump $user;
77         }
78         my $line = join('#',@_);
79         open(my $fh, '>>', $path);
80         print $fh "$line\n";
81         close $fh;
82         warn "## $path $line\n";
83 }
84
85 sub send_file {
86         my ( $self, $f_uid,$f_path, $t_uid,$t_path ) = @_;
87
88         my $f = $self->user_info($f_uid);
89         my $t = $self->user_info($t_uid);
90         my $md5 = $self->user_info('md5');
91
92         my $f_full = "$f->{dir}/$f_path";
93         my $t_full = "$t->{dir}/$t_path";
94
95         mkbasepath $t_full, { uid => $t->{uid} };
96
97         my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat $f_full;
98         if ( $uid == $f->{uid} ) {
99                 warn "# send_file - move $f_uid $f_path to pool\n";
100                 chown $md5->{uid}, $md5->{gid}, $f_full;
101                 chmod oct("0444"), $f_full;
102         } elsif ( $uid == $md5->{uid} ) {
103                 warn "# send_file - shared $f_full\n";
104         }
105
106         $self->append( $f, 'sent', -s $f_full, $t->{uid}, $f_path );
107         link $f_full, $t_full; 
108         $self->append( $t, 'recv', -s $t_full, $f->{uid}, $t_path );
109 }
110
111 sub rename_file {
112         my ( $self, $uid, $from, $to ) = @_;
113
114         $self->append( $uid, 'rename', $from, $to );
115 }
116
117
118 sub delete {
119         my ( $self, $uid, $path ) = @_;
120
121         $self->append( $uid, 'delete', $path );
122 }
123
124 sub usage {
125         my ( $uid ) = @_;
126
127 }
128
129 1;