File Coverage

blib/lib/App/PerlXLock.pm
Criterion Covered Total %
statement 17 45 37.7
branch 0 10 0.0
condition 0 3 0.0
subroutine 7 13 53.8
pod 0 8 0.0
total 24 79 30.3


line stmt bran cond sub pod time code
1             package App::PerlXLock;
2 1     1   821 use strict;
  1         2  
  1         47  
3 1     1   7 use warnings;
  1         2  
  1         37  
4 1     1   6 use base 'Exporter';
  1         2  
  1         169  
5             our $VERSION = "0.01";
6             our @EXPORT = qw(main_loop);
7 1     1   836 use Inline C => Config => LIBS => '-lX11';
  1         23980  
  1         9  
8             use Inline
9 1         4 C => "DATA",
10             NAME => "App::PerlXLock",
11             VERSION => '0.01',
12 1     1   199 INC => '/usr/include';
  1         2  
13              
14             END {
15             Inline->init();
16             }
17              
18             my @buffer;
19             my @windows;
20             my @screens;
21              
22             sub lock_all {
23 0     0 0 0 my $d = shift();
24 0         0 for ( 0 .. screen_count($d) - 1 ) {
25 0         0 push( @screens, $_ );
26 0         0 push( @windows, open_lock( $d, $_ ) );
27             }
28             }
29              
30             sub has_shadow {
31 1     1 0 35 -e "/etc/shadow";
32             }
33              
34             sub shadow_readable {
35 1     1 0 16 -r "/etc/shadow";
36             }
37              
38             sub password_accessible {
39 0 0   0 0   has_shadow() && shadow_readable();
40             }
41              
42             sub open_locks {
43 0     0 0   my $d = shift();
44 0           for (@windows) {
45 0           close_window( $d, $_ );
46             }
47             }
48              
49             sub check_event {
50 0     0 0   my $ev = read_event( $_[0] );
51 0 0         $ev > 0 ? push( @buffer, chr($ev) ) : undef;
52             }
53              
54             sub main_loop {
55 0     0 0   my $d = open_connection();
56 0           lock_all($d);
57 0           grab_keyboard( $d, 0 );
58 0           my $locked = 1;
59 0           while ($locked) {
60 0           check_event($d);
61 0 0 0       if ( $buffer[-1] && $buffer[-1] eq "\n" ) {
62 0           pop(@buffer);
63 0 0         if ( password_accessible() ) {
64 0           for my $n ( 0 .. $#buffer ) {
65 0 0         if ( check_password( join( "", @buffer[ $n .. $#buffer ] ) ) == 0 ) {
66 0           $locked = 0;
67             }
68             }
69             }
70             else {
71 0           $locked = 0;
72             }
73 0           @buffer = ();
74             }
75             }
76 0           unlock_all($d);
77 0           ungrab_keyboard($d);
78             }
79              
80             sub unlock_all {
81 0     0 0   my $d = shift;
82 0           destroy_window( $d, $_ ) for (@windows);
83             }
84              
85             has_shadow() || print "/etc/shadow does not exist. Xlock is not password protected.\n";
86             shadow_readable
87             || print "No permissions to read /etc/shadow. Xlock is not password protected.\n";
88              
89             1;
90              
91             __DATA__