is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. xml to make Docutils-native XML files
+ echo. pseudoxml to make pseudoxml-XML files for display purposes
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\complexity.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\complexity.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdf" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf
+ cd %BUILDDIR%/..
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdfja" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf-ja
+ cd %BUILDDIR%/..
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+if "%1" == "xml" (
+ %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The XML files are in %BUILDDIR%/xml.
+ goto end
+)
+
+if "%1" == "pseudoxml" (
+ %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
+ goto end
+)
+
+:end
diff --git a/docs/readme.rst b/docs/readme.rst
new file mode 100644
index 0000000..72a3355
--- /dev/null
+++ b/docs/readme.rst
@@ -0,0 +1 @@
+.. include:: ../README.rst
diff --git a/docs/usage.rst b/docs/usage.rst
new file mode 100644
index 0000000..81afb04
--- /dev/null
+++ b/docs/usage.rst
@@ -0,0 +1,15 @@
+========
+Usage
+========
+
+Tomcat Module:
+
+.. image:: https://cdn.acugis.com/apache-tomcat-webmin-plugin/tomcat-module-plugin.gif
+
+Tomcat Module WAR Manager:
+
+.. image:: https://cdn.acugis.com/apache-tomcat-webmin-plugin/tomcat-module-war-deploy.gif
+
+Tomcat Module Configuration Editor:
+
+.. image:: https://cdn.acugis.com/apache-tomcat-webmin-plugin/tomcat-module-edit-configs.gif
diff --git a/edit_java.cgi b/edit_java.cgi
new file mode 100644
index 0000000..f4f7c5c
--- /dev/null
+++ b/edit_java.cgi
@@ -0,0 +1,91 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+require './java-lib.pl';
+require '../webmin/webmin-lib.pl'; #for OS detection
+
+&ReadParse();
+
+&ui_print_header(undef, $text{'java_title'}, "");
+
+# Show tabs
+@tabs = ( [ "install", $text{'java_tabinstall'}, "edit_java.cgi?mode=install" ],
+ [ "uninstall", $text{'java_tabuninstall'}, "edit_java.cgi?mode=uninstall" ],
+ [ "default", $text{'java_tabdefault'}, "edit_java.cgi?mode=default" ]
+ );
+
+print &ui_tabs_start(\@tabs, "mode", $in{'mode'} || "install", 1);
+
+
+print &ui_tabs_start_tab("mode", "install");
+print "$text{'java_desc1'}\n";
+
+print &ui_form_start("install_java.cgi", "form-data");
+print &ui_table_start($text{'java_install'}, undef, 2);
+
+my %jdk_version = &get_latest_jdk_version();
+@opt_avail_jdk = ();
+foreach $ver (keys %jdk_version) {
+ push(@opt_avail_jdk, [ "$ver=$jdk_version{$ver}", $ver]);
+}
+
+my %openjdk_version = &get_openjdk_versions();
+@opt_avail_openjdk = ();
+foreach $ver (reverse sort { $a <=> $b } keys %openjdk_version) {
+ push(@opt_avail_openjdk, [ "$ver=$openjdk_version{$ver}", $ver]);
+}
+
+print &ui_table_row($text{'jdk_installsource'},
+ &ui_radio_table("source", 200,
+ [ [ 200, $text{'openjdk_latest'}, &ui_select("openjdk_ver", undef, \@opt_avail_openjdk, 1, 0).
+ '
'.
+ &ui_checkbox("openjdk_headless", 1,undef, 1).$text{'openjdk_headless'}.
+ &ui_hr()],
+ [ 100, $text{'jdk_latest'}, &ui_select("jdk_ver", undef, \@opt_avail_jdk, 1, 0)],
+ [ 0, $text{'source_local'}, &ui_textbox("file", undef, 40)." ". &file_chooser_button("file", 0) ],
+ [ 1, $text{'source_uploaded'},&ui_upload("upload", 40) ],
+ [ 2, $text{'source_ftp'}, &ui_textbox("url", undef, 40) ]
+ ]), 2);
+print &ui_table_row($text{'java_def_jdk'},
+ &ui_checkbox("def_jdk", 1,undef, 1).$text{'java_def_jdk_desc'}
+ ,2);
+
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'java_installok'} ] ]);
+print &ui_tabs_end_tab();
+
+
+print &ui_tabs_start_tab("mode", "uninstall");
+print "$text{'java_desc2'}
\n";
+
+print &ui_form_start("uninstall_java.cgi", "post");
+print &ui_table_start($text{'java_uninstall'}, undef, 2);
+
+@jdk_vlist = &get_installed_jdk_versions();
+@opts_inst_jdk = ( );
+foreach $jdk_ver (@jdk_vlist) {
+ push(@opts_inst_jdk, [ $jdk_ver, $jdk_ver ]);
+}
+print &ui_table_row($text{'java_installed'}, &ui_select("inst_jdk", undef, \@opts_inst_jdk, 1, 0)."
\n", 2);
+print &ui_table_row($text{'java_rm_def_jdk'}, &ui_checkbox("rm_def_jdk", 1,undef, 1), 2);
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'java_deleteok'} ] ]);
+print &ui_tabs_end_tab();
+
+print &ui_tabs_start_tab("mode", "default");
+print "$text{'java_desc3'}
\n";
+
+print &ui_form_start("default_java.cgi", "post");
+print &ui_table_start($text{'java_default'}, undef, 2);
+
+print &ui_table_row($text{'java_installed'}, &ui_select("inst_jdk2", undef, \@opts_inst_jdk, 1, 0)."
\n", 2);
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'java_defaultok'} ] ]);
+print &ui_tabs_end_tab();
+
+print &ui_tabs_end(1);
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/edit_libs.cgi b/edit_libs.cgi
new file mode 100644
index 0000000..27cf0f3
--- /dev/null
+++ b/edit_libs.cgi
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+&ReadParse();
+
+&ui_print_header(undef, $text{'libs_title'}, "");
+
+# Show tabs
+@tabs = ( [ "install", $text{'libs_tabinstall'}, "edit_libs.cgi?mode=install" ],
+ [ "uninstall", $text{'libs_tabuninstall'}, "edit_libs.cgi?mode=uninstall" ]
+ );
+
+print &ui_tabs_start(\@tabs, "mode", $in{'mode'} || "install", 1);
+
+# Display installation form
+print &ui_tabs_start_tab("mode", "install");
+print "$text{'libs_desc1'}
\n";
+
+print &ui_form_start("install_libs.cgi", "form-data");
+print &ui_table_start($text{'libs_install'}, undef, 2);
+
+print &ui_table_row($text{'libs_installsource'},
+ &ui_radio_table("source", 0,
+ [ [ 0, $text{'source_local'}, &ui_textbox("file", undef, 40)." ". &file_chooser_button("file", 0) ],
+ [ 1, $text{'source_uploaded'},&ui_upload("upload", 40) ],
+ [ 2, $text{'source_ftp'}, &ui_textbox("url", undef, 40) ]
+ ]));
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'libs_installok'} ] ]);
+print &ui_tabs_end_tab();
+
+
+# Display deletion form
+print &ui_tabs_start_tab("mode", "uninstall");
+print "$text{'libs_desc2'}
\n";
+
+print &ui_form_start("uninstall_libs.cgi", "post");
+print &ui_table_start($text{'libs_delete'}, undef, 2);
+
+@libs_lists = &get_installed_libs();
+@opts_inst_libs = ( );
+foreach $lib_file (@libs_lists) {
+ $lib_file =~ /^lib_([a-z0-9\.\-_\s]+)\.list$/i;
+ push(@opts_inst_libs, [ $1, $1 ]);
+}
+print &ui_table_row($text{'libs_installed'}, &ui_select("inst_lib", undef, \@opts_inst_libs, 10, 1), 2);
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'libs_deleteok'} ] ]);
+print &ui_tabs_end_tab();
+
+
+print &ui_tabs_end(1);
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/edit_manual.cgi b/edit_manual.cgi
new file mode 100644
index 0000000..42e952b
--- /dev/null
+++ b/edit_manual.cgi
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+# Show a page for manually editing an Tomcat server.xml config file
+
+require './tomcat-lib.pl';
+&ReadParse();
+&ui_print_header(undef, $text{'manual_title'}, "");
+
+my $catalina_home = get_catalina_home();
+
+# Work out and show the files
+@files = ( "$catalina_home/bin/setenv.sh",
+ "$catalina_home/conf/context.xml",
+ "$catalina_home/conf/server.xml",
+ "$catalina_home/conf/tomcat-users.xml",
+ "$catalina_home/conf/web.xml");
+$in{'file'} ||= $files[0];
+&indexof($in{'file'}, @files) >= 0 || &error($text{'manual_efile'});
+
+print &ui_form_start("edit_manual.cgi");
+print "$text{'manual_file'}\n";
+print &ui_select("file", $in{'file'}, [ map { [ $_ ] } @files ], 1, 0);
+print &ui_submit($text{'manual_ok'});
+print &ui_form_end();
+
+# Show the file contents
+print &ui_form_start("save_manual.cgi", "form-data");
+print &ui_hidden("file", $in{'file'}),"\n";
+$data = &read_file_contents($in{'file'});
+print &ui_textarea("data", $data, 20, 80),"\n";
+print &ui_form_end([ [ "save", $text{'save'} ] ]);
+
+&ui_print_footer("", $text{'index_return'});
+
diff --git a/edit_proxy.cgi b/edit_proxy.cgi
new file mode 100644
index 0000000..1baa3a3
--- /dev/null
+++ b/edit_proxy.cgi
@@ -0,0 +1,188 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+foreign_require('apache', 'apache-lib.pl');
+
+sub get_proxy_file{
+ my $domain_user = $_[0];
+ my $proxy_file = '';
+
+ if( -d '/etc/httpd/conf.d' ){
+ $proxy_file = '/etc/httpd/conf.d/tomcat.conf';
+ }elsif( -d '/etc/apache2/conf-enabled/'){ #ubuntu or debian
+ $proxy_file = '/etc/apache2/conf-enabled/tomcat.conf';
+ }
+ return $proxy_file;
+}
+
+sub load_proxy_maps{
+ my $proxy_file = $_[0];
+
+ my %maps;
+ open(my $fh, '<', $proxy_file) or return %maps;
+ while(my $line = <$fh>){
+ if($line =~ /^ProxyPass ([\/a-z0-9_\-\.]+) ([a-z:\/0-9\.\-]+)/i){
+ $maps{$2} = $1;
+ }
+ }
+ close $fh;
+
+ return %maps;
+}
+
+sub add_proxy{
+ my $proxy_file = $_[0];
+ my $app_name = $_[1];
+ my $default = $_[2];
+ my $ssl_port = $_[3];
+ my $wildcard = $_[4];
+
+ my %idata = ('port_http'=>'8080', 'port_https'=>'8443');
+
+ my $app_path = '/';
+ if($default == 0){ #if app is not default
+ $app_path .= $app_name;
+ }
+
+ if($wildcard == 1){
+ $app_name = '';
+ }
+
+ my $lref = &read_file_lines($proxy_file);
+ my $lnum = 0;
+ my $proxy_header_section = 0;
+ my $user_domain = 'localhost';
+ foreach my $line (@$lref) {
+ if($line =~ /^ProxyPass \/ |^ProxyPassReverse \/ /){ #another default app
+ if($default == 1){ #if new app is default
+ delete @{$lref}[$lnum]; #remove old default app
+ }
+ }elsif($line =~ /^ProxyPass.*\/$app_name$/){ #if its a line with our app
+ delete @{$lref}[$lnum];
+ }elsif($line =~ /^ProxyRequests Off$/){
+ $proxy_header_section = 1; #proxy settings are found
+ }elsif($line =~ /^ServerName (.*)$/){
+ $user_domain = $1;
+ }
+ $lnum++;
+ }
+
+
+ my $conf_tail;
+ if(@$lref[$lnum] eq ''){
+ $conf_tail = pop @{$lref};
+ }
+ if($proxy_header_section == 0){
+ my $line = "ProxyRequests Off
+ProxyPreserveHost On
+
+ Order allow,deny
+ Allow from all
+";
+ push(@$lref, $line);
+ }
+
+ my $proto = '';
+ if($ssl_port == 1){
+ $proto = 's';
+ }
+
+ push(@$lref, "ProxyPass $app_path http".$proto."://$user_domain:".$idata{'port_http'.$proto}."/$app_name");
+ push(@$lref, "ProxyPassReverse $app_path http".$proto."://$user_domain:".$idata{'port_http'.$proto}."/$app_name");
+ if($conf_tail){
+ push(@$lref, $conf_tail); #Restore conf end
+ }
+
+ flush_file_lines($proxy_file);
+}
+
+sub remove_proxy{
+ my ($proxy_file, $app_path) = @_;
+
+ my $lref = &read_file_lines($proxy_file);
+ my $lnum = 0;
+ foreach my $line (@$lref) {
+ if($line =~ /^ProxyPass $app_path |^ProxyPassReverse $app_path /){ #if its a line with our app
+ delete @{$lref}[$lnum];
+ }
+ $lnum++;
+ }
+ flush_file_lines($proxy_file);
+}
+
+&ReadParse();
+
+my $form_submit = 0;
+if ($in{'submit_flag'}) {
+ $form_submit = 1;
+}
+
+&ui_print_header(undef, $text{'proxy_title'}, "");
+
+
+my $proxy_file = get_proxy_file($remote_user);
+if($proxy_file eq ''){
+ print "Error: Failed to find proxy file for user $remote_user"
+}
+
+if($form_submit == 1){
+ if($in{'app_path'}){
+ remove_proxy($proxy_file, $in{'app_path'});
+ }else{
+ add_proxy($proxy_file, $in{'app_name'}, $in{'app_default'}, $in{'proxy_ssl'}, $in{'app_wildcard'});
+ }
+ apache::restart_apache();
+}
+
+my %maps = load_proxy_maps($proxy_file);
+my @tds = ();
+print &ui_columns_start(['Path','URL'], undef, 0, \@tds, 'Apps with proxy ('.$proxy_file.')');
+foreach my $url (keys %maps) {
+
+ my @cols;
+ push(@cols, $maps{$url});
+ push(@cols, "$url");
+
+ print &ui_columns_row(\@cols, \@tds);
+}
+print &ui_columns_end();
+
+
+print &ui_form_start("edit_proxy.cgi", "post");
+print &ui_hidden('submit_flag', 1);
+print &ui_table_start($text{'proxy_add_options'}, undef, 2);
+
+my @apps = get_all_war_infos();
+@opt_apps = ( );
+foreach $app (@apps) {
+ push(@opt_apps, [ $app, $app ]);
+}
+print &ui_table_row($text{'proxy_wildcard'},
+ &ui_checkbox("app_wildcard", 1, $text{'proxy_wildcard_info'}, 0), 2);
+print &ui_table_hr();
+print &ui_table_row($text{'wars_installed'}, &ui_select("app_name", undef, \@opt_apps, 10, 1), 2);
+print &ui_table_row($text{'proxy_default_app'},
+ &ui_checkbox("app_default", 1, $text{'proxy_app_default_warning'}, 0), 2);
+print &ui_table_row($text{'proxy_ssl'},
+ &ui_checkbox("proxy_ssl", 1, $text{'proxy_ssl_info'}, 0), 2);
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'proxy_installok'} ] ]);
+
+
+print &ui_form_start("edit_proxy.cgi", "post");
+print &ui_hidden('submit_flag', 1);
+print &ui_table_start($text{'proxy_remove_options'}, undef, 2);
+
+
+@opt_paths = ( );
+foreach $path (keys %maps) {
+ my $val = $maps{$path};
+ push(@opt_paths, [ $val, $val ]);
+}
+print &ui_table_row($text{'proxy_list'}, &ui_select("app_path", undef, \@opt_paths, 10, 1), 2);
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'proxy_removeok'} ] ]);
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/edit_war.cgi b/edit_war.cgi
new file mode 100644
index 0000000..b354775
--- /dev/null
+++ b/edit_war.cgi
@@ -0,0 +1,57 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+&ReadParse();
+
+&ui_print_header(undef, $text{'wars_title'}, "");
+
+# Show tabs
+@tabs = ( [ "install", $text{'wars_tabinstall'}, "edit_wars.cgi?mode=install" ],
+ [ "delete", $text{'wars_tabdelete'}, "edit_wars.cgi?mode=delete" ]
+ );
+
+print &ui_tabs_start(\@tabs, "mode", $in{'mode'} || "install", 1);
+
+# Display installation form
+print &ui_tabs_start_tab("mode", "install");
+print "$text{'wars_desc1'}
\n";
+
+print &ui_form_start("install_war.cgi", "form-data");
+print &ui_table_start($text{'war_install'}, undef, 2);
+
+print &ui_table_row($text{'war_installsource'},
+ &ui_radio_table("source", 0,
+ [ [ 0, $text{'source_local'}, &ui_textbox("file", undef, 40)." ". &file_chooser_button("file", 0) ],
+ [ 1, $text{'source_uploaded'}, &ui_upload("upload", 40) ],
+ [ 2, $text{'source_ftp'},&ui_textbox("url", undef, 40) ]
+ ]));
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'war_installok'} ] ]);
+print &ui_tabs_end_tab();
+
+
+# Display deletion form
+print &ui_tabs_start_tab("mode", "delete");
+print "$text{'wars_desc2'}
\n";
+
+print &ui_form_start("delete_war.cgi", "post");
+print &ui_table_start($text{'wars_delete'}, undef, 2);
+
+@wlist = &get_all_war_infos();
+@opts = ( );
+foreach $d (@wlist) {
+ push(@opts, [ $d, $d ]);
+}
+print &ui_table_row($text{'wars_installed'},
+ &ui_select("mod", undef, \@opts, 10, 1)."
\n".
+ &ui_checkbox("rmwar", 1, $text{'wars_rmwar'}, 0), 2);
+
+print &ui_table_end();
+print &ui_form_end([ [ "", $text{'wars_deleteok'} ] ]);
+print &ui_tabs_end_tab();
+
+
+print &ui_tabs_end(1);
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/help/intro.html b/help/intro.html
new file mode 100644
index 0000000..7274854
--- /dev/null
+++ b/help/intro.html
@@ -0,0 +1,29 @@
+Apache_Tomcat">Apache Tomcat
+
+
Module produced by Cited, Inc. © 2019 AcuGIS, Cited, Inc.
+
+The Apache Tomcat® software is an open source implementation
+of the Java Servlet, JavaServer Pages, Java Expression Language and Java
+WebSocket technologies. The Java Servlet, JavaServer Pages, Java Expression
+Language and Java WebSocket specifications are developed under the
+Java Community
+Process.
+
+
+The Apache Tomcat software is developed in an open and participatory
+environment and released under the
+Apache License version 2. The
+Apache Tomcat project is intended to be a collaboration of the best-of-breed
+developers from around the world. We invite you to participate in this open
+development project. To learn more about getting involved,
+click here.
+
+Apache Tomcat software powers numerous large-scale, mission-critical web
+applications across a diverse range of industries and organizations. Some of
+these users and their stories are listed on the
+PoweredBy wiki page.
+
+Apache Tomcat, Tomcat, Apache, the Apache feather, and the Apache Tomcat
+project logo are trademarks of the Apache Software Foundation.
+
+
diff --git a/images/edit-file.png b/images/edit-file.png
new file mode 100644
index 0000000..9ee10d7
Binary files /dev/null and b/images/edit-file.png differ
diff --git a/images/icon.gif b/images/icon.gif
new file mode 100644
index 0000000..a2d1fdc
Binary files /dev/null and b/images/icon.gif differ
diff --git a/images/jar.png b/images/jar.png
new file mode 100644
index 0000000..130a797
Binary files /dev/null and b/images/jar.png differ
diff --git a/images/java.png b/images/java.png
new file mode 100644
index 0000000..1ac8e42
Binary files /dev/null and b/images/java.png differ
diff --git a/images/manual.gif b/images/manual.gif
new file mode 100644
index 0000000..e65c7f0
Binary files /dev/null and b/images/manual.gif differ
diff --git a/images/mapping.png b/images/mapping.png
new file mode 100644
index 0000000..6268659
Binary files /dev/null and b/images/mapping.png differ
diff --git a/images/war.png b/images/war.png
new file mode 100644
index 0000000..fbc0ad6
Binary files /dev/null and b/images/war.png differ
diff --git a/index.cgi b/index.cgi
new file mode 100644
index 0000000..ae4d04d
--- /dev/null
+++ b/index.cgi
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+# index.cgi
+
+require './tomcat-lib.pl';
+require '../webmin/webmin-lib.pl'; #for OS detection
+
+# Check if config file exists
+if (! -r $config{'tomcat_config'}) {
+ &ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1);
+ print &text('index_econfig', "$config{'tomcat_config'}",
+ "$gconfig{'webprefix'}/config.cgi?$module_name"),"\n";
+ &ui_print_footer("/", $text{"index"});
+ exit;
+}
+
+if(-f "$module_root_directory/setup.cgi"){
+ &redirect("setup.cgi?mode=checks");
+ exit;
+}
+
+my %version = get_catalina_version();
+
+&ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1, 0,
+ &help_search_link("tomcat", "man", "doc", "google"), undef, undef,
+ "Tomcat $version{'number'} / Java $version{'jvm'}");
+
+push(@links, "edit_manual.cgi");
+push(@titles, $text{'manual_title'});
+push(@icons, "images/edit-file.png");
+
+push(@links, "edit_war.cgi");
+push(@titles, $text{'wars_title'});
+push(@icons, "images/war.png");
+
+push(@links, "edit_libs.cgi");
+push(@titles, $text{'libs_title'});
+push(@icons, "images/jar.png");
+
+push(@links, "edit_java.cgi");
+push(@titles, $text{'java_title'});
+push(@icons, "images/java.png");
+
+push(@links, "edit_proxy.cgi");
+push(@titles, $text{'proxy_title'});
+push(@icons, "images/mapping.png");
+
+&icons_table(\@links, \@titles, \@icons, 2);
+
+# Check if tomcat is running
+print &ui_hr().&ui_buttons_start();
+my ($running, $status) = &tomcat_service_ctl('status');
+print "$status
";
+if ($running == 1) {
+ # Running .. offer to apply changes and stop
+ print &ui_buttons_row("stop.cgi", $text{'index_stop'}, "$text{'index_stopmsg'}");
+ print &ui_buttons_row("restart.cgi", $text{'index_restart'}, "$text{'index_restartmsg'}");
+}else {
+ # Not running .. offer to start
+ print &ui_buttons_row("start.cgi", $text{'index_start'}, $text{'index_startmsg'});
+}
+
+
+#Check for an update of tomcat, once a day
+my $latest_ver = upgrade_available();
+if($latest_ver){
+ print &ui_buttons_row("tomcat_upgrade.cgi", $text{'index_upgrade'}, "Tomcat will be updated to $latest_ver. All WARs will be moved and config will be copied to new install!");
+}
+print &ui_buttons_end();
+
+
+&ui_print_footer("/", $text{"index"});
diff --git a/install_check.sh b/install_check.sh
new file mode 100644
index 0000000..6f8c85a
--- /dev/null
+++ b/install_check.sh
@@ -0,0 +1,14 @@
+# install_check.pl
+
+do 'tomcat-lib.pl';
+
+# is_installed(mode)
+# For mode 1, returns 2 if the server is installed and configured for use by
+# Webmin, 1 if installed but not configured, or 0 otherwise.
+# For mode 0, returns 1 if installed, 0 if not
+sub is_installed
+{
+return 0 if (!-r $config{'tomcat_config'} || !&has_command($config{'tomcat_path'}));
+return $_[0] ? 2 : 1;
+}
+
diff --git a/install_java.cgi b/install_java.cgi
new file mode 100644
index 0000000..1d338dc
--- /dev/null
+++ b/install_java.cgi
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+require './java-lib.pl';
+require '../webmin/webmin-lib.pl'; #require
+foreign_require('software', 'software-lib.pl');
+
+use File::Basename;
+
+sub extract_java_archive{
+ my $jdk_archive = $_[0];
+
+ my $java_dir = '/usr/java';
+ if( ! -d $java_dir){
+ &make_dir($java_dir, 0755, 1);
+ }
+
+ $cmd_out='';
+ $cmd_err='';
+ print "
Extracting $jdk_archive to $java_dir...
";
+ local $out = &execute_command("tar -x -v --overwrite -f \"$jdk_archive\" -C/usr/java", undef, \$cmd_out, \$cmd_err, 0, 0);
+
+ my $jdk_tar_first_line = ( split /\n/, $cmd_out )[0];
+ my $jdk_dir = $java_dir."/".(split /\//, $jdk_tar_first_line)[0];
+
+ if($cmd_err){
+ $cmd_err = s/\n/
/g;
+ &error("Error: tar: $cmd_err");
+ }else{
+ $cmd_out = s/\n/
/g;
+ print &html_escape($cmd_out);
+ }
+
+ &set_ownership_permissions('root','root', 0755, $jdk_dir);
+ &execute_command("chown -R root:root $jdk_dir", undef, \$cmd_out, \$cmd_err, 0, 0);
+ if($cmd_err){
+ $cmd_err = s/\n/
/g;
+ &error("Error: chown: $cmd_err");
+ }
+
+ return $jdk_dir;
+}
+
+#$| = 1;
+
+if ($ENV{REQUEST_METHOD} eq "POST") {
+ &ReadParse(\%getin, "GET");
+ &ReadParseMime(undef, \&read_parse_mime_callback, [ $getin{'id'} ]);
+ }
+else {
+ &ReadParse();
+ $no_upload = 1;
+ }
+&error_setup($text{'install_err'});
+&ui_print_header(undef, $text{'java_title'}, "");
+
+my $jdk_path = '';
+if($in{'source'} == 200){
+
+ my $jdk_name = (split /=/, $in{'openjdk_ver'})[1];
+ my $openjdk_pkg = $jdk_name;
+ if($in{'openjdk_headless'} == 1){
+ $openjdk_pkg .= '-headless';
+ }
+
+ software::update_system_install($openjdk_pkg, undef);
+ $jdk_path = get_jdk_dir_by_name($jdk_name);
+
+} else {
+ if ($in{'source'} == 100) {
+
+ my ($jdk_name, $url) = split /=/, $in{'jdk_ver'};
+ $in{'url'} = $url;
+ $in{'source'} = 2;
+ }
+ my $jdk_archive = process_file_source();
+ $jdk_path = extract_java_archive($jdk_archive);
+}
+
+if($in{'def_jdk'} == 1){
+ set_default_java($jdk_path);
+}
+
+print "
Done
";
+&ui_print_footer("", $text{'index_return'});
diff --git a/install_libs.cgi b/install_libs.cgi
new file mode 100644
index 0000000..e04d9d9
--- /dev/null
+++ b/install_libs.cgi
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+
+use File::Basename;
+use File::Path 'rmtree';
+
+sub inst_error{
+ print "$main::whatfailed : $_[0] \n";
+ &ui_print_footer("", $text{'index_return'});
+ exit;
+}
+
+if($ENV{'CONTENT_TYPE'} =~ /boundary=(.*)$/) {
+ &ReadParseMime();
+}else {
+ &ReadParse();
+ $no_upload = 1;
+}
+
+$| = 1;
+&ui_print_header(undef, $text{'libs_install_title'}, "");
+
+my $lib_file = process_file_source();
+my @suffixlist = ('\.zip', '\.jar');
+($lib_name,$path,$lib_suffix) = fileparse($lib_file,@suffixlist);
+
+my $unzip_dir = '';
+my @lib_jars;
+
+#Check if its a .zip or .jar
+print "Source: $lib_file
";
+if($lib_suffix eq ".zip"){
+ $unzip_dir = unzip_file($lib_file);
+
+ #make a list of extension jars
+ opendir(DIR, $unzip_dir) or die $!;
+ @lib_jars = grep { $_ = $unzip_dir.'/'.$_ ; -f && /\.jar$/ } readdir(DIR);
+ closedir(DIR);
+
+}elsif($lib_suffix eq ".jar"){
+ push(@lib_jars, $lib_file);
+}else{
+ &error("Error: Unsupported file type $lib_suffix");
+ &ui_print_footer("", $text{'index_return'});
+}
+
+print "
Installing $lib_name files...
";
+my $catalina_home = get_catalina_home();
+
+#move jars to Tomcat lib and save list of installed jars to lib file
+open(my $fh, '>', "$module_config_directory/lib_$lib_name.list") or die "open:$!";
+foreach $j (@lib_jars) {
+ #move jars to Tomcat lib
+ if(!move("$j", "$catalina_home/lib/")){
+ &error("Error: Can't move file: $!");
+ }
+ my $j_name = basename($j);
+ &set_ownership_permissions('tomcat','tomcat', 0444, "$catalina_home/lib/$j_name");
+
+ print "$catalina_home/lib/$j_name
";
+ print $fh "$j_name=$catalina_home/lib/$j_name\n";
+}
+close $fh;
+
+print "
Done.
";
+
+if($unzip_dir ne ''){
+ &rmtree($unzip_dir); #remove temp dir
+}
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/install_war.cgi b/install_war.cgi
new file mode 100644
index 0000000..651c812
--- /dev/null
+++ b/install_war.cgi
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+use File::Basename;
+use File::Path 'rmtree';
+
+sub inst_error{
+ print "$main::whatfailed : $_[0] \n";
+ &ui_print_footer("", $text{'index_return'});
+ exit;
+}
+
+if($ENV{'CONTENT_TYPE'} =~ /boundary=(.*)$/) { &ReadParseMime(); }
+else { &ReadParse(); $no_upload = 1; }
+
+$| = 1;
+$theme_no_table = 1 if ($in{'source'} == 2 || $in{'source'} == 4);
+&ui_print_header(undef, $text{'install_title'}, "");
+
+my $file = process_file_source();
+
+my @suffixlist = ('\.zip', '\.war');
+($file_name,$path,$file_suffix) = fileparse($file,@suffixlist);
+
+my $unzip_dir = '';
+my @wars;
+
+#Check if its a .zip or .jar
+print "Source: $file
";
+if($file_suffix eq ".zip"){
+ $unzip_dir = unzip_file($file);
+
+ #make a list of extension jars
+ opendir(DIR, $unzip_dir) or die $!;
+ @wars = grep { $_ = $unzip_dir.'/'.$_ ; -f && /\.war$/ } readdir(DIR);
+ closedir(DIR);
+
+}elsif($file_suffix eq ".war"){
+ push(@wars, $file);
+}else{
+ &error("Error: Unsupported file type $file_suffix");
+ &ui_print_footer("", $text{'index_return'});
+}
+
+$catalina_home = get_catalina_home();
+
+foreach $war (@wars) {
+ my $war_name = basename($war);
+ if(!move($war, "$catalina_home/webapps/")){
+ &error("Error: Can't move file: $!");
+ }else{
+ print "Install of $war_name is successful
";
+ }
+ &set_ownership_permissions('tomcat','tomcat', 0444, "$catalina_home/webapps/$war_name");
+}
+
+if($unzip_dir ne ''){
+ &rmtree($unzip_dir); #remove temp dir
+}
+
+#tomcat_service_ctl('restart');
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/java-lib.pl b/java-lib.pl
new file mode 100644
index 0000000..62f4f63
--- /dev/null
+++ b/java-lib.pl
@@ -0,0 +1,363 @@
+=head1 java-lib.pl
+
+Functions for managing Oracle JDK installations.
+
+ foreign_require("tomcat", "tomcat-lib.pl");
+ @sites = tomcat::list_tomcat_websites()
+
+=cut
+
+BEGIN { push(@INC, ".."); };
+use warnings;
+use WebminCore;
+
+foreign_require('software', 'software-lib.pl');
+
+sub search_pkg{
+ my $pattern = $_[0];
+
+ my @avail = ();
+ if (defined(&software::update_system_search)) {
+ # Call the search function
+ @avail = &software::update_system_search($pattern);
+ } else {
+ # Scan through list manually
+ @avail = &software::update_system_available();
+ @avail = grep { $_->{'name'} =~ /\Q$pattern\E/i } @avail;
+ }
+ return sort @avail;
+}
+
+sub get_openjdk_patterns(){
+ my %osinfo = &detect_operating_system();
+
+ my %rv;
+ if( ($osinfo{'real_os_type'} =~ /centos/i) or #CentOS
+ ($osinfo{'real_os_type'} =~ /fedora/i) or #Fedora
+ ($osinfo{'real_os_type'} =~ /rocky/i) or # Rocky
+ ($osinfo{'real_os_type'} =~ /alma/i) or # Alma
+ ($osinfo{'real_os_type'} =~ /scientific/i) ){
+
+ $rv{'search'} = 'openjdk';
+ $rv{'version'} = '^java-([0-9\.]+)-openjdk$';
+
+ }elsif( $osinfo{'os_type'} =~ /debian/i){ #ubuntu
+ $rv{'search'} = 'openjdk-[0-9]+-jdk$';
+ $rv{'version'} = 'openjdk-([0-9]+)-jdk';
+ }
+ return %rv;
+}
+
+sub get_openjdk_versions(){
+ my $cache_file = "$module_config_directory/openjdk_version_cache";
+ my %openjdk_versions;
+
+ if(-f $cache_file){
+ read_file_cached($cache_file, \%openjdk_versions);
+
+ if($openjdk_versions{'updated'} >= (time() - 86400)){ #if last update was less than a day ago
+ delete $openjdk_versions{'updated'}; #remove the cache mtime key
+ return %openjdk_versions;
+ }
+ }
+
+ my %patterns = get_openjdk_patterns();
+ my @avail = search_pkg($patterns{'search'});
+ foreach $a (@avail) {
+ if($a->{'name'} =~ /$patterns{'version'}/){
+ $openjdk_versions{$1} = $a->{'name'};
+ }
+ }
+
+ #cache the results
+ $openjdk_versions{'updated'} = time();
+ &write_file($cache_file, \%openjdk_versions);
+ delete $openjdk_versions{'updated'}; #remove the cache mtime key
+
+ return %openjdk_versions;
+}
+
+sub get_latest_jdk_version(){
+
+ my %java_tar_gz;
+ my $cache_file = "$module_config_directory/oracle_version_cache";
+ if(-f $cache_file){
+ read_file_cached($cache_file, \%java_tar_gz);
+ if($java_tar_gz{'updated'} >= (time() - 86400)){ #if last update was less than a day ago
+ delete $java_tar_gz{'updated'}; #remove the cache mtime key
+ return %java_tar_gz;
+ }
+ }
+
+ my $error;
+ my $url = 'https://www.oracle.com/java/technologies/downloads/';
+ $tmpfile = &transname("javase.html");
+ &error_setup(&text('install_err3', $url));
+ &http_download("www.oracle.com", 443, "/java/technologies/downloads/", $tmpfile, \$error,
+ undef, 1, undef, 0, 0, 1);
+
+ open($fh, '<', $tmpfile) or die "open:$!";
+ while(my $line = <$fh>){
+ #https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz
+ if($line =~ /(https:\/\/download.oracle.com\/java\/([0-9]+)\/latest\/jdk-[0-9]+_linux-x64_bin.tar.gz)/){
+ #if($line =~ /"filepath":"(https:\/\/download.oracle.com\/otn-pub\/java\/jdk\/([a-z0-9-\.+]+)\/[a-z0-9]+\/jdk-[a-z0-9-\.]+_linux-x64_bin.tar.gz)/){
+ $java_tar_gz{$2} = $1;
+ #last;
+ }
+ }
+ close $fh;
+
+ #cache the results
+ $java_tar_gz{'updated'} = time();
+ &write_file($cache_file, \%java_tar_gz);
+ delete $java_tar_gz{'updated'}; #remove the cache mtime key
+
+ return %java_tar_gz;
+}
+
+sub get_installed_jdk_versions(){
+ my @jdks = get_installed_oracle_jdk_versions();
+
+ push(@jdks, get_installed_openjdk_versions());
+ return @jdks;
+}
+
+sub get_installed_openjdk_versions{
+
+ my @pkgs = ();
+ my %patterns = get_openjdk_patterns();
+
+ my $cmd_out='';
+ my $cmd_err='';
+ if(has_command('rpm')){
+ local $out = &execute_command("rpm -qa --queryformat \"%{NAME}\n\" \"*$patterns['search']*\"", undef, \$cmd_out, \$cmd_err, 0, 0);
+
+ my @lines = split /\n/, $cmd_out;
+ foreach my $line (@lines){
+ if($line =~ /^(java-[0-9\.]+-openjdk).*/i){ #package pgdg96-centos is not installed
+ push(@pkgs, $1);
+ }
+ }
+ }elsif(has_command('dpkg')){
+ local $out = &execute_command("dpkg -l \"*openjdk*\"", undef, \$cmd_out, \$cmd_err, 0, 0);
+
+ my %all_pkgs;
+ my @lines = split /\n/, $cmd_out;
+ foreach my $line (@lines){
+ if($line =~ /^(..)\s+(openjdk-[0-9\.]*)-.*:.*/i){
+ my $pkg = $2;
+ if($1 =~ /[uirph]i/){
+ $all_pkgs{$pkg} = 1;
+ }
+ }
+ }
+ @pkgs = keys %all_pkgs;
+ }else{
+ my @dirs;
+ opendir(DIR, '/usr/java/') or return @dirs;
+ @dirs
+ = grep {
+ /^jdk-[0-9\.]+/
+ && -d "/usr/java/$_"
+ } readdir(DIR);
+ closedir(DIR);
+ }
+
+ return sort @pkgs;
+}
+
+sub get_installed_oracle_jdk_versions{
+ my @dirs;
+ opendir(DIR, '/usr/java/') or return @dirs;
+ @dirs
+ = grep {
+ /^jdk[0-9\.\-_]+/
+ && -d "/usr/java/$_"
+ } readdir(DIR);
+ closedir(DIR);
+
+ return sort @dirs;
+}
+
+sub is_default_jdk{
+ my $jdk_dir = $_[0];
+
+ my %os_env;
+ if(-f '/etc/profile.d/jdk.sh'){
+ read_env_file('/etc/profile.d/jdk.sh', \%os_env);
+ }elsif(-f '/etc/environment'){
+ read_env_file('/etc/environment', \%os_env);
+ }
+
+ if($os_env{'JAVA_HOME'} eq $jdk_dir){
+ return 1;
+ }else{
+ return 0;
+ }
+}
+
+sub get_java_version(){
+ local %version;
+ local $out = &backquote_command('java \-version 2>&1');
+
+ #Oracle Java <= 8
+ if ($out =~ /Java\(TM\)\sSE\sRuntime\sEnvironment\s\(build\s([0-9]\.([0-9]+)\.[0-9]_([0-9]+)\-([a-z0-9]+))\)/) {
+ $version{'full'} = $1;
+ $version{'major'} = $2;
+ $version{'release'} = $3;
+ $version{'build'} = $4;
+ $version{'vendor'} = 'oracle';
+
+ #Oracle Java >=12 - Java(TM) SE Runtime Environment (build 12.0.1+12)
+ }elsif ($out =~ /Java\(TM\)\sSE\sRuntime\sEnvironment\s\(build\s((\d+)\.\d+\.\d+\+(\d+))\)/) {
+ $version{'full'} = $1;
+ $version{'major'} = $2;
+ $version{'release'} = 0;
+ $version{'build'} = $3;
+ $version{'vendor'} = 'oracle';
+
+ # OpenJDK Runtime Environment (build 11.0.7+10-post-Ubuntu-2ubuntu218.04)
+ # OpenJDK Runtime Environment (build 11.0.9+11-Ubuntu-0ubuntu1.20.04)
+ # OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1~18.04-b09)
+ }elsif ($out =~ /Runtime\sEnvironment\s\(build\s((\d+)\.(\d+)\.\d+[\+_](\d+))/) {
+ if($2 eq '1'){ #1.8.x
+ $version{'major'} = $3;
+ $version{'release'} = $4;
+ $version{'build'} = $5;
+ }else{ #11.0.x
+ $version{'major'} = $2;
+ $version{'release'} = $3;
+ $version{'build'} = $4;
+ }
+ $version{'full'} = $1;
+
+ $version{'vendor'} = 'openjdk';
+ }else {
+ $version{'major'} = 0;
+ $version{'full'} = $out;
+ $version{'release'} = 0;
+ $version{'build'} = 0;
+ }
+ return %version;
+}
+
+sub get_java_home(){
+ my $java_path = &resolve_links('/usr/bin/java');
+ $java_path =~ s/\/bin\/java//;
+ return $java_path;
+}
+
+sub set_default_java{
+ my $jdk_dir = $_[0];
+
+ my $alt_cmd = "";
+ if(has_command('alternatives')){ #CentOS
+ $alt_cmd = 'alternatives';
+ }elsif(has_command('update-alternatives')){ #ubuntu
+ $alt_cmd = 'update-alternatives';
+ }else{
+ print "Warning: No alternatives command found
";
+ }
+
+ if($alt_cmd ne ""){
+ print "Updating Java using $alt_cmd
";
+ my @jdk_progs = ('java', 'jar', 'javac');
+ foreach my $prog (@jdk_progs){
+
+ $cmd_out='';
+ $cmd_err='';
+ local $out = &execute_command("$alt_cmd --install /usr/bin/$prog $prog $jdk_dir/bin/$prog 1", undef, \$cmd_out, \$cmd_err, 0, 0);
+ $out.= &execute_command("$alt_cmd --set $prog $jdk_dir/bin/$prog", undef, \$cmd_out, \$cmd_err, 0, 0);
+
+ if($cmd_err){
+ $cmd_err = s/\n/
/g;
+ &error("Error: $alt_cmd: $cmd_err");
+ }elsif($cmd_out){
+ $cmd_out = s/\n/
/g;
+ print &html_escape($cmd_out);
+ }
+ }
+ }
+
+ print "
Setting Java environment variables...
";
+ my %os_env;
+ $os_env{'J2SDKDIR'} = $jdk_dir;
+ $os_env{'JAVA_HOME'} = $jdk_dir;
+ $os_env{'DERBY_HOME'}= "$jdk_dir/db";
+ $os_env{'J2REDIR'} = "$jdk_dir/jre";
+
+ if(-e '/etc/profile.d/'){
+ $os_env{'PATH'} = "\$PATH:$jdk_dir/bin:$jdk_dir/db/bin:$jdk_dir/jre/bin";
+ write_env_file('/etc/profile.d/jdk.sh', \%os_env, 1);
+ }elsif(-e '/etc/environment'){
+ read_env_file('/etc/environment', \%os_env);
+ $os_env{'PATH'} = "$os_env{'PATH'}:$jdk_dir/bin:$jdk_dir/db/bin:$jdk_dir/jre/bin";
+ write_env_file('/etc/environment', \%os_env, 0);
+ }
+}
+
+sub unset_default_java{
+ my $jdk_dir = $_[0];
+ print "Removing Java environment variables ...
";
+ if(-f '/etc/profile.d/jdk.sh'){
+ unlink_file('/etc/profile.d/jdk.sh');
+ }elsif(-f '/etc/environment'){
+ my %os_env;
+ read_env_file('/etc/environment', \%os_env);
+ delete $os_env{'J2SDKDIR'};
+ delete $os_env{'JAVA_HOME'};
+ delete $os_env{'DERBY_HOME'};
+ delete $os_env{'J2REDIR'};
+ write_env_file('/etc/environment', \%os_env, 0);
+ }
+
+ my $alt_cmd = "";
+ if(has_command('alternatives')){ #CentOS
+ $alt_cmd = 'alternatives';
+ }elsif(has_command('update-alternatives')){ #ubuntu
+ $alt_cmd = 'update-alternatives';
+ }else{
+ print "Warning: No alternatives command found
";
+ }
+
+ if($alt_cmd ne ""){
+ print "Removing Java using $alt_cmd
";
+ my @jdk_progs = ('java', 'jar', 'javac');
+ foreach my $prog (@jdk_progs){
+
+ $cmd_out='';
+ $cmd_err='';
+ local $out = &execute_command("$alt_cmd --remove $prog $jdk_dir/bin/$prog", undef, \$cmd_out, \$cmd_err, 0, 0);
+ if($cmd_err){
+ &error("Error: $alt_cmd: $cmd_err");
+ }else{
+ $cmd_out = s/\r\n/
/g;
+ print &html_escape($cmd_out);
+ }
+ }
+ }
+}
+
+sub get_jdk_dir_by_name{
+ my $jdk_name = $_[0];
+ my $jdk_dir = '';
+
+ if($jdk_name =~ /.*openjdk.*/){
+
+ my $jdk_ver = (split /-/, $jdk_name)[1]; #get version from name
+ my @known_dirs = ('java-'.$jdk_ver.'-openjdk', 'java-'.$jdk_ver.'-openjdk-amd64', 'jre-'.$jdk_ver.'-openjdk');
+
+ foreach $jvm_name (@known_dirs){
+ if(-d '/usr/lib/jvm/'.$jvm_name){
+ $jdk_dir = '/usr/lib/jvm/'.$jvm_name;
+ last;
+ }
+ }
+
+ }else{
+ $jdk_dir = '/usr/java/'.$jdk_name;
+ }
+ return $jdk_dir;
+}
+
+1;
diff --git a/lang/en b/lang/en
new file mode 100644
index 0000000..fda3959
--- /dev/null
+++ b/lang/en
@@ -0,0 +1,121 @@
+index_title=Tomcat Server
+index_root=The root directory is $1.
+
+index_start=Start Server
+index_startmsg=Click this button to start the Tomcat server
+index_stop=Stop Server
+index_stopmsg=Click this button to stop the running Tomcat server
+index_restart=Restart Server
+index_restartmsg=Click this button to restart the running Tomcat server
+index_return=Tomcat
+index_install=Install Tomcat
+index_upgrade=Upgrade Tomcat
+
+users_title=Users
+
+wars_title=WARs
+manual_title=Edit config
+manual_ecannot=You are not allowed to edit the Tomcat server.xml config file
+manual_ok=Edit
+manual_efile=Selected file is not part of the Tomcat server configuration
+manual_file=Edit config file:
+manual_edata=Nothing entered!
+manual_err=Failed to save config file
+
+war_install=Install Application
+war_installsource=Install source (.war or .zip)
+war_installok=Deploy
+wars_tabinstall=Deploy
+wars_tabdelete=Undeploy
+wars_tablist=List
+wars_desc1=Tomcat applications can be installed using .war files from local or remote locations.
+wars_desc2=After deleting an application, Tomcat server will be restarted. If you keep, the war file, application will be redeployed!
+wars_delete=Delete Application
+wars_deleteok=Undeploy
+wars_rmwar=Remove war file too
+wars_installed=Installed Apps
+
+install_title=Install WAR
+install_err1=Invalid URL
+install_err2=Failed to install uploaded module
+install_err3=Failed to install module from $1
+install_efile=File does not exist
+install_ebrowser=Your browser does not support file uploads
+
+delete_title=Uninstall WAR
+delete_err=Failed to delete modules
+delete_enone=No modules selected
+
+start_err=Failed to start Tomcat
+stop_err=Failed to stop Tomcat
+restart_err=Failed to restart Tomcat
+
+java_title=Java
+java_tabinstall=Install
+java_tabuninstall=Uninstall
+java_tabdefault=Default
+java_desc1=Install Java Development Kit(JDK) from distribution repository or from Oracle .tar.gz archive
+java_desc2=Uninstall Oracle Java 8 files from /usr/share
+java_desc3=Set default Java, using update-alternatives and /etc/profile.d/jdk.sh
+java_install=Install Options
+java_uninstall=Uninstall Options
+java_default=update-alternatives Options
+jdk_installsource=JDK source
+jdk_latest=Oracle JDK
+java_installok=Install
+java_deleteok=Uninstall
+java_defaultok=Update
+java_def_jdk=Set as system default Java
+java_def_jdk_desc= ( using alternatives )
+java_rm_def_jdk=Remove, if default Java
+java_installed=JDK versions
+openjdk_latest=OpenJDK
+openjdk_headless=Headless package
+openjdk_headless_desc=only for OpenJDK
+
+libs_title=Libraries
+libs_desc1=Install libraries into Tomcat's lib/ directory
+libs_desc2=Uninstall librarues from Tomcat's lib/ directory
+libs_install=Libraries to be installed
+libs_delete=Libraries to be uninstalled
+libs_installsource=Library source(.zip or .jar)
+libs_tabinstall=Install
+libs_tabuninstall=Uninstall
+libs_installok=Install
+libs_deleteok=Uninstall
+libs_installed=Libraries found
+libs_install_title=Installing Tomcat library
+libs_uninstall_title=Uninstalling Tomcat libraries
+
+source_local=Local file
+source_uploaded=Uploaded file
+source_ftp=FTP or HTTP URL
+source_archive=Apache Archive
+
+source_err0=File Error
+source_err1=Upload Error
+source_err1.2=No upload file
+source_err2=Download error
+source_err3=Invalid URL
+
+setup_title=Setup
+
+base_options=Options
+base_major=Tomcat Major Version
+base_archive=Release
+base_installok=Download
+base_installsource=Install source
+base_desc1=Download an archive of Apache Tomcat Server from Apache website and install it
+
+proxy_title=Proxy
+proxy_add_options=Add proxy
+proxy_remove_options=Remove proxy
+proxy_default_app=Make this the default (/)
+proxy_app_default_warning=Will remove previous default path!
+proxy_ssl=Use SSL port
+proxy_ssl_info=Use Tomcat HTTPs port
+proxy_list=Available proxies
+proxy_installok=Add
+proxy_removeok=Remove
+proxy_wildcard=Add Wildcard map
+proxy_wildcard_info=Proxy Apache:80 to Tomcat:8080
diff --git a/module.info b/module.info
new file mode 100644
index 0000000..b419d77
--- /dev/null
+++ b/module.info
@@ -0,0 +1,3 @@
+desc=Apache Tomcat
+os_support=*-linux freebsd archlinux
+category=servers
diff --git a/restart.cgi b/restart.cgi
new file mode 100644
index 0000000..8599e08
--- /dev/null
+++ b/restart.cgi
@@ -0,0 +1,15 @@
+#!/usr/bin/perl
+# restart.cgi
+# Restart the tomcat daemon
+
+require './tomcat-lib.pl';
+&ReadParse();
+&error_setup($text{'restart_err'});
+my ($rc, $err) = tomcat_service_ctl('restart');
+if ($rc != 0){
+ &ui_print_header(undef, $text{'index_title'}, "");
+ &error($err);
+ &ui_print_footer("", $text{'index_return'});
+ exit;
+}
+&redirect("");
diff --git a/save_manual.cgi b/save_manual.cgi
new file mode 100644
index 0000000..977a3cf
--- /dev/null
+++ b/save_manual.cgi
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+# Update a manually edited config file
+
+require './tomcat-lib.pl';
+&error_setup($text{'manual_err'});
+&ReadParseMime();
+
+my $catalina_home = get_catalina_home();
+
+# Work out the file
+@files = ( "$catalina_home/bin/setenv.sh",
+ "$catalina_home/conf/context.xml",
+ "$catalina_home/conf/server.xml",
+ "$catalina_home/conf/tomcat-users.xml",
+ "$catalina_home/conf/web.xml");
+&indexof($in{'file'}, @files) >= 0 || &error($text{'manual_efile'});
+$in{'data'} =~ s/\r//g;
+$in{'data'} =~ /\S/ || &error($text{'manual_edata'});
+
+# Write to it
+&open_lock_tempfile(DATA, ">$in{'file'}");
+&print_tempfile(DATA, $in{'data'});
+&close_tempfile(DATA);
+
+&webmin_log("manual", undef, $in{'file'});
+&redirect("");
+
diff --git a/scripts/alma-rocky.sh b/scripts/alma-rocky.sh
new file mode 100644
index 0000000..1e38817
--- /dev/null
+++ b/scripts/alma-rocky.sh
@@ -0,0 +1,95 @@
+# !/bin/bash -e
+# Tomcat Module Script for Rocky Linux
+# Usage:
+# wget https://raw.githubusercontent.com/cited/Tomcat-Webmin-Module/master/scripts/rocky-linux.sh
+# chmod +x pre-installer
+# ./pre-installer.sh
+
+function get_deps(){
+
+ yum -y install wget unzip bzip2
+
+}
+
+function setup_selinux(){
+
+ #allow apache port for django app
+ semanage port -a -t http_port_t -p tcp 7800
+ semanage port -m -t http_port_t -p tcp 9000
+
+ setsebool -P httpd_can_network_connect 1
+}
+
+
+function install_apache(){
+
+ yum -y install httpd
+
+}
+
+function install_webmin(){
+ wget -P/tmp 'https://download.webmin.com/developers-key.asc'
+ rpm --import /tmp/developers-key.asc || true
+ cp -f /tmp/developers-key.asc /etc/pki/rpm-gpg/RPM-GPG-KEY-webmin-developers
+
+ cat >/etc/yum.repos.d/webmin.repo < Tomcat to complete installation"
+
+}
+
+get_deps;
+#install_apache;
+#install_webmin;
+#download_certbot_module;
+setup_selinux;
+#install_certbot_module;
+download_tomcat_module;
+install_tomcat_module;
diff --git a/scripts/index.rst b/scripts/index.rst
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/scripts/index.rst
@@ -0,0 +1 @@
+1
diff --git a/scripts/pre-install.sh b/scripts/pre-install.sh
new file mode 100644
index 0000000..9de6a81
--- /dev/null
+++ b/scripts/pre-install.sh
@@ -0,0 +1,124 @@
+# !/bin/bash -e
+# Tomcat Module Script for CentOS and Ubuntu
+# For use on clean CentOS or Ubuntu box only
+# Usage:
+# wget https://raw.githubusercontent.com/cited/Tomcat-Webmin-Module/master/scripts/pre-install.sh
+# chmod +x pre-installer
+# ./pre-installer.sh
+
+function get_repo(){
+ if [ -f /etc/centos-release ]; then
+ REPO='rpm'
+
+ elif [ -f /etc/debian_version ]; then
+ REPO='apt'
+fi
+}
+
+function install_webmin(){
+
+ if [ "${REPO}" == 'apt' ]; then
+
+ echo "deb http://download.webmin.com/download/repository sarge contrib" > /etc/apt/sources.list.d/webmin.list
+ wget -qO - http://www.webmin.com/jcameron-key.asc | apt-key add -
+ apt-get -y update
+ apt-get -y install webmin
+
+ elif [ "${REPO}" == 'rpm' ]; then
+
+
+
+
+
+ wget -P/tmp 'https://download.webmin.com/developers-key.asc'
+ rpm --import /tmp/developers-key.asc || true
+ cp -f /tmp/developers-key.asc /etc/pki/rpm-gpg/RPM-GPG-KEY-webmin-developers
+
+ cat >/etc/yum.repos.d/webmin.repo < Tomcat to complete installation"
+
+}
+
+
+
+function download_certbot_module(){
+pushd /tmp/
+ wget https://github.com/cited/Certbot-Webmin-Module/archive/master.zip
+ unzip master.zip
+ mv Certbot-Webmin-Module-master certbot
+ tar -czf /opt/certbot.wbm.gz certbot
+ rm -rf certbot master.zip
+popd
+}
+
+function install_apache(){
+ if [ "${REPO}" == 'apt' ]; then
+ apt-get -y install apache2
+ elif [ "${REPO}" == 'rpm' ]; then
+ yum -y install httpd
+ fi
+}
+
+function install_certbot_module(){
+pushd /opt/
+ if [ "${REPO}" == 'apt' ]; then
+ /usr/share/webmin/install-module.pl certbot.wbm.gz
+ elif [ "${REPO}" == 'rpm' ]; then
+ /usr/libexec/webmin/install-module.pl certbot.wbm.gz
+ fi
+popd
+ echo -e "Certbot is now installed. Go to Servers > Certbot to complete installation"
+
+}
+
+function get_deps(){
+if [ "${REPO}" == 'apt' ]; then
+ apt-get -y install wget unzip
+ elif [ "${REPO}" == 'rpm' ]; then
+ yum -y install wget unzip bzip2
+ fi
+}
+
+get_repo;
+get_deps;
+# Uncomment line(s) below if you wish to install Webmin, Apache HTTP Server, and Certbot as well.
+#install_webmin;
+#install_apache;
+#download_certbot_module;
+#install_certbot_module;
+download_tomcat_module;
+install_tomcat_module;
diff --git a/scripts/rocky-linux.sh b/scripts/rocky-linux.sh
new file mode 100644
index 0000000..1e38817
--- /dev/null
+++ b/scripts/rocky-linux.sh
@@ -0,0 +1,95 @@
+# !/bin/bash -e
+# Tomcat Module Script for Rocky Linux
+# Usage:
+# wget https://raw.githubusercontent.com/cited/Tomcat-Webmin-Module/master/scripts/rocky-linux.sh
+# chmod +x pre-installer
+# ./pre-installer.sh
+
+function get_deps(){
+
+ yum -y install wget unzip bzip2
+
+}
+
+function setup_selinux(){
+
+ #allow apache port for django app
+ semanage port -a -t http_port_t -p tcp 7800
+ semanage port -m -t http_port_t -p tcp 9000
+
+ setsebool -P httpd_can_network_connect 1
+}
+
+
+function install_apache(){
+
+ yum -y install httpd
+
+}
+
+function install_webmin(){
+ wget -P/tmp 'https://download.webmin.com/developers-key.asc'
+ rpm --import /tmp/developers-key.asc || true
+ cp -f /tmp/developers-key.asc /etc/pki/rpm-gpg/RPM-GPG-KEY-webmin-developers
+
+ cat >/etc/yum.repos.d/webmin.repo < Tomcat to complete installation"
+
+}
+
+get_deps;
+#install_apache;
+#install_webmin;
+#download_certbot_module;
+setup_selinux;
+#install_certbot_module;
+download_tomcat_module;
+install_tomcat_module;
diff --git a/scripts/tomcat.wbm.gz b/scripts/tomcat.wbm.gz
new file mode 100644
index 0000000..f96281b
Binary files /dev/null and b/scripts/tomcat.wbm.gz differ
diff --git a/scripts/ubuntu.sh b/scripts/ubuntu.sh
new file mode 100644
index 0000000..9de6a81
--- /dev/null
+++ b/scripts/ubuntu.sh
@@ -0,0 +1,124 @@
+# !/bin/bash -e
+# Tomcat Module Script for CentOS and Ubuntu
+# For use on clean CentOS or Ubuntu box only
+# Usage:
+# wget https://raw.githubusercontent.com/cited/Tomcat-Webmin-Module/master/scripts/pre-install.sh
+# chmod +x pre-installer
+# ./pre-installer.sh
+
+function get_repo(){
+ if [ -f /etc/centos-release ]; then
+ REPO='rpm'
+
+ elif [ -f /etc/debian_version ]; then
+ REPO='apt'
+fi
+}
+
+function install_webmin(){
+
+ if [ "${REPO}" == 'apt' ]; then
+
+ echo "deb http://download.webmin.com/download/repository sarge contrib" > /etc/apt/sources.list.d/webmin.list
+ wget -qO - http://www.webmin.com/jcameron-key.asc | apt-key add -
+ apt-get -y update
+ apt-get -y install webmin
+
+ elif [ "${REPO}" == 'rpm' ]; then
+
+
+
+
+
+ wget -P/tmp 'https://download.webmin.com/developers-key.asc'
+ rpm --import /tmp/developers-key.asc || true
+ cp -f /tmp/developers-key.asc /etc/pki/rpm-gpg/RPM-GPG-KEY-webmin-developers
+
+ cat >/etc/yum.repos.d/webmin.repo < Tomcat to complete installation"
+
+}
+
+
+
+function download_certbot_module(){
+pushd /tmp/
+ wget https://github.com/cited/Certbot-Webmin-Module/archive/master.zip
+ unzip master.zip
+ mv Certbot-Webmin-Module-master certbot
+ tar -czf /opt/certbot.wbm.gz certbot
+ rm -rf certbot master.zip
+popd
+}
+
+function install_apache(){
+ if [ "${REPO}" == 'apt' ]; then
+ apt-get -y install apache2
+ elif [ "${REPO}" == 'rpm' ]; then
+ yum -y install httpd
+ fi
+}
+
+function install_certbot_module(){
+pushd /opt/
+ if [ "${REPO}" == 'apt' ]; then
+ /usr/share/webmin/install-module.pl certbot.wbm.gz
+ elif [ "${REPO}" == 'rpm' ]; then
+ /usr/libexec/webmin/install-module.pl certbot.wbm.gz
+ fi
+popd
+ echo -e "Certbot is now installed. Go to Servers > Certbot to complete installation"
+
+}
+
+function get_deps(){
+if [ "${REPO}" == 'apt' ]; then
+ apt-get -y install wget unzip
+ elif [ "${REPO}" == 'rpm' ]; then
+ yum -y install wget unzip bzip2
+ fi
+}
+
+get_repo;
+get_deps;
+# Uncomment line(s) below if you wish to install Webmin, Apache HTTP Server, and Certbot as well.
+#install_webmin;
+#install_apache;
+#download_certbot_module;
+#install_certbot_module;
+download_tomcat_module;
+install_tomcat_module;
diff --git a/setup.cgi b/setup.cgi
new file mode 100644
index 0000000..3079809
--- /dev/null
+++ b/setup.cgi
@@ -0,0 +1,307 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+require '../webmin/webmin-lib.pl'; #for OS detection
+foreign_require('software', 'software-lib.pl');
+
+sub add_tomcat_user{
+ #check if tomcat user exists
+ if(read_file_contents('/etc/passwd') !~ /\ntomcat:/){
+ #add tomcat user
+ local $out = &backquote_command('useradd -m tomcat', 0);
+ }elsif(! -d '/home/tomcat'){
+ &make_dir("/home/tomcat", 0755, 1);
+ &set_ownership_permissions('tomcat','tomcat', undef, '/home/tomcat');
+ }
+}
+
+sub setup_catalina_env{
+ my $tomcat_ver = $_[0];
+
+ my %os_env;
+
+ print "
Setting CATALINA environment...";
+
+ read_env_file('/etc/environment', \%os_env);
+ $os_env{'CATALINA_HOME'} = "/home/tomcat/apache-tomcat-$tomcat_ver/";
+ $os_env{'CATALINA_BASE'} = "/home/tomcat/apache-tomcat-$tomcat_ver/";
+ write_env_file('/etc/environment', \%os_env, 0);
+
+ open(my $fh, '>>', "/home/tomcat/apache-tomcat-$tomcat_ver/bin/setenv.sh") or die "open:$!";
+ print $fh "CATALINA_PID=\"/home/tomcat/apache-tomcat-$tomcat_ver/temp/tomcat.pid\"\n";
+ close $fh;
+}
+
+sub setup_tomcat_users{
+ my $tomcat_ver = $_[0];
+ my @pw_chars = ("A".."Z", "a".."z", "0".."9", "_", "-");
+ my $manager_pass;
+ my $admin_pass;
+
+ $manager_pass .= $pw_chars[rand @pw_chars] for 1..32;
+ $admin_pass .= $pw_chars[rand @pw_chars] for 1..32;
+
+ #Save tomcat-users.xml
+ open(my $fh, '>', "/home/tomcat/apache-tomcat-$tomcat_ver/conf/tomcat-users.xml") or die "open:$!";
+ print $fh <
+
+
+
+
+
+
+
+EOF
+ close $fh;
+ print "
Setting Tomcat users...";
+}
+
+sub install_tomcat_from_archive{
+
+ add_tomcat_user();
+ my $tomcat_ver = download_and_install($in{'source_archive'});
+
+ setup_catalina_env($tomcat_ver);
+ setup_tomcat_users($tomcat_ver);
+ setup_tomcat_service($tomcat_ver);
+}
+
+sub get_apache_proxy_file(){
+ my $proxy_file;
+ my %osinfo = &detect_operating_system();
+ if( ( $osinfo{'real_os_type'} =~ /centos/i) or #CentOS
+ ( $osinfo{'real_os_type'} =~ /rocky/i) or #rocky
+ ( $osinfo{'real_os_type'} =~ /alma/i) or #alma
+ ($osinfo{'real_os_type'} =~ /fedora/i) ){ #Fedora
+ if( ! -d '/etc/httpd/'){
+ return 0;
+ }
+ $proxy_file = '/etc/httpd/conf.d/tomcat.conf';
+
+ }elsif( ($osinfo{'real_os_type'} =~ /ubuntu/i) or
+ ($osinfo{'real_os_type'} =~ /debian/i) ){ #ubuntu or debian
+ if( ! -d '/etc/apache2/'){
+ return 0;
+ }
+ $proxy_file = '/etc/apache2/conf-enabled/tomcat.conf';
+ }
+ return $proxy_file;
+}
+
+sub setup_default_apache_proxy(){
+ my $proxy_file = get_apache_proxy_file();
+ my %osinfo = &detect_operating_system();
+
+ if(-f $proxy_file){
+ return 0;
+ }
+
+ open(my $fh, '>', $proxy_file) or die "open:$!";
+
+ if( ($osinfo{'real_os_type'} =~ /centos/i) or #CentOS
+ ($osinfo{'real_os_type'} =~ /fedora/i) ){ #Fedora
+
+ &execute_command('setsebool httpd_can_network_connect 1');
+
+ print $fh "LoadModule proxy_module modules/mod_proxy.so\n";
+ print $fh "LoadModule proxy_http_module modules/mod_proxy_http.so\n";
+ print $fh "LoadModule rewrite_module modules/mod_rewrite.so\n";
+
+ }elsif( $osinfo{'os_type'} =~ /debian/i){ #ubuntu or debian
+
+ print $fh "LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so\n";
+ print $fh "LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so\n";
+ print $fh "LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so\n";
+ }
+
+ print $fh "ProxyRequests Off\n";
+ print $fh "ProxyPreserveHost On\n";
+ print $fh " \n";
+ print $fh " Order allow,deny\n";
+ print $fh " Allow from all\n";
+ print $fh " \n";
+ print $fh "ProxyPass / http://localhost:8080/\n";
+ print $fh "ProxyPassReverse / http://localhost:8080/\n";
+
+ close $fh;
+
+ print "Added proxy configuration / -> 8080 in $proxy_file\n";
+}
+
+sub select_tomcat_archive{
+ print "$text{'base_desc1'}\n";
+ print &ui_form_start("setup.cgi", "form-data");
+ print ui_hidden('mode', 'tomcat_install');
+ print &ui_table_start($text{'base_options'}, undef, 2);
+
+ my @tmver = &get_tomcat_major_versions();
+ my $sel_tmver = $in{'tmver'} || $tmver[0];
+ my @tm_opts = ( );
+ foreach my $v (@tmver) {
+ push(@tm_opts, [ $v, $v ]);
+ }
+
+ print <
+ function update_select(){
+ var majorSel = document.getElementById('base_major');
+ var major = majorSel.options[majorSel.selectedIndex].value;
+
+ get_pjax_content('/tomcat/setup.cgi?mode=tomcat_install_form&tmver='+major);
+ }
+
+EOF
+
+ print &ui_table_row($text{'base_major'},
+ &ui_select("base_major", $sel_tmver, \@tm_opts, 1, 0, undef, undef, 'id="base_major" onchange="update_select()"'));
+
+ my @tver = &major_tomcat_versions($sel_tmver);
+ my @tver_opts = ( );
+ foreach my $v (reverse @tver) {
+ push(@tver_opts, [ $v, $v ]);
+ }
+
+ print &ui_table_row($text{'base_installsource'},
+ &ui_radio_table("source", 100,
+ [ [ 100, $text{'source_archive'}, &ui_select("source_archive", undef, \@tver_opts,1, 0)],
+ [ 0, $text{'source_local'}, &ui_textbox("file", undef, 40)." ". &file_chooser_button("file", 0) ],
+ [ 1, $text{'source_uploaded'}, &ui_upload("upload", 40) ],
+ [ 2, $text{'source_ftp'},&ui_textbox("url", undef, 40) ]
+ ]));
+
+ print &ui_table_end();
+ print &ui_form_end([ [ "", $text{'base_installok'} ] ]);
+}
+
+sub setup_selinux{
+ my $tomcat_home = get_catalina_home();
+
+ local $out = &execute_command("semanage fcontext -a -t bin_t \"$tomcat_home/bin(/.*)?\"", undef, \$cmd_out, \$cmd_err, 0, 0);
+ print &html_escape($cmd_out.$cmd_err);
+
+ local $out = &execute_command("restorecon -r -v \"$tomcat_home/bin\"", undef, \$cmd_out, \$cmd_err, 0, 0);
+ print &html_escape($cmd_out.$cmd_err);
+}
+
+sub setup_checks{
+
+ my %osinfo = &detect_operating_system();
+
+ #Check for commands
+ if (!&has_command('java')) {
+ print 'Warning: Java is not found. Install it manually or from the '.
+ "Java tab
";
+ }
+
+ my @pinfo = software::package_info('haveged', undef, );
+ if(!@pinfo){
+ if( ($osinfo{'real_os_type'} =~ /centos/i) or #CentOS
+ ($osinfo{'real_os_type'} =~ /alma/i) or #Alma
+ ($osinfo{'real_os_type'} =~ /rocky/i) ){ #Rocky
+ @pinfo = software::package_info('epel-release', undef, );
+ if(!@pinfo){
+ print "Warning: haveged needs epel-release. Install it manually or ".
+ "click here to have it downloaded and installed.
";
+ }
+ }
+ print "Warning: haveged package is not installed. Install it manually or ".
+ "click here to have it downloaded and installed.
";
+ }
+
+ my $tomcat_ver = installed_tomcat_version();
+ if(!$tomcat_ver){
+ print "Click here to install Tomcat from Apache site.
";
+ }
+
+ if (!&has_command('unzip')) {
+ print 'Warning: unzip command is not found. Install it manually or '.
+ "click here to have it downloaded and installed.
";
+ }
+
+ my $proxy_file = get_apache_proxy_file();
+ my $www_name = '';
+
+ if( ( $osinfo{'real_os_type'} =~ /centos/i) or #CentOS
+ ( $osinfo{'real_os_type'} =~ /rocky/i) or #Rocky
+ ( $osinfo{'real_os_type'} =~ /alma/i) or #Alma
+ ($osinfo{'real_os_type'} =~ /fedora/i) ){ #Fedora
+ $www_name = 'httpd';
+
+ }elsif( ($osinfo{'real_os_type'} =~ /ubuntu/i) or
+ ($osinfo{'real_os_type'} =~ /debian/i) ){ #ubuntu or debian
+ $www_name = 'apache2';
+ }
+
+ @pinfo = software::package_info($www_name, undef, );
+ if(!@pinfo){
+ print "Warning: $www_name is not installed. Install it manually or ".
+ "click here to have it downloaded and installed.
";
+ }
+
+ if(! -f $proxy_file){
+ print "Apache default proxy is not configured. ".
+ "click here
";
+ }
+
+ if(@pinfo){
+ if( ($osinfo{'real_os_type'} =~ /alma/i) or #Alma
+ ($osinfo{'real_os_type'} =~ /rocky/i) ){ #Rocky
+
+ local $out = &execute_command("sestatus", undef, \$cmd_out, \$cmd_err, 0, 0);
+ if($cmd_out =~ /SELinux status:\s+enabled/i){
+ my $se_utils_pkg = 'policycoreutils-python-utils';
+ @pinfo = software::package_info($se_utils_pkg, undef, );
+ if(!@pinfo){
+ print "Warning: $se_utils_pkg is not installed. Install it manually or ".
+ "click here to have it downloaded and installed.
";
+ }else{
+ my $tomcat_home = get_catalina_home();
+ local $out = &execute_command("ls -lZ $tomcat_home/bin/startup.sh", undef, \$cmd_out, \$cmd_err, 0, 0);
+ if($cmd_out !~ /:bin_t:/i){
+ printf "SELinux is enabled. Configured it from ".
+ "here.
";
+ }
+ }
+ }
+ }
+ }
+ print 'If you don\'t see any warning above, you can complete setup from '.
+ "here
";
+}
+
+#Remove all setup files
+sub setup_cleanup{
+ my $file = $module_root_directory.'/setup.cgi';
+ print "Completing Installation";
+ &unlink_file($file);
+ print &js_redirect("index.cgi");
+}
+
+
+&ui_print_header(undef, $text{'setup_title'}, "");
+
+if($ENV{'CONTENT_TYPE'} =~ /boundary=(.*)$/) {
+ &ReadParseMime();
+}else {
+ &ReadParse(); $no_upload = 1;
+}
+
+my $mode = $in{'mode'} || "checks";
+
+if($mode eq "checks"){ setup_checks();
+ &ui_print_footer('', $text{'index_return'});
+ exit 0;
+}elsif($mode eq "cleanup"){ setup_cleanup();
+ &ui_print_footer('', $text{'index_return'});
+ exit 0;
+}elsif($mode eq "tomcat_install_form"){ select_tomcat_archive();
+}elsif($mode eq "tomcat_install"){ install_tomcat_from_archive();
+}elsif($mode eq "tomcat_upgrade"){ upgrade_tomcat_from_archive();
+}elsif($mode eq "setup_apache_proxy"){ setup_default_apache_proxy();
+}elsif($mode eq "setup_selinux"){ setup_selinux();
+}else{
+ print "Error: Invalid setup mode\n";
+}
+
+&ui_print_footer('setup.cgi', $text{'setup_title'});
diff --git a/start.cgi b/start.cgi
new file mode 100644
index 0000000..4a94b3c
--- /dev/null
+++ b/start.cgi
@@ -0,0 +1,15 @@
+#!/usr/bin/perl
+# start.cgi
+# Start the tomcat daemon
+
+require './tomcat-lib.pl';
+&ReadParse();
+&error_setup($text{'start_err'});
+my ($rc, $err) = tomcat_service_ctl('start');
+if ($rc != 0){
+ &ui_print_header(undef, $text{'index_title'}, "");
+ &error($err);
+ &ui_print_footer("", $text{'index_return'});
+ exit;
+}
+&redirect("");
diff --git a/stop.cgi b/stop.cgi
new file mode 100644
index 0000000..a5d1ad1
--- /dev/null
+++ b/stop.cgi
@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+&ReadParse();
+&error_setup($text{'stop_err'});
+my ($rc, $err) = tomcat_service_ctl('stop');
+if ($rc != 0){
+ &ui_print_header(undef, $text{'index_title'}, "");
+ &error($err);
+ &ui_print_footer("", $text{'index_return'});
+ exit;
+}
+&redirect("");
+
diff --git a/tomcat-lib.pl b/tomcat-lib.pl
new file mode 100644
index 0000000..770703b
--- /dev/null
+++ b/tomcat-lib.pl
@@ -0,0 +1,408 @@
+=head1 tomcat-lib.pl
+
+Functions for managing Tomcat server configuration files.
+
+ foreign_require("tomcat", "tomcat-lib.pl");
+ @sites = tomcat::list_tomcat_websites()
+
+=cut
+
+BEGIN { push(@INC, ".."); };
+use WebminCore;
+use File::Copy;
+init_config();
+
+sub get_tomcat_config
+{
+my $lref = &read_file_lines($config{'foobar_conf'});
+my @rv;
+my $lnum = 0;
+foreach my $line (@$lref) {
+ my ($n, $v) = split(/\s+/, $line, 2);
+ if ($n) {
+ push(@rv, { 'name' => $n, 'value' => $v, 'line' => $lnum });
+ }
+ $lnum++;
+ }
+return @rv;
+}
+
+# Returns a hash containing the version type, number and full version
+sub get_catalina_version
+{
+ local %version;
+ local $catalina_home = get_catalina_home();
+ local $out = &backquote_command($catalina_home."/bin/catalina.sh version 2>&1 '.$k.': '.$1."";
+ }
+ }
+ }
+
+ $running = $out >> 8;
+ if($ctl eq 'status'){
+ # swap running values, to match init.d logic
+ if($running == 0){
+ $running = 1;
+ }elsif($running > 0){
+ $running = 0;
+ }
+ }
+
+ }else{
+ local $out = &execute_command("/etc/init.d/tomcat $ctl", undef, \$cmd_out, \$cmd_err, 0, 0);
+
+ $running = $out >> 8;
+ if($cmd_err ne ""){
+ $status = $cmd_err;
+ }else{
+ $status = $cmd_out;
+ }
+ }
+
+ return ($running, $status);
+}
+
+sub get_all_war_infos(){
+ my $catalina_home = get_catalina_home();
+ opendir(DIR, $catalina_home.'/webapps') or die $!;
+ my @dirs
+ = grep {
+ ! /^\./ # Doesn't begins with a period
+ && -d "$catalina_home/webapps/$_" # and is a directory
+ } readdir(DIR);
+ closedir(DIR);
+
+ return sort @dirs;
+}
+
+sub file_basename
+{
+ my $rv = $_[0];
+ $rv =~ s/^.*[\/\\]//;
+ return $rv;
+}
+
+sub sort_version {
+ my @A = split(/\./, $a);
+ my @B = split(/\./, $b);
+ # a sort subroutine, expect $a and $b
+ for(my $i=0; $i < 3; $i++){
+ if ($A[$i] < $B[$i]) { return -1 } elsif ($A[$i] > $B[$i]) { return 1 }
+ }
+ return 0;
+}
+
+sub latest_tomcat_version{
+ my $tomcat_ver = $_[0];
+ my %version;
+ if(-f "$module_config_directory/version"){
+ read_file_cached("$module_config_directory/version", \%version);
+
+ if( $version{'updated'} >= (time() - 86400)){ #if last update was less than a day ago
+ return $version{'latest'} if ($version{'latest'} ne '0.0.0');
+ }
+ }
+
+ my $major = (split /\./, $tomcat_ver)[0];
+ my @all_ver = &major_tomcat_versions($major);
+ my $latest_ver = $all_ver[-1];
+
+ #renew the updated timestamp and latest version
+ $version{'updated'} = time();
+ $version{'latest'} = $latest_ver;
+ &write_file("$module_config_directory/version", \%version);
+
+ return $latest_ver;
+}
+
+sub installed_tomcat_version(){
+ my %os_env;
+ read_env_file('/etc/environment', \%os_env);
+
+ if($os_env{'CATALINA_HOME'}){
+ $os_env{'CATALINA_HOME'} =~ /\/home\/tomcat\/apache-tomcat-([0-9\.]+)/;
+ return $1;
+ }else{
+ return undef;
+ }
+}
+
+sub get_catalina_home(){
+ my $tomcat_ver = installed_tomcat_version();
+ return "/home/tomcat/apache-tomcat-$tomcat_ver";
+}
+
+sub download_and_install{
+ my $tomcat_ver = $_[0];
+ my $major = (split /\./, $tomcat_ver)[0];
+
+ #download tomcat archive
+ $in{'url'} = "https://archive.apache.org/dist/tomcat/tomcat-$major/v$tomcat_ver/bin/apache-tomcat-$tomcat_ver.tar.gz";
+ $in{'source'} = 2;
+
+ my $tmpfile = process_file_source();
+
+ #extract tomcat archive
+ my $cmd_out='';
+ my $cmd_err='';
+ print "
Extracting to /home/tomcat/apache-tomcat-$tomcat_ver/ ...
";
+ local $out = &execute_command("tar -x -v --overwrite -f \"$tmpfile\" -C/home/tomcat/", undef, \$cmd_out, \$cmd_err, 0, 0);
+
+ if($cmd_err ne ""){
+ &error("Error: tar: $cmd_err");
+ }else{
+ $cmd_out = s/\n/
/g;
+ print &html_escape($cmd_out);
+ print "Done
";
+ }
+
+ #folder is created after tomcat is started, but we need it now
+ &make_dir("/home/tomcat/apache-tomcat-$tomcat_ver/conf/Catalina/localhost/", 0755, 1);
+
+ open(my $fh, '>', "/home/tomcat/apache-tomcat-$tomcat_ver/conf/Catalina/localhost/manager.xml") or die "open:$!";
+ print $fh <
+
+
+EOF
+ close $fh;
+
+ #&set_ownership_permissions('tomcat','tomcat', undef, "/home/tomcat/apache-tomcat-$tomcat_ver/");
+ &execute_command("chown -R tomcat:tomcat /home/tomcat/apache-tomcat-$tomcat_ver");
+
+ return $tomcat_ver;
+}
+
+sub setup_catalina_env{
+ my $tomcat_ver = $_[0];
+
+ my %os_env;
+
+ print "
Setting CATALINA environment...";
+
+ read_env_file('/etc/environment', \%os_env);
+ $os_env{'CATALINA_HOME'} = "/home/tomcat/apache-tomcat-$tomcat_ver/";
+ $os_env{'CATALINA_BASE'} = "/home/tomcat/apache-tomcat-$tomcat_ver/";
+ write_env_file('/etc/environment', \%os_env, 0);
+
+ open(my $fh, '>>', "/home/tomcat/apache-tomcat-$tomcat_ver/bin/setenv.sh") or die "open:$!";
+ print $fh "CATALINA_PID=\"/home/tomcat/apache-tomcat-$tomcat_ver/temp/tomcat.pid\"\n";
+ close $fh;
+}
+
+sub get_installed_libs{
+ opendir(DIR, $module_config_directory) or die $!;
+ my @lib_lists
+ = grep {
+ /^lib_[a-z0-9\.\-_\s]+\.list$/i #
+ && -f "$module_config_directory/$_" # and is a file
+ } readdir(DIR);
+ closedir(DIR);
+
+ return sort @lib_lists;
+}
+
+sub process_file_source{
+ my $file = '';
+
+ if (($in{'source'} == 0) && ($in{'file'} ne "")) { # from local file
+ &error_setup(&text('source_err0', $in{'file'}));
+ $file = $in{'file'};
+ if (!(-r $file)){
+ &error($text{'source_err0'});
+ }
+
+ }elsif (($in{'source'} == 1) && ($in{'upload_filename'} ne "")) { # from uploaded file
+ &error_setup($text{'source_err1'});
+ $need_unlink = 1;
+ if ($no_upload) {
+ &error($text{'source_err1.2'});
+ }
+ $file = transname(file_basename($in{'upload_filename'}));
+ open(MOD, ">$file");
+ binmode(MOD);
+ print MOD $in{'upload'};
+ close(MOD);
+
+ }elsif ($in{'source'} == 2 and $in{'url'} ne '') { # from ftp or http url (possible third-party)
+ $url = $in{'url'};
+ &error_setup(&text('source_err2', $url));
+ $file = &transname(file_basename($url));
+ $need_unlink = 1;
+ my $error;
+ $progress_callback_url = $url;
+ if ($url =~ /^(http|https):\/\/([^\/]+)(\/.*)$/) {
+ $ssl = $1 eq 'https';
+ $host = $2; $page = $3; $port = $ssl ? 443 : 80;
+ if ($host =~ /^(.*):(\d+)$/) { $host = $1; $port = $2; }
+ my %cookie_headers = ('Cookie'=>'oraclelicense=accept-securebackup-cookie');
+ &http_download($host, $port, $page, $file, \$error,
+ \&progress_callback, $ssl, undef, undef, 0, 0, 1, \%cookie_headers);
+ } elsif (
+ $url =~ /^ftp:\/\/([^\/]+)(:21)?\/(.*)$/) {
+ $host = $1; $ffile = $3;
+ &ftp_download($host, $ffile, $file, \$error, \&progress_callback);
+ }else {
+ &error($text{'source_err3'});
+ }
+ &error($error) if ($error);
+ }
+ return $file;
+}
+
+sub unzip_file{
+ my $file = $_[0];
+ my @suffixlist = ('.zip');
+ ($lib_name,$path,$lib_suffix) = fileparse($file,@suffixlist);
+
+ my $unzip_dir = "/tmp/.webmin/$lib_name";
+
+ #if old temp extension dir exist, remove it
+ #if( -d $unzip_dir and rmtree($unzip_dir) == 0){
+ # &error("Failed to remove temp extension dir");
+ # &ui_print_footer("", $text{'index_return'});
+ # exit;
+ #}
+ &make_dir($unzip_dir, 0754, 1);
+
+ my $unzip_out;
+ my $unzip_err;
+ print "
Unzipping to $unzip_dir ...
";
+ local $out = &execute_command("unzip -u \"$file\" -d \"$unzip_dir\"", undef, \$unzip_out, \$unzip_err, 0, 0);
+
+ if($unzip_err){
+ &error("Error: unzip: $unzip_err");
+ }else{
+ $unzip_out = s/\r\n/
/g;
+ print &html_escape($unzip_out);
+ }
+ return $unzip_dir;
+}
+
+sub get_tomcat_major_versions(){
+ my @majors = ();
+ my $url = "https://archive.apache.org/dist/tomcat/";
+ &error_setup(&text('install_err3', $url));
+ my $error = '';
+ my $tmpfile = &transname('tomcat.html');
+
+
+ &http_download('archive.apache.org', 80, "/dist/tomcat/", $tmpfile, \$error);
+ if($error){
+ error($error);
+ }
+
+ my @latest_versions;
+ open(my $fh, '<', $tmpfile) or die "open:$!";
+ while(my $line = <$fh>){
+ if($line =~ /tomcat\-[0-9\.]+\/<\/a>/){
+ push(@majors, $1);
+ }
+ }
+ close $fh;
+
+ return reverse sort sort_version @majors;
+}
+
+sub major_tomcat_versions{
+ my $major = $_[0]; #Tomcat major version 6,7,8,9
+
+ my $url = "https://archive.apache.org/dist/tomcat/tomcat-$major/";
+ &error_setup(&text('install_err3', $url));
+ my $error = '';
+ my $tmpfile = &transname('tomcat.html');
+
+
+ &http_download('archive.apache.org', 80, "/dist/tomcat/tomcat-$major/", $tmpfile, \$error);
+ if($error){
+ error($error);
+ }
+
+ my @latest_versions;
+ open(my $fh, '<', $tmpfile) or die "open:$!";
+ while(my $line = <$fh>){
+ if($line =~ /v[0-9\.]+\/<\/a>/){
+ push(@latest_versions, $1);
+ }
+ }
+ close $fh;
+
+ return sort sort_version @latest_versions;
+}
+
+sub setup_tomcat_service{
+ my $tomcat_ver = $_[0];
+ if (&has_command('systemctl')) {
+
+ copy_source_dest("$module_root_directory/tomcat.service", '/etc/systemd/system/tomcat.service');
+
+ my $ln = 0;
+ $lref = read_file_lines('/etc/systemd/system/tomcat.service');
+ foreach $line (@$lref){
+ chomp $line;
+ if($line =~ /\$TOMCAT_VER/){ #if its a section start
+ $line =~ s/\$TOMCAT_VER/$tomcat_ver/;
+ @{$lref}[$ln] = $line;
+ }elsif($line =~ /\$CATALINA_HOME/){
+ $line =~ s/\$CATALINA_HOME/\/home\/tomcat\/apache-tomcat-$tomcat_ver/;
+ @{$lref}[$ln] = $line;
+ }
+ $ln=$ln+1;
+ }
+ &flush_file_lines('/etc/systemd/system/tomcat.service');
+
+ &set_ownership_permissions('root','root', 0555, "/etc/systemd/system/tomcat.service");
+
+ &backquote_command("systemctl daemon-reload", undef, \$cmd_out, \$cmd_err, 0, 0);
+ }else{
+ copy_source_dest("$module_root_directory/tomcat.init", '/etc/init.d/tomcat');
+ &set_ownership_permissions('root','root', 0555, "/etc/init.d/tomcat");
+ }
+ print "
Setting Tomcat service ...";
+}
+
+sub upgrade_available(){
+ my $tomcat_ver = installed_tomcat_version();
+ my $latest_ver = latest_tomcat_version($tomcat_ver);
+
+ my @versions = ($tomcat_ver, $latest_ver);
+ @versions = sort sort_version @versions;
+
+ if($versions[0] eq $tomcat_ver){
+ return '';
+ }else {
+ return $latest_ver;
+ }
+}
\ No newline at end of file
diff --git a/tomcat.init b/tomcat.init
new file mode 100644
index 0000000..4276ed1
--- /dev/null
+++ b/tomcat.init
@@ -0,0 +1,57 @@
+#!/bin/bash
+### BEGIN INIT INFO
+# Provides: tomcat
+# Required-Start: $network
+# Required-Stop: $network
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Start/Stop Tomcat server
+### END INIT INFO
+
+# Source function library.
+. /etc/environment; #Catalina variables
+. $CATALINA_HOME/bin/setenv.sh
+
+RETVAL=$?
+
+function start(){
+ echo "Starting Tomcat"
+ /bin/su - tomcat $CATALINA_HOME/bin/startup.sh
+ RETVAL=$?
+}
+
+function stop(){
+ echo "Stopping Tomcat"
+ /bin/su - tomcat -c "$CATALINA_HOME/bin/shutdown.sh 60 -force"
+ RETVAL=$?
+}
+
+case "$1" in
+ start)
+ start;
+ ;;
+ stop)
+ stop;
+ ;;
+ restart)
+ echo "Restarting Tomcat"
+ stop;
+ start;
+ ;;
+ status)
+
+ if [ -f "${CATALINA_PID}" ]; then
+ TOMCAT_PID=$(cat "${CATALINA_PID}")
+ echo "Tomcat is running with PID ${TOMCAT_PID}";
+ RETVAL=1
+ else
+ echo "Tomcat is not running";
+ RETVAL=0
+ fi
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|restart|status}"
+ exit 1
+ ;;
+esac
+exit $RETVAL
diff --git a/tomcat.service b/tomcat.service
new file mode 100644
index 0000000..70a4765
--- /dev/null
+++ b/tomcat.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=Tomcat $TOMCAT_VER
+After=multi-user.target
+
+[Service]
+User=tomcat
+Group=tomcat
+
+WorkingDirectory=$CATALINA_HOME
+Type=forking
+Restart=always
+
+EnvironmentFile=/etc/environment
+
+ExecStart=$CATALINA_HOME/bin/startup.sh
+ExecStop=$CATALINA_HOME/bin/shutdown.sh 60 -force
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/tomcat_upgrade.cgi b/tomcat_upgrade.cgi
new file mode 100644
index 0000000..debf6a0
--- /dev/null
+++ b/tomcat_upgrade.cgi
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+require './tomcat-lib.pl';
+
+sub migrate_settings_and_apps{
+ my $old_ver = $_[0];
+ my $new_ver = $_[1];
+ my $apps_ref = $_[2];
+
+ #Copy Settings
+ my @files = ('bin/setenv.sh', 'conf/tomcat-users.xml');
+ foreach my $file (@files){
+ if( -f "/home/tomcat/apache-tomcat-$old_ver/$file"){
+ copy_source_dest("/home/tomcat/apache-tomcat-$old_ver/$file",
+ "/home/tomcat/apache-tomcat-$new_ver/$file");
+ print "Copying $file to /home/tomcat/apache-tomcat-$new_ver/$file
";
+ }
+ }
+
+ #make a list of installed apps
+ my @exclude_apps = ('docs', 'examples', 'host-manager', 'manager', 'ROOT');
+
+ #move apps
+ print "Copying apps ...
";
+ foreach my $app (@$apps_ref){
+
+ next if grep( /^$app$/, @exclude_apps);
+
+ if(!copy_source_dest( "/home/tomcat/apache-tomcat-$old_ver/webapps/$app",
+ "/home/tomcat/apache-tomcat-$new_ver/webapps/$app")){
+ &error("Error: Can't copy $app: $!");
+ }else{
+ print "$app
";
+ }
+
+ if(-f "/home/tomcat/apache-tomcat-$old_ver/webapps/$app.war"){
+ if(!copy_source_dest( "/home/tomcat/apache-tomcat-$old_ver/webapps/$app.war",
+ "/home/tomcat/apache-tomcat-$new_ver/webapps/$app.war")){
+ &error("Error: Can't copy $app.war: $!");
+ }else{
+ print "$app.war
";
+ }
+ }
+ }
+}
+
+sub upgrade_tomcat_from_archive{
+
+ my $install_ver = installed_tomcat_version();
+ my $latest_ver = latest_tomcat_version($install_ver);
+
+ my @installed_apps = get_all_war_infos();
+
+ #add_tomcat_user();
+ download_and_install($latest_ver);
+
+ tomcat_service_ctl('stop');
+
+ setup_catalina_env($latest_ver);
+ #setup_tomcat_users($latest_ver);
+ setup_tomcat_service($latest_ver);
+
+ migrate_settings_and_apps($install_ver, $latest_ver, \@installed_apps);
+
+ print("Update done, starting new Tomcat ".$latest_ver);
+ tomcat_service_ctl('start');
+}
+
+
+&ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1);
+&ReadParse();
+&error_setup($text{'start_err'});
+$err = upgrade_tomcat_from_archive();
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/uninstall_java.cgi b/uninstall_java.cgi
new file mode 100644
index 0000000..4bbc2fb
--- /dev/null
+++ b/uninstall_java.cgi
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+
+use File::Path 'rmtree';
+
+require './tomcat-lib.pl';
+require './java-lib.pl';
+require '../webmin/webmin-lib.pl'; #For OS Fetection
+&ReadParse();
+
+&error_setup($text{'delete_err'});
+
+my $jdk_name = $in{'inst_jdk'};
+$jdk_name || &error($text{'delete_enone'});
+
+my $jdk_dir = get_jdk_dir_by_name($jdk_name);
+my $def_jdk = is_default_jdk($jdk_dir);
+
+if(($def_jdk == 1) and ($in{'rm_def_jdk'} == 0)){
+
+ &ui_print_header(undef, $text{'java_tabuninstall'}, "");
+ print "Uninstall stopped, since $jdk_dir is default JDK.
";
+
+}else{
+
+ if($jdk_name =~ /.*openjdk.*/){
+ &redirect("/software/search.cgi?search=$jdk_name");
+ return;
+ }
+
+ &ui_print_header(undef, $text{'delete_title'}, "");
+
+ print "Removing $jdk_dir...
";
+
+ if($def_jdk == 1){
+ unset_default_java($jdk_dir);
+ }
+
+ if( -d $jdk_dir){
+ rmtree($jdk_dir);
+ }
+
+ print "
Uninstall of $jdk_name is successful
";
+}
+
+&ui_print_footer("", $text{'index_return'});
diff --git a/uninstall_libs.cgi b/uninstall_libs.cgi
new file mode 100644
index 0000000..111d081
--- /dev/null
+++ b/uninstall_libs.cgi
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+
+use File::Path 'rmtree';
+
+require './tomcat-lib.pl';
+&ReadParse();
+
+sub uninstall_lib{
+ my $lib_name = $_[0];
+
+ #get extension files
+ my $lib_list = "$module_config_directory/lib_$lib_name.list";
+ my %lib_files;
+ &read_file($lib_list, \%lib_files);
+
+ foreach $j (keys %lib_files){
+ if( -e $lib_files{$j} or -l $lib_files{$j}){
+ &unlink_file($lib_files{$j});
+ print "$lib_files{$j}
";
+ }elsif( -d $lib_files{$j}){
+ rmtree($lib_files{$j});
+ }else{
+ print "Listed jar $j doesn't exist!
";
+ }
+ }
+ &unlink_file($lib_list);
+
+ print "
Uninstall of $lib_name is successful
";
+}
+
+&error_setup($text{'delete_err'});
+&ui_print_header(undef, $text{'libs_uninstall_title'}, "");
+
+@libs = split(/\0/, $in{'inst_lib'});
+@libs || &error($text{'delete_enone'});
+
+tomcat_service_ctl('stop');
+
+#delete each of the specified directories
+my $catalina_home = get_catalina_home();
+foreach $lib (@libs) {
+ print "Removing $lib
";
+ uninstall_lib($lib);
+}
+
+tomcat_service_ctl('start');
+
+&ui_print_footer("", $text{'index_return'});