forked from unraid/webgui
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOpenTerminal.php
More file actions
141 lines (131 loc) · 4.91 KB
/
OpenTerminal.php
File metadata and controls
141 lines (131 loc) · 4.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?PHP
/* Copyright 2005-2023, Lime Technology
* Copyright 2012-2023, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
require_once "$docroot/webGui/include/Secure.php";
require_once "$docroot/webGui/include/Wrappers.php";
// add translations
$_SERVER['REQUEST_URI'] = '';
require_once "$docroot/webGui/include/Translations.php";
// Get the webGui configuration preferences
extract(parse_plugin_cfg('dynamix',true));
$rows = 90;
$wait = "read -N 1 -p '\n\e[92m** "._('Press ANY KEY to close this window')." ** \e[0m'";
$run = "$docroot/webGui/scripts/run_cmd";
// set tty window font size
if (!empty($display['tty'])) exec("sed -ri 's/fontSize=[0-9]+/fontSize={$display['tty']}/' /etc/default/ttyd");
function wait($name,$cmd) {
global $run,$wait;
$exec = "/var/tmp/$name.run.sh";
file_put_contents($exec,"#!/bin/bash\n$run $cmd\n$wait\n");
chmod($exec,0755);
return $exec;
}
function command($path,$file) {
global $run,$wait,$rows;
return (file_exists($file) && substr($file,0,strlen($path))==$path) ? "$run tail -f -n $rows '$file'" : $wait;
}
switch ($_GET['tag']) {
case 'ttyd':
// check if ttyd already running
$sock = "/var/run/ttyd.sock";
exec('pgrep --ns $$ -f '."'$sock'", $ttyd_pid, $retval);
if ($retval == 0) {
// check if there are any child processes, ie, curently open tty windows
exec('pgrep --ns $$ -P '.$ttyd_pid[0], $output, $retval);
// no child processes, restart ttyd to pick up possible font size change
if ($retval != 0) exec("kill ".$ttyd_pid[0]);
}
$more = $_GET['more'] ?? '';
if (!empty($more) && substr($more, 0, 1) === '/') {
// Terminal at specific path - use 'more' parameter to pass path
// Note: openTerminal(tag, name, more) in JS only has 3 params, so we reuse 'more'
// Note: Used by File Manager to open terminal at specific folder
// Validate path
$real_path = realpath($more);
if ($real_path === false) {
// Path doesn't exist - fall back to home directory
$real_path = '/root';
}
$name = unbundle($_GET['name']);
$exec = "/var/tmp/$name.run.sh";
$escaped_path = str_replace("'", "'\\''", $real_path);
// Escape sed metacharacters: & (matched string), \\ (escape char), / (delimiter)
$sed_escaped = str_replace(['\\', '&', '/'], ['\\\\', '\\&', '\\/'], $escaped_path);
// Create startup script similar to ~/.bashrc
// Note: We can not use ~/.bashrc as it loads /etc/profile which does 'cd $HOME'
$script_content = <<<BASH
#!/bin/bash
# Modify /etc/profile to replace 'cd \$HOME' with our target path
sed 's#^cd \$HOME#cd '\''$sed_escaped'\''#' /etc/profile > /tmp/$name.profile
source /tmp/$name.profile
source /root/.bash_profile 2>/dev/null
rm /tmp/$name.profile
exec bash --norc -i
BASH;
file_put_contents($exec, $script_content);
chmod($exec, 0755);
exec("ttyd-exec -i '$sock' $exec");
} else {
// Standard login shell
if ($retval != 0) exec("ttyd-exec -i '$sock' '" . posix_getpwuid(0)['shell'] . "' --login");
}
break;
case 'syslog':
// read syslog file
$path = '/var/log/';
$file = realpath($path.$_GET['name']);
$sock = "/var/run/syslog.sock";
exec("ttyd-exec -s9 -om1 -i '$sock' ".command($path,$file));
break;
case 'disklog':
// read disk log info (main page)
$name = unbundle($_GET['name']);
$sock = "/var/tmp/$name.sock";
$ata = exec("ls -n '/sys/block/$name'|grep -Pom1 'ata\d+'");
$dev = $ata ? $name.'|'.$ata.'[.:]' : $name;
exec("ttyd-exec -s9 -om1 -i '$sock' ".wait($name,"grep -P \"'$dev'\" '/var/log/syslog*'"));
break;
case 'log':
// read vm log file
$path = '/var/log/';
$name = unbundle($_GET['name']);
$file = realpath($path.$_GET['more']);
$sock = "/var/tmp/$name.sock";
exec("ttyd-exec -s9 -om1 -i '$sock' ".command($path,$file));
break;
case 'docker':
$name = unbundle($_GET['name']);
$more = unbundle($_GET['more']) ?: 'sh';
if ($more=='.log') {
// read docker container log
$sock = "/var/tmp/$name.log.sock";
if (empty(exec("docker ps --filter=name='$name' --format={{.Names}}")))
$docker = wait($name,"docker logs -n $rows '$name'"); // container stopped
else
$docker = "$run docker logs -f -n $rows '$name'"; // container started
exec("ttyd-exec -s9 -om1 -i '$sock' $docker");
} else {
// docker console command
$sock = "/var/tmp/$name.sock";
exec("ttyd-exec -s9 -om1 -i '$sock' docker exec -it '$name' $more");
}
break;
case 'lxc':
$name = unbundle($_GET['name']);
$more = unbundle($_GET['more']);
$sock = "/var/tmp/$name.sock";
exec("ttyd-exec -s9 -om1 -i '$sock' lxc-attach '$name' $more");
break;
}
?>