#!/usr/bin/env perl use Digest::SHA qw(sha256_hex); use JSON; use POSIX qw(strftime); use Time::Piece; my $LINK = "1~{0} /~{0} tilde.club 70"; sub compare_gophermaps { my ($user, $cache) = @_; my $user_path = "/home/$user/public_gopher/gophermap"; my $current_time = time; my $time_threshold = 259200; if (! -e $user_path) { # Ignore user if public_gopher folder is not found return; } if (exists $cache->{$user} && $current_time - $cache->{$user} < $time_threshold) { print $LINK =~ s/{0}/$user/r; return; } my $skel_path = "/etc/skel/public_gopher/gophermap"; open my $skel_fh, '<', $skel_path or die "Unable to open file: $!"; my $skel_hash = sha256_hex(do { local $/; <$skel_fh> }); close $skel_fh; eval { open my $user_fh, '<', $user_path or die "Unable to open file: $!"; my $user_hash = sha256_hex(do { local $/; <$user_fh> }); close $user_fh; if ($user_hash ne $skel_hash) { $cache->{$user} = $current_time; print $LINK =~ s/{0}/$user/r; } else { delete $cache->{$user} if exists $cache->{$user}; } } or do { # Ignore exceptions and treat the gophermap file as one to not list delete $cache->{$user} if exists $cache->{$user}; }; } sub main { my $cache_path = "cache.json"; # Load the cache from disk if it exists, otherwise create a new cache my $cache = (-e $cache_path) ? decode_json(do { local $/; open my $fh, '<', $cache_path or die "Unable to open file: $!"; <$fh> }) : {}; opendir my $home_dir, '/home' or die "Unable to open directory: $!"; foreach my $user (sort { lc $a cmp lc $b } readdir $home_dir) { compare_gophermaps($user, $cache); } closedir $home_dir; # Save the cache to disk open my $cache_fh, '>', $cache_path or die "Unable to open file: $!"; print $cache_fh to_json($cache); close $cache_fh; }