#!/usr/bin/perl use strict; use warnings; use File::Path qw(make_path); use Time::HiRes qw(time); use OpenBSD::Pledge; use OpenBSD::Unveil; unveil("/tmp", "rwc") or die "unveil /tmp failed: $!"; unveil() or die "unveil lock failed: $!"; pledge('stdio rpath wpath cpath') or die "pledge failed: $!"; my $content_type = $ENV{'CONTENT_TYPE'} || ''; my $content_length = $ENV{'CONTENT_LENGTH'} // 0; if ($content_length > 0) { binmode(STDIN); my $raw_data = ''; read(STDIN, $raw_data, $content_length); # Extract boundary string from CONTENT_TYPE or raw payload my $boundary; if ($content_type =~ /boundary="?([^";\s]+)"?/i) { $boundary = $1; } elsif ($raw_data =~ /^--([^\r\n]+)/) { $boundary = $1; } my %params; if ($boundary) { my @parts = split(/--\Q$boundary\E(?:--)?\r?\n/, $raw_data); for my $part (@parts) { next unless $part =~ /\S/; my ($header_block, $body_block) = split(/\r?\n\r?\n/, $part, 2); next unless defined $header_block && defined $body_block; $body_block =~ s/\r?\n$//; if ($header_block =~ /Content-Disposition:[^\n]*?\bname="([^"]+)"/i) { my $name = $1; $params{$name} //= $body_block; } } } my $mail_body = $params{'stripped-text'} // $params{'body-plain'} // ''; if ($mail_body ne '') { my $dir = "/tmp/lex"; unless (-d $dir) { make_path($dir); } my $msg_id = sprintf("msg_%.6f_$$", time()); my $filename = "${dir}/${msg_id}.txt"; if (open(my $fh, '>', $filename)) { print $fh $mail_body; close($fh); } else { warn "Failed to write $filename: $!"; } } } print "Status: 200 OK\r\n"; print "Content-Type: text/plain; charset=utf-8\r\n\r\n"; print "OK\n"; exit 0;