From 65f88683641b108dde39810b64ee526d76b8d667 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 13 Apr 2026 01:15:07 +0900 Subject: [PATCH] Add misc. scripts --- README.md | 5 + detect-mail-loop/detect-mail-loop.sh | 4 + make-homes/make-homes.pl | 45 ++++ merge-group/merge-group.pl | 42 ++++ merge-passwd/merge-passwd.pl | 87 ++++++++ msgsh/msgsh | 13 ++ new-user/nybruker.pl | 210 ++++++++++++++++++ new-user/velkommenmail.template | 0 .../pull-updates-from-salt.sh | 14 ++ .../send-quota-warning-mail.pl | 74 ++++++ sperret/sperret | 16 ++ update-packages/update-packages.sh | 32 +++ update-quota/update-quota.pl | 106 +++++++++ uquota/uquota.pl | 34 +++ 14 files changed, 682 insertions(+) create mode 100644 README.md create mode 100755 detect-mail-loop/detect-mail-loop.sh create mode 100755 make-homes/make-homes.pl create mode 100755 merge-group/merge-group.pl create mode 100755 merge-passwd/merge-passwd.pl create mode 100755 msgsh/msgsh create mode 100755 new-user/nybruker.pl create mode 100644 new-user/velkommenmail.template create mode 100755 pull-updates-from-salt/pull-updates-from-salt.sh create mode 100755 send-quota-warning-mail/send-quota-warning-mail.pl create mode 100755 sperret/sperret create mode 100755 update-packages/update-packages.sh create mode 100755 update-quota/update-quota.pl create mode 100755 uquota/uquota.pl diff --git a/README.md b/README.md new file mode 100644 index 0000000..186598e --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# spook + +This repository contains all sorts of code snippets, scripts and timed jobs that haunts our machine park, as well as any packaging and configuration needed to make them run. + +Some of these scripts used to be part of the salt-stack configuration repository, but have since been moved here. diff --git a/detect-mail-loop/detect-mail-loop.sh b/detect-mail-loop/detect-mail-loop.sh new file mode 100755 index 0000000..9a84635 --- /dev/null +++ b/detect-mail-loop/detect-mail-loop.sh @@ -0,0 +1,4 @@ +#! /bin/bash + +[ `grep -c 'retry time not reached for any host after a long failure period' /var/log/exim4/mainlog` -gt 100 ] && grep 'retry time not reached for any host after a long failure period' /var/log/exim4/mainlog | tail | mail -s "Possible mail loop detected" root +exit 0 diff --git a/make-homes/make-homes.pl b/make-homes/make-homes.pl new file mode 100755 index 0000000..3009a16 --- /dev/null +++ b/make-homes/make-homes.pl @@ -0,0 +1,45 @@ +#! /usr/bin/perl + +# Går gjennom passwd.pvv og oppretter alle hjemmekataloger som mangler. + +use strict; +use warnings; +use File::Basename; + +sub execute { + if (system(@_) != 0) { + die "Failed to execute " . join(" ", @_); + } +} + +my $passwd = "/etc/passwd.pvv"; + +my $homes_created = 0; + +open (my $passwd_fd, $passwd) or die "Unable to open $passwd: $!"; +while (<$passwd_fd>) { + chomp; + my ($user, undef, $uid, $gid, undef, $homedir, $shell) = split(":"); + + # Ignorer brukere som uansett ikke får lvov til å logge inn + next if $shell eq "/bin/sperret" || $shell eq "/bin/msgsh" || $shell eq "/bin/false"; + + # Prefix med /export, som er lokal path på NFS-serveren + $homedir = "/export" . $homedir; + + # Only create homedir if it is missing, and it would have been exported from here + if (-d dirname($homedir) && !-d $homedir) { + print "Oppretter hjemmekatalog for $user: $homedir\n"; + $homes_created = 1; + execute("mkdir", "-p", "-m", "711", $homedir); + execute("cp -r /local/skel/usr/.??* $homedir"); + execute("chown", "-R", "$uid:$gid", $homedir); + execute("find", $homedir, "-type", "f", "-exec", "chmod", "600", "{}", "+"); + execute("find", $homedir, "-type", "d", "-exec", "chmod", "700", "{}", "+"); + execute("chmod", "711", $homedir); # Må ha execute, så ~/web-docs virker + } +} + +if ($homes_created) { + execute("/local/quota/makeexportsandquota.pl"); +} diff --git a/merge-group/merge-group.pl b/merge-group/merge-group.pl new file mode 100755 index 0000000..dbbe2f9 --- /dev/null +++ b/merge-group/merge-group.pl @@ -0,0 +1,42 @@ +#! /usr/bin/perl +use strict; +use warnings; + +if (scalar @ARGV < 1) { + die "Usage: $0 "; +} + +my $LOWEST_PVV_GID = int($ARGV[0]); + +my @lines = (); + +# Read old group file +open(IN, "/etc/group") || die "Unable to open /etc/group: $!"; +while() { + my @parts = split(":"); + if ($parts[2] < $LOWEST_PVV_GID || $parts[0] eq "nogroup") { + push @lines, $_; + } +} +close IN || die "Unable to close /etc/group: $!"; + +# Read pvv group file +my $groupcount = 0; +open(PVV, "/etc/group.pvv") || die "Unable to open /etc/group.pvv: $!"; +while() { + ++$groupcount; + push @lines, $_; +} +close PVV || die "Unable to close /etc/group.pvv: $!"; + +if ($groupcount < 200) { + die "/etc/group.pvv has less than 200 groups, something went wrong"; +} + +open(OUT, ">/etc/group.tmp") || die "Unable to open /etc/group.tmp for writing: $!"; +foreach (@lines) { + print OUT $_ || die "Can't write to /etc/group.tmp: $!"; +} +close OUT || die "Unable to close /etc/group.tmp: $!"; + +rename "/etc/group.tmp", "/etc/group" || die "Unable to move /etc/group.tmp to /etc/group: $!"; diff --git a/merge-passwd/merge-passwd.pl b/merge-passwd/merge-passwd.pl new file mode 100755 index 0000000..1aa61b1 --- /dev/null +++ b/merge-passwd/merge-passwd.pl @@ -0,0 +1,87 @@ +#! /usr/bin/perl +use strict; +use warnings; + +if (scalar @ARGV < 1) { + die "Usage: $0 "; +} + +my $LOWEST_PVV_UID = int($ARGV[0]); + +my @passwd = (); +my %passwd_idx = (); +my %shadow = (); + +my %filter = ( + "nobody" => 1, + "news" => 1, +); + +my $seen_nobody = 0; +open(PASSWD_IN, "/etc/passwd") || die "Unable to open /etc/passwd: $!"; +while() { + my @parts = split(":"); + if ($parts[2] ne '' && $parts[2] < $LOWEST_PVV_UID || defined $filter{$parts[0]} && $filter{$parts[0]} == 1) { + push @passwd, $_; + $passwd_idx{$parts[0]} = $#passwd; + } + if (defined $filter{$parts[0]} && $filter{$parts[0]} == 1) { + $filter{$parts[0]}++; + } +} +close PASSWD_IN || die "Unable to close /etc/passwd: $!"; + +open(SHADOW_IN, "/etc/shadow") || die "Unable to open /etc/shadow: $!"; +while() { + my @parts = split(":"); + if (defined $passwd_idx{$parts[0]}) { + $shadow{$parts[0]} = $_; + } +} +close SHADOW_IN || die "Unable to close /etc/shadow: $!"; + +open(PVV, "/etc/passwd.pvv") || die "Unable to open /etc/passwd.pvv: $!"; +my $usercount = 0; +while() { + ++$usercount; + my @parts = split(":"); + my $user = $parts[0]; + my $hash = $parts[1]; + $parts[1] = "x"; + push @passwd, join(":", @parts); + $passwd_idx{$parts[0]} = $#passwd; + $shadow{$parts[0]} = "$user:$hash:13777:0:99999:7:::\n"; +} +close PVV || die "Unable to close /etc/passwd.pvv: $!"; + +if ($usercount < 1500) { + die "/etc/passwd.pvv has less than 1500 users, something went wrong"; +} + +# Passwd skal være world readable +umask 022; + +open(PASSWD, ">/etc/passwd.tmp") || die "Unable to open /etc/passwd.tmp for writing: $!"; +foreach (@passwd) { + print PASSWD $_ || die "Can't write to /etc/passwd.tmp: $!"; +} +close PASSWD || die "Unable to close /etc/passwd.tmp: $!"; + +# Shadow skal IKKE være world readable +umask 027; + +open(SHADOW, ">/etc/shadow.tmp") || die "Unable to open /etc/shadow.tmp for writing: $!"; +foreach (keys %passwd_idx) { + if (exists($shadow{$_})) { + print SHADOW $shadow{$_}; + } else { + print SHADOW "$_:*:12849:0:99999:7:::\n"; + } +} +close SHADOW || die "Unable to close /etc/shadow.tmp: $!"; + +# Chown shadowfilen til root:Debian-exim +chown 0, scalar getgrnam("shadow"), "/etc/shadow.tmp"; + +rename "/etc/passwd.tmp", "/etc/passwd" || die "Unable to move /etc/passwd.tmp to /etc/passwd: $!"; +rename "/etc/shadow.tmp", "/etc/shadow" || die "Unable to move /etc/shadow.tmp to /etc/shadow: $!"; diff --git a/msgsh/msgsh b/msgsh/msgsh new file mode 100755 index 0000000..15e713a --- /dev/null +++ b/msgsh/msgsh @@ -0,0 +1,13 @@ +#!/bin/sh + +if [ -f $HOME/.msgsh ]; then + cat $HOME/.msgsh +else + cat <"); +vsystem("git", "push"); + +print < $tmpfile"); + my $editor = &ask("Editor (brukes kun for aa redigere epost som sendes)", $ENV{EDITOR} || "vim") unless $batchmode; + vsystem($editor, $tmpfile) unless $batchmode; + my $confirm = "yes"; + $confirm = &ask("Send?", $confirm) unless $batchmode; + return unless ($confirm =~ m/^[yY]/); + vsystem("/usr/sbin/sendmail " . $ui{email} . " < $tmpfile"); + vsystem("rm", $tmpfile); +} + +sub vsystem { + my $rc; + do { + print(join(" ", map { $a = /\s/ ? "'$_'" : $_ } @_), "\n"); + system(@_); + $rc = $?; + if ($rc) { + $rc = &ask("Systemkall feilet, prøv igjen?", "ja") !~ /n/i; + } + } while ($rc); # Repeat until successful +} + + +sub makeuser { + my ($passwd, $pwline) = @_; + open (my $passwd_fd, ">>", $passwd) or die "Unable to open $passwd: $!"; + print $passwd_fd "$pwline\n"; + close $passwd_fd; +} + +sub getuserinfo { + my ($passwd) = @_; + my %ui; + + for(my $i = 0; $i < $#ARGV; $i++) { + if ($ARGV[$i] eq "-n") { + $ui{name} = $ARGV[$i + 1]; + $i++; + } elsif ($ARGV[$i] eq "-u") { + $ui{uid} = $ARGV[$i + 1]; + $i++; + } elsif ($ARGV[$i] eq "-g") { + $ui{gid} = $ARGV[$i + 1]; + $i++; + } elsif ($ARGV[$i] eq "-d") { + $ui{dir} = $ARGV[$i + 1]; + $i++; + } elsif ($ARGV[$i] eq "-s") { + $ui{shell} = $ARGV[$i + 1]; + $i++; + } elsif ($ARGV[$i] eq "-e") { + $ui{email} = $ARGV[$i + 1]; + $i++; + } + } + + my %users; + my %uids; + open (my $passwd_fd, $passwd) or die "Unable to open $passwd: $!"; + while (<$passwd_fd>) { + chomp; + my ($user, undef, $uid, $gid) = split(":"); + $users{$user} = $_; + $uids{$uid} = $_; + } + + $ui{name} = &ask("User name", $ui{name}) unless ($ui{name} && $batchmode); + die "Brukernavn $ui{name} finnes allerede!\n" if exists $users{$ui{name}}; + + # my $pwent = `grep '^$ui{name}\:' /local/pwdist/passwd`; + my $pwent_str = `/usr/bin/python3 $ENV{'HOME'}/salt/standard/passwd/ask_stud_ldap.py $ui{name}`; + chomp($pwent_str); + my @pwent = split(":", $pwent_str); + if (scalar @pwent >= 5) { + $ui{uid} = $pwent[2] unless $ui{uid}; + $ui{gid} = $pwent[3] unless $ui{gid}; + $ui{gecos} = $pwent[4] unless $ui{gecos}; + } else { + # Bruker finnes ikke i passordfilen, og er altså litt sær. + # Da er det nok best vi spør om alt. + $batchmode = 0; + } + + $ui{uid} = &ask("UID", $ui{uid}) unless ($ui{uid} && $batchmode); + die "UID $ui{uid} finnes allerede!" if exists $uids{$ui{uid}}; + + $ui{gid} = &ask("GID, should be 13401", $ui{gid}) unless ($ui{gid} && $batchmode); + + $ui{gecos} = &ask("Full name", $ui{gecos}) unless ($ui{gecos} && $batchmode); + + $ui{dir} = $homepath . "/" . $ui{name} unless $ui{dir}; + $ui{dir} = &ask("Home, should be /home/pvv/d/$ui{name}", $ui{dir}) unless ($batchmode); + + $ui{email} = $ui{name} . '@stud.ntnu.no' unless $ui{email}; + $ui{email} = &ask("E-mail", $ui{email}) unless ($batchmode); + + $ui{shell} = "/bin/bash" unless $ui{shell}; + $ui{shell} = &ask("Shell, should be /bin/bash", $ui{shell}) unless ($ui{shell} && $batchmode); + + return %ui; +} + +sub ask { + my ($prompt, $default) = @_; + return $term->readline($prompt . ": ", $default); +} + +sub checkuserdata { + my (%ui) = @_; + if ($ui{uid} eq "") { + die "UID er ikkje definert\n"; + } + + if ($ui{gid} eq "") { + die "GID er ikkje definert\n"; + } +} + +sub createprincipal { + my %ui = @_; + my $adminprincipal = &ask( 'Admin principal' , $ENV{LOGNAME} . "/admin" ) unless $batchmode; + if ($adminprincipal ne '' ){ + vsystem("kadmin -p $adminprincipal add $ui{name}"); + } + return; +} diff --git a/new-user/velkommenmail.template b/new-user/velkommenmail.template new file mode 100644 index 0000000..e69de29 diff --git a/pull-updates-from-salt/pull-updates-from-salt.sh b/pull-updates-from-salt/pull-updates-from-salt.sh new file mode 100755 index 0000000..17ac7b3 --- /dev/null +++ b/pull-updates-from-salt/pull-updates-from-salt.sh @@ -0,0 +1,14 @@ +#! /bin/sh + +# Run salt-call state.highstate, logging to /var/log/salt/nightly-highstate. +# If there is an error, we cat the entire file to stdout, so cron will complain +# to the admin. + +export PATH=/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin + +salt-call state.highstate --retcode-passthrough saltenv=base pillarenv=base > /var/log/salt/nightly-highstate 2>&1 +RET=$? +if [ $RET -ne 0 ] || grep '^Failed:[[:space:]]*[1-9][0-9]*$' /var/log/salt/nightly-highstate >/dev/null 2>&1; then + cat /var/log/salt/nightly-highstate +fi +exit $RET diff --git a/send-quota-warning-mail/send-quota-warning-mail.pl b/send-quota-warning-mail/send-quota-warning-mail.pl new file mode 100755 index 0000000..30b9550 --- /dev/null +++ b/send-quota-warning-mail/send-quota-warning-mail.pl @@ -0,0 +1,74 @@ +#! /usr/bin/perl + +use warnings; +use strict; +use Quota; +use Mail::Mailer; +use POSIX qw(strftime); +use Sys::Syslog qw(:standard :macros); + +openlog("pvv-warnmailquota", "", LOG_LOCAL0); + +open(USERS, "/etc/passwd.pvv") or die "Unable to open /etc/passwd.pvv: $!"; +my @users = or die "Unable to read from /etc/passwd.pvv: $!"; +close USERS; +chomp @users; + +my $mailer = new Mail::Mailer; + + +foreach my $line (@users) { + my ($uname,$pass,$uid,$gid,$gcos,$home,$shell) = split(/:/,$line) or next; + next if ($shell eq "/bin/msgsh"); + next if ($shell eq "/bin/false"); + next if ($home !~ /^\/home\/pvv/); + if (! -d $home) { + print "$uname ($uid:$gid) missing $home ($shell)\n"; + next; + } + my ($block_curr, $block_soft, $block_hard, $block_timelimit, $inode_curr, $inode_soft, $inode_hard, $inode_timelimit) = Quota::query(Quota::getqcarg($home),$uid); + next if (! $block_soft || ! $block_curr); + next if ($block_curr < $block_soft); + + # Kan ikke sende mail likevel... + next if (($block_curr + 16) >= $block_hard); + next if ($block_timelimit < time()); + + # next if (($uname ne "kvadrat") && ($uname ne "knuta") && ($uname ne "thorvan") && ($uname ne "oyving")); + + my $forbruk = sprintf("%.1f", $block_curr * 100.0 / $block_soft); + my $timelimit = strftime("%Y-%m-%d %H:%M",localtime($block_timelimit)); + + my %headers; + $headers{'From'} = "Kvotesystem "; + $headers{'To'} = "$uname\@pvv.ntnu.no"; + $headers{'Subject'} = "PVV kvotebruk ${forbruk}% ($uname)"; + $headers{'Content-Type'} = 'text/plain; charset=UTF-8'; + $mailer->open(\%headers); + + print $mailer qq{ +Du har brukt opp ${forbruk}% av kvoten din på PVV. Hvis du +ikke er under kvota $timelimit, vil du miste muligheten +til å opprette og skrive til filer på PVV frem til du +sletter nok filer til at du er under kvoten igjen. Å miste +skrivetilgang medfører blandt annet at du ikke kan motta +mer epost, så vi anbefaler deg å rette på situasjonen +så snart som mulig. + +Dette er en gyllen anledning til å kjøpe mer disk på PVV. +Disk koster NOK 32 per GiB, og minstekjøp er 6 GiB (NOK 192). + +Se på http://www.pvv.ntnu.no/disk/ for mer detaljer. + +For å se hvor mye kvote du har brukt, bruk kommandoen +"uquota" når du er logget inn. Ikke alle maskiner støtter denne +kommandoen, men den fungerer ihvertfall fra microbel. +}; +#Hvis du ikke er under kvoten innen $timelimit +#vil du miste skrivetilgang til katalogen, som blandt +#annet vil forhindre leveranse av ny mail. + $mailer->close(); + syslog("info", "%s mailed", $uname); +} + +closelog(); diff --git a/sperret/sperret b/sperret/sperret new file mode 100755 index 0000000..9372240 --- /dev/null +++ b/sperret/sperret @@ -0,0 +1,16 @@ +#!/bin/sh + + cat < for å få satt nytt passord og +få kontoen gjenåpnet. + + 2003-01-24 + drift@pvv.ntnu.no + +! +sleep 15 + diff --git a/update-packages/update-packages.sh b/update-packages/update-packages.sh new file mode 100755 index 0000000..bb33d95 --- /dev/null +++ b/update-packages/update-packages.sh @@ -0,0 +1,32 @@ +#! /bin/sh + +LOG=/var/log/pvvpakke.log + +silentrun () { + if ! "$@" >>"$LOG" 2>&1; then + cat "$LOG" + exit 1; + fi +} + +#Trunker loggen +echo -n > "$LOG" + +if [ `uname` = FreeBSD ]; then + silentrun pkg update -q + silentrun pkg upgrade -q -y + silentrun pkg clean -q -y +elif [ -f /etc/debian_version ]; then + export DEBIAN_FRONTEND=noninteractive + silentrun /usr/bin/apt-get -q -q update + silentrun /usr/bin/apt-get --force-yes -q -q -s upgrade + silentrun /usr/bin/apt-get --force-yes -q -q upgrade + silentrun /usr/bin/apt-get clean +elif [ -f /etc/gentoo-release ]; then + true +# dette håndteres av 50emergesync.cron og 51glsacheck.cron +else + echo "Fant ikke systemtype!" + hostname + uname -a +fi diff --git a/update-quota/update-quota.pl b/update-quota/update-quota.pl new file mode 100755 index 0000000..7b04a3c --- /dev/null +++ b/update-quota/update-quota.pl @@ -0,0 +1,106 @@ +#! /usr/bin/perl +# vim:et:sw=2:ts=2 + +use warnings; +use strict; +use Quota; + +my $reload_nfs = 1; +if (scalar @ARGV > 0 && $ARGV[0] eq '--noreload') { + $reload_nfs = 0; + shift @ARGV; # remove option +} + +# Default kvotefil er /local/quota/quota.txt, men man kan override ved +# å oppgi en som første argument +my $quotafile = $ARGV[0] ? $ARGV[0] : "/local/quota/quota.txt"; +my $tmpquotafile = $ARGV[1] ? $ARGV[1] : "/local/quota/tempquota.txt"; + +my %users; + +#tie %nis, 'Net::NIS', 'netgroup', 'pvv'; + +open(USERS, "/etc/passwd.pvv") or die "Unable to open /etc/passwd.pvv: $!"; +while() { + chomp; + $users{(split(":"))[0]} = $_; +} + +my (%quota, %export); + +open(QUOTA, $quotafile); +while() { + chomp; + s/#.*//; + s/\s*$//; + next if ($_ eq ""); + my ($uname,$mb,$export)=split(/:/,$_); + $quota{$uname}=$mb; + $export{$uname}=$export; +} +close(QUOTA); + +# Midlertidige kvoter (typisk under restoring av filer) +if (-e $tmpquotafile) { + open(TMPQUOTA, $tmpquotafile); + while() { + chomp; + s/#.*//; + s/\s*$//; + next if ($_ eq ""); + my ($until,$uname,$mb)=split(/:/,$_); + if ($until > time) { + $quota{$uname}=$mb; + } + } + close(TMPQUOTA); +} + +open(DIRS, "/usr/bin/find /export/home/pvv -mindepth 1 -maxdepth 1 -type d|"); +open(EXPORT, ">/etc/exports"); +while() { + chomp(); + my $dir=$_; + next if ($dir =~ /lost\+found$/); + next if ($dir =~ /\/x$/); + next if ($dir =~ /\/x\//); + my $user = (reverse(split(/\//,$dir)))[0]; + my @hosts = ("\@pvvhosts(no_subtree_check,rw,async)"); + if ($export{$user}) { + push @hosts, map { "$_(rw,async)" } split(/[ ,]/,$export{$user}); + } + my $hosts = join(" ", @hosts); + print EXPORT "$dir\t$hosts\n"; +# print "$dir $user\n"; +} +close(DIRS); +close(EXPORT); + +$quota{'root'} = 0; +$quota{'nobody'} = 0; + +# httpd er ikke i YP fordi den har samme UID som nobody der, men +# nobody har en annen UID i Ubuntu. +$users{'httpd'} = "httpd:*:60001:60001"; +$quota{'httpd'} = 0; + +my $dev=Quota::getqcarg("/export/home/pvv"); + +foreach my $uname (keys %users) { + my $quota=757; + my ($un,$pass,$uid,$gid) = split(/:/,$users{$uname}) or next; + if (defined($quota{$uname})) { + $quota+=$quota{$uname}; + } + my $hardquota = $quota * 1.25; + if ($hardquota != 0 && $hardquota < 100) { + $hardquota = 100; + } + + my ($block_curr, $block_soft, $block_hard) = Quota::query($dev, $uid); + if ($quota * 1024 != $block_soft || $hardquota * 1024 != $block_hard) { + print "Updating quota for $uname from ",($block_soft/1024)," MiB to $quota MiB\n"; + Quota::setqlim($dev, $uid, $quota * 1024, $hardquota * 1024, 0, 0); + } +} +system("/etc/init.d/nfs-kernel-server reload") if $reload_nfs; diff --git a/uquota/uquota.pl b/uquota/uquota.pl new file mode 100755 index 0000000..67dfb5d --- /dev/null +++ b/uquota/uquota.pl @@ -0,0 +1,34 @@ +#! /usr/bin/perl + +# Bare på nyere perl. Sukk. +# use warnings; +use strict; +use Quota; +use POSIX qw(strftime); + +my ($name,$passwd,$uid,$gid, $quota,$comment,$gcos,$dir,$shell,$expire) = getpwuid($<); +my ($block_curr, $block_soft, $block_hard, $block_timelimit, $inode_curr, $inode_soft, $inode_hard, $inode_timelimit) = Quota::query(Quota::getqcarg($dir)); + +if (! $block_hard && ! $block_soft) { + print "Du har uendelig kvote.\n"; +} + +my $filled = sprintf("%.1f", $block_curr * 100.0 / $block_soft); +my $max = "(ingen maksimum)"; +if ($block_hard) { + $max = sprintf("(max %.0f%%)",$block_hard * 100.0 / $block_soft); +} + +my $mb_curr = int($block_curr / 1024); +my $mb_soft = int($block_soft / 1024); + +my $days_timelimit = strftime("%Y-%m-%d %H:%M",localtime($block_timelimit)); + +print "Du har brukt ${mb_curr}MiB av ${mb_soft}MiB, eller ${filled}%.\n"; +if ($block_timelimit) { + print "Du er over kvoten din ${max}, og etter $days_timelimit\n"; + print "vil du miste skrivetilgang frem til du har slettet nok til å\n"; + print "komme under 100% igjen.\n"; +} else { + print "Du kan gå over kvoten din ${max} i opptil 7 dager.\n"; +}