mirror of
https://github.com/webmin/webmin.git
synced 2026-03-20 16:50:24 +00:00
Merge branch 'master' into dev/fix-systemd-lost-properties
This commit is contained in:
@@ -35,7 +35,7 @@ my @extra_reverse = split(/\s+/, $config{'extra_reverse'} || '');
|
||||
our %is_extra = map { $_, 1 } (@extra_forward, @extra_reverse);
|
||||
our %access = &get_module_acl();
|
||||
my $zone_names_cache = "$module_config_directory/zone-names";
|
||||
my $zone_names_version = 3;
|
||||
my $zone_names_version = 4;
|
||||
my @list_zone_names_cache;
|
||||
my $slave_error;
|
||||
my %lines_count;
|
||||
@@ -2196,7 +2196,7 @@ return undef;
|
||||
sub before_editing
|
||||
{
|
||||
my ($zone) = @_;
|
||||
if (!$freeze_zone_count{$zone->{'name'}}) {
|
||||
if ($zone->{'dynamic'} && !$freeze_zone_count{$zone->{'name'}}) {
|
||||
my ($out, $ok) = &try_cmd(
|
||||
"freeze ".quotemeta($zone->{'name'})." IN ".
|
||||
quotemeta($zone->{'view'} || ""));
|
||||
@@ -2226,19 +2226,21 @@ sub restart_zone
|
||||
{
|
||||
my ($dom, $view) = @_;
|
||||
my ($out, $ex);
|
||||
my $zone = &get_zone_name($dom, $view);
|
||||
my $dyn = $zone && $zone->{'dynamic'};
|
||||
if ($view) {
|
||||
# Reload a zone in a view
|
||||
&try_cmd("freeze ".quotemeta($dom)." IN ".quotemeta($view));
|
||||
&try_cmd("freeze ".quotemeta($dom)." IN ".quotemeta($view)) if ($dyn);
|
||||
$out = &try_cmd("reload ".quotemeta($dom)." IN ".quotemeta($view));
|
||||
$ex = $?;
|
||||
&try_cmd("thaw ".quotemeta($dom)." IN ".quotemeta($view));
|
||||
&try_cmd("thaw ".quotemeta($dom)." IN ".quotemeta($view)) if ($dyn);
|
||||
}
|
||||
else {
|
||||
# Just reload one top-level zone
|
||||
&try_cmd("freeze ".quotemeta($dom));
|
||||
&try_cmd("freeze ".quotemeta($dom)) if ($dyn);
|
||||
$out = &try_cmd("reload ".quotemeta($dom));
|
||||
$ex = $?;
|
||||
&try_cmd("thaw ".quotemeta($dom));
|
||||
&try_cmd("thaw ".quotemeta($dom)) if ($dyn);
|
||||
}
|
||||
if ($out =~ /not found/i) {
|
||||
# Zone is not known to BIND yet - do a total reload
|
||||
@@ -2457,8 +2459,11 @@ if ($changed || !$znc{'version'} ||
|
||||
my $type = &find_value("type", $z->{'members'});
|
||||
next if (!$type);
|
||||
my $file = &find_value("file", $z->{'members'});
|
||||
my $up = &find("update-policy", $z->{'members'});
|
||||
my $au = &find("allow-update", $z->{'members'});
|
||||
my $dynamic = $up || $au ? 1 : 0;
|
||||
$znc{"zone_".($n++)} = join("\t", $z->{'value'},
|
||||
$z->{'index'}, $type, $v->{'value'}, $file);
|
||||
$z->{'index'}, $type, $v->{'value'}, $dynamic, $file);
|
||||
$files{$z->{'file'}}++;
|
||||
}
|
||||
$znc{"view_".($n++)} = join("\t", $v->{'value'}, $v->{'index'});
|
||||
@@ -2469,8 +2474,11 @@ if ($changed || !$znc{'version'} ||
|
||||
next if (!$type);
|
||||
my $file = &find_value("file", $z->{'members'});
|
||||
$file ||= ""; # slaves and other types with no file
|
||||
my $up = &find("update-policy", $z->{'members'});
|
||||
my $au = &find("allow-update", $z->{'members'});
|
||||
my $dynamic = $up || $au ? 1 : 0;
|
||||
$znc{"zone_".($n++)} = join("\t", $z->{'value'},
|
||||
$z->{'index'}, $type, "*", $file);
|
||||
$z->{'index'}, $type, "*", $dynamic, $file);
|
||||
$files{$z->{'file'}}++;
|
||||
}
|
||||
|
||||
@@ -2501,12 +2509,13 @@ if (scalar(@list_zone_names_cache)) {
|
||||
my (@rv, %viewidx);
|
||||
foreach my $k (keys %znc) {
|
||||
if ($k =~ /^zone_(\d+)$/) {
|
||||
my ($name, $index, $type, $view, $file) =
|
||||
split(/\t+/, $znc{$k}, 5);
|
||||
my ($name, $index, $type, $view, $dynamic, $file) =
|
||||
split(/\t+/, $znc{$k}, 6);
|
||||
push(@rv, { 'name' => $name,
|
||||
'type' => $type,
|
||||
'index' => $index,
|
||||
'view' => !$view || $view eq '*' ? undef : $view,
|
||||
'dynamic' => $dynamic,
|
||||
'file' => $file });
|
||||
}
|
||||
elsif ($k =~ /^view_(\d+)$/) {
|
||||
@@ -2534,7 +2543,7 @@ undef(@list_zone_names_cache);
|
||||
unlink($zone_names_cache);
|
||||
}
|
||||
|
||||
# get_zone_name(index|name, [viewindex|"any"])
|
||||
# get_zone_name(index|name, [viewindex|view-name|"any"])
|
||||
# Returns a zone cache object, looked up by name or index
|
||||
sub get_zone_name
|
||||
{
|
||||
@@ -2546,7 +2555,8 @@ foreach my $z (@zones) {
|
||||
if ($z->{$field} eq $key &&
|
||||
($viewidx eq 'any' ||
|
||||
$viewidx eq '' && !defined($z->{'viewindex'}) ||
|
||||
$viewidx ne '' && $z->{'viewindex'} == $_[1])) {
|
||||
$viewidx =~ /^\d+$/ && $z->{'viewindex'} == $viewidx ||
|
||||
$viewidx ne '' && $z->{'view'} eq $viewidx)) {
|
||||
return $z;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ cron_input=Cron pozwala na dodawanie zadań,1,1-Tak,0-Nie
|
||||
cron_allow_file=Plik z listą dopuszczonych użytkowników,0
|
||||
cron_deny_file=Plik z listą użytkowników bez dostępu,0
|
||||
cron_deny_all=Uprawnienia przy braku plików pozwoleń/zakazu,1,0-Zablokuj dla wszystkich,1-Zablokuj oprócz roota,2-Pozwól wszystkim
|
||||
vixie_cron=Obsluga rozszerzeń vixie-crona,1,1-Tak,0-Nie
|
||||
vixie_cron=Obsługa rozszerzeń vixie-crona,1,1-Tak,0-Nie
|
||||
system_crontab=Scieżka do systemowego pliku zadań vixie-crona,0
|
||||
single_file=Ścieżka do pliku crontab pojedynczego użytkownika,0
|
||||
cronfiles_dir=Ścieżka do katalogu z dodatkowymi plikami crona,3,Brak
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
desc_pl=Harmonogram zadaĂą Cron
|
||||
longdesc_pl=TwĂłrz, edytuj i usuwaj zadania Cron.
|
||||
desc_pl=Harmonogram zadań Cron
|
||||
longdesc_pl=Twórz, edytuj i usuwaj zadania Cron.
|
||||
|
||||
0
init/init-lib.pl
Executable file → Normal file
0
init/init-lib.pl
Executable file → Normal file
@@ -346,7 +346,7 @@ else {
|
||||
$gid++;
|
||||
}
|
||||
$rv = $ldap->add($newdn, attr =>
|
||||
[ "cn" => $group,
|
||||
[ "cn" => $grp,
|
||||
"gidNumber" => $gid,
|
||||
@props,
|
||||
"objectClass" => \@classes ] );
|
||||
|
||||
26
miniserv.pl
26
miniserv.pl
@@ -5623,6 +5623,15 @@ if (!$key) {
|
||||
&http_error(500, "Missing Sec-Websocket-Key header");
|
||||
return 0;
|
||||
}
|
||||
my @users = split(/\s+/, $ws->{'user'});
|
||||
my @busers = split(/\s+/, $ws->{'buser'});
|
||||
if (@users || @busers) {
|
||||
if (&indexof($authuser, @users) < 0 &&
|
||||
&indexof($baseauthuser, @busers) < 0) {
|
||||
&http_error(500, "Invalid user for Websockets connection");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
my @protos = split(/\s*,\s*/, $header{'sec-websocket-protocol'});
|
||||
print DEBUG "websockets protos ",join(" ", @protos),"\n";
|
||||
|
||||
@@ -5640,23 +5649,6 @@ elsif ($ws->{'pipe'}) {
|
||||
&http_error(500, "Websockets pipe failed : $?");
|
||||
print DEBUG "websockets pipe $ws->{'pipe'}\n";
|
||||
}
|
||||
elsif ($ws->{'cmd'}) {
|
||||
# Backend is a shell command
|
||||
eval "use IO::Pty";
|
||||
$@ && &http_error(500,"Websockets command requires the IO::Pty module");
|
||||
my $ptyfh = new IO::Pty;
|
||||
my $ttyfh = $ptyfh->slave();
|
||||
my $tty = $ptyfh->ttyname();
|
||||
# XXX chown tty?
|
||||
my $pid = fork();
|
||||
if (!$pid) {
|
||||
# Run command in a forked process
|
||||
# XXX todo here
|
||||
exit(1);
|
||||
}
|
||||
$ptyfh->close_slave();
|
||||
print DEBUG "websockets command $ws->{'cmd'}\n";
|
||||
}
|
||||
else {
|
||||
&http_error(500, "Invalid Webmin websockets config");
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ what_is_it=Co to jest?
|
||||
opts_default=Domyślnie
|
||||
opts_none=Brak
|
||||
opts_relayhost=Wysyłać pocztę wychodzącą poprzez host
|
||||
opts_direct=Deręczać bezpośrednio
|
||||
opts_direct=Doręczać bezpośrednio
|
||||
opts_myorigin=Własna domena w poczcie wychodzącej
|
||||
opts_myorigin_as_myhostname=Używać nazwy hosta
|
||||
opts_myorigin_as_mydomain=Używać nazwy domeny
|
||||
|
||||
@@ -52,6 +52,12 @@ if ($type eq 'char' || $type eq 'varchar' || $type eq 'numeric' ||
|
||||
}
|
||||
}
|
||||
|
||||
if (!$in{'type'}) {
|
||||
# Display if primary key
|
||||
print &ui_table_row($text{'field_key'},
|
||||
$f->{'key'} eq 'PRI' ? $text{'yes'} : $text{'no'});
|
||||
}
|
||||
|
||||
if ($in{'type'}) {
|
||||
# Ask if this is an array
|
||||
print &ui_table_row($text{'field_arr'},
|
||||
|
||||
@@ -1013,6 +1013,9 @@ if ($info->{'create'} =~ /using\s+(\S+)\s/) {
|
||||
}
|
||||
if ($info->{'create'} =~ /\((.*)\)/) {
|
||||
$info->{'cols'} = [ split(/\s*,\s*/, $1) ];
|
||||
foreach my $c (@{$info->{'cols'}}) {
|
||||
$c =~ s/^"(.*)"$/$1/;
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<header>Alias aktywny</header>
|
||||
|
||||
OkreĹla, czy ten alias jest w chwili obecnej aktywny. Aliasy nie aktywne sÄ
|
||||
ignorowane podczas przetwarzania przychodzÄ
cej poczty.
|
||||
Określa, czy ten alias jest w chwili obecnej aktywny. Aliasy nie aktywne są
|
||||
ignorowane podczas przetwarzania przychodzącej poczty.
|
||||
<hr>
|
||||
|
||||
1
xterm/config
Normal file
1
xterm/config
Normal file
@@ -0,0 +1 @@
|
||||
base_port=555
|
||||
1
xterm/config.info
Normal file
1
xterm/config.info
Normal file
@@ -0,0 +1 @@
|
||||
base_port=Base port number for Websockets connections,0
|
||||
1
xterm/defaultacl
Normal file
1
xterm/defaultacl
Normal file
@@ -0,0 +1 @@
|
||||
user=root
|
||||
65
xterm/index.cgi
Normal file
65
xterm/index.cgi
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Show a terminal that is connected to a Websockets server via Webmin proxying
|
||||
|
||||
BEGIN { push(@INC, ".."); };
|
||||
use WebminCore;
|
||||
&init_config();
|
||||
my %access = &get_module_acl();
|
||||
|
||||
&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1, 0, undef,
|
||||
"<link rel=stylesheet href=xterm.css>\n".
|
||||
"<script src=xterm.js></script>\n".
|
||||
"<script src=xterm-addon-attach.js></script>\n"
|
||||
);
|
||||
|
||||
# Check for needed modules
|
||||
my $modname = "Net::WebSocket::Server";
|
||||
eval "use ${modname};";
|
||||
if ($@) {
|
||||
print &text('index_cpan', "<tt>$modname</tt>",
|
||||
"../cpan/download.cgi?source=3&cpan=$modname&mode=2&return=/$module_name/&returndesc=".&urlize($module_info{'desc'})),"<p>\n";
|
||||
&ui_print_footer("/", $text{'index'});
|
||||
return;
|
||||
}
|
||||
|
||||
# Pick a port and configure Webmin to proxy it
|
||||
my $port = $config{'base_port'} || 555;
|
||||
while(1) {
|
||||
&open_socket("127.0.0.1", $port, TEST, \$err);
|
||||
last if ($err);
|
||||
close(TEST);
|
||||
$port++;
|
||||
}
|
||||
my %miniserv;
|
||||
&get_miniserv_config(\%miniserv);
|
||||
my $wspath = "/$module_name/ws-".$port;
|
||||
$miniserv{'websockets_'.$wspath} = "host=127.0.0.1 port=$port wspath=/ user=$remote_user";
|
||||
&put_miniserv_config(\%miniserv);
|
||||
&reload_miniserv();
|
||||
|
||||
# Launch the shell server on that port
|
||||
&foreign_require("cron");
|
||||
my $shellserver_cmd = "$module_config_directory/shellserver.pl";
|
||||
if (!-r $shellserver_cmd) {
|
||||
&cron::create_wrapper($shellserver_cmd, $module_name, "shellserver.pl");
|
||||
}
|
||||
my $user = $access{'user'};
|
||||
my $tmpdir = &tempname_dir();
|
||||
&system_logged("$shellserver_cmd $port $user >$tmpdir/ws-$port.out 2>&1 </dev/null &");
|
||||
sleep(2);
|
||||
|
||||
# Open the terminal
|
||||
my $url = "wss://".$ENV{'HTTP_HOST'}.$wspath;
|
||||
print <<EOF;
|
||||
<div id="terminal"></div>
|
||||
<script>
|
||||
var term = new Terminal();
|
||||
term.open(document.getElementById('terminal'));
|
||||
var socket = new WebSocket('$url', 'binary');
|
||||
var attachAddon = new AttachAddon.AttachAddon(socket);
|
||||
term.loadAddon(attachAddon);
|
||||
</script>
|
||||
EOF
|
||||
|
||||
&ui_print_footer("/", $text{'index'});
|
||||
|
||||
2
xterm/lang/en
Normal file
2
xterm/lang/en
Normal file
@@ -0,0 +1,2 @@
|
||||
index_title=Websockets Shell
|
||||
index_cpan=The Perl module <tt>$1</tt> needed to accept Websockets connections is not available, but you can install it automatically using Webmin's <a href='$2'>Perl Modules</a> module.
|
||||
3
xterm/module.info
Normal file
3
xterm/module.info
Normal file
@@ -0,0 +1,3 @@
|
||||
desc=Websockets Shell
|
||||
name=xterm
|
||||
longdesc=Access the shell on your system without the need for a separate SSH client, using XTerm over Websockets
|
||||
35
xterm/shellserver.pl
Executable file
35
xterm/shellserver.pl
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Start a websocket server connected to a shell
|
||||
|
||||
BEGIN { push(@INC, ".."); };
|
||||
use WebminCore;
|
||||
use Net::WebSocket::Server;
|
||||
&init_config();
|
||||
|
||||
my ($port, $user) = @ARGV;
|
||||
if ($user ne "root" && $<) {
|
||||
my @uinfo = getpwnam($user);
|
||||
@uinfo || die "User $user does not exist!";
|
||||
&switch_to_unix_user(@uinfo);
|
||||
}
|
||||
|
||||
$SIG{'ALRM'} = sub { die "timeout waiting for connection"; };
|
||||
alarm(60);
|
||||
print STDERR "listening on port $port\n";
|
||||
Net::WebSocket::Server->new(
|
||||
listen => $port,
|
||||
on_connect => sub {
|
||||
my ($serv, $conn) = @_;
|
||||
print STDERR "got connection\n";
|
||||
alarm(0);
|
||||
$conn->on(
|
||||
utf8 => sub {
|
||||
my ($conn, $msg) = @_;
|
||||
$conn->send_utf8($msg);
|
||||
},
|
||||
disconnect => sub {
|
||||
exit(0);
|
||||
},
|
||||
);
|
||||
},
|
||||
)->start;
|
||||
2
xterm/xterm-addon-attach.js
Normal file
2
xterm/xterm-addon-attach.js
Normal file
@@ -0,0 +1,2 @@
|
||||
!function(s,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AttachAddon=t():s.AttachAddon=t()}(self,(function(){return(()=>{"use strict";var s={};return(()=>{var t=s;function e(s,t,e){return s.addEventListener(t,e),{dispose:()=>{e&&s.removeEventListener(t,e)}}}Object.defineProperty(t,"__esModule",{value:!0}),t.AttachAddon=void 0,t.AttachAddon=class{constructor(s,t){this._disposables=[],this._socket=s,this._socket.binaryType="arraybuffer",this._bidirectional=!(t&&!1===t.bidirectional)}activate(s){this._disposables.push(e(this._socket,"message",(t=>{const e=t.data;s.write("string"==typeof e?e:new Uint8Array(e))}))),this._bidirectional&&(this._disposables.push(s.onData((s=>this._sendData(s)))),this._disposables.push(s.onBinary((s=>this._sendBinary(s))))),this._disposables.push(e(this._socket,"close",(()=>this.dispose()))),this._disposables.push(e(this._socket,"error",(()=>this.dispose())))}dispose(){for(const s of this._disposables)s.dispose()}_sendData(s){1===this._socket.readyState&&this._socket.send(s)}_sendBinary(s){if(1!==this._socket.readyState)return;const t=new Uint8Array(s.length);for(let e=0;e<s.length;++e)t[e]=255&s.charCodeAt(e);this._socket.send(t)}}})(),s})()}));
|
||||
//# sourceMappingURL=xterm-addon-attach.js.map
|
||||
1
xterm/xterm-addon-attach.js.map
Normal file
1
xterm/xterm-addon-attach.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"xterm-addon-attach.js","mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAqB,YAAID,IAEzBD,EAAkB,YAAIC,GACvB,CATD,CASGK,MAAM,WACT,M,gDC2DA,SAASC,EAAqDC,EAAmBC,EAASC,GAExF,OADAF,EAAOG,iBAAiBF,EAAMC,GACvB,CACLE,QAAS,KACFF,GAILF,EAAOK,oBAAoBJ,EAAMC,EAAQ,EAG/C,C,sEAnEA,oBAKEI,YAAYN,EAAmBO,GAFvB,KAAAC,aAA8B,GAGpCC,KAAKC,QAAUV,EAEfS,KAAKC,QAAQC,WAAa,cAC1BF,KAAKG,iBAAmBL,IAAqC,IAA1BA,EAAQM,cAC7C,CAEOC,SAASC,GACdN,KAAKD,aAAaQ,KAChBjB,EAAkBU,KAAKC,QAAS,WAAWO,IACzC,MAAMC,EAA6BD,EAAGC,KACtCH,EAASI,MAAsB,iBAATD,EAAoBA,EAAO,IAAIE,WAAWF,GAAM,KAItET,KAAKG,iBACPH,KAAKD,aAAaQ,KAAKD,EAASM,QAAOH,GAAQT,KAAKa,UAAUJ,MAC9DT,KAAKD,aAAaQ,KAAKD,EAASQ,UAASL,GAAQT,KAAKe,YAAYN,OAGpET,KAAKD,aAAaQ,KAAKjB,EAAkBU,KAAKC,QAAS,SAAS,IAAMD,KAAKL,aAC3EK,KAAKD,aAAaQ,KAAKjB,EAAkBU,KAAKC,QAAS,SAAS,IAAMD,KAAKL,YAC7E,CAEOA,UACL,IAAK,MAAMqB,KAAKhB,KAAKD,aACnBiB,EAAErB,SAEN,CAEQkB,UAAUJ,GAGgB,IAA5BT,KAAKC,QAAQgB,YAGjBjB,KAAKC,QAAQiB,KAAKT,EACpB,CAEQM,YAAYN,GAClB,GAAgC,IAA5BT,KAAKC,QAAQgB,WACf,OAEF,MAAME,EAAS,IAAIR,WAAWF,EAAKW,QACnC,IAAK,IAAIC,EAAI,EAAGA,EAAIZ,EAAKW,SAAUC,EACjCF,EAAOE,GAA0B,IAArBZ,EAAKa,WAAWD,GAE9BrB,KAAKC,QAAQiB,KAAKC,EACpB,E","sources":["webpack://AttachAddon/webpack/universalModuleDefinition","webpack://AttachAddon/./src/AttachAddon.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"AttachAddon\"] = factory();\n\telse\n\t\troot[\"AttachAddon\"] = factory();\n})(self, function() {\nreturn ","/**\n * Copyright (c) 2014, 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Implements the attach method, that attaches the terminal to a WebSocket stream.\n */\n\nimport { Terminal, IDisposable, ITerminalAddon } from 'xterm';\n\ninterface IAttachOptions {\n bidirectional?: boolean;\n}\n\nexport class AttachAddon implements ITerminalAddon {\n private _socket: WebSocket;\n private _bidirectional: boolean;\n private _disposables: IDisposable[] = [];\n\n constructor(socket: WebSocket, options?: IAttachOptions) {\n this._socket = socket;\n // always set binary type to arraybuffer, we do not handle blobs\n this._socket.binaryType = 'arraybuffer';\n this._bidirectional = !(options && options.bidirectional === false);\n }\n\n public activate(terminal: Terminal): void {\n this._disposables.push(\n addSocketListener(this._socket, 'message', ev => {\n const data: ArrayBuffer | string = ev.data;\n terminal.write(typeof data === 'string' ? data : new Uint8Array(data));\n })\n );\n\n if (this._bidirectional) {\n this._disposables.push(terminal.onData(data => this._sendData(data)));\n this._disposables.push(terminal.onBinary(data => this._sendBinary(data)));\n }\n\n this._disposables.push(addSocketListener(this._socket, 'close', () => this.dispose()));\n this._disposables.push(addSocketListener(this._socket, 'error', () => this.dispose()));\n }\n\n public dispose(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n }\n\n private _sendData(data: string): void {\n // TODO: do something better than just swallowing\n // the data if the socket is not in a working condition\n if (this._socket.readyState !== 1) {\n return;\n }\n this._socket.send(data);\n }\n\n private _sendBinary(data: string): void {\n if (this._socket.readyState !== 1) {\n return;\n }\n const buffer = new Uint8Array(data.length);\n for (let i = 0; i < data.length; ++i) {\n buffer[i] = data.charCodeAt(i) & 255;\n }\n this._socket.send(buffer);\n }\n}\n\nfunction addSocketListener<K extends keyof WebSocketEventMap>(socket: WebSocket, type: K, handler: (this: WebSocket, ev: WebSocketEventMap[K]) => any): IDisposable {\n socket.addEventListener(type, handler);\n return {\n dispose: () => {\n if (!handler) {\n // Already disposed\n return;\n }\n socket.removeEventListener(type, handler);\n }\n };\n}\n"],"names":["root","factory","exports","module","define","amd","self","addSocketListener","socket","type","handler","addEventListener","dispose","removeEventListener","constructor","options","_disposables","this","_socket","binaryType","_bidirectional","bidirectional","activate","terminal","push","ev","data","write","Uint8Array","onData","_sendData","onBinary","_sendBinary","d","readyState","send","buffer","length","i","charCodeAt"],"sourceRoot":""}
|
||||
180
xterm/xterm.css
Normal file
180
xterm/xterm.css
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
||||
* https://github.com/chjj/term.js
|
||||
* @license MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Originally forked from (with the author's permission):
|
||||
* Fabrice Bellard's javascript vt100 for jslinux:
|
||||
* http://bellard.org/jslinux/
|
||||
* Copyright (c) 2011 Fabrice Bellard
|
||||
* The original design remains. The terminal itself
|
||||
* has been extended to include xterm CSI codes, among
|
||||
* other features.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default styles for xterm.js
|
||||
*/
|
||||
|
||||
.xterm {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.xterm.focus,
|
||||
.xterm:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.xterm .xterm-helpers {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
/**
|
||||
* The z-index of the helpers must be higher than the canvases in order for
|
||||
* IMEs to appear on top.
|
||||
*/
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.xterm .xterm-helper-textarea {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
left: -9999em;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: -5;
|
||||
/** Prevent wrapping so the IME appears against the textarea at the correct position */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.xterm .composition-view {
|
||||
/* TODO: Composition position got messed up somewhere */
|
||||
background: #000;
|
||||
color: #FFF;
|
||||
display: none;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.xterm .composition-view.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport {
|
||||
/* On OS X this is required in order for the scroll bar to appear fully opaque */
|
||||
background-color: #000;
|
||||
overflow-y: scroll;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-scroll-area {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.xterm-char-measure-element {
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -9999em;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.xterm {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.xterm.enable-mouse-events {
|
||||
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.xterm.xterm-cursor-pointer,
|
||||
.xterm .xterm-cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.xterm.column-select.focus {
|
||||
/* Column selection mode */
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility,
|
||||
.xterm .xterm-message {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.xterm .live-region {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.xterm-dim {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.xterm-underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.xterm-strikethrough {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.xterm-screen .xterm-decoration-container .xterm-decoration {
|
||||
z-index: 6;
|
||||
position: absolute;
|
||||
}
|
||||
2
xterm/xterm.js
Normal file
2
xterm/xterm.js
Normal file
File diff suppressed because one or more lines are too long
1
xterm/xterm.js.map
Normal file
1
xterm/xterm.js.map
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user