Issues (25)

SSVNCDaemon.php (1 issue)

1
<?php namespace palma;
2
3
// Copyright (C) 2014 Universitätsbibliothek Mannheim
4
// See file LICENSE for license details.
5
6
require_once("DBConnector.class.php");
7
require_once("globals.php");
8
9
class SSVNCDaemon
10
{
11
12
    // all during session connected VNC Clients
13
    private $VNC_CLIENTS;
14
15
    // count of all connected clients
16
    // private $_VNC_CLIENT_COUNT;
17
18
    // active client count
19
    private $CONNECTIONS = 0;
20
21
    // ignored VNC Clients
22
    // TODO: check if no more longer helpful, has to be cleaned
23
    private $IGNORE_LIST = array();
24
25
    public $db;
26
27
    public function __construct()
28
    {
29
        global $db;
30
        $this->db = $db;
31
32
        // Start Vncviewer
33
        $handle = $this->startVNCViewer();
34
35
        // Read log in loop
36
        $this->readLog($handle);
37
    }
38
39
    protected function startVNCViewer()
40
    {
41
        // Startup SSVNC-Viewer in Multilisten-Mode
42
        $cmd = "export DISPLAY=" . CONFIG_DISPLAY .
43
        "; killall -q ssvncviewer; ssvncviewer -viewonly -multilisten 0 2>&1";
44
        $handle = popen($cmd, 'r');
45
        print("[Daemon]: vnc_viewer started");
46
47
        return $handle;
48
    }
49
50
    protected function readLog($handle)
51
    {
52
        print("\n[Daemon]: +++ readLog() +++");
53
54
        // local SSVNC-Client info
55
        $client = array(
56
                    "ip" => "",
57
                    "hostname" => "",
58
                    "active" => 1,
59
                    "exit" => 0
60
                    );
61
62
        // Read File continuously
63
        while (!feof($handle)) {
64
            $buffer = fgets($handle);
65
            print($buffer);
66
67
            if ($this->CONNECTIONS == 0) {
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
                // add client
88
                $this->addClient($client["ip"], $client["hostname"]);
89
90
                // reset local Client information after adding it
91
                $client["ip"] = "";
92
                $client["hostname"] = "";
93
            }
94
95
            if ($exit == 1) {
96
                // decrease active client count
97
                if ($this->CONNECTIONS > 0) {
98
                    $this->CONNECTIONS--;
99
                    $this->deleteInactiveVncWindow();
100
                }
101
            }
102
103
            $halt=$this->CONNECTIONS;
104
105
            if ($halt == -1) {
106
                exit(0);
107
            }
108
109
            flush();
110
        }
111
112
        pclose($handle);
113
    }
114
115
    protected function parseIP($buffer)
116
    {
117
        $ip = "";
118
        $line = $buffer;
119
        if (strpos($line, "Reverse VNC connection from IP")) {
120
            $line=trim($line);
121
            $item=explode(":", $line);
122
            $ip=trim($item[1]);
123
            $ip=preg_replace('/\W\W\d{4}\/\d{2}\/\d{2} \d{2}/', '', $ip);
124
        }
125
126
        if ($ip!="") {
127
            print("\nFOUND IP: " . $ip . "\n");
128
        }
129
130
        return $ip;
131
    }
132
133
    protected function parseHostname($buffer)
134
    {
135
        $hostname = "";
136
        $line = $buffer;
137
        if (strpos($line, "Hostname")) {
138
            $line=trim($line);
139
            $item=explode(":", $line);
140
            $hostname=trim($item[1]);
141
            $hostname=preg_replace('/\.uni\-mannheim\.de/', '', $hostname);
142
        }
143
144
        if ($hostname!="") {
145
            print("\nFOUND HOSTNAME: " . $hostname . "\n");
146
        }
147
148
        return $hostname;
149
    }
150
151
    protected function parseExit($line)
152
    {
153
        $exit = 0;
154
        if (strpos($line, "VNC Viewer exiting")) {
155
            $exit = 1;
156
        }
157
158
        if ($exit!=0) {
159
            print("\nCLIENT HAS DISCONNECTED " . $exit . "\n");
160
        }
161
162
        return $exit;
163
    }
164
165
    protected function addClient($ip, $hostname)
166
    {
167
        $vncclient = array(
168
                        "ip" => $ip,
169
                        "hostname" => $hostname,
170
                        "active" => 1,
171
                        "exit" => 0
172
                        );
173
        if (count($this->VNC_CLIENTS) == 0) {
174
            $id=1;
175
        } else {
176
            $id=count($this->VNC_CLIENTS) + 1;
177
        }
178
179
        $this->VNC_CLIENTS[$id] = $vncclient;
180
181
        print("\nCLIENT OBJECT with ID " . $id . " CREATED : "
182
            . $vncclient["ip"] . " | " . $vncclient["hostname"] . " | "
183
            . $vncclient["active"] . " | " . $vncclient["exit"] . "\n");
184
        print($this->CONNECTIONS+1 . " CLIENT(S) CONNECTED ...");
185
186
        $this->sendVncWindowToNuc($id, $vncclient);
187
188
        $this->CONNECTIONS++;
189
190
        print("\n active connections: ".$this->CONNECTIONS+1);
191
        print("\n all saved clients: " . serialize($this->VNC_CLIENTS));
192
    }
193
194
    protected function sendVncWindowToNuc($id, $vncclient)
195
    {
196
        print("\n[Daemon]: +++sendVncWindowToNuc() +++ ");
197
198
        $vnc_id = $vncclient["hostname"] . "-" . $id;
199
200
        $db = new DBConnector();
201
202
        // already existing in db?
203
        $clients_in_db = array();
204
        $client_info = $db->getVNCClientInfo();
205
206
        foreach ($client_info as $info) {
207
            $clients_in_db[] = $info["file"];
208
        }
209
210
        $ip = $vncclient["ip"];
211
        $name = $db->querySingle('SELECT user.name FROM address, user
212
                                  WHERE user.userid = (
213
                                    SELECT address.userid
214
                                    FROM address
215
                                    WHERE address.address ="' . $ip . '"
216
                                  )');
217
218
        // print("\n[Daemon]: USERNAME : " . $name);
219
220
        // $vncClientCount = $db->querySingle('SELECT count(id) FROM window WHERE handler = "vnc"');
221
        // $vncClientsAll = $db->query("SELECT user.name FROM address");
222
223
        // print("\n[Daemon]: clients in db = " . $vncClientCount);
224
        // print("\n[Daemon]: clients ignored = " . serialize($this->IGNORE_LIST));
225
226
        // if vnc_id not in database create window and send to nuc
227
        if (!(in_array($vnc_id, $clients_in_db))) {
228
            // print("\n[Daemon]: insert $vnc_id into db");
229
230
            $dt = new \DateTime();
231
            $date = $dt->format('Y-m-d H:i:s');
232
233
            $window = array(
234
                "id" => "",
235
                "win_id" => "",
236
                "name" => "",
237
                "state" => "",
238
                "file" => $name . "@" . $vnc_id,
239
                "handler" => "vnc",
240
                "userid" => $name,
241
                "date" => $date
242
            );
243
244
            $serializedWindow = serialize($window);
245
246
            $sw = urlencode($serializedWindow);
247
            // Get cURL resource
248
            $curl = curl_init();
249
            // Set some options - we are passing in a useragent too here
250
            curl_setopt_array($curl, array(
251
            CURLOPT_RETURNTRANSFER => 1,
252
            CURLOPT_URL => CONFIG_CONTROL_FILE . '?newVncWindow=' . $sw,
253
            CURLOPT_USERAGENT => 'PalMA cURL Request'
254
            ));
255
            // Send the request
256
            curl_exec($curl);
257
            // Close request to clear up some resources
258
            curl_close($curl);
259
        }
260
261
        // add unique id to ignore list after sending to nuc
262
        array_push($this->IGNORE_LIST, $vnc_id);
263
    }
264
265
    protected function deleteInactiveVncWindow()
266
    {
267
        // print("\n[Daemon]: +++ TODO: deleteInactiveWindow() +++");
268
269
        $db = new DBConnector();
270
271
        // window_ids in db
272
        $vnc_windows_in_db = array();
273
        $client_info = $db->getVNCClientInfo();
274
        foreach ($client_info as $info) {
275
            $vnc_windows_in_db[] = $info["win_id"];
276
        }
277
278
        // window_ids on screen
279
        $windows_on_screen = array();
280
        $windows = explode("\n", shell_exec('wmctrl -l'));
281
282
        foreach ($windows as $w) {
283
            $field = explode(' ', $w);
284
            $id = $field[0];
285
            if ($id != '') {
286
                $windows_on_screen[] = $id;
287
            }
288
        }
289
290
        // print("[Daemon]: clients in db = " . serialize($vnc_windows_in_db));
291
        // print("[Daemon]: client on screen = " . serialize($windows_on_screen));
292
293
        // window_ids that are in the db, but not on the screen (window already closed)
294
        $inactive_vnc_window_ids = array_diff($vnc_windows_in_db, $windows_on_screen);
295
296
        foreach ($inactive_vnc_window_ids as $inactive_win_id) {
297
            // define vnc-id
298
            $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...
299
300
            // delete from database (send to control.php)
301
            $curl = curl_init();
302
303
            curl_setopt_array($curl, array(
304
                CURLOPT_RETURNTRANSFER => 1,
305
                CURLOPT_URL => CONFIG_CONTROL_FILE .
306
                    '?window=vncwin&delete=VNC&vncid=' . $inactive_win_id,
307
                CURLOPT_USERAGENT => 'PalMA cURL Request'
308
                ));
309
310
            curl_exec($curl);
311
            curl_close($curl);
312
313
            // print("[Daemon]: inactive vnc_id = $inactive_vnc_id >> add to list: " .serialize($this->IGNORE_LIST));
314
        }
315
    }
316
}
317
318
$vnc = new SSVNCDaemon();
319