#!/usr/bin/env perl # # pe was written by Omar Polo and is placed in the # public domain. The author hereby disclaims copyright to this source # code. use open ":std", ":encoding(UTF-8)"; use strict; use warnings; use v5.32; use Digest::SHA; use Encode qw(encode); use IO::Poll qw(POLLOUT); use SMArc qw(parse); my $jobs = $ENV{'MAKE_JOBS'} // 1; my $csumdir = $ENV{'CSUMDIR'}; die '$CSUMDIR undefined' unless defined $csumdir; my $poll = IO::Poll->new(); for (1..$jobs) { open(my $kid, '|-', 'mexp') or die "can't exec mexp: $!"; $poll->mask($kid => POLLOUT); } # get current thread checksum sub thrsum { my $sha = Digest::SHA->new(256); $sha->add(encode('UTF-8', $_)) for @_; return $sha->hexdigest; } # get stored thread checksum sub oldsum { my $tid = shift; open my $fh, '<', "$csumdir/$tid" or return ""; my $sum = <$fh>; chomp $sum; return $sum; } # save thread checksum sub savesum { my ($tid, $sum) = @_; open my $fh, '>', "$csumdir/$tid" or die "can't open checksum file $csumdir/$tid: $!"; say $fh $sum; close $fh; } sub process { my @entries = @_; return unless @entries; my $mail = parse $entries[0]; die "wtf?" if $mail->{level} != 0; my $tid = $mail->{mid}; my $thrsum = thrsum @_; my $oldsum = oldsum $tid; return if $thrsum eq $oldsum; die "poll: $!" if $poll->poll() == -1; my @handles = $poll->handles(POLLOUT) or die "no procs ready?"; my $handle = $handles[int(rand(@handles))]; print $handle $_ foreach @entries; savesum($tid, $thrsum); } if (`uname` =~ "OpenBSD") { use OpenBSD::Pledge; use OpenBSD::Unveil; unveil($csumdir, "rwc") or die "unveil $csumdir: $!"; pledge("stdio rpath wpath cpath") or die "pledge: $!"; } my @thread; while (<>) { print; # continue the pipeline my $new_thread = m/^-/; if ($new_thread && @thread) { process @thread; @thread = (); } push @thread, $_; } process @thread if @thread;