Merge branch 'master' of github.com:webmin/webmin
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled
Close inactive / close-inactive (push) Has been cancelled

This commit is contained in:
Jamie Cameron
2026-06-13 18:51:30 -07:00
49 changed files with 969 additions and 186 deletions

View File

@@ -1,4 +1,4 @@
name: Build
name: Package and upload artifacts
on:
push:

View File

@@ -1,6 +1,6 @@
name=At
desc=Scheduled Commands
os_support=solaris slackware-linux redhat-linux mandrake-linux debian-linux suse-linux united-linux open-linux turbo-linux corel-linux msc-linux freebsd netbsd openbsd generic-linux openserver macos gentoo-linux irix sol-linux coherent-linux openmamba-linux syno-linux
os_support=solaris slackware-linux redhat-linux mandrake-linux debian-linux suse-linux united-linux open-linux turbo-linux corel-linux msc-linux freebsd netbsd openbsd generic-linux alpine-linux openserver macos gentoo-linux irix sol-linux coherent-linux openmamba-linux syno-linux
category=system
longdesc=Schedule the execution of one-off commands or scripts.
depends=proc

View File

@@ -1,6 +1,6 @@
name=Cluster Software
desc=Cluster Software Packages
os_support=cobalt-linux mandrake-linux redhat-linux open-linux msc-linux suse-linux united-linux turbo-linux debian-linux solaris openserver gentoo-linux trustix-linux coherent-linux slackware-linux windows pardus-linux
os_support=cobalt-linux mandrake-linux redhat-linux open-linux msc-linux suse-linux united-linux turbo-linux debian-linux solaris openserver gentoo-linux alpine-linux trustix-linux coherent-linux slackware-linux windows pardus-linux
depends=software servers
category=cluster
longdesc=Install RPMs, debian and solaris packages across multiple servers from one source.

17
dhcpd/config-alpine-linux Normal file
View File

@@ -0,0 +1,17 @@
dhcpd_conf=/etc/dhcp/dhcpd.conf
pid_file=/var/run/dhcp/dhcpd.pid
dhcpd_path=/usr/sbin/dhcpd
lease_file=/var/lib/dhcp/dhcpd.leases
lease_sort=0
dhcpd_nocols=5
lease_tz=0
start_cmd=/etc/init.d/dhcpd start
stop_cmd=/etc/init.d/dhcpd stop
restart_cmd=/etc/init.d/dhcpd restart
show_ip=0
show_mac=0
group_name=0
display_max=100
desc_name=0
interfaces_type=alpine
lease_vendor=0

View File

@@ -19,5 +19,5 @@ restart_cmd=Command to apply configuration,3,Kill and re-start
stop_cmd=Command to stop DHCP server,3,Kill process
pid_file=Path to DHCP server PID file,3,None
lease_file=DHCP server lease file,0
interfaces_type=Interfaces file type,4,redhat-Redhat,mandrake-Mandrake,suse-SuSE,debian-Debian,caldera-Caldera,gentoo-Gentoo,freebsd-FreeBSD,-Webmin
interfaces_type=Interfaces file type,4,redhat-Redhat,mandrake-Mandrake,suse-SuSE,debian-Debian,caldera-Caldera,gentoo-Gentoo,alpine-Alpine,freebsd-FreeBSD,-Webmin
version=DHCP server version,3,Work out automatically

View File

@@ -73,6 +73,11 @@ elsif ($config{'interfaces_type'} eq 'gentoo') {
&read_env_file("/etc/conf.d/dhcp", \%dhcp);
$iface = $dhcp{'IFACE'};
}
elsif ($config{'interfaces_type'} eq 'alpine') {
# Interfaces are set in a file on Alpine
&read_env_file("/etc/conf.d/dhcpd", \%dhcp);
$iface = $dhcp{'DHCPD_IFACE'};
}
elsif ($config{'interfaces_type'} eq 'freebsd') {
# From FreeBSD rc.conf file
&foreign_require("init");
@@ -114,4 +119,3 @@ print &ui_submit($text{'save'});
print &ui_form_end(undef,undef,1);
&ui_print_footer("", $text{'listl_return'});

View File

@@ -1,5 +1,5 @@
name=DHCPD
category=servers
os_support=debian-linux freebsd osf1 redhat-linux mandrake-linux slackware-linux solaris suse-linux united-linux unixware openserver open-linux turbo-linux openbsd corel-linux cobalt-linux irix netbsd msc-linux generic-linux gentoo-linux hpux trustix-linux macos sol-linux coherent-linux openmamba-linux pardus-linux
os_support=debian-linux freebsd osf1 redhat-linux mandrake-linux slackware-linux solaris suse-linux united-linux unixware openserver open-linux turbo-linux openbsd corel-linux cobalt-linux irix netbsd msc-linux generic-linux alpine-linux gentoo-linux hpux trustix-linux macos sol-linux coherent-linux openmamba-linux pardus-linux
desc=DHCP Server
longdesc=Manage shared networks, subnets, hosts and groups for ISC DHCPD.

View File

@@ -103,6 +103,12 @@ elsif ($config{'interfaces_type'} eq 'gentoo') {
$dhcp{'IFACE'} = $iface;
&write_env_file("/etc/conf.d/dhcp", \%dhcp);
}
elsif ($config{'interfaces_type'} eq 'alpine') {
# Interfaces are set in a file on Alpine
&read_env_file("/etc/conf.d/dhcpd", \%dhcp);
$dhcp{'DHCPD_IFACE'} = $iface;
&write_env_file("/etc/conf.d/dhcpd", \%dhcp);
}
elsif ($config{'interfaces_type'} eq 'freebsd') {
# Update FreeBSD rc.conf file
&foreign_require("init");
@@ -110,4 +116,3 @@ elsif ($config{'interfaces_type'} eq 'freebsd') {
}
&redirect("");

View File

@@ -2,6 +2,6 @@ name=Dump
desc=Filesystem Backup
category=system
depends=mount cron proc mailboxes
os_support=redhat-linux mandrake-linux slackware-linux debian-linux suse-linux united-linux open-linux turbo-linux corel-linux cobalt-linux msc-linux generic-linux solaris freebsd macos gentoo-linux irix trustix-linux coherent-linux pardus-linux
os_support=redhat-linux mandrake-linux slackware-linux debian-linux suse-linux united-linux open-linux turbo-linux corel-linux cobalt-linux msc-linux generic-linux alpine-linux solaris freebsd macos gentoo-linux irix trustix-linux coherent-linux pardus-linux
longdesc=Backup and restore filesystems using the dump and restore family of commands.
readonly=1

View File

@@ -124,6 +124,15 @@ elsif ($init_mode eq "systemd") {
# Create systemd
# See updateboot.pl
}
elsif ($init_mode eq "openrc") {
# Create OpenRC script, if missing
&enable_at_boot($product, $ucproduct,
"$config_directory/.start-init",
"$config_directory/.stop-init",
undef,
{ 'fork' => 1,
'pidfile' => $var_directory."/miniserv.pid" });
}
elsif ($init_mode eq "rc" || $init_mode eq "upstart") {
# Create RC or upstart script
&enable_at_boot($product, $ucproduct,
@@ -141,4 +150,3 @@ elsif ($init_mode eq "launchd") {
$config{'atboot_product'} = $product;
&save_module_config();

11
init/config-alpine-linux Normal file
View File

@@ -0,0 +1,11 @@
init_mode=openrc
init_base=/etc/runlevels
init_dir=/etc/init.d
reboot_command=reboot
shutdown_command=poweroff
expert=0
desc=1
status_check=1
order=0
sort_mode=0
boot_levels=default

View File

@@ -1,11 +1,12 @@
line1=Configurable options,11
expert=Allow selection of individual runlevels?,1,1-Yes,0-No
desc=Display actions with descriptions,1,2-Yes, and show all runlevels,1-Yes,0-No
systemd_dedicated=Hide systemd services table?,1,-No,1-Yes
order=Show boot order of actions?,1,1-Yes,0-No
status_check=Show current status of actions,1,2-On index and action pages,1-On action page only,0-No
sort_mode=Sort actions by,1,1-Boot order,0-Name
line2=System configuration,11
init_mode=Boot system,4,-Detect automatically,init-SysV init,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-FreeBSD RC scripts,win32-Windows services,local-Single boot script
init_mode=Boot system,4,-Detect automatically,systemd-Systemd,init-SysV init,openrc-OpenRC,upstart-Upstart,local-Single boot script,rc-FreeBSD RC scripts,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Windows services
init_base=Directory in which runlevel directories are located,0
init_dir=Directory containing master init scripts,0
order_digits=Number of digits in action order,0
@@ -17,8 +18,8 @@ shutdown_command=Command to shutdown the system,0
inittab_id=inittab ID for bootup runlevel,0
rc_dir=FreeBSD rc scripts directories,3,None
rc_conf=FreeBSD configuration files,3,None
line3=OSX system configuration,11
startup_dirs=Darwin StartupItems directories,0
line3=macOS StartupItems configuration,11
startup_dirs=macOS StartupItems directories,0
darwin_setup=Directory for custom StartupItems,0
hostconfig=Darwin hostconfig file,0
hostconfig=Legacy hostconfig file,0
plist=Name of plist in a StartupItems directory,0

View File

@@ -5,7 +5,7 @@ order=Mostra l'ordre d'engegada de les accions,1,1-Sí,0-No
status_check=Mostra l'estat actual de les accions,1,2-A les pàgines d'índex i de l'acció,1-Només a la pàgina de l'acció,0-No
sort_mode=Ordena les accions per,1,1-Ordre d'engegada,0-Nom
line2=Configuració del sistema,11
init_mode=Engegada del sistema,4,-Detecta-ho automàticament,init-Init de SysV,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-Scripts RC de FreeBSD,win32-Serveis Windows,local-Script únic d'engegada
init_mode=Engegada del sistema,4,-Detecta-ho automàticament,systemd-Systemd,init-Init de SysV,openrc-OpenRC,upstart-Upstart,local-Script únic d'engegada,rc-Scripts RC de FreeBSD,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Serveis Windows
init_base=Directori on s'allotgen els directoris de nivells d'execució,0
init_dir=Directori que conté els scripts init mestres,0
order_digits=Nombre de dígits de l'ordre de l'acció,0

View File

@@ -5,7 +5,7 @@ order=Zeige die Aktionen in Reihenfolge des Starts an?,1,1-Ja,0-Nein
status_check=Zeige aktuellen Status der Aktionen,1,2-Auf Index- und Aktionen-Seite,1-Nur auf der Aktionen-Seite,0-Nein
sort_mode=Sortiere Aktionen nach,1,1-Boot-Reihenfolge,0-Name
line2=Systemkonfiguration,11
init_mode=Boot-System,4,-automatisch erkennen,init-SysV init,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-FreeBSD RC Script,win32-Windows-Dienste,local-Single Bootskript
init_mode=Boot-System,4,-automatisch erkennen,systemd-Systemd,init-SysV init,openrc-OpenRC,upstart-Upstart,local-Single Bootskript,rc-FreeBSD RC Script,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Windows-Dienste
init_base=Verzeichnis, in dem die Runlevel-Verzeichnisse liegen,0
init_dir=Verzeichnis, in dem das Haupt-Skript liegt,0
order_digits=Anzahl Ziffern in Aktionsreihenfolge,0

View File

@@ -5,7 +5,7 @@ order=Vis handlingenes oppstartsrekkefølge?1,1-Ja,0-Nei
status_check=Vis handlingenes gjeldende status,1,2-På indeks- og handlingssider,1-Bare på handlingssider,0-Nei
sort_mode=Sorter handlinger etter,1,1-Oppstartrekkefølge,0-Navn
line2=System konfigurasjon,11
init_mode=Oppstartssystem,4,-Oppdag automatisk,init-SysV init,upstart-Upstart,systemd-Systemd,osx-MacOS,rc-FreeBSD RC scripts,win32-Windows tjenester,local-Enkelt oppstartsscript
init_mode=Oppstartssystem,4,-Oppdag automatisk,systemd-Systemd,init-SysV init,openrc-OpenRC,upstart-Upstart,local-Enkelt oppstartsscript,rc-FreeBSD RC scripts,launchd-macOS launchd,osx-Legacy macOS StartupItems,win32-Windows tjenester
init_base=Katalog hvor kjøretids-kataloger finnes,0
init_dir=Katalog som inneholder master init scripts,0
order_digits=Antall sifre i handlingssortering,0

View File

@@ -329,70 +329,74 @@ elsif ($init_mode eq "upstart" && $access{'bootup'}) {
}
elsif ($init_mode eq "systemd" && $access{'bootup'}) {
# Show systemd actions
print &ui_form_start("mass_systemd.cgi", "post");
@links = ( &select_all_link("d"),
&select_invert_link("d"),
&ui_link("edit_systemd.cgi?new=1", $text{'index_sadd'}) );
print &ui_links_row(\@links);
print &ui_columns_start([ "", $text{'systemd_name'},
$config{'desc'} ? $text{'systemd_desc'} : (),
$text{'systemd_type'},
$text{'systemd_status'},
$text{'systemd_boot'},
$text{'index_ustatus'} ]);
my $units_piped = join('|', map { quotemeta } &get_systemd_unit_types());
foreach $u (&list_systemd_services()) {
if ($u->{'legacy'}) {
$l = "edit_action.cgi?0+".&urlize($u->{'name'});
}
else {
$l = "edit_systemd.cgi?name=".&urlize($u->{'name'});
}
my $sname = $u->{'name'};
my ($type) = $sname =~ /\.([^.]+)$/;
if (defined($type) && $type =~ /^(?:$units_piped)$/) {
$sname =~ s/\.$type$//;
}
else {
$type = '';
}
my $title = ($u->{'boot'} == -1 ?
&html_escape($sname) :
&ui_link($l, &html_escape($sname)));
my $desc = $config{'desc'} ? &html_escape($u->{'desc'}) : undef;
print &ui_columns_row([
&ui_checkbox("d", $u->{'name'}, undef),
$title,
$desc // (),
$type,
$u->{'fullstatus'} || "<i>$text{'index_unknown'}</i>",
$u->{'boot'} == 1 ?
&ui_text_color("$text{'yes'}", 'success') :
$u->{'boot'} == 2 ?
&ui_text_color("$text{'index_sboot6'}", 'success') :
$u->{'boot'} == -1 ?
&ui_text_color("$text{'index_sboot5'}", 'warn') :
&ui_text_color("$text{'no'}", 'warn'),
$u->{'status'} == 1 ? &ui_text_color("$text{'yes'}", 'success') :
$u->{'status'} == 0 ?
&ui_text_color("$text{'no'}", 'warn') :
"<i>$text{'index_unknown'}</i>",
]);
if (!&init_show_systemd_services()) {
my $systemd_link = &ui_tag('a',
$text{'index_systemd_module'},
{ 'href' => '../systemd/' });
print &ui_alert_box(
&text('index_systemd_dedicated', $systemd_link),
'info', undef, undef, ""),"\n";
}
print &ui_columns_end();
print &ui_links_row(\@links);
print &ui_form_end([ [ "start", $text{'index_start'} ],
[ "stop", $text{'index_stop'} ],
[ "restart", $text{'index_restart'} ],
undef,
[ "addboot", $text{'index_addboot'} ],
[ "delboot", $text{'index_delboot'} ],
undef,
[ "addboot_start", $text{'index_addboot_start'} ],
[ "delboot_stop", $text{'index_delboot_stop'} ],
]);
else {
# Show systemd actions
print &ui_form_start("mass_systemd.cgi", "post");
@links = ( &select_all_link("d"),
&select_invert_link("d"),
&ui_link("edit_systemd.cgi?new=1",
$text{'index_sadd'}) );
print &ui_links_row(\@links);
print &ui_columns_start([ "", $text{'systemd_name'},
$config{'desc'} ?
$text{'systemd_desc'} : (),
$text{'systemd_status'},
$text{'systemd_boot'},
$text{'index_ustatus'} ]);
foreach $u (&list_systemd_services()) {
if ($u->{'legacy'}) {
$l = "edit_action.cgi?0+".&urlize($u->{'name'});
}
else {
$l = "edit_systemd.cgi?name=".&urlize($u->{'name'});
}
my $sname = $u->{'name'};
$sname =~ s/\.service$//;
my $title = ($u->{'boot'} == -1 ?
&html_escape($sname) :
&ui_link($l, &html_escape($sname)));
my $desc = $config{'desc'} ?
&html_escape($u->{'desc'}) : undef;
print &ui_columns_row([
&ui_checkbox("d", $u->{'name'}, undef),
$title,
$desc // (),
$u->{'fullstatus'} || "<i>$text{'index_unknown'}</i>",
$u->{'boot'} == 1 ?
&ui_text_color("$text{'yes'}", 'success') :
$u->{'boot'} == 2 ?
&ui_text_color("$text{'index_sboot6'}", 'success') :
$u->{'boot'} == -1 ?
&ui_text_color("$text{'index_sboot5'}", 'warn') :
&ui_text_color("$text{'no'}", 'warn'),
$u->{'status'} == 1 ? &ui_text_color("$text{'yes'}", 'success') :
$u->{'status'} == 0 ?
&ui_text_color("$text{'no'}", 'warn') :
"<i>$text{'index_unknown'}</i>",
]);
}
print &ui_columns_end();
print &ui_links_row(\@links);
print &ui_form_end([ [ "start", $text{'index_start'} ],
[ "stop", $text{'index_stop'} ],
[ "restart", $text{'index_restart'} ],
undef,
[ "addboot", $text{'index_addboot'} ],
[ "delboot", $text{'index_delboot'} ],
undef,
[ "addboot_start", $text{'index_addboot_start'} ],
[ "delboot_stop", $text{'index_delboot_stop'} ],
]);
}
}
elsif ($init_mode eq "launchd" && $access{'bootup'}) {
# Show launchd agents
@@ -449,4 +453,3 @@ if ($access{'shutdown'}) {
print &ui_buttons_end();
&ui_print_footer("/", $text{'index'});

View File

@@ -28,9 +28,9 @@ use WebminCore;
This variable is set based on the bootup system in use. Possible values are :
=item osx - MacOSX hostconfig files, for older versions
=item osx - Legacy macOS StartupItems and hostconfig files
=item launchd - MacOS Launchd, for newer versions
=item launchd - macOS launchd, for newer versions
=item rc - FreeBSD 6+ RC files
@@ -44,6 +44,8 @@ This variable is set based on the bootup system in use. Possible values are :
=item systemd - SystemD, seen on Fedora 16
=item openrc - OpenRC, seen on Alpine Linux and Gentoo
=cut
if ($config{'init_mode'}) {
$init_mode = $config{'init_mode'};
@@ -100,6 +102,14 @@ local($dir, $f, @stbuf, @rv);
$dir = &runlevel_dir($_[0]);
opendir(DIR, $dir);
foreach $f (readdir(DIR)) {
if ($init_mode eq "openrc") {
next if ($_[1] ne "S" || $f eq "." || $f eq "..");
next if (-d "$dir/$f");
if (@stbuf = stat("$dir/$f")) {
push(@rv, "00 $f $stbuf[1]");
}
next;
}
if ($f !~ /^([A-Z])(\d+)(.*)$/ || $1 ne $_[1]) { next; }
if (!(@stbuf = stat("$dir/$f"))) { next; }
push(@rv, "$2 $3 $stbuf[1]");
@@ -120,7 +130,11 @@ sub list_runlevels
local(@rv);
opendir(DIR, $config{init_base});
foreach (readdir(DIR)) {
if (/^rc([A-z0-9])\.d$/ || /^(boot)\.d$/) {
if ($init_mode eq "openrc") {
push(@rv, $_) if ($_ ne "." && $_ ne ".." &&
-d "$config{init_base}/$_");
}
elsif (/^rc([A-z0-9])\.d$/ || /^(boot)\.d$/) {
push(@rv, $1);
}
}
@@ -174,6 +188,16 @@ foreach $rl (&list_runlevels()) {
$dir = &runlevel_dir($rl);
opendir(DIR, $dir);
foreach $f (readdir(DIR)) {
if ($init_mode eq "openrc") {
next if ($_[0] ne "S" || $f eq "." || $f eq "..");
next if (-d "$dir/$f");
@stbuf2 = stat("$dir/$f");
if ($stbuf[1] == $stbuf2[1]) {
push(@rv, "$rl 00 $f");
last;
}
next;
}
if ($f =~ /^([A-Z])(\d+)(.*)$/ && $1 eq $_[0]) {
@stbuf2 = stat("$dir/$f");
if ($stbuf[1] == $stbuf2[1]) {
@@ -242,6 +266,14 @@ Add some existing action to a runlevel. The parameters are :
=cut
sub add_rl_action
{
if ($init_mode eq "openrc") {
return if ($_[2] ne "S");
my $file = &runlevel_dir($_[1])."/$_[0]";
&lock_file($file);
&symlink_file(&action_filename($_[0]), $file) if (!-e $file);
&unlock_file($file);
return;
}
$file = &runlevel_filename($_[1], $_[2], $_[3], $_[0]);
while(-r $file) {
if ($file =~ /^(.*)_(\d+)$/) { $file = "$1_".($2+1); }
@@ -269,6 +301,11 @@ sub delete_rl_action
local(@stbuf, $dir, $f, @stbuf2);
@stbuf = stat(&action_filename($_[0]));
$dir = &runlevel_dir($_[1]);
if ($init_mode eq "openrc") {
my $file = "$dir/$_[0]";
&unlink_logged($file) if ($_[2] eq "S" && -e $file);
return;
}
opendir(DIR, $dir);
foreach $f (readdir(DIR)) {
if ($f =~ /^([A-Z])(\d+)(.+)$/ && $1 eq $_[2]) {
@@ -565,6 +602,11 @@ elsif ($init_mode eq "systemd") {
return 1 if ($out eq "disabled");
}
}
elsif ($init_mode eq "openrc") {
my $exists = -r &action_filename($name);
my @boot = &action_levels("S", $name);
return !$exists ? 0 : @boot ? 2 : 1;
}
if ($init_mode eq "init" || $init_mode eq "upstart" ||
$init_mode eq "systemd") {
# Look for init script
@@ -710,6 +752,48 @@ if ($init_mode eq "systemd" && (!-r "$config{'init_dir'}/$action" ||
quotemeta($unit)." >/dev/null 2>&1");
return;
}
if ($init_mode eq "openrc") {
if ($st == 0) {
$start || $stop || &error("OpenRC service $action does not exist");
my $fn = &action_filename($action);
my $qdesc = $desc || "";
$qdesc =~ s/\\/\\\\/g;
$qdesc =~ s/"/\\"/g;
&lock_file($fn);
&open_tempfile(ACTION, ">$fn");
&print_tempfile(ACTION, "#!/sbin/openrc-run\n\n");
&print_tempfile(ACTION, "description=\"$qdesc\"\n\n") if ($desc);
&print_tempfile(ACTION, "start() {\n");
&print_tempfile(ACTION, &tab_indent($start));
&print_tempfile(ACTION, "}\n\n");
if ($stop) {
&print_tempfile(ACTION, "stop() {\n");
&print_tempfile(ACTION, &tab_indent($stop));
&print_tempfile(ACTION, "}\n\n");
}
if ($status) {
&print_tempfile(ACTION, "status() {\n");
&print_tempfile(ACTION, &tab_indent($status));
&print_tempfile(ACTION, "}\n");
}
&close_tempfile(ACTION);
chmod(0755, $fn);
&unlock_file($fn);
}
my @levels = &get_start_runlevels();
if (&has_command("rc-update")) {
foreach my $level (@levels) {
&system_logged("rc-update add ".quotemeta($action)." ".
quotemeta($level)." >/dev/null 2>&1");
}
}
else {
foreach my $level (@levels) {
&add_rl_action($action, $level, "S", 0);
}
}
return;
}
if ($init_mode eq "init" || $init_mode eq "local" || $init_mode eq "upstart" ||
$init_mode eq "systemd") {
# In these modes, we create a script to run
@@ -1087,6 +1171,18 @@ elsif ($init_mode eq "systemd") {
&system_logged("systemctl disable ".quotemeta($unit).
" >/dev/null 2>&1");
}
elsif ($init_mode eq "openrc") {
if (&has_command("rc-update")) {
&system_logged("rc-update del ".quotemeta($_[0]).
" >/dev/null 2>&1");
}
else {
foreach my $a (&action_levels('S', $_[0])) {
$a =~ /^(\S+)\s+(\S+)\s+(\S+)$/ &&
&delete_rl_action($_[0], $1, 'S');
}
}
}
if ($init_mode eq "init" || $init_mode eq "upstart" ||
$init_mode eq "systemd") {
# Unlink or disable init script
@@ -1251,6 +1347,11 @@ elsif ($mode eq "init") {
my $fn = &action_filename($name);
&unlink_logged($fn);
}
elsif ($mode eq "openrc") {
&disable_at_boot($name);
my $fn = &action_filename($name);
&unlink_logged($fn);
}
elsif ($mode eq "win32") {
# Delete windows service
&delete_win32_service($name);
@@ -1303,6 +1404,16 @@ if ($action_mode eq "init" || $action_mode eq "local") {
my $ex = $?;
return (!$ex, $out);
}
elsif ($action_mode eq "openrc") {
my $cmd = &has_command("rc-service") ?
"rc-service ".quotemeta($name)." start" :
&action_filename($name)." start";
&clean_environment();
my $out = &backquote_logged("$cmd 2>&1 </dev/null");
&reset_environment();
my $ex = $?;
return (!$ex, $out);
}
elsif ($action_mode eq "rc") {
# Run FreeBSD RC script
return &start_rc_script($name);
@@ -1351,6 +1462,14 @@ if ($action_mode eq "init" || $action_mode eq "local") {
my $ex = $?;
return (!$ex, $out);
}
elsif ($action_mode eq "openrc") {
my $cmd = &has_command("rc-service") ?
"rc-service ".quotemeta($name)." stop" :
&action_filename($name)." stop";
my $out = &backquote_logged("$cmd 2>&1 </dev/null");
my $ex = $?;
return (!$ex, $out);
}
elsif ($action_mode eq "rc") {
# Run FreeBSD RC script
return &stop_rc_script($name);
@@ -1392,6 +1511,11 @@ if ($action_mode eq "upstart") {
elsif ($action_mode eq "systemd") {
return &restart_systemd_service($name);
}
elsif ($action_mode eq "openrc" && &has_command("rc-service")) {
my $out = &backquote_logged("rc-service ".quotemeta($name).
" restart 2>&1 </dev/null");
return $? ? (0, $out) : (1, $out);
}
else {
&stop_action($name);
return &start_action($name);
@@ -1413,6 +1537,11 @@ if ($action_mode eq "upstart") {
elsif ($action_mode eq "systemd") {
return &reload_systemd_service($name);
}
elsif ($action_mode eq "openrc" && &has_command("rc-service")) {
my $out = &backquote_logged("rc-service ".quotemeta($name).
" reload 2>&1 </dev/null");
return $? ? (0, $out) : (1, $out);
}
elsif ($action_mode eq "init") {
my $file = &action_filename($name);
my $hasarg = &get_action_args($file);
@@ -1438,6 +1567,13 @@ if ($action_mode eq "init") {
# Run init script to get status
return &action_running(&action_filename($name));
}
elsif ($action_mode eq "openrc") {
my $cmd = &has_command("rc-service") ?
"rc-service ".quotemeta($name)." status" :
&action_filename($name)." status";
my $out = &backquote_command("$cmd 2>&1 </dev/null");
return $? == 0 ? 1 : $out =~ /stopped|inactive/i ? 0 : -1;
}
elsif ($action_mode eq "win32") {
# Check with Windows if it is running
my ($w) = &list_win32_services($name);
@@ -1519,6 +1655,9 @@ elsif ($init_mode eq "systemd") {
elsif ($init_mode eq "init") {
return map { my @w = split(/\s+/, $_); $w[0] } &list_actions();
}
elsif ($init_mode eq "openrc") {
return map { my @w = split(/\s+/, $_); $w[0] } &list_actions();
}
elsif ($init_mode eq "win32") {
return map { $_->{'name'} } &list_win32_services();
}
@@ -1595,7 +1734,10 @@ like /etc/rc2.d.
=cut
sub runlevel_dir
{
if ($_[0] eq "boot") {
if ($init_mode eq "openrc") {
return "$config{init_base}/$_[0]";
}
elsif ($_[0] eq "boot") {
return "$config{init_base}/boot.d";
}
else {
@@ -2169,16 +2311,15 @@ if (@list_systemd_services_cache && !$noinit) {
return @list_systemd_services_cache;
}
my $units_piped = join('|', &get_systemd_unit_types());
# Get all systemd unit names
my $out = &backquote_command("systemctl list-units --full --all -t service --no-legend");
my $ex = $?;
foreach my $l (split(/\r?\n/, $out)) {
$l =~ s/^[^a-z0-9\-\_\.]+//i;
my ($unit, $loaded, $active, $sub, $desc) = split(/\s+/, $l, 5);
next if ($unit !~ /\.service$/);
my $a = $unit;
$a =~ s/\.($units_piped)$//;
$a =~ s/\.service$//;
my $f = &action_filename($a);
if ($unit ne "UNIT" && $loaded eq "loaded" && !-r $f) {
push(@units, $unit);
@@ -2190,29 +2331,26 @@ foreach my $l (split(/\r?\n/, $out)) {
# and so don't show up in systemctl list-units
my $root = &get_systemd_root(undef, 1);
opendir(UNITS, $root);
push(@units, grep { !/\.wants$/ && !/^\./ && !-d "$root/$_" } readdir(UNITS));
push(@units, grep { /\.service$/ && !-d "$root/$_" } readdir(UNITS));
closedir(UNITS);
# Also add units from list-unit-files that also don't show up
$out = &backquote_command("systemctl list-unit-files -t service --no-legend");
foreach my $l (split(/\r?\n/, $out)) {
if ($l =~ /^(\S+\.($units_piped))\s+disabled/ ||
$l =~ /^(\S+)\s+disabled/) {
if ($l =~ /^(\S+\.service)\s+disabled/) {
push(@units, $1);
}
}
# Skip useless units
@units = grep { !/^sys-devices-/ &&
!/^\-\.mount/ &&
!/^\-\.slice/ &&
!/^dev-/ &&
!/^systemd-/ } @units;
@units = &unique(@units);
# Filter out templates
my @templates = grep { /\@$/ || /\@\.($units_piped)$/ } @units;
@units = grep { !/\@$/ && !/\@\.($units_piped)$/ } @units;
my @templates = grep { /\@$/ || /\@\.service$/ } @units;
@units = grep { !/\@$/ && !/\@\.service$/ } @units;
# Dump state of all of them, 100 at a time
my %info;
@@ -3000,11 +3138,90 @@ return $name =~ /\./ ? $name : "com.webmin.".$name;
}
# config_pre_load(mod-info, [mod-order])
# Check if some config options are conditional
# Hides config options that do not apply to the detected boot system.
sub config_pre_load
{
my ($modconf_info, $modconf_order) = @_;
$modconf_info->{'desc'} =~ s/2-[^,]+,// if ($init_mode eq "systemd");
return if (ref($modconf_info) ne 'HASH');
if ($init_mode eq "systemd" && $modconf_info->{'desc'}) {
# Systemd has no runlevels, so keep only the plain yes/no choices.
$modconf_info->{'desc'} =~ s/2-[^,]+,//;
}
my %keep = map { $_, 1 } &init_config_options_for_mode($init_mode);
foreach my $key (keys %$modconf_info) {
delete($modconf_info->{$key}) if (!$keep{$key});
}
if (ref($modconf_order) eq 'ARRAY') {
@$modconf_order = grep { $keep{$_} } @$modconf_order;
}
&hide_single_init_config_section($modconf_info, $modconf_order);
}
# init_config_options_for_mode(mode)
# Returns config.info keys that should be visible for a boot system.
sub init_config_options_for_mode
{
my ($mode) = @_;
my @display = ( 'expert', 'desc', 'order', 'status_check', 'sort_mode' );
my @common = ( 'init_mode', 'reboot_command', 'shutdown_command' );
my @sysv = ( @common, 'init_base', 'init_dir', 'order_digits',
'boot_levels', 'local_script', 'local_down', 'inittab_id' );
my @systemd_display = ( 'desc' );
push(@systemd_display, 'systemd_dedicated')
if (&init_dedicated_systemd_module_available());
return ( 'line1', @systemd_display, 'line2', @common )
if ($mode eq 'systemd');
return ( 'line1', @display, 'line2', @sysv )
if ($mode eq 'init' || $mode eq 'upstart' || $mode eq 'openrc');
return ( 'line2', @common, 'local_script', 'local_down',
'rc_dir', 'rc_conf' )
if ($mode eq 'rc');
return ( 'line2', @common, 'local_script', 'local_down' )
if ($mode eq 'local');
return ( 'line2', @common, 'line3', 'startup_dirs', 'darwin_setup',
'hostconfig', 'plist' )
if ($mode eq 'osx');
return ( 'line2', @common )
if ($mode eq 'launchd' || $mode eq 'win32');
return ( 'line1', @display, 'line2', @sysv, 'rc_dir', 'rc_conf',
'line3', 'startup_dirs', 'darwin_setup', 'hostconfig', 'plist' );
}
# hide_single_init_config_section(&config-info, [&config-order])
# Removes the lone section header when filtering leaves only one group.
sub hide_single_init_config_section
{
my ($modconf_info, $modconf_order) = @_;
my @sections = grep {
exists($modconf_info->{$_}) &&
(split(/,/, $modconf_info->{$_}))[1] == 11
} keys %$modconf_info;
return if (@sections != 1);
delete($modconf_info->{$sections[0]});
if (ref($modconf_order) eq 'ARRAY') {
@$modconf_order = grep { $_ ne $sections[0] } @$modconf_order;
}
}
# init_dedicated_systemd_module_available()
# Returns 1 if the standalone Systemd module can be used by this Webmin user.
sub init_dedicated_systemd_module_available
{
return &foreign_available("systemd") && &foreign_installed("systemd");
}
# init_show_systemd_services()
# Returns 1 if this module should show its legacy systemd service table.
sub init_show_systemd_services
{
return 1 if (!&init_dedicated_systemd_module_available());
return 0 if ($config{'systemd_dedicated'} &&
$config{'systemd_dedicated'} eq '1');
return 1;
}
1;

View File

@@ -188,13 +188,14 @@ change_title=Switch Runlevel
change_cmd=Switching to runlevel $1 with command $2. This may take some time, and Webmin might not be available anymore after switching.
mode_init=SysV init
mode_osx=MacOS
mode_osx=Legacy macOS StartupItems
mode_local=Single boot script
mode_win32=Windows services
mode_rc=FreeBSD RC scripts
mode_upstart=Upstart
mode_systemd=Systemd
mode_launchd=LaunchD
mode_launchd=macOS launchd
mode_openrc=OpenRC
upstart_title1=Create Upstart Service
upstart_title2=Edit Upstart Service
@@ -246,6 +247,8 @@ systemd_edesc=Missing unit description
systemd_return=systemd unit
systemd_econf=No systemd unit configuration entered
systemd_estart=Missing commands to run on startup
index_systemd_module=Systemd Services and Units
index_systemd_dedicated=Use the dedicated $1 module to manage systemd services and units. This page now shows only system reboot and shutdown controls.
launchd_title1=Create Launchd Agent
launchd_title2=Edit Launchd Agent

View File

@@ -56,6 +56,26 @@ if ($product) {
quotemeta($product).".service >/dev/null 2>&1");
}
}
elsif ($init_mode eq "openrc") {
my $status = &action_status($product);
my %miniserv;
&get_miniserv_config(\%miniserv);
my $want_boot = $miniserv{'atboot'} ? 1 : 0;
my $temp = &transname();
$ENV{'WEBMIN_KILLCMD'} = &has_command('kill');
&copy_source_dest("$root_directory/webmin-openrc-init", "$temp");
my $lref = &read_file_lines($temp);
foreach my $l (@{$lref}) {
$l =~ s/(WEBMIN_[A-Z]+)/$ENV{$1}/g;
}
&flush_file_lines($temp);
&copy_source_dest($temp, "/etc/init.d/$product");
chmod(0755, "/etc/init.d/$product");
&unlink_file($temp);
if ($status == 2 || $want_boot) {
&enable_at_boot($product);
}
}
elsif ($init_mode eq "launchd") {
# Update or create launchd agent to use start init wrapper
my $name = &launchd_name($product);

View File

@@ -1,6 +1,6 @@
name=lpadmin
category=hardware
os_support=solaris coherent-linux redhat-linux mandrake-linux slackware-linux suse-linux united-linux debian-linux freebsd hpux unixware macos open-linux turbo-linux openbsd corel-linux irix netbsd msc-linux generic-linux gentoo-linux trustix-linux openmamba-linux aix pardus-linux
os_support=solaris coherent-linux redhat-linux mandrake-linux slackware-linux suse-linux united-linux debian-linux freebsd hpux unixware macos open-linux turbo-linux openbsd corel-linux irix netbsd msc-linux generic-linux alpine-linux gentoo-linux trustix-linux openmamba-linux aix pardus-linux
desc=Printer Administration
longdesc=Create and edit local and remote printers. Supports Windows print servers and Ghostscript print drivers.
readonly=1

View File

@@ -81,7 +81,7 @@ system("cd $usr_dir && rm -f mount/freebsd-mounts*");
system("cd $usr_dir && rm -f mount/openbsd-mounts*");
if ($product eq "webmin") {
system("cd $usr_dir && rm -f mount/macos-mounts*");
system("cd $usr_dir && rm -f webmin-gentoo-init");
system("cd $usr_dir && rm -f webmin-openrc-init");
system("cd $usr_dir && rm -rf format bsdexports hpuxexports sgiexports zones rbac bsdfdisk");
system("cd $usr_dir && rm -rf acl/Authen-SolarisRBAC-0.1*");
}

View File

@@ -46,7 +46,7 @@ $vers || usage();
"defaulttheme",
"javascript-lib.pl", "webmin-pam", "webmin-debian-pam", "maketemp.pl",
"run-uninstalls.pl",
"webmin-gentoo-init", "run-postinstalls.pl",
"webmin-openrc-init", "run-postinstalls.pl",
"config-lib.pl", "entities_map.txt", "ui-lib.pl",
"password_form.cgi", "password_change.cgi", "pam_login.cgi",
"module_chooser.cgi", "config-windows", "xmlrpc.cgi",

View File

@@ -112,7 +112,7 @@ browser and login as root with your root password.
rm -f mount/freebsd-mounts*
rm -f mount/openbsd-mounts*
rm -f mount/macos-mounts*
rm -f webmin-gentoo-init
rm -f webmin-openrc-init
rm -rf format bsdexports hpuxexports sgiexports zones rbac bsdfdisk
rm -rf acl/Authen-SolarisRBAC-0.1*
chmod -R og-w .
@@ -360,4 +360,3 @@ foreach $rpm ("rpm", "newkey/rpm") {
system("cp $rpm/webmin-$ver-$rel.noarch.rpm /usr/local/webadmin/$rpm/yum");
}
}

View File

@@ -1,3 +1,5 @@
---- Changes since 2.641 ----
Added defaults for alpine linux and fix package installs
---- Changes since 1.140 ----
The not null flag and a default value can be specified for fields in new tables.
The form for creating an initial table in a new database is now the same as the one for adding a table to an existing database.

25
mysql/config-alpine-linux Normal file
View File

@@ -0,0 +1,25 @@
start_cmd=rc-service mariadb start
mysql=/usr/bin/mariadb
mysqld=/usr/bin/mariadbd
mysqldump=/usr/bin/mysqldump
mysqlimport=/usr/bin/mariadb-import
mysql_libs=/usr/lib/mariadb/plugin
mysqladmin=/usr/bin/mariadb-admin
mysqlshow=/usr/bin/mariadb-show
perpage=25
style=1
add_mode=1
nodbi=0
access=*: *
blob_mode=0
date_subs=0
passwd_mode=0
mysql_data=/var/lib/mysql
max_dbs=50
my_cnf=/etc/my.cnf
max_text=1000
nopwd=0
webmin_subs=0
ssl=0
stop_cmd=rc-service mariadb stop

38
net/alpine-linux-lib.pl Normal file
View File

@@ -0,0 +1,38 @@
# Networking functions for Alpine Linux
do 'debian-linux-lib.pl';
$network_interfaces_config = '/etc/network/interfaces';
# apply_network()
# Apply the interface and routing settings
sub apply_network
{
if (&has_command("rc-service")) {
&system_logged("(cd / ; rc-service networking restart) >/dev/null 2>&1");
}
elsif (-x "/etc/init.d/networking") {
&system_logged("(cd / ; /etc/init.d/networking restart) >/dev/null 2>&1");
}
else {
&system_logged("(cd / ; ifdown -a ; ifup -a) >/dev/null 2>&1");
}
}
sub network_config_files
{
return ( "/etc/hostname", "/etc/HOSTNAME", "/etc/mailname",
$network_interfaces_config );
}
sub supports_bonding
{
return &has_command("ifenslave");
}
sub supports_vlans
{
return &has_command("vconfig");
}
1;

View File

@@ -1,6 +1,6 @@
name=Networking
category=net
os_support=solaris coherent-linux redhat-linux/5.0-* mandrake-linux united-linux suse-linux/6.0-* open-linux unixware turbo-linux/4.0 freebsd/3.2-* openbsd debian-linux/2.2-* cobalt-linux/2.2-* msc-linux gentoo-linux macos/1.5-* trustix-linux slackware-linux/8.0-* openmamba-linux cygwin windows pardus-linux
os_support=solaris coherent-linux redhat-linux/5.0-* mandrake-linux united-linux suse-linux/6.0-* open-linux unixware turbo-linux/4.0 freebsd/3.2-* openbsd debian-linux/2.2-* cobalt-linux/2.2-* msc-linux gentoo-linux alpine-linux macos/1.5-* trustix-linux slackware-linux/8.0-* openmamba-linux cygwin windows pardus-linux
desc=Network Configuration
longdesc=Configure boot time and active interfaces, DNS, routing and /etc/hosts.
readonly=1

View File

@@ -334,6 +334,9 @@ Immunix Linux $1 redhat-linux $1 $etc_issue =~ /Immunix.*\s([0-9\.]+)/i || `ca
# All versions of Gentoo (which don't appear to have version numbers)
Gentoo Linux Any version gentoo-linux * -d "/usr/portage" || `cat /etc/os-release 2>/dev/null` =~ /gentoo/
# Alpine Linux
Alpine Linux $1 alpine-linux $1 `cat /etc/alpine-release 2>/dev/null` =~ /^([0-9][0-9\.]*)/ || `cat /etc/os-release 2>/dev/null` =~ /^ID="?alpine"?$/m && `cat /etc/os-release 2>/dev/null` =~ /^VERSION_ID="?([0-9\.]+)/m
# Secure Linux (now called Trustix?)
Secure Linux 1.0 redhat-linux 7.2 `cat /etc/securelinux-release 2>/dev/null` =~ /SecureLinux.*1\.0/i

View File

@@ -2,4 +2,4 @@ desc=Software Package Updates
longdesc=Displays available package updates from YUM, APT or other update systems
category=system
depends=software cron mailboxes
os_support=redhat-linux debian-linux mandrake-linux/10.2-* solaris freebsd macos syno-linux
os_support=redhat-linux debian-linux mandrake-linux/10.2-* solaris freebsd macos syno-linux alpine-linux

View File

@@ -1,6 +1,6 @@
name=PPP
category=net
os_support=redhat-linux mandrake-linux suse-linux united-linux slackware-linux debian-linux open-linux turbo-linux corel-linux msc-linux generic-linux gentoo-linux cobalt-linux solaris trustix-linux coherent-linux openmamba-linux pardus-linux
os_support=redhat-linux mandrake-linux suse-linux united-linux slackware-linux debian-linux open-linux turbo-linux corel-linux msc-linux generic-linux alpine-linux gentoo-linux cobalt-linux solaris trustix-linux coherent-linux openmamba-linux pardus-linux
desc=PPP Dialin Server
depends=inittab
longdesc=Set up a dialin server using mgetty and PPP.

View File

@@ -1,6 +1,6 @@
name=Sendmail
category=servers
os_support=solaris slackware-linux redhat-linux mandrake-linux suse-linux united-linux debian-linux freebsd hpux irix macos open-linux openserver unixware turbo-linux openbsd corel-linux cobalt-linux aix netbsd msc-linux osf1 generic-linux gentoo-linux{-r "/etc/sendmail.cf" || -r "/etc/mail/sendmail.cf"} sol-linux coherent-linux
os_support=solaris slackware-linux redhat-linux mandrake-linux suse-linux united-linux debian-linux freebsd hpux irix macos open-linux openserver unixware turbo-linux openbsd corel-linux cobalt-linux aix netbsd msc-linux osf1 generic-linux alpine-linux gentoo-linux{-r "/etc/sendmail.cf" || -r "/etc/mail/sendmail.cf"} sol-linux coherent-linux
desc=Sendmail Mail Server
longdesc=Manage sendmail aliases, masquerading, address rewriting and other features.
library=sendmail-lib.pl access-lib.pl aliases-lib.pl boxes-lib.pl domain-lib.pl features-lib.pl generics-lib.pl mailers-lib.pl virtusers-lib.pl

View File

@@ -1,3 +1,5 @@
---- Changes since 2.641 ----
Fix Alpine Linux mysql/mariadb package installs names due missing server utils (means at least Alpine Linux package installation is supported since Alpine linux v 3.16 up to edge)
---- Changes since 1.130 ----
Packages can now be installed directly from yum, if installed.
The entire system can also be upgraded from yum.

378
software/apk-lib.pl Normal file
View File

@@ -0,0 +1,378 @@
# apk-lib.pl
# Functions for Alpine Package Keeper package management
$ENV{'PATH'} .= ":/sbin:/usr/sbin";
$apk_installed_db = "/lib/apk/db/installed";
sub list_package_system_commands
{
return ("apk");
}
sub list_update_system_commands
{
return ("apk");
}
# parse_apk_installed()
# Returns installed packages from APK's package database
sub parse_apk_installed
{
my @rv;
my $pkg = { };
my $last;
open(my $db, "<", $apk_installed_db) || return ();
while(my $line = <$db>) {
$line =~ s/\r?\n$//;
if ($line eq "") {
push(@rv, $pkg) if ($pkg->{'P'});
$pkg = { };
$last = undef;
next;
}
if ($line =~ /^([A-Za-z]):(.*)$/) {
$pkg->{$1} = $2;
$last = $1;
}
elsif ($line =~ /^\t(.*)$/ && defined($last)) {
$pkg->{$last} .= "\n".$1;
}
}
close($db);
push(@rv, $pkg) if ($pkg->{'P'});
return @rv;
}
sub apk_package_class
{
return lc($_[0]) =~ /^[a-e]/ ? "A-E" :
lc($_[0]) =~ /^[f-j]/ ? "F-J" :
lc($_[0]) =~ /^[k-o]/ ? "K-O" :
lc($_[0]) =~ /^[p-t]/ ? "P-T" :
lc($_[0]) =~ /^[u-z]/ ? "U-Z" : "Other";
}
sub split_apk_name_version
{
my ($nv) = @_;
return ($1, $2) if ($nv =~ /^(.+)-([0-9][^\s]*)$/);
return ($nv, undef);
}
sub apk_package_record
{
my ($name, $ver) = @_;
foreach my $p (&parse_apk_installed()) {
next if ($p->{'P'} ne $name);
next if ($ver && $p->{'V'} ne $ver);
return $p;
}
return undef;
}
sub apk_quote_packages
{
return join(" ", map { quotemeta($_) } split(/\s+/, $_[0]));
}
# list_packages([package]*)
# Fills the array %packages with a list of all packages
sub list_packages
{
my %wanted = map { $_ => 1 } @_;
my $i = 0;
%packages = ( );
foreach my $p (sort { $a->{'P'} cmp $b->{'P'} } &parse_apk_installed()) {
next if (@_ && !$wanted{$p->{'P'}});
$packages{$i,'name'} = $p->{'P'};
$packages{$i,'class'} = &apk_package_class($p->{'P'});
$packages{$i,'version'} = $p->{'V'};
$packages{$i,'desc'} = $p->{'T'};
$packages{$i,'arch'} = $p->{'A'};
$packages{$i,'url'} = $p->{'U'};
$i++;
}
return $i;
}
# package_search(string)
# Searches installed packages by name and description
sub package_search
{
my ($search) = @_;
my $n = &list_packages();
my $i = 0;
my %old = %packages;
%packages = ( );
for(my $j=0; $j<$n; $j++) {
if ($old{$j,'name'} =~ /\Q$search\E/i ||
$old{$j,'desc'} =~ /\Q$search\E/i) {
foreach my $k ('name', 'class', 'version', 'desc', 'arch',
'url') {
$packages{$i,$k} = $old{$j,$k};
}
$i++;
}
}
return $i;
}
# package_info(package, [version])
# Returns name, class, description, arch, version, vendor, installtime, url
sub package_info
{
my ($name, $ver) = @_;
my $p = &apk_package_record($name, $ver);
return ( ) if (!$p);
return ( $p->{'P'}, &apk_package_class($p->{'P'}),
$p->{'T'} || $text{'apk_unknown'},
$p->{'A'} || $text{'apk_unknown'},
$p->{'V'} || $text{'apk_unknown'},
$p->{'m'} || "Alpine Linux",
undef,
$p->{'U'} );
}
sub virtual_package_info
{
return ( );
}
# package_files(package)
# Returns a list of all files in some package
sub package_files
{
my ($name) = @_;
my $qname = quotemeta($name);
my @rv;
&open_execute_command(PKGINFO, "apk info -L $qname 2>/dev/null", 1, 1);
while(<PKGINFO>) {
s/\r|\n//g;
next if (!$_ || / contains:$/);
$_ = "/".$_ if ($_ !~ /^\//);
push(@rv, $_);
}
close(PKGINFO);
return @rv;
}
# check_files(package)
# Fills in the %files array with information about files belonging to a package
sub check_files
{
my ($name) = @_;
my @pkgfiles = &package_files($name);
%files = ( );
for(my $i=0; $i<@pkgfiles; $i++) {
my $path = $pkgfiles[$i];
my $real = &translate_filename($path);
my @st = stat($real);
$files{$i,'path'} = $path;
$files{$i,'type'} = -l $real ? 3 : -d $real ? 1 : 0;
$files{$i,'user'} = @st ? getpwuid($st[4]) : undef;
$files{$i,'group'} = @st ? getgrgid($st[5]) : undef;
$files{$i,'mode'} = @st ? sprintf("%o", $st[2] & 07777) : undef;
$files{$i,'size'} = @st ? $st[7] : 0;
$files{$i,'link'} = readlink($real);
$files{$i,'error'} = "Does not exist" if (!@st);
}
return scalar(@pkgfiles);
}
# installed_file(file)
# Fills %file with details of the package that owns a file
sub installed_file
{
my ($path) = @_;
my $qpath = quotemeta($path);
my $out = &backquote_command("apk info -W $qpath 2>&1", 1);
return 0 if ($? || $out !~ / is owned by (\S+)/);
my ($pkg, $ver) = &split_apk_name_version($1);
my $real = &translate_filename($path);
my @st = stat($real);
%file = ( );
$file{'path'} = $path;
$file{'type'} = -l $real ? 3 : -d $real ? 1 : 0;
$file{'user'} = @st ? getpwuid($st[4]) : undef;
$file{'group'} = @st ? getgrgid($st[5]) : undef;
$file{'mode'} = @st ? sprintf("%o", $st[2] & 07777) : undef;
$file{'size'} = @st ? $st[7] : 0;
$file{'link'} = readlink($real);
$file{'packages'} = $pkg;
$file{'versions'} = $ver;
return 1;
}
# is_package(file)
sub is_package
{
my ($path) = @_;
my $qpath = quotemeta($path);
my $out = &backquote_command("tar -tzf $qpath .PKGINFO 2>/dev/null", 1);
return $? ? 0 : 1;
}
# file_packages(file)
# Returns a list of packages in an apk file, in "package description" form
sub file_packages
{
my ($path) = @_;
my $qpath = quotemeta($path);
my $out = &backquote_command("tar -xOzf $qpath .PKGINFO 2>/dev/null", 1);
return ( ) if ($?);
my %info;
foreach my $line (split(/\r?\n/, $out)) {
if ($line =~ /^(\S+)\s*=\s*(.*)$/) {
$info{$1} = $2;
}
}
return $info{'pkgname'} ? ( $info{'pkgname'}." ".$info{'pkgdesc'} ) : ( );
}
sub install_options
{
print &ui_table_row($text{'apk_untrusted'},
&ui_yesno_radio("untrusted", 0));
}
# install_package(file, package, [&inputs])
sub install_package
{
my ($path, $package, $inref) = @_;
$inref ||= \%in;
my $qpath = quotemeta($path);
my $args = $inref->{'untrusted'} ? "--allow-untrusted " : "";
my $out = &backquote_logged("apk add $args$qpath 2>&1 </dev/null");
return $? ? "<pre>$out</pre>" : undef;
}
# delete_package(package)
sub delete_package
{
my ($name) = @_;
my $out = &backquote_logged("apk del ".quotemeta($name)." 2>&1 </dev/null");
return $? ? "<pre>$out</pre>" : undef;
}
sub package_dependencies
{
my ($name, $ver) = @_;
my $p = &apk_package_record($name, $ver);
return ( ) if (!$p || !$p->{'D'});
my @rv;
foreach my $dep (split(/\s+/, $p->{'D'})) {
next if (!$dep);
$dep =~ s/^\!//;
if ($dep =~ /^([A-Za-z0-9+_.-]+)([<>=~]+)(\S+)$/) {
push(@rv, { 'package' => $1,
'compare' => $2,
'version' => $3 });
}
elsif ($dep =~ /^[A-Za-z0-9+_.-]+$/) {
push(@rv, { 'package' => $dep });
}
else {
push(@rv, { 'other' => $dep });
}
}
return @rv;
}
sub package_system
{
return $text{'apk_manager'};
}
sub package_help
{
return "apk";
}
###### Update system functions
sub update_system_search
{
my ($search) = @_;
my $pattern = defined($search) && $search ne "" && $search ne ".*" ?
"*".$search."*" : "*";
my @rv;
&clean_language();
&open_execute_command(SEARCH, "apk search -v ".quotemeta($pattern)." 2>/dev/null", 1, 1);
while(<SEARCH>) {
s/\r|\n//g;
if (/^(.+)-([0-9][^\s]*)\s+-\s+(.*)$/) {
push(@rv, { 'name' => $1,
'version' => $2,
'desc' => $3 });
}
}
close(SEARCH);
&reset_environment();
return @rv;
}
sub update_system_available
{
&execute_command("apk update");
return &update_system_search(".*");
}
sub update_system_updates
{
my @rv;
&execute_command("apk update");
&clean_language();
&open_execute_command(UPDATES, "apk version -l '<' -v 2>/dev/null", 1, 1);
while(<UPDATES>) {
s/\r|\n//g;
if (/^(.+)-([0-9][^\s]*)\s+<\s+(\S+)/) {
push(@rv, { 'name' => $1,
'oldversion' => $2,
'version' => $3 });
}
}
close(UPDATES);
&reset_environment();
return @rv;
}
sub update_system_install
{
my $update = $_[0] || $in{'update'};
my @rv;
my $qupdate = &apk_quote_packages($update);
my $cmd = "apk add --update --upgrade $qupdate";
print &text('apk_install', "<tt>".&html_escape($cmd)."</tt>"),"\n";
print "<pre data-installer>";
&additional_log('exec', undef, $cmd);
&open_execute_command(CMD, "$cmd 2>&1 </dev/null", 2);
while(<CMD>) {
if (/\b(?:Installing|Upgrading|Downgrading)\s+(\S+)\s+\(/) {
push(@rv, $1);
}
print &html_escape($_);
}
close(CMD);
print "</pre>\n";
if ($?) { print "$text{'apk_failed'}<p>\n"; }
else { print "$text{'apk_ok'}<p>\n"; }
return &unique(@rv);
}
sub update_system_resolve
{
my ($name) = @_;
return $name eq "apache" ? "apache2" :
$name eq "dhcpd" ? "dhcp" :
$name eq "mysql" ? "mariadb mariadb-client mariadb-server-utils" :
$name eq "postgresql" ? "postgresql postgresql-client" :
$name eq "openldap" ? "openldap openldap-clients" :
$name eq "ldap" ? "openldap openldap-clients" :
$name eq "dovecot" ? "dovecot" :
$name eq "samba" ? "samba samba-client" :
$name eq "openssh" ? "openssh" :
$name eq "squid" ? "squid" :
$name;
}
1;

View File

@@ -0,0 +1,2 @@
package_system=apk
update_system=apk

View File

@@ -1,3 +1,3 @@
package_system=Package management system,1,rpm-RPM,pkgadd-Solaris,hpux-HPUX,freebsd-FreeBSD,slackware-Slackware,debian-Debian,aix-AIX,emerge-Gentoo,cygwin-Cygwin,msi-Microsoft Installer,pkgsrc-PKGsrc,ipkg-Synology IPKG
update_system=Package update system,1,-Detect automatically,apt-APT,yum-YUM,rhn-Redhat Network,csw-Blastwave CSW,urpmi-URPMI,emerge-Emerge,ports-FreeBSD Ports,pkg-FreeBSD pkgng,pkgsrc-PKGsrc,ipkg-Synology IPKG update,*-None
package_system=Package management system,1,rpm-RPM,pkgadd-Solaris,hpux-HPUX,freebsd-FreeBSD,slackware-Slackware,debian-Debian,aix-AIX,emerge-Gentoo,apk-Alpine APK,cygwin-Cygwin,msi-Microsoft Installer,pkgsrc-PKGsrc,ipkg-Synology IPKG
update_system=Package update system,1,-Detect automatically,apt-APT,yum-YUM,rhn-Redhat Network,csw-Blastwave CSW,urpmi-URPMI,emerge-Emerge,apk-Alpine APK,ports-FreeBSD Ports,pkg-FreeBSD pkgng,pkgsrc-PKGsrc,ipkg-Synology IPKG update,*-None
apt_mode=Command to use for APT installs,1,0-apt&#45;get,1-aptitude

View File

@@ -180,6 +180,10 @@ debian_overwrite=Overwrite files from other packages?
debian_downgrade=Replace newer package with old?
debian_manager=Debian
apk_unknown=Unknown
apk_manager=Alpine Package Keeper
apk_untrusted=Allow untrusted package file?
log_install_package=Installed package $1
log_install_apt_l=Installed package(s) $1 from APT
log_install_apt=Installed $2 package(s) from APT
@@ -361,6 +365,13 @@ emerge_onlydeps=Only install dependencies?
emerge_title=Search Portage
emerge_name=Portage
apk_input=Package from APK
apk_find=Search APK ..
apk_install=Installing package(s) with command $1 ..
apk_ok=.. install complete
apk_failed=.. install failed!
apk_name=APK
cygwin_fmissing=The file is missing
cygwin_lmissing=The file to which the link points is missing
cygwin_estat=Failed to stat file: $1

View File

@@ -1,6 +1,6 @@
name=PackageAdmin
category=system
os_support=solaris coherent-linux redhat-linux mandrake-linux suse-linux united-linux hpux open-linux openserver unixware freebsd/3.0-* slackware-linux/4.0-* debian-linux/2.0-* turbo-linux openbsd corel-linux cobalt-linux netbsd msc-linux aix gentoo-linux trustix-linux openmamba-linux cygwin windows syno-linux
os_support=solaris coherent-linux redhat-linux mandrake-linux suse-linux united-linux hpux open-linux openserver unixware freebsd/3.0-* slackware-linux/4.0-* debian-linux/2.0-* turbo-linux openbsd corel-linux cobalt-linux netbsd msc-linux aix gentoo-linux alpine-linux trustix-linux openmamba-linux cygwin windows syno-linux
desc=Software Packages
longdesc=Manage software packages on your system, and install new packages.
readonly=1

View File

@@ -1,6 +1,6 @@
name=Squid
category=servers
os_support=solaris hpux redhat-linux mandrake-linux debian-linux suse-linux united-linux slackware-linux freebsd osf1 irix aix open-linux openserver unixware turbo-linux openbsd corel-linux cobalt-linux lfs-linux macos netbsd msc-linux generic-linux gentoo-linux trustix-linux sol-linux coherent-linux openmamba-linux pardus-linux
os_support=solaris hpux redhat-linux mandrake-linux debian-linux suse-linux united-linux slackware-linux freebsd osf1 irix aix open-linux openserver unixware turbo-linux openbsd corel-linux cobalt-linux lfs-linux macos netbsd msc-linux generic-linux alpine-linux gentoo-linux trustix-linux sol-linux coherent-linux openmamba-linux pardus-linux
desc=Squid Proxy Server
longdesc=Configure Squid options, ACLs, caching parameters and proxy users.
syslog=1

View File

@@ -1,6 +1,6 @@
name=User Manager
category=system
os_support=slackware-linux redhat-linux mandrake-linux solaris debian-linux suse-linux united-linux hpux freebsd osf1 open-linux unixware turbo-linux openbsd corel-linux cobalt-linux irix aix netbsd msc-linux openserver generic-linux macos gentoo-linux trustix-linux sol-linux coherent-linux openmamba-linux pardus-linux syno-linux
os_support=slackware-linux redhat-linux mandrake-linux solaris debian-linux suse-linux united-linux hpux freebsd osf1 open-linux unixware turbo-linux openbsd corel-linux cobalt-linux irix aix netbsd msc-linux openserver generic-linux alpine-linux macos gentoo-linux trustix-linux sol-linux coherent-linux openmamba-linux pardus-linux syno-linux
desc=Users and Groups
longdesc=Create and edit Unix users and groups from the /etc/passwd and /etc/group files.
readonly=1

View File

@@ -6259,7 +6259,8 @@ Returns a hash containing details of the given module. Some useful keys are :
=item dir - The module directory, like sendmail.
=item desc - Human-readable description, in the current users' language.
=item desc - Human-readable description, in the current users' language. This
may be selected from an alternate desc+suffix key.
=item version - Optional module version number.
@@ -6321,6 +6322,24 @@ $rv{'realcategory'} = $rv{'category'};
$rv{'category'} = $module_categories{$mod}
if (defined($module_categories{$mod}));
# Apply alternate description from cached module mode
if (my @descplus = grep { /^desc\+/ } keys %rv) {
my %mode;
&read_file_cached("$config_directory/$mod/mode", \%mode);
my $alt = $mode{'mode'};
if ($alt) {
$alt =~ s/^\s+|\s+$//g;
$alt =~ s/^desc\+//;
my $desc = $rv{"desc+$alt"};
foreach my $o (@lang_order_list) {
my $k = "desc+${alt}_$o";
$desc = $rv{$k} if ($rv{$k});
}
$rv{'desc'} = $desc if ($desc);
}
delete(@rv{@descplus});
}
# Apply overrides from local configuration files, such as for the title
my %overs;
&read_file("$config_directory/$mod/module.info.override", \%overs);

View File

@@ -1,52 +0,0 @@
#!/sbin/openrc-run
# Copyright 2024 webmin & mckaygerhard
# Distributed under the terms of the GNU General Public License, v2 or later
name="webmin"
# config file must be in sync with setup script, so i will not touch cos process will be the same as webmin-systemd
# like calling updateboot.pl with a new procedure method defined as openrc and not just assumed sysvinit if not systemd is present
# and also atboot.pl with new procedure for openrc the alpine linux init system at the moment
#conf_file="WEBMIN_CONFIG/miniserv.conf"
conf_file="/etc/webmin/miniserv.conf"
depend() {
need logger localmount
use net
after bootmisc
}
start() {
# same problem here.. we need to use WEBMIN_CONFIG variable to find the start script
# WEBMIN_CONFIG/start
/etc/webmin/start
eend $?
}
stop() {
# same problem here.. we need to use WEBMIN_CONFIG variable to find the stop script
# WEBMIN_CONFIG/stop
/etc/webmin/stop
eend $?
}
status() {
pidfile=`grep "^pidfile=" "${conf_file}" | sed -e 's/pidfile=//g'`
if [ -s $pidfile ]; then
pid=`cat $pidfile`
kill -0 $pid >/dev/null 2>&1
if [ "$?" = "0" ]; then
einfo "webmin (pid $pid) is running"
return 0
else
einfo "webmin is stopped"
return 0
fi
else
einfo "webmin is stopped"
return 0
fi
}

44
webmin-openrc-init Executable file
View File

@@ -0,0 +1,44 @@
#!/sbin/openrc-run
# Copyright 2024 webmin & mckaygerhard
# Distributed under the terms of the GNU General Public License, v2 or later
name="webmin"
conf_file="WEBMIN_CONFIG/miniserv.conf"
depend() {
need logger localmount
use net
after bootmisc
}
start() {
WEBMIN_CONFIG/start
eend $?
}
stop() {
WEBMIN_CONFIG/stop
eend $?
}
status() {
pidfile=`grep "^pidfile=" "${conf_file}" | sed -e 's/pidfile=//g'`
if [ -s $pidfile ]; then
pid=`cat $pidfile`
kill -0 $pid >/dev/null 2>&1
if [ "$?" = "0" ]; then
einfo "webmin (pid $pid) is running"
return 0
else
einfo "webmin is stopped"
return 0
fi
else
einfo "webmin is stopped"
return 0
fi
}

View File

@@ -4,15 +4,12 @@ Wants=network-online.target
After=network.target network-online.target
[Service]
Type=simple
Environment="PERLLIB=WEBMIN_LIBDIR"
ExecStart=WEBMIN_LIBDIR/miniserv.pl WEBMIN_CONFIG/miniserv.conf
ExecStop=WEBMIN_KILLCMD $MAINPID
ExecStart=WEBMIN_LIBDIR/miniserv.pl --nofork WEBMIN_CONFIG/miniserv.conf
ExecReload=WEBMIN_KILLCMD -HUP $MAINPID
PIDFile=WEBMIN_VAR/miniserv.pid
Type=forking
Restart=always
Restart=on-failure
RestartSec=2s
TimeoutSec=15s
TimeoutStopSec=300s
[Install]

View File

@@ -132,7 +132,7 @@ else {
&save_renewal_only(\@doms, $webroot, $mode,
$size, $in{'subset'}, $in{'use'},
$in{'directory_url'},
$in{'eab_kid'}, $in{'eab_hmac'});
$in{'eab_kid'}, $in{'eab_hmac'}, 1);
# Copy cert, key and chain to Webmin
if ($in{'use'}) {
@@ -182,12 +182,12 @@ else {
}
# save_renewal_only(&doms, webroot, mode, size, subset-mode, used-by-webmin,
# directory-url, eab-kid, eab-hmac)
# directory-url, eab-kid, eab-hmac, [reset-renewal-time])
# Save for future renewals
sub save_renewal_only
{
my ($doms, $webroot, $mode, $size, $subset, $usewebmin, $directory_url,
$eab_kid, $eab_hmac) = @_;
$eab_kid, $eab_hmac, $reset_renewal_time) = @_;
$config{'letsencrypt_doms'} = join(" ", @$doms);
$config{'letsencrypt_webroot'} = $webroot;
$config{'letsencrypt_mode'} = $mode;
@@ -219,14 +219,24 @@ if (&foreign_check("webmincron")) {
&webmincron::delete_webmin_cron($job) if ($job);
}
else {
my @tm = localtime(time() - 60);
# A manual cert request does not update Webmin cron's last-run
# state, so re-create the job to start the elapsed renewal
# interval from now instead of immediately running an overdue
# job with the old ID
if ($job && $reset_renewal_time) {
&webmincron::delete_webmin_cron($job);
$job = undef;
}
$job ||= { 'module' => $module_name,
'func' => 'renew_letsencrypt_cert' };
$job->{'mins'} ||= $tm[1];
$job->{'hours'} ||= $tm[2];
$job->{'days'} ||= $tm[3];
# Scheduling is driven by 'interval' (elapsed seconds); 'months'
# is retained only so edit_ssl.cgi can show the renewal interval
$job->{'mins'} = '';
$job->{'hours'} = '';
$job->{'days'} = '';
$job->{'months'} = '*/'.$in{'renew'};
$job->{'weekdays'} = '*';
$job->{'weekdays'} = '';
$job->{'interval'} = $in{'renew'}*30*24*60*60;
&webmincron::create_webmin_cron($job);
}
}

View File

@@ -34,6 +34,21 @@ elsif ($miniserv{'cipher_list_def'} == 2 || $miniserv{'cipher_list_def'} == 3) {
$strong_ssl_ciphers : $pfs_ssl_ciphers;
}
# Convert old Let's Encrypt renewal schedules to elapsed interval timers
if (&foreign_check("webmincron")) {
my $job = &find_letsencrypt_cron_job();
if ($job && !$job->{'interval'} &&
$job->{'months'} =~ /^\*\/([1-9][0-9]*)$/) {
my $renew = $1;
$job->{'mins'} = '';
$job->{'hours'} = '';
$job->{'days'} = '';
$job->{'weekdays'} = '';
$job->{'interval'} = $renew*30*24*60*60;
&webmincron::save_webmin_cron($job);
}
}
# If this is the first install, enable recording of logins by default
if (!-r $first_install_file || $miniserv{'login_script'} eq $record_login_cmd) {
&foreign_require("cron");

View File

@@ -1,2 +1,2 @@
// 0.12.0
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AttachAddon=t():e.AttachAddon=t()}(globalThis,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;function s(e,t,s){return e.addEventListener(t,s),{dispose:()=>{s&&e.removeEventListener(t,s)}}}Object.defineProperty(t,"__esModule",{value:!0}),t.AttachAddon=void 0,t.AttachAddon=class{constructor(e,t){this._disposables=[],this._socket=e,this._socket.binaryType="arraybuffer",this._bidirectional=!(t&&!1===t.bidirectional)}activate(e){this._disposables.push(s(this._socket,"message",(t=>{const s=t.data;e.write("string"==typeof s?s:new Uint8Array(s))}))),this._bidirectional&&(this._disposables.push(e.onData((e=>this._sendData(e)))),this._disposables.push(e.onBinary((e=>this._sendBinary(e))))),this._disposables.push(s(this._socket,"close",(()=>this.dispose()))),this._disposables.push(s(this._socket,"error",(()=>this.dispose())))}dispose(){for(const e of this._disposables)e.dispose()}_sendData(e){this._checkOpenSocket()&&this._socket.send(e)}_sendBinary(e){if(!this._checkOpenSocket())return;const t=new Uint8Array(e.length);for(let s=0;s<e.length;++s)t[s]=255&e.charCodeAt(s);this._socket.send(t)}_checkOpenSocket(){switch(this._socket.readyState){case WebSocket.OPEN:return!0;case WebSocket.CONNECTING:throw new Error("Attach addon was loaded before socket was open");case WebSocket.CLOSING:return console.warn("Attach addon socket is closing"),!1;case WebSocket.CLOSED:throw new Error("Attach addon socket is closed");default:throw new Error("Unexpected socket state")}}}})(),e})()));
// 0.13.0-beta.285
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AttachAddon=t():e.AttachAddon=t()}(globalThis,()=>(()=>{"use strict";var e={};return(()=>{var t=e;function s(e,t,s){return e.addEventListener(t,s),{dispose:()=>{s&&e.removeEventListener(t,s)}}}Object.defineProperty(t,"__esModule",{value:!0}),t.AttachAddon=void 0,t.AttachAddon=class{constructor(e,t){this._disposables=[],this._socket=e,this._socket.binaryType="arraybuffer",this._bidirectional=!(t&&!1===t.bidirectional)}activate(e){this._disposables.push(s(this._socket,"message",t=>{const s=t.data;e.write("string"==typeof s?s:new Uint8Array(s))})),this._bidirectional&&(this._disposables.push(e.onData(e=>this._sendData(e))),this._disposables.push(e.onBinary(e=>this._sendBinary(e)))),this._disposables.push(s(this._socket,"close",()=>this.dispose())),this._disposables.push(s(this._socket,"error",()=>this.dispose()))}dispose(){for(const e of this._disposables)e.dispose()}_sendData(e){this._checkOpenSocket()&&this._socket.send(e)}_sendBinary(e){if(!this._checkOpenSocket())return;const t=new Uint8Array(e.length);for(let s=0;s<e.length;++s)t[s]=255&e.charCodeAt(s);this._socket.send(t)}_checkOpenSocket(){switch(this._socket.readyState){case WebSocket.OPEN:return!0;case WebSocket.CONNECTING:throw new Error("Attach addon was loaded before socket was open");case WebSocket.CLOSING:return console.warn("Attach addon socket is closing"),!1;case WebSocket.CLOSED:throw new Error("Attach addon socket is closed");default:throw new Error("Unexpected socket state")}}}})(),e})());

View File

@@ -1,2 +1,2 @@
// 0.11.0
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(globalThis,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core._renderService.dimensions;if(0===e.css.cell.width||0===e.css.cell.height)return;const t=0===this._terminal.options.scrollback?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),i=parseInt(r.getPropertyValue("height")),o=Math.max(0,parseInt(r.getPropertyValue("width"))),s=window.getComputedStyle(this._terminal.element),n=i-(parseInt(s.getPropertyValue("padding-top"))+parseInt(s.getPropertyValue("padding-bottom"))),l=o-(parseInt(s.getPropertyValue("padding-right"))+parseInt(s.getPropertyValue("padding-left")))-t;return{cols:Math.max(2,Math.floor(l/e.css.cell.width)),rows:Math.max(1,Math.floor(n/e.css.cell.height))}}}})(),e})()));
// 0.12.0-beta.285
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(globalThis,()=>(()=>{"use strict";var e={};return(()=>{var t=e;function i(e){return(t=e,t?.ownerDocument?.defaultView?t.ownerDocument.defaultView:window).getComputedStyle(e,null);var t}Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();e&&this._terminal&&!isNaN(e.cols)&&!isNaN(e.rows)&&this._terminal.resize(e.cols,e.rows)}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal.dimensions;if(!e||0===e.css.cell.width||0===e.css.cell.height)return;const t=this._terminal.options.scrollbar?.showScrollbar??!0,r=0!==this._terminal.options.scrollback&&t?this._terminal.options.scrollbar?.width??14:0,o=i(this._terminal.element.parentElement),n=Math.max(0,parseInt(o.getPropertyValue("height"),10)||0),s=Math.max(0,parseInt(o.getPropertyValue("width"),10)||0),l=i(this._terminal.element),a=n-((parseInt(l.getPropertyValue("padding-top"),10)||0)+(parseInt(l.getPropertyValue("padding-bottom"),10)||0)),p=s-((parseInt(l.getPropertyValue("padding-right"),10)||0)+(parseInt(l.getPropertyValue("padding-left"),10)||0))-r;return{cols:Math.max(2,Math.floor(p/e.css.cell.width)),rows:Math.max(1,Math.floor(a/e.css.cell.height))}}}})(),e})());

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long