#!/usr/bin/env perl use POSIX; use Term::ReadLine; use IO::File; use IO::Socket; use IO::Socket::SSL; use HTTP::Tiny; sub bprint{ if ( defined($_[0]) and length($_[0]) > 0 ){ print( "\e[94m[MirrorlistUpdater] " . $_[0] . "\e[0m\n" ); } } sub gprint{ if ( defined($_[0]) and length($_[0]) > 0 ){ print( "\e[32m[MirrorlistUpdater] " . $_[0] . "\e[0m\n" ); } } sub rprint{ if ( defined($_[0]) and length($_[0]) > 0 ){ print( "\e[31m[MirrorlistUpdater] " . $_[0] . "\e[0m\n" ); } } my $url_template = "https://archlinux.org/mirrorlist/?country={country_code}&protocol={http_proto}&ip_version={ip_ver}"; my $term_prompt = Term::ReadLine->new( "term_prompt" ); my $cc_str = uc( $term_prompt->readline("\e[95m2 character country code for mirror servers:\e[0m ") ); if ( not defined($cc_str) or length($cc_str) <= 0 ){ rprint( "Error: no mirror server country code given" ); exit( 0 ); } gprint( "Mirror servers country set to " . $cc_str ); my $mirror_proto = $term_prompt->readline( "\e[95mProtocol (https/http):\e[0m " ); if ( not defined($mirror_proto) or length($mirror_proto) <= 0 or $mirror_proto ne "https" and $mirror_proto ne "http" ){ rprint( "Error: no valid protocol given" ); exit( 0 ); } gprint( "Protocol set to " . $mirror_proto ); my $ip_proto_ver = "4"; my $ip_proto = $term_prompt->readline( "\e[95mProtocol version (ipv4/ipv6):\e[0m " ); if ( not defined($ip_proto) or length($ip_proto) <= 0 or $ip_proto ne "ipv4" and $ip_proto ne "ipv6" ){ rprint( "Error: no valid protocol version given" ); exit( 0 ); } if ( $ip_proto eq "ipv4" ){ $ip_proto_ver = "4"; } elsif ( $ip_proto eq "ipv6" ){ $ip_proto_ver = "6"; } else { $ip_proto_ver = "4"; } gprint( "Protocol version set to ipv" . $ip_proto_ver ); $url_template =~ s/{country_code}/$cc_str/g; $url_template =~ s/{http_proto}/$mirror_proto/g; $url_template =~ s/{ip_ver}/$ip_proto_ver/g; my $https_obj = HTTP::Tiny->new( "agent" => "MirrorlistUpdater" ) or die "Error: failed to initialize HTTPS"; my $https_req = $https_obj->request( "GET", $url_template, { "headers" => { "Accept" => "*/*", "Pragma" => "no-cache" } } ) or die "Error: failed to make HTTPS request"; if ( $https_req->{"success"} ){ my $gen_mirrors_config = $https_req->{"content"} =~ s/#Server/Server/gr; if ( defined($gen_mirrors_config) and length($gen_mirrors_config) > 0 ){ gprint( "Generated configuration:\n" . $gen_mirrors_config ); my $save_opt = $term_prompt->readline( "\e[95mDo you want to save the configuration shown above? (y/n):\e[0m " ); if ( not defined($save_opt) or length($save_opt) <= 0 or $save_opt ne "y" and $save_opt ne "n" ){ rprint( "No valid option given" ); if ( defined($save_opt) ){ undef $save_opt; } if ( defined($gen_mirrors_config) ){ undef $gen_mirrors_config; } exit( 0 ); } if ( $save_opt eq "y" ){ my $mirrorlist_file = IO::File->new( "/etc/pacman.d/mirrorlist", "w" ) or die "Error: failed to open /etc/pacman.d/mirrorlist for writing"; syswrite( $mirrorlist_file, $gen_mirrors_config ) or die "Error: failed to write to /etc/pacman.d/mirrorlist"; undef $mirrorlist_file; gprint( "Success, configuration written to /etc/pacman.d/mirrorlist" ); } undef $save_opt; undef $gen_mirrors_config; } else { rprint( "Error: failed to generate mirrorlist" ); if ( defined($gen_mirrors_config) ){ undef $gen_mirrors_config; } } } else { rprint( "Error: HTTPS request failed (" . $https_req->{"status"} . ": " . $https_req->{"reason"} . ")" ); } undef $https_req; undef $https; undef $ip_proto; undef $ip_proto_ver; undef $cc_str; undef $mirror_proto; undef $term_prompt; undef $url_template; exit( 0 );