';
+ my $adb = esmith::AccountsDB->open()
+ || die $self->localise("UNABLE_TO_OPEN_ACCOUNTS");
+
+ my @userAccounts = $adb->users;
+
+ unless (scalar @userAccounts)
+ {
+ print $q->h3 ($self->localise('ACCOUNT_USER_NONE'));
+ }
+ else
+ {
+ print $q->p ($self->localise('QUOTA_DESC')),"\n";
+ print $q->h3 ($self->localise('CURRENT_USAGE_AND_SETTINGS')),"\n";
+ #print $q->p ($q->b ($self->localise('CURRENT_USAGE_AND_SETTINGS')));
+ print $q->Tr ($q->start_table({class => "sme-border"})),"\n";
+ my $limit = $self->localise('LIMIT_WITH_GRACE_MB'); $limit =~ s#(grace)# $1#;
+ my $absolute = $self->localise('ABS_LIMIT_MB'); $absolute =~ s#(limit)# $1#;
+ my $current = $self->localise('CURRENT_USAGE'); $current =~ s#(usage)# $1#;
+ print $q->Tr (esmith::cgi::genSmallCell ($q, ($self->localise('ACCOUNT')),"header"),
+ esmith::cgi::genSmallCell ($q, ($self->localise('USER_NAME')),"header"),
+ esmith::cgi::genSmallCell ($q, $limit,"header"),
+ esmith::cgi::genSmallCell ($q, $absolute,"header"),
+ esmith::cgi::genSmallCell ($q, $current,"header"),
+ esmith::cgi::genSmallCell ($q, ($self->localise('ACTION')),"header"));
+
+ foreach my $user (@userAccounts)
+ {
+ my $uid = getpwnam($user->key);
+ unless ($uid)
+ {
+ warn($self->localise('COULD_NOT_GET_UID'),$user->key);
+ next;
+ }
+ my $dev = Quota::getqcarg('/home/e-smith/files');
+ my ($bc, $bs, $bh, $bt, $ic, $is, $ih, $it) =
+ Quota::query($dev, $uid);
+
+ my $name = $user->prop("FirstName")." ".$user->prop("LastName");
+
+ print $q->Tr (esmith::cgi::genSmallCell ($q, $user->key,"normal"),
+ esmith::cgi::genSmallCell ($q, $name,"normal"),
+ esmith::cgi::genSmallCellRightJustified ($q,
+ $self->toMB($bs)),
+ esmith::cgi::genSmallCellRightJustified ($q,
+ $self->toMB($bh)),
+ esmith::cgi::genSmallCellRightJustified ($q, $self->toMB($bc)),
+ esmith::cgi::genSmallCell ($q,
+ $q->a ({href => $q->url (-absolute => 1)
+ . "?page=0&Next=Next&acct="
+ . $user->key},
+ $self->localise("MODIFY")),"normal"));
+ }
+ print '';
+ }
+ print ' |
';
+ return '';
+}
+
+=pod
+
+=head2 modifyUser
+
+Display the modify user form for the specified user
+
+=begin testing
+
+$FM->{cgi}->param(-name=>'acct', -value=>'foononex');
+is($FM->modifyUser(),'','modifyUser');
+
+=end testing
+
+=cut
+
+sub modifyUser
+{
+ my $self = shift;
+ my $q = $self->{cgi};
+ my $msg;
+
+ my $adb = esmith::AccountsDB->open();
+ my $acct = $q->param ('acct');
+ my $rec = $adb->get($acct);
+ unless (defined $rec)
+ {
+ $msg = $self->localise('ERR_NO_SUCH_ACCT').$acct;
+ return $self->error($msg, 'Initial');
+ }
+ my $type = $rec->prop('type');
+ unless ($type eq "user")
+ {
+ $msg = $self->localise('ERR_NOT_A_USER_ACCT').$acct.$self->localise('ACCOUNT_IS_TYPE').$type;
+ return $self->error($msg, 'Initial');
+ }
+ my $uid = getpwnam($acct);
+ unless ($uid)
+ {
+ $msg = $self->localise('COULD_NOT_GET_UID').$acct;
+ return $self->error($msg, 'Initial');
+ }
+
+ my $name = $rec->prop("FirstName")." ".$rec->prop("LastName");
+ my $dev = Quota::getqcarg('/home/e-smith/files');
+ my ($bc, $bs, $bh, $bt, $ic, $is, $ih, $it) =
+ Quota::query($dev, $uid);
+ print '';
+
+ print
+ $q->p($self->localise('USER')." $name (\"$acct\") ".
+ $self->localise('CURRENTLY_HAS')." $ic ".
+ $self->localise('FILES')." ".
+ $self->localise('OCCUPYING')." ". $self->toMB($bc) ." ".
+ $self->localise('MEGABYTES'));
+
+ print
+ $q->p($self->localise('INSTRUCTIONS'));
+
+ print $q->table ({border => 0, cellspacing => 0, cellpadding => 4},
+
+ $q->Tr (esmith::cgi::genCell ($q, $self->localise("USER_NAME")),
+ esmith::cgi::genCell ($q, $name)),
+ $q->Tr (esmith::cgi::genCell ($q, $self->localise('LIMIT_WITH_GRACE')),
+ esmith::cgi::genCell ($q,
+ $q->textfield (-name => 'soft',
+ -override => 1,
+ -default => $self->toBestUnit($bs),
+ -size => 12))),
+ $q->Tr (esmith::cgi::genCell ($q, $self->localise('ABS_LIMIT')),
+ esmith::cgi::genCell ($q,
+ $q->textfield (-name => 'hard',
+ -override => 1,
+ -default => $self->toBestUnit($bh),
+ -size => 12))));
+ print ' |
';
+ return '';
+}
+
+
+=pod
+
+=head2 performModifyUser
+
+Perform the modifications requested by the Modify page
+
+=begin testing
+
+$FM->{cgi}->param(-name=>'acct', -value=>'fooquuxb');
+is($FM->performModifyUser(),'','performModifyUser');
+
+=end testing
+
+=cut
+
+sub performModifyUser
+{
+ my $self = shift;
+ my $q = $self->{cgi};
+ my $msg;
+
+ my $adb = esmith::AccountsDB->open();
+ my $acct = $q->param ('acct');
+
+ my $rec = $adb->get($acct);
+ unless (defined $rec)
+ {
+ $msg = $self->localise('ERR_NO_SUCH_ACCT').$acct;
+ return $self->error($msg, 'Initial');
+ }
+ my $type = $rec->prop('type');
+ unless ($type eq "user")
+ {
+ $msg = $self->localise('ERR_NOT_A_USER_ACCT').$acct.$self->localise('ACCOUNT_IS_TYPE').$type;
+ return $self->error($msg, 'Initial');
+ }
+ my $uid = getpwnam($acct);
+ unless ($uid)
+ {
+ $msg = $self->localise('COULD_NOT_GET_UID').$acct;
+ return $self->error($msg, 'Initial');
+ }
+ my $softlim = $q->param ('soft');
+
+ if (($softlim !~ /^(.+?)\s*([KMGT])?$/ ) || (!looks_like_number ($1)))
+ {
+ return $self->error('SOFT_VAL_MUST_BE_NUMBER', 'Initial');
+ }
+ my $exponent = 1; # Entries with no suffix are assumed to be in megabytes.
+ if (defined ($2))
+ {
+ $exponent = index("KMGT",$2);
+ }
+ $softlim = ($1 * 1024 ** $exponent);
+
+ my $hardlim = $q->param ('hard');
+ if (($hardlim !~ /^(.+?)\s*([KMGT])?$/ ) || (!looks_like_number ($1)))
+ {
+ return $self->error('HARD_VAL_MUST_BE_NUMBER', 'Initial');
+ }
+ $exponent = 1; # Entries with no suffix are assumed to be in megabytes.
+ if (defined ($2))
+ {
+ $exponent = index("KMGT",$2);
+ }
+ $hardlim = ($1 * 1024 ** $exponent);
+
+ #------------------------------------------------------------
+ # Make sure that soft limit is less than hard limit.
+ #------------------------------------------------------------
+
+ unless ($hardlim == 0 or $hardlim > $softlim)
+ {
+ return $self->error('ERR_HARD_LT_SOFT', 'Initial');
+ }
+
+
+ #------------------------------------------------------------
+ # Update accounts database and signal the user-modify event.
+ #------------------------------------------------------------
+
+ $rec->set_prop('MaxBlocks', $hardlim);
+ $rec->set_prop('MaxBlocksSoftLim', $softlim);
+
+ # Untaint $acct before using in system().
+ $acct =~ /^(\w[\-\w_\.]*)$/; $acct = $1;
+ system ("/sbin/e-smith/signal-event", "user-modify", "$acct") == 0
+ or die ($self->localise('ERR_MODIFYING')."\n");
+
+ $msg = $self->localise('SUCCESSFULLY_MODIFIED').$acct;
+ return $self->success($msg, 'Initial');
+}
+
+=pod
+
+=head2 toMB ($kb)
+
+Utility function to convert KB to MB
+
+=for testing
+is($FM->toMB(1024),'1.00','toMB');
+
+=cut
+
+sub toMB
+{
+ my ($self,$kb) = @_;
+ return sprintf("%.2f", $kb / 1024);
+}
+
+=pod
+
+=head2 toMBNoDecimalPlaces ($kb)
+
+Utility function to convert KB to MB with no decimal places
+
+=for testing
+is($FM->toMBNoDecimalPlaces(2050), '2', 'toMBNoDecimalPlaces');
+
+=cut
+
+sub toMBNoDecimalPlaces
+{
+ my ($self,$kb) = @_;
+ return sprintf("%.0f", $kb / 1024);
+}
+
+sub toGBNoDecimalPlaces
+{
+ my ($self,$kb) = @_;
+ return sprintf("%.0f", $kb / 1024 / 1024);
+}
+
+
+=pod
+
+=head2 toKB ($mb)
+
+Utility function to convert MB to KB.
+
+=for testing
+is($FM->toKB(4),'4096','toKB');
+
+=cut
+
+sub toKB
+{
+ my ($self,$mb) = @_;
+ return sprintf("%.0f", $mb * 1024);
+}
+
+=pod
+
+Utility to convert GB to KB
+
+=for testing
+is($FM->GBtoKB(1),1048576,'GBtoKB');
+
+=cut
+
+sub GBtoKB
+{
+ my ($self,$gb) = @_;
+ return sprintf("%.0f", $gb * 1024 * 1024);
+}
+
+sub MBtoKB
+{
+ my ($self,$mb) = @_;
+ return sprintf("%.0f", $mb * 1024);
+}
+
+sub toBestUnit
+{
+ my ($self,$kb) = @_;
+ return 0 if($kb == 0);
+ return $kb."K" if($kb < 1024);
+ return $kb."K" if($kb > 1024 && $kb < 1048576 && $kb % 1024 != 0);
+ return $self->toMBNoDecimalPlaces($kb)."M" if($kb < 1048576);
+ return $self->toMBNoDecimalPlaces($kb)."M" if($kb > 1048576
+ && ($kb % 1048576 != 0));
+ return $self->toGBNoDecimalPlaces($kb)."G";
+}
+
+1;
+