Completed
Branch — master (f6660f)
by Stefan
02:22
created

SSVNCDaemon.php (13 issues)

1
<?php
2
3
// Copyright (C) 2014 Universitätsbibliothek Mannheim
4
// See file LICENSE for license details.
5
6
require_once("DBConnector.class.php");
7
8
class SSVNCDaemon
9
{
10
11
    // all during session connected VNC Clients
12
    private $_VNC_CLIENTS;
13
14
    // count of all connected clients
15
    // private $_VNC_CLIENT_COUNT;
16
17
    // active client count
18
    private $_CONNECTIONS = 0;
19
20
    // ignored VNC Clients
21
    // TODO: check if no more longer helpful, has to be cleaned
22
    private $_IGNORE_LIST = array();
23
24
    public $db;
25
26
    public function __construct()
27
    {
28
        global $db;
29
        $this->db = $db;
30
31
        // Start Vncviewer
32
        $handle = $this->startVNCViewer();
33
34
        // Read log in loop
35
        $this->readLog($handle);
36
    }
37
38
    protected function startVNCViewer()
39
    {
40
        // Startup SSVNC-Viewer in Multilisten-Mode
41
        $cmd = "export DISPLAY=" . CONFIG_DISPLAY .
42
        "; killall -q ssvncviewer; ssvncviewer -viewonly -multilisten 0 2>&1";
43
        $handle = popen($cmd, 'r');
44
        print("[Daemon]: vnc_viewer started");
45
46
        return $handle;
47
    }
48
49
    protected function readLog($handle)
50
    {
51
        print("\n[Daemon]: +++ readLog() +++");
52
53
        // local SSVNC-Client info
54
        $client = array(
55
                    "ip" => "",
56
                    "hostname" => "",
57
                    "active" => 1,
58
                    "exit" => 0
59
                    );
60
61
        // Read File continuously
62
        while (!feof($handle)) {
63
64
            $buffer = fgets($handle);
65
            print($buffer);
66
67
            if ($this->_CONNECTIONS == 0) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
68
                //print("\n --- WAITING FOR NEW CONNECTIONS --- \n");
69
            }
70
71
            $ip = $this->parseIP($buffer);
72
            $hostname = $this->parseHostname($buffer);
73
            $exit = $this->parseExit($buffer);
74
75
            if ($ip!="") {
76
                $client["ip"] = $ip;
77
            }
78
            if ($hostname!="") {
79
                $client["hostname"] = $hostname;
80
            }
81
            if ($exit!=0) {
82
                $client["exit"] = $exit;
83
            }
84
85
            if (strstr($buffer, 'create_image') && $client["ip"] != "" &&
86
            $client["hostname"]!="" ) {
87
88
                // add client
89
                $this->addClient($client["ip"], $client["hostname"]);
90
91
                // reset local Client information after adding it
92
                $client["ip"] = "";
93
                $client["hostname"] = "";
94
            }
95
96
            if ($exit == 1) {
97
98
                // decrease active client count
99
                if ($this->_CONNECTIONS > 0) {
100
                    $this->_CONNECTIONS--;
101
                    $this->deleteInactiveVncWindow();
102
                }
103
            }
104
105
            $halt=$this->_CONNECTIONS;
106
107
            if ($halt == -1) {
108
                exit(0);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
109
            }
110
111
            flush();
112
113
        }
114
115
        pclose($handle);
116
117
    }
118
119
    protected function parseIP($buffer)
120
    {
121
        $ip = "";
122
        $line = $buffer;
123
        if (strpos($line, "Reverse VNC connection from IP")) {
124
            $line=trim($line);
125
            $item=explode(":", $line);
126
            $ip=trim($item[1]);
127
            $ip=preg_replace('/\W\W\d{4}\/\d{2}\/\d{2} \d{2}/', '', $ip);
128
        }
129
130
        if ($ip!="") {
131
            print("\nFOUND IP: " . $ip . "\n");
132
        }
133
134
        return $ip;
135
    }
136
137
    protected function parseHostname($buffer)
138
    {
139
        $hostname = "";
140
        $line = $buffer;
141
        if (strpos($line, "Hostname")) {
142
            $line=trim($line);
143
            $item=explode(":", $line);
144
            $hostname=trim($item[1]);
145
            $hostname=preg_replace('/\.uni\-mannheim\.de/', '', $hostname);
146
        }
147
148
        if ($hostname!="") {
149
            print("\nFOUND HOSTNAME: " . $hostname . "\n");
150
        }
151
152
        return $hostname;
153
    }
154
155
    protected function parseExit($line)
156
    {
157
        $exit = 0;
158
        if (strpos($line, "VNC Viewer exiting")) {
159
            $exit = 1;
160
        }
161
162
        if ($exit!=0) {
163
            print("\nCLIENT HAS DISCONNECTED " . $exit . "\n");
164
        }
165
166
        return $exit;
167
    }
168
169
    protected function addClient($ip, $hostname)
170
    {
171
        $vncclient = array(
172
                        "ip" => $ip,
173
                        "hostname" => $hostname,
174
                        "active" => 1,
175
                        "exit" => 0
176
                        );
177
        if (count($this->_VNC_CLIENTS) == 0) {
178
            $id=1;
179
        } else {
180
            $id=count($this->_VNC_CLIENTS) + 1;
181
        }
182
183
        $this->_VNC_CLIENTS[$id] = $vncclient;
184
185
        print("\nCLIENT OBJECT with ID " . $id . " CREATED : "
186
            . $vncclient["ip"] . " | " . $vncclient["hostname"] . " | "
187
            . $vncclient["active"] . " | " . $vncclient["exit"] . "\n");
188
        print($this->_CONNECTIONS+1 . " CLIENT(S) CONNECTED ...");
189
190
        $this->sendVncWindowToNuc($id, $vncclient);
191
192
        $this->_CONNECTIONS++;
193
194
        print("\n active connections: ".$this->_CONNECTIONS+1);
195
        print("\n all saved clients: " . serialize($this->_VNC_CLIENTS));
196
197
    }
198
199
    protected function sendVncWindowToNuc($id, $vncclient)
200
    {
201
        print("\n[Daemon]: +++sendVncWindowToNuc() +++ ");
202
203
        $vnc_id = $vncclient["hostname"] . "-" . $id;
204
205
        $db = new DBConnector();
206
207
        // already existing in db?
208
        $clients_in_db = array();
209
        $client_info = $db->getVNC_ClientInfo();
210
211
        foreach ($client_info as $info) {
212
            $clients_in_db[] = $info["file"];
213
        }
214
215
        $ip = $vncclient["ip"];
216
        $name = $db->querySingle('SELECT user.name FROM address, user
217
                                  WHERE user.userid = (
218
                                    SELECT address.userid
219
                                    FROM address
220
                                    WHERE address.address ="' . $ip . '"
221
                                  )');
222
223
        // print("\n[Daemon]: USERNAME : " . $name);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
224
225
        // $vncClientCount = $db->querySingle('SELECT count(id) FROM window WHERE handler = "vnc"');
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
226
        // $vncClientsAll = $db->query("SELECT user.name FROM address");
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
227
228
        // print("\n[Daemon]: clients in db = " . $vncClientCount);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
229
        // print("\n[Daemon]: clients ignored = " . serialize($this->_IGNORE_LIST));
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
230
231
        // if vnc_id not in database create window and send to nuc
232
        if (!(in_array($vnc_id, $clients_in_db))) {
233
234
            // print("\n[Daemon]: insert $vnc_id into db");
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
235
236
            $dt = new DateTime();
237
            $date = $dt->format('Y-m-d H:i:s');
238
239
            $window = array(
240
                "id" => "",
241
                "win_id" => "",
242
                "name" => "",
243
                "state" => "",
244
                "file" => $name . "@" . $vnc_id,
245
                "handler" => "vnc",
246
                "userid" => $name,
247
                "date" => $date
248
            );
249
250
            $serializedWindow = serialize($window);
251
252
            $sw = urlencode($serializedWindow);
253
            // Get cURL resource
254
            $curl = curl_init();
255
            // Set some options - we are passing in a useragent too here
256
            curl_setopt_array($curl, array(
257
            CURLOPT_RETURNTRANSFER => 1,
258
            CURLOPT_URL => CONFIG_CONTROL_FILE . '?newVncWindow=' . $sw,
259
            CURLOPT_USERAGENT => 'PalMA cURL Request'
260
            ));
261
            // Send the request
262
            curl_exec($curl);
263
            // Close request to clear up some resources
264
            curl_close($curl);
265
266
        }
267
268
        // add unique id to ignore list after sending to nuc
269
        array_push($this->_IGNORE_LIST, $vnc_id);
270
271
    }
272
273
    protected function deleteInactiveVncWindow()
274
    {
275
        // print("\n[Daemon]: +++ TODO: deleteInactiveWindow() +++");
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
276
277
        $db = new DBConnector();
278
279
        // window_ids in db
280
        $vnc_windows_in_db = array();
281
        $client_info = $db->getVNC_ClientInfo();
282
        foreach ($client_info as $info) {
283
            $vnc_windows_in_db[] = $info["win_id"];
284
        }
285
286
        // window_ids on screen
287
        $windows_on_screen = array();
288
        $windows = explode("\n", shell_exec('wmctrl -l'));
289
290
        foreach ($windows as $w) {
291
            $field = explode(' ', $w);
292
            $id = $field[0];
293
            if ($id != '') {
294
                $windows_on_screen[] = $id;
295
            }
296
        }
297
298
        // print("[Daemon]: clients in db = " . serialize($vnc_windows_in_db));
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
299
        // print("[Daemon]: client on screen = " . serialize($windows_on_screen));
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
300
301
        // window_ids that are in the db, but not on the screen (window already closed)
302
        $inactive_vnc_window_ids = array_diff($vnc_windows_in_db, $windows_on_screen);
303
304
        foreach ($inactive_vnc_window_ids as $inactive_win_id) {
305
            // define vnc-id
306
            $inactive_vnc_id = $db->querySingle("SELECT file FROM window WHERE win_id='".$inactive_win_id."'");
0 ignored issues
show
The assignment to $inactive_vnc_id is dead and can be removed.
Loading history...
307
308
            // delete from database (send to control.php)
309
            $curl = curl_init();
310
311
            curl_setopt_array($curl, array(
312
                CURLOPT_RETURNTRANSFER => 1,
313
                CURLOPT_URL => CONFIG_CONTROL_FILE .
314
                    '?window=vncwin&delete=VNC&vncid=' . $inactive_win_id,
315
                CURLOPT_USERAGENT => 'PalMA cURL Request'
316
                ));
317
318
            curl_exec($curl);
319
            curl_close($curl);
320
321
            // print("[Daemon]: inactive vnc_id = $inactive_vnc_id >> add to list: " .serialize($this->_IGNORE_LIST));
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
322
        }
323
    }
324
}
325
326
$vnc = new SSVNCDaemon();
327