]> arthur.barton.de Git - netatalk.git/blob - contrib/macusers/macusers.in
Merge remote-tracking branch 'origin/branch-netatalk-3-1'
[netatalk.git] / contrib / macusers / macusers.in
1 #!@PERL@
2
3 use strict;
4 use Socket;
5 use File::Basename;
6 use vars qw($MAIN_PID $NETATALK_PROCESS $AFPD_PROCESS $PS_STR $MATCH_STR $ASIP_PORT_NO $ASIP_PORT $LSOF);
7
8 # Written for linux; may have to be modified for your brand of Unix.
9 # Support for FreeBSD added by Joe Clarke <marcus@marcuscom.com>.
10 # Support Solaris added by Frank Lahm <franklahm@googlemail.com>.
11 # Support has also been added for 16 character usernames.
12
13 if ($ARGV[0] =~ /^(-v|-version|--version)$/ ) {
14         printf ("%s \(Netatalk @NETATALK_VERSION@\)\n", basename($0));
15         exit(1);
16 } elsif ($ARGV[0] =~ /^(-h|-help|--help)$/ ) {
17         printf ("usage: %s \[-v|-version|--version|-h|-help|--help\]\n", basename($0));
18         printf ("Show users connecting via AFP\n");
19         exit(1);
20 }
21
22 $NETATALK_PROCESS = "netatalk";
23 $AFPD_PROCESS = "afpd";
24 if ($^O eq "freebsd" || $^O eq "openbsd") {
25         $PS_STR    = "-awwxouser,pid,ppid,start,command";
26         $MATCH_STR = '(\w+)\s+(\d+)\s+(\d+)\s+([\d\w:]+)';
27 } elsif ($^O eq "solaris") {
28         $PS_STR    = "-eo user,pid,ppid,c,stime,tty,time,comm";
29         $MATCH_STR = '\s*(\w+)\s+(\d+)\s+(\d+)\s+\d+\s+([\d\w:]+)';
30 } else {
31         $PS_STR    = "-eo user:32,pid,ppid,c,stime,tty,time,cmd";
32         $MATCH_STR = '\s*(\w+)\s+(\d+)\s+(\d+)\s+\d+\s+([\d\w:]+)';
33 }
34 $ASIP_PORT    = "afpovertcp";
35 $ASIP_PORT_NO = 548;
36
37 # Change to 0 if you don't have lsof
38 $LSOF = 1;
39 my %mac = ();
40
41 if ($^O eq "freebsd") {
42         open(SOCKSTAT, "sockstat -4 | grep $AFPD_PROCESS | grep -v grep |");
43
44         while (<SOCKSTAT>) {
45                 next if ($_ !~ /$AFPD_PROCESS/);
46                 $_ =~
47                     /\S+\s+\S+\s+(\d+)\s+\d+\s+[\w\d]+\s+[\d\.:]+\s+([\d\.]+)/;
48                 my ($pid, $addr, $host);
49                 $pid  = $1;
50                 $addr = $2;
51                 $host = gethostbyaddr(pack('C4', split (/\./, $addr)), AF_INET);
52                 ($host) = ( $host =~ /(^(\d+\.){3}\d+|[\w\d\-]+)/ );
53                 $mac{$pid} = $host;
54         }
55         print
56             "PID      UID      Username         Name                 Logintime Mac\n";
57         close(SOCKSTAT);
58 } elsif ($^O eq "solaris") {
59         if ($< != 0) {
60             print "must be run as root\n";
61             exit(1);
62         }
63         print "PID      UID      Username         Name                 Logintime Mac\n";
64 } elsif ($LSOF == 1) {
65         open(LSOF, "lsof -i :$ASIP_PORT |");
66
67         while (<LSOF>) {
68                 next if ($_ !~ /$ASIP_PORT/);
69                 $_ =~ /\w+\s+(\d+).*->([\w\.-]+).*/;
70                 my ($pid, $host);
71                 $pid  = $1;
72                 $host = $2;
73                 ($host) = ( $host =~ /(^(\d+\.){3}\d+|[\w\d\-]+)/ );
74                 $mac{$pid} = $host;
75         }
76         print
77             "PID      UID      Username         Name                 Logintime Mac\n";
78         close(LSOF);
79 } else {
80         print
81             "PID      UID      Username         Name                 Logintime\n";
82 }
83
84 open(PS, "ps $PS_STR |") || die "Unable to open a pipe to ``ps''";
85
86 $MAIN_PID = 1;
87 while (<PS>) {
88         next if ($_ !~ /$NETATALK_PROCESS/);
89         my ($user, $pid, $ppid, $time, $name, $uid, $t, $ip);
90         $_ =~ /$MATCH_STR/;
91         $MAIN_PID = $2;
92 }
93
94 close(PS);
95 open(PS, "ps $PS_STR |") || die "Unable to open a pipe to ``ps''";
96
97 while (<PS>) {
98         next if ($_ !~ /$AFPD_PROCESS/);
99         my ($user, $pid, $ppid, $time, $name, $uid, $t, $ip);
100         $_ =~ /$MATCH_STR/;
101         $user = $1;
102         $pid  = $2;
103         $ppid = $3;
104         $time = $4;
105
106         if ($ppid != $MAIN_PID) {
107                 if ($^O eq "solaris") {
108                         open(PFILES, "pfiles $pid |");
109                         while (<PFILES>) {
110                                 next if ($_ !~ /port: $ASIP_PORT_NO/);
111                                 while (<PFILES>) {
112                                         next if ($_ !~ /peername/);
113                                         if ($_ =~ /AF_INET (.*) port/) {
114                                             $ip = $1;
115                                             if ($ip =~ /::ffff:(.*)/ ) {
116                                                 $ip = $1;
117                                             }
118                                         }
119                                         $mac{$pid} = $ip;
120                                         last;
121                                 }
122                                 last;
123                         }
124                         close(PFILES);
125                 }
126
127                 ($t, $t, $uid, $t, $t, $t, $name, $t, $t) = getpwnam($user);
128                 ($name) = ( $name =~ /(^[^,]+)/ );
129                 printf "%-8d %-8d %-16s %-20s %-9s %s\n", $pid, $uid, $user,
130                     $name, $time, $mac{$pid};
131         }
132 }
133
134 close(PS);