3 # CLI admin client for the FEX service
5 # Author: Ulli Horlacher <framstag@rus.uni-stuttgart.de>
12 use Digest::MD5 'md5_hex';
14 use constant M => 1024*1024;
15 use constant DS => 60*60*24;
18 exit if $ENV{SCRIPT_NAME};
20 unless ($FEXLIB = $ENV{FEXLIB}) {
22 $FEXLIB = $ENV{FEXHOME}.'/lib';
23 } elsif (-f '/usr/share/fex/lib/fex.ph') {
24 $FEXLIB = '/usr/share/fex/lib';
26 $FEXLIB = dirname(dirname(abs_path($0))).'/lib';
28 $ENV{FEXLIB} = $FEXLIB;
30 die "$0: no FEXLIB\n" unless -f "$FEXLIB/fex.pp";
32 # become effective user fex
34 if (my @pw = getpwnam('fex')) {
39 die "$0: no such user 'fex'\n";
46 our ($FEXHOME,$FHS,$hostname,$spooldir,@logdir,$logdir,$akeydir,$docdir);
47 our ($durl,@durl,$mdomain,$admin,$mailmode);
48 our ($autodelete,$keep_default,$keep_max,$recipient_quota,$sender_quota);
49 our (@local_rdomains);
50 local $notification = 'full';
52 # load common code, local config : $HOME/lib/fex.ph
53 require "$FEXLIB/fex.pp" or die "$0: cannot load $FEXLIB/fex.pp - $!\n";
55 die "$0: \$admin not configured in $FEXLIB/fex.ph\n" unless $admin;
57 $EDITOR = $ENV{EDITOR} || $ENV{VISUAL} ||
58 (-x '/usr/bin/editor' ? '/usr/bin/editor' : 'vi');
60 $opt_c = $opt_v = $opt_l = $opt_L = $opt_h = $opt_w = $opt_u = 0;
62 $opt_r = $opt_d = $opt_q = $opt_a = $opt_n = $opt_k = $opt_m = '';
63 $opt_y = $opt_S = $opt_C = $opt_D = $opt_A = $opt_V = $opt_P = $opt_R = '';
67 while (my $a = shift @__) {
75 chdir $spooldir or die "$0: no $spooldir\n";
77 @stat = stat $spooldir or die "$0: cannot access $spooldir - $!\n";
78 warn "WARNING: $spooldir with owner=root !?\n" unless $stat[4];
79 if (abs_path($spooldir) ne abs_path("$FEXHOME/spool")) {
80 warn "WARNING: \$spooldir differs from $FEXHOME/spool !\n";
83 getopts('hcvlLwuME/q:r:d:a:n:k:m:y:S:C:A:V:D:P:R:') or usage(2);
89 my $id = shift or die "usage: $0 -/ admin-email-address auth-ID\n";
90 if ($admin !~ /.\@[\w.-]+\.[a-z]+$/) {
91 die "$0: $admin is not an email address\n";
94 my $aa = "$spooldir/$admin/@";
95 open $aa,'>',$aa or die "$0: cannot write $aa - $!\n";
97 close $aa or die "$0: cannot write $aa - $!\n";
98 my $fph = "$FEXLIB/fex.ph";
99 $_ = slurp($fph) or die "$0: cannot read $fph\n";
100 s/^\s*\$admin\s*=.*/\$admin = '$admin';/m or
101 $_ = "\$admin = '$admin';\n".$_;
102 open $fph,">$fph.new" or die "$0: cannot write $fph.new\n";
105 rename "$fph.new",$fph or die "$0: cannot rename $fph.new to $fph\n";
106 my $fid = "$ENV{HOME}/.fex/id";
108 rename $fid,$fid.'_save';
109 open $fid,'>',$fid or die "$0: cannot create $fid - $!\n";
110 if ($durl =~ m{(https?://.+?)/}) {
113 print {$fid} "$hostname\n";
115 print {$fid} "$admin\n";
116 print {$fid} "$id\n";
118 print "new admin account: $admin\n";
125 while (my ($hh,$vh) = each (%vhost)) {
126 if ($opt_V eq basename($vh) or $opt_V eq $hh) {
127 $ENV{HTTP_HOST} = $hh;
128 $ENV{VHOST} = "$hh:$vh";
129 $ENV{FEXLIB} = "$vh/lib";
130 die "$0: no $ENV{FEXLIB}/fex.ph\n" unless -f "$ENV{FEXLIB}/fex.ph";
132 die "$0: cannot re-exec\n";
135 die "$0: no virtual host $opt_V defined\n";
139 $fup =~ s:/[^/]+$:/fup:;
143 if ($opt_m eq 'exit') {
144 if (unlink '@MAINTENANCE') {
145 warn "$0: leaving maintenance mode\n";
147 warn "$0: no maintenance mode\n";
150 unlink '@MAINTENANCE';
151 symlink $opt_m,'@MAINTENANCE'
152 or die "$0: cannot write $spooldir/\@MAINTENANCE - $!";
153 warn "$0: entering maintenance mode\n";
158 # list files or resend notification e-mails
160 my ($mtime,$comment,$file,$keep);
164 foreach $file (glob("@ARGV")) {
165 $mtime = mtime("$file/data") or next;
166 $comment = slurp("$file/comment")||'';
167 next if $comment =~ /NOMAIL/;
168 $keep = readlink "$file/keep"
169 || readlink "$file/../../\@KEEP"
171 $keep = $keep - int((time-mtime("$file/data"))/60/60/24);
175 dkey => readlink "$file/dkey",
176 filename => filename($file),
179 warn => int(($mtime-time)/DS)+$keep,
180 autodelete => readlink "$file/autodelete" || $autodelete,
182 print "send notification e-mail for $file\n";
186 foreach $file (glob "*/*/*/data") {
187 next if $file =~ /^_?(anonymous|fexmail)/;
189 $comment = "$file/comment";
190 if (open $comment,$comment and <$comment> =~ /NOMAIL/) {
201 $log = "$logdir/fexsrv.log";
202 warn "$0: polling $log\n\n";
203 exec "$FEXHOME/bin/logwatch",$log;
204 die "$0: logwatch not found\n";
207 # list files and download URLs
210 chdir $spooldir or die "$0: $spooldir - $!\n";
211 foreach $file (glob "*/*/*") {
212 if (-s "$file/data" and
213 $dkey = readlink("$file/dkey") and
216 push @L,sprintf "%2\$s --> %1\$s : $durl/$dkey/%3\$s\n",split "/",$file;
223 # list files detailed
226 my ($comment,$file,$keep,$old,$size,$download);
229 foreach $file (glob "*/*/*/data") {
230 next if $file =~ m:(.+?)/: and -l $1;
231 $size = -s $file or next;
233 next if $filter and $file !~ /$filter/;
234 $comment = slurp("$file/comment")||'';
235 $dkey = readlink("$file/dkey")||'';
236 $keep = readlink("$file/keep")||$keep_default;
237 $old = int((time-mtime("$file/data"))/60/60/24);
238 $download = join(' & ',split("\n",(slurp("$file/download")||'')));
240 printf " comment: %s\n",decode_utf8($comment);
241 printf " size: %s\n",d3($size);
242 printf " sender ip: %s\n",readlink("$file/ip")||'';
243 printf " expire in: %s days\n",$keep-$old;
244 printf " upload speed: %s kB/s\n",readlink("$file/speed")||0;
245 printf " URL: $durl/$dkey/%3\$s\n",split "/",$file;
246 printf " download: %s\n",$download;
253 $idf = "$spooldir/$opt_d/\@";
254 die "$0: no such user $opt_d\n" unless -f $idf;
255 unlink $idf or die "$0: cannot remove $idf - $!\n";
256 foreach $rf (glob "$spooldir/$opt_d/\@*") { unlink $rf }
257 print "$opt_d deleted\n";
261 # set user restriction file
264 $user = shift or die "usage: $0 -Ri user\n";
265 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
266 die "$0: no user $user\n" unless -d "$spooldir/$user";
267 unless (@local_rdomains) {
268 die "$0: no \@local_rdomains in server config\n";
270 my $rf = "$spooldir/$user/\@ALLOWED_RECIPIENTS";
271 open $rf,'>',$rf or die "$0: cannot open $rf - $!";
272 print {$rf} "\@LOCAL_RDOMAINS\n";
274 print "$user restricted to internal recipients\n";
276 } elsif ($opt_R eq 'l') {
277 $user = shift or die "usage: $0 -Rl user\n";
278 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
279 die "$0: no user $user\n" unless -d "$spooldir/$user";
280 my $rf = "$spooldir/$user/\@ALLOWED_RECIPIENTS";
281 open $rf,'>',$rf or die "$0: cannot open $rf - $!";
282 print {$rf} "\@LOCAL_USERS\n";
284 print "$user restricted to local recipients\n";
292 # edit user restriction file
294 if ($opt_r =~ /^r/i) { $opt_r = 'ALLOWED_RECIPIENTS' }
295 elsif ($opt_r =~ /^u/i) { $opt_r = 'UPLOAD_HOSTS' }
296 elsif ($opt_r =~ /^d/i) { $opt_r = 'DOWNLOAD_HOSTS' }
298 $user = shift or usage(2);
299 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
300 die "$0: no user $user\n" unless -d "$spooldir/$user";
301 my $rf = "$spooldir/$user/\@$opt_r";
303 open $rf,'>',$rf or die "$0: cannot open $rf - $!";
304 if ($opt_r eq 'ALLOWED_RECIPIENTS') {
306 # Restrict allowed recipients. Only listed addresses are allowed as recipients.
307 # Make this file COMPLETLY empty if you want to disable the restriction.
308 # An allowed recipient is an e-mail address. You can use * as wildcard.
310 # framstag\@rus.uni-stuttgart.de
313 } elsif ($opt_r eq 'UPLOAD_HOSTS') {
315 # Restrict allowed upload hosts.
316 # Only listed addresses are allowed as upload hosts.
317 # Make this file COMPLETLY empty if you want to disable the restriction.
318 # You can add single ip adresses or ip ranges.
321 # 10.0.10.0-10.0.10.255
323 } elsif ($opt_r eq 'DOWNLOAD_HOSTS') {
325 # Restrict allowed download hosts.
326 # Only listed addresses are allowed as download hosts.
327 # Make this file COMPLETLY empty if you want to disable the restriction.
328 # You can add single ip adresses or ip ranges.
331 # 10.0.10.0-10.0.10.255
334 die "$0: unknown option -r $opt_r\n";
339 unlink $rf if -s $rf<5;
345 exec $EDITOR,"$FEXLIB/fex.ph";
350 if ($opt_A =~ /(.+):(.+)/) {
354 die "usage: $0 -A alias:hostname\n".
355 "example: $0 -A flupp:fex.flupp.org\n";
358 $vhd = "/var/lib/fex/vhosts/$vhost";
359 mkdir $vhd or die "$0: cannot mkdir $vhd - $!\n";
360 mkdir "/etc/fex/vhosts/$vhost";
361 symlink "/etc/fex/vhosts/$vhost", "$vhd/lib";
362 mkdir "$spooldir/vhosts/$vhost";
363 symlink "$spooldir/vhosts/$vhost","$vhd/spool";
365 $vhd = "$FEXHOME/$vhost";
366 mkdir $vhd or die "$0: cannot mkdir $vhd - $!\n";
372 mkdir "$vhd/htdocs/locale";
373 $_ = slurp("$FEXLIB/fex.ph");
374 s/\$hostname\s*=.*/\$hostname = '$hhost';/ or s/^/\$hostname = '$hhost';\n/;
375 $fph = "$vhd/lib/fex.ph";
376 open $fph,">$fph" or die "$0: cannot write to $fph - $!\n";
379 cpa("$FEXLIB/fup.pl","$vhd/lib");
380 foreach $i (qw'dop fex.pp fup.pl lf.pl reactivation.txt') {
381 # symlink "$FEXLIB/$i","$vhd/lib/$i";
382 symlink "../../lib/$i","$vhd/lib/$i";
385 index.html tools.html SEX.html robots.txt
386 logo.jpg small_logo.jpg action-fex-camel.gif favicon.ico
389 cpa("$docdir/$i","$vhd/htdocs");
391 symlink "$docdir/version","../../htdocs/version";
392 symlink "$docdir/download","../../htdocs/download";
393 cpa("$FEXHOME/locale",$vhd);
394 foreach $ld (glob "$vhd/locale/*") {
395 if (not -l $ld and -d "$ld/cgi-bin") {
396 $locale = basename($ld);
398 # symlink "../../../locale/$locale/cgi-bin","$ld/cgi-bin";
399 symlink "../../../locale/$locale/htdocs","$vhd/htdocs/locale/$locale";
400 unlink "$ld/lib/fex.ph";
401 symlink "../../../lib/fex.ph","$ld/lib/fex.ph";
402 symlink "../../../../locale/$locale/lib","$ld/lib/master";
403 foreach $f (qw'dop fex.pp lf.pl reactivation.txt') {
405 symlink "master/$f","$ld/lib/$f";
409 $fph = "$FEXLIB/fex.ph";
410 open $fph,">>$fph" or die "$0: cannot write to $fph = $!\n";
411 print {$fph} "\n\$vhost{'$hhost'} = '$vhd';\n";
413 print "You must now edit and configure $vhd/lib/fex.ph\n";
414 print "or execute: $0 -V $vhost -c\n";
419 if ($opt_v and not @ARGV) {
420 print "config from $FEXLIB/fex.ph :\n";
421 print " spooldir = $spooldir\n";
422 print " logdir = @logdir\n";
423 print " docdir = $docdir\n";
424 print " durl = @durl\n";
425 print " admin = $admin\n";
426 print " mdomain = $mdomain\n";
427 print " mailmode = $mailmode\n";
428 print " autodelete = $autodelete\n";
429 print " keep_default = $keep_default\n";
430 printf " keep_max = %s\n",$keep_max||'unlimited';
431 printf " recipient_quota = %d GB\n",int($recipient_quota/1024);
432 printf " sender_quota = %d GB\n",int($sender_quota/1024);
433 while (($hh,$vh) = each %vhost) {
434 printf " virtual server %s : %s\n",basename($vh),$hh;
437 # foreach $ph (glob "$ENV{HOME}/*/lib/fex.ph") {
438 # $ENV{FEXLIB} = dirname($ph);
440 # system $0,'-v',$ph;
443 if ($m = readlink '@MAINTENANCE') {
444 print "server is in maintenance mode ($m)!\n" ;
449 # add user or show user config
451 chdir $spooldir or die "$0: cannot chdir $spooldir = $!\n";
452 if ($opt_u = shift @ARGV) {
454 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
457 if (open $idf,$idf) {
458 chomp($ido = <$idf>||'');
462 die "$0: $user is not a regular FEX user\n" unless -f "$user/@";
463 showuser($user,$ido);
466 unless ($user =~ /\w@[\w.-]+\.[a-z]+$/) {
467 die "$0: $user is not a valid email-address!\n";
471 or die "$0: cannot mkdir $user - $!\n";
473 open F,">$idf" or die "$0: cannot write $idf - $!\n";
475 close F or die "$0: cannot write $idf - $!\n";
478 print "Users in $spooldir:\n";
479 foreach $user (glob "*/@") {
480 $user =~ s:.*/(.+)/@:$1:;
487 # set user autodelete default
490 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
491 $_ = shift @ARGV || '';
492 if (/^n/i) { $autodelete = 'no' }
493 elsif (/^y/i) { $autodelete = 'yes' }
494 elsif (/^d/i) { $autodelete = 'delay' }
496 die "usage: $0 -a user yes\n".
497 "usage: $0 -a user no\n".
498 "usage: $0 -a user delay\n".
499 "example: $0 -a framstag\@rus.uni-stuttgart.de no\n";
501 mkdir "$spooldir/$user",0755;
502 my $adf = "$spooldir/$user/\@AUTODELETE";
504 symlink $autodelete,$adf or die "$0: cannot create symlink $adf - $!\n";
508 # set user notification default
511 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
512 $_ = shift @ARGV || '';
513 if (/^n/i) { $notification = 'no' }
514 elsif (/^[sb]/i) { $notification = 'short' }
515 elsif (/^[fd]/i) { $notification = '' }
517 die "usage: $0 -n user no\n".
518 "usage: $0 -n user brief\n".
519 "usage: $0 -n user detailed\n".
520 "example: $0 -n framstag\@rus.uni-stuttgart.de brief\n";
522 mkdir "$spooldir/$user",0755;
523 my $ndf = "$spooldir/$user/\@NOTIFICATION";
526 symlink $notification,$ndf or die "$0: cannot create symlink $ndf - $!\n";
531 # set user keep default
534 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
535 my $keep = shift @ARGV || '';
536 if ($keep !~ /^\d+$/) {
537 die "usage: $0 -k user keep_days\n".
538 "example: $0 -k framstag\@rus.uni-stuttgart.de 30\n";
540 mkdir "$spooldir/$user",0755;
541 my $kf = "$spooldir/$user/\@KEEP";
543 symlink $keep,$kf or die "$0: cannot create symlink $kf - $!\n";
550 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
551 unless (-d "$spooldir/$user") {
552 die "$0: $user is not a FEX user\n";
560 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
561 unless (-f "$spooldir/$user/@") {
562 die "$0: $user is not a regular FEX user\n";
564 $_ = shift @ARGV || '';
566 open $user,">>$spooldir/$user/\@CAPTIVE";
568 print "$user is now captive\n";
570 unlink "$spooldir/$user/\@CAPTIVE";
571 print "$user is no more captive\n";
573 die "usage: $0 -C user yes\n".
574 "usage: $0 -C user no\n".
575 "example: $0 -C framstag\@rus.uni-stuttgart.de no\n";
580 # FEXYOURSELF = user can only fex to himself via web interface
583 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
584 unless (-f "$spooldir/$user/@") {
585 die "$0: $user is not a regular FEX user\n";
587 $_ = shift @ARGV || '';
589 open $user,">>$spooldir/$user/\@FEXYOURSELF";
591 print "$user has now \"fex yourself\" web default\n";
593 unlink "$spooldir/$user/\@FEXYOURSELF";
594 print "$user has no \"fex yourself\" web default\n";
596 die "usage: $0 -y user yes\n".
597 "usage: $0 -y user no\n".
598 "example: $0 -y framstag\@rus.uni-stuttgart.de no\n";
605 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
608 unlink "$spooldir/$user/\@DISABLED";
609 print "$user is now enabled\n";
611 open $user,">>$spooldir/$user/\@DISABLED";
612 print {$user} "@ARGV\n";
614 print "$user is now disabled\n";
621 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
622 $_ = shift @ARGV || '';
624 open $user,">>$spooldir/$user/\@PERSISTENT";
626 print "$user is now persistent\n";
628 unlink "$spooldir/$user/\@PERSISTENT";
629 print "$user is no more persistent\n";
631 die "usage: $0 -P user yes\n".
632 "usage: $0 -P user no\n".
633 "example: $0 -P framstag\@rus.uni-stuttgart.de yes\n";
638 if ($opt_S eq 'fup') {
643 if ($opt_S eq 'fop') {
653 my ($keep,$autodelete,$notification,$login);
655 $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
657 print "[using config $FEXLIB/fex.ph]\n";
658 print "$fup?from=$user&id=$id\n";
659 printf "%s/%s\n",$fup,b64("from=$user&id=$id");
660 # printf "%s/%s\n",$fup,b64("from=$user&to=$user&id=$id&submit=.");
661 print "spool: $spooldir/$user/\n";
662 if ($login_check and $login = readlink "$user/.login") {
663 my $lc = &$login_check($login);
665 print "login: $login\n";
667 print "login: DELETED\n";
671 if (-e "$spooldir/$user/\@DISABLED") {
672 $disabled = slurp("$spooldir/$user/\@DISABLED");
676 printf "fex yourself web default: %s\n",
677 -e "$spooldir/$user/\@FEXYOURSELF" ? 'yes' : 'no';
678 printf "persistent: %s\n",
679 -e "$spooldir/$user/\@PERSISTENT" ? 'yes' : 'no';
680 printf "captive: %s\n",
681 -e "$spooldir/$user/\@CAPTIVE" ? 'yes' : 'no';
682 printf "disabled: %s\n",$disabled;
683 printf "recipients restrictions: %s\n",
684 -e "$spooldir/$user/\@ALLOWED_RECIPIENTS" ? 'yes' : 'no';
685 printf "upload restrictions: %s\n",
686 -e "$spooldir/$user/\@UPLOAD_HOSTS" ? 'yes' : 'no';
687 printf "download restrictions: %s\n",
688 -e "$spooldir/$user/\@DOWNLOAD_HOSTS" ? 'yes' : 'no';
689 $autodelete = lc(readlink "$spooldir/$user/\@AUTODELETE" || $::autodelete);
690 print "autodelete default: $autodelete\n";
691 $notification = lc(readlink "$spooldir/$user/\@NOTIFICATION" || $::notification);
692 print "notification default: $notification\n";
693 $keep = readlink "$spooldir/$user/\@KEEP" || $keep_default;
694 print "keep default: $keep\n";
696 printf "account creation: %s\n",slurp("$spooldir/$user/.auto")||'manual';
699 # set or show disk quota
704 my $qf = "$spooldir/$user/\@QUOTA";
710 $rquota = $1 if /recipient.*?(\d+)/i;
711 $squota = $1 if /sender.*?(\d+)/i;
718 $rquota = $1 if /^r.*:(\d*)/i;
719 $squota = $1 if /^s.*:(\d*)/i;
721 open $qf,'>',$qf or die "$0: cannot write $qf - $!\n";
722 print {$qf} "recipient:$rquota\n" if $rquota;
723 print {$qf} "sender:$squota\n" if $squota;
727 printf "recpient quota (used): %d (%d) MB\n",check_recipient_quota($user);
728 printf "sender quota (used): %d (%d) MB\n",check_sender_quota($user);
733 my (%user,%domain,%du);
737 if (-t) { $log = "$logdir/fup.log" }
738 else { $log = '>&=STDIN' }
739 open $log,$log or die "$0: cannot open $log - $!\n";
742 if (/^([\d: -]+) (\[[\d_]+\] )?(\w\S*) .* (\d+)$/) {
745 $u .= '@'.$mdomain if $mdomain and $u !~ /@/;
749 $d =~ s/.*\.(.+\.\w+)/$1/;
756 foreach $u (sort {$user{$a} <=> $user{$b}} keys %user) {
757 printf "%s : %d\n",$u,$user{$u}/M;
759 print "========================================================\n";
760 foreach $d (sort {$domain{$a} <=> $domain{$b}} keys %domain) {
761 printf "%s : %d MB, %d user\n",$d,$domain{$d}/M,scalar(keys %{$du{$d}});
763 printf "Total: %d GB\n",$Z/M/1024;
772 my (%user,%domain,%du);
774 if (-t) { $log = "$logdir/fop.log" }
775 else { $log = '>&=STDIN' }
776 open $log,$log or die "$0: cannot open $log - $!\n";
779 if (/^([\d: -]+) (\[[\d_]+\] )?[\d.]+ (.+?)\/.* (\d+)\/\d+/) {
782 $u .= '@'.$mdomain if $mdomain and $u !~ /@/;
786 $d =~ s/.*\.(.+\.\w+)/$1/;
793 foreach $u (sort {$user{$a} <=> $user{$b}} keys %user) {
794 printf "%s : %d\n",$u,$user{$u}/M;
796 print "========================================================\n";
797 foreach $d (sort {$domain{$a} <=> $domain{$b}} keys %domain) {
798 printf "%s : %d MB, %d user\n",$d,$domain{$d}/M,scalar(keys %{$du{$d}});
800 printf "Total: %d GB\n",$Z/M/1024;
809 die "(cpa): $dd is not a directory" unless -d $dd;
810 system "rsync -a @_ $dd/" ;
816 my $admin_id = slurp("$spooldir/$admin/@") or
817 die "$0: no admin account - you have to create it with:\n".
818 "$0 -/ $admin ".randstring(8)."\n";
822 my $fid = "$ENV{HOME}/.fex/id";
823 if (open $fid,$fid) {
825 chomp($_ = <$fid>||'');
827 warn "WARNING: user $admin not in $fid\n";
830 chomp($_ = <$fid>||'');
831 if ($_ ne $admin_id) {
832 warn "WARNING: $admin auth-ID mismatch in $fid\n";
837 warn "$0: moving $fid to ${fid}_save\n";
838 rename $fid,$fid.'_save';
843 open $fid,'>',$fid or die "$0: cannot create $fid - $!\n";
844 if ($durl =~ m{(https?://.+?)/}) {
847 print {$fid} "$hostname\n";
849 print {$fid} "$admin\n";
850 print {$fid} "$admin_id\n";
852 warn "$0: new $fid created\n";
859 while (s/(\d)(\d\d\d\b)/$1,$2/) {};
868 if ($durl =~ /:(\d+)/) { $port = ":$1" }
869 if ($durl =~ /^(https?)/) { $proto = $1 }
874 $0 -u # list full users
875 $0 -u user # show user config
876 $0 -u user auth-ID # create new user or set new auth-ID
877 $0 -/ admin auth-ID # set new admin and auth-ID
878 $0 -q user s:quota # set new disk quota (MB) for sender user
879 $0 -q user r:quota # set new disk quota (MB) for recipient user
880 $0 -Ri user # restrict user: only internal domain recipients allowed
881 $0 -Rl user # restrict user: only local users as recipients allowed
882 $0 -rr user # edit user recipients restriction
883 $0 -ru user # edit user upload restriction
884 $0 -rd user # edit user download restriction
885 $0 -d user # delete user
886 $0 -D user "reason" # disable user
887 $0 -D user "no" # re-enable user
888 $0 -P user [yn] # make user persistent = no account expiration (yes,no)
889 $0 -a user [ynd] # set user autodelete default (yes,no,delay)
890 $0 -n user [dbn] # set user notification default (detailed,brief,no)
891 $0 -k user days # set user keep default in days
892 $0 -C user [yn] # set user captive (yes,no)
893 $0 -y user [yn] # set user "fex yourself" web default (yes,no)
894 $0 -S fup # file upload statistics
895 $0 -S fop # file download statistics
896 $0 -v # show server config
897 $0 -c # edit server config
898 $0 -w # watch fexsrv.log (continously)
899 $0 -l # list pending files with download URLs
900 $0 -L [filter] # list pending files in detail
901 $0 -M # list pending files with TO/FROM/FILE
902 $0 -M TO/FROM/FILE # resend notification email
903 $0 -m "reason" # enter maintenance mode (reason "exit" to leave)
904 $0 -E # show usage examples
906 # $0 -A alias:hostname # add new virtual server
907 # $0 -V virtualhost ... # operations on virtualhost (alias or hostname)
908 if (-x "$FEXHOME/cgi-bin/fac") {
909 print "See also web admin interface $proto://$hostname$port/fac\n";
918 $0 -u framstag\@rus.uni-stuttgart.de schwubbeldidu
920 set 10 GB sender quota for this user:
921 $0 -q framstag\@rus.uni-stuttgart.de s:10240
923 set file expiration to 30 days for this user:
924 $0 -k framstag\@rus.uni-stuttgart.de 30
926 disable account expiration for this user:
927 $0 -P framstag\@rus.uni-stuttgart.de y
929 list spooled files and resend notification email for this file:
931 $0 -M framstag\@rus.uni-stuttgart.de/hoppel\@flupp.org/jump.avi