%PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
Server IP : 49.231.201.246 / Your IP : 216.73.216.149 Web Server : Apache/2.4.18 (Ubuntu) System : User : root ( 0) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : exec,passthru,mail,shell_exec,system,proc_open,popen,ini_alter,dl,proc_close,curl_exec,curl_multi_exec,readfile,parse_ini_file,escapeshellarg,escapeshellcmd,show_source,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,mail,php_uname,phpinfo MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/webmin/bin/ |
Upload File : |
#!/usr/bin/env perl # patch - Apply a patch to Webmin core or its modules from GitHub or a local file use strict; use warnings; use 5.010; use Getopt::Long qw(:config permute pass_through); use Pod::Usage; use File::Basename; use Cwd qw(cwd); my %opt; GetOptions( 'help|h' => \$opt{'help'}, 'config|c=s' => \$opt{'config'}, ); pod2usage(0) if ($opt{'help'}); # Get Webmin path my $path = cwd; my $lib = "web-lib-funcs.pl"; if (!-r "$path/$lib") { $path = dirname(dirname($0)); if (!-r "$path/$lib") { $path = $path = Cwd::realpath('..'); } } # Init core my $config_dir = $opt{'config'} || '/etc/webmin'; $ENV{'WEBMIN_CONFIG'} = $config_dir; push(@INC, $path); eval 'use WebminCore'; init_config(); # Check if curl is installed if (!has_command('curl')) { print "\"curl\" command is not installed\n"; exit 1; } # Check if git is installed if (!has_command('patch')) { if (!has_command('git')) { print "Neither \"patch\" nor \"git\" commands are installed\n"; exit 1; } } # Get patch URL or file my $patch = $ARGV[0]; # Params check if (!$patch) { pod2usage(0); exit 1; } # Patch check if ($patch !~ /^https?:\/\//) { if (!-r $patch) { print "Patch file $patch doesn't exist\n"; exit 1; } } elsif ($patch =~ /^https?:\/\/(github|gitlab)\.com/ && $patch !~ /\.patch$/ && $patch !~ /\.diff$/) { $patch .= '.patch'; } # Parse module name from URL my $module = ""; if ($patch =~ m{ (?| # GitHub/GitLab commit URL https://(?:github|gitlab)\.com/([^/]+)/([^/]+)/commit/([^/]+) | # GitHub pull request commit URL https://github\.com/([^/]+)/([^/]+)/pull/\d+/commits/([^/]+) | # GitLab merge request URL with commit ID https://gitlab\.com/([^/]+)/([^/]+)/-/merge_requests/\d+/diffs\?commit_id=([^&]+) | # GitHub raw URL https://raw\.githubusercontent\.com/([^/]+)/([^/]+)/([^/]+)/(.+) | # GitLab raw URL https://gitlab\.com/([^/]+)/([^/]+)/-/raw/([^/]+)/(.+) ) }x) { $module = $2; $module = "" if ($2 eq 'webmin'); # Special handling for some modules $module = $module =~ /^virtualmin-pro$/ ? 'virtual-server/pro' : 'virtual-server' if $module =~ /^virtualmin-(gpl|pro)$/; } # Check if module exists if (!-d "$path/$module") { print "Module '$module' doesn't exist\n"; exit 1; } # Prepare patch command my $cmd; my $direct; my $filename; my $dir; my $output; # If raw URL given, try to download and just replace the whole file if ($patch =~ m{^https?://raw\.githubusercontent\.com/} || $patch =~ m{^https?://gitlab\.com/.*?/-/raw/}) { if ($patch =~ m{ .*? # Non-greedy match of everything up to the branch name (?:master|main)/ # Branches name (.*/)? # Capture all directories after the branch (group 1) ([^/]+)$ # Filename (group 2) }x) { $direct = 1; $dir = $1 // ""; $filename = $2; } else { print "Patch failed: Can't parse file name from URL\n"; exit 1; } my $cd = "$path/$module/$dir"; $cd =~ s|/+|/|g; chdir "$cd"; $cmd = "curl -w \"%{http_code}\\n\" -s -o $filename @{[quotemeta($patch)]}"; } # Download command elsif ($patch =~ /^https?:\/\//) { $cmd = "curl -L -s @{[quotemeta($patch)]}"; chdir "$path/$module"; } # Local file else { $cmd = "cat @{[quotemeta($patch)]}"; } # Download file directly if ($direct) { $output = `$cmd 2>&1`; if ($output != 200) { print "Patch failed: Cannot download '$filename'. HTTP status code: $output\n"; exit 1; } } # Apply patch using patch command elsif (has_command('patch')) { $output = `$cmd 2>&1 | patch -p1 --verbose 2>&1`; if ($output !~ /succeeded/i) { print "Patch failed: $output\n"; exit 1; } } # Apply patch using git command else { $output = `$cmd 2>&1 | git apply --reject --verbose --whitespace=fix 2>&1`; if ($output !~ /applied patch.*?cleanly/i) { print "Patch failed: $output\n"; exit 1; } } # Print results if ($direct) { print "File replaced successfully:\n"; if ($dir) { $dir = $dir ? "/$dir" : ""; $dir =~ s|^/||; } print " $dir$filename\n"; system("sed -i '1s|^#!/usr/local/bin/perl|#!/usr/bin/perl|' \"$filename\""); } else { print "Patch applied successfully to:\n"; print " $1\n" while $output =~ /^(?|Applied patch\s+(\S+)|patching file\s+(\S+))/mg; } # Restart Webmin system("$config_dir/restart"); =pod =head1 NAME patch =head1 DESCRIPTION Apply a patch to Webmin core or its modules from GitHub/GitLab, a local file, or by downloading and replacing the entire file from a raw URL. =head1 SYNOPSIS webmin patch patch-url/file =head1 OPTIONS =over =item --help, -h Give this help list. =item --config, -c Specify the full path to the Webmin configuration directory. Defaults to C</etc/webmin> Examples of usage: Apply a patch from a URL. - webmin patch https://github.com/webmin/webmin/commit/e6a2bb15b0.patch - webmin patch https://github.com/virtualmin/virtualmin-gpl/commit/f4433153d Apply a patch from local file. - cd /usr/libexec/webmin/virtual-server/pro && webmin patch /root/virtualmin-pro/patches/patch-1.patch =back =head1 LICENSE AND COPYRIGHT Copyright 2024 Ilia Ross <ilia@virtualmin.com>