3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-09 13:39:34 +01:00
pbot/applets/compiler_vm/host/bin/vm-exec
Pragmatic Software 1326b0ac5f compiler_vm: major refactor to support VM sockets (AF_VSOCK)
VM socket communication is superior to VM serial communication in
every way. Unfortunately at this time only Linux supports them.
Fortunately, that's 99% of PBot's userbase.

If you're not using Linux or if you're using an older Linux that
does not support VM sockets, the PBot VM scripts will gracefully
fallback to using the serial connection. You may explicitly
disable VM socket connection attempts by setting PBOTVM_CID=0.
2022-02-12 16:06:04 -08:00

112 lines
2.7 KiB
Perl
Executable File

#!/usr/bin/env perl
# File: vm-exec
#
# Purpose: Process and send commands to the PBot Guest server (guest-server) on
# the default serial TCP port (5555). Use the PBOTVM_SERIAL environment variable
# to override the port. E.g., to use port 7777 instead:
#
# $ PBOTVM_SERIAL=7777 vm-exec -lang=sh echo test
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
# SPDX-License-Identifier: MIT
use warnings;
use strict;
use File::Basename;
use JSON::XS;
use FindBin qw($RealBin);
use lib "$RealBin/../lib";
use constant {
SERIAL => $ENV{PBOTVM_SERIAL} // 5555,
CID => $ENV{PBOTVM_CID} // 7,
VPORT => $ENV{PBOTVM_VPORT} // 5555,
};
my $json = join ' ', @ARGV;
my $data = eval { decode_json $json };
if ($@) {
# wasn't JSON; make structure manually
if ($json =~ s/^-lang=([^ ]+)\s+//) {
$data = { lang => $1, code => $json };
} else {
$data = { code => $json };
}
}
if (not exists $data->{code}) {
die "Usage: $0 <code>\n";
}
# set any missing fields to default values
$data->{nick} //= 'vm';
$data->{channel} //= 'vm';
$data->{lang} //= 'c11';
$data->{'vm-serial'} //= SERIAL;
$data->{'vm-cid'} //= CID;
$data->{'vm-vport'} //= VPORT;
# parse -lang option
if ($data->{code} =~ s/^-lang=([^ ]+)\s+//) {
$data->{lang} = $1;
}
my $language = lc $data->{lang};
eval {
require "Languages/$language.pm";
} or do {
my $found = 0;
my ($languages, $comma) = ('', '');
foreach my $module (sort glob "$RealBin/../lib/Languages/*.pm") {
$module = basename $module;
$module =~ s/.pm$//;
next if $module =~ m/^_/;
require "Languages/$module.pm" or die $!;
my $mod = "Languages::$module"->new;
if (exists $mod->{name} and $mod->{name} eq $language) {
$language = $module;
$found = 1;
last;
}
$module = $mod->{name} if exists $mod->{name};
$languages .= "$comma$module";
$comma = ', ';
}
if (not $found) {
print "Language '$language' is not supported.\nSupported languages are: $languages\n";
exit;
}
};
if (not length $data->{code}) {
if (exists $data->{usage}) {
print "$data->{usage}\n";
} else {
print "Usage: cc [-lang=<language>] [-info] [-paste] [-args \"command-line arguments\"] [compiler/language options] <code> [-stdin <stdin input>]\n";
}
exit;
}
my $lang = "Languages::$language"->new(%$data);
$lang->{local} = $ENV{CC_LOCAL};
$lang->process_interactive_edit;
$lang->process_standard_options;
$lang->process_custom_options;
$lang->process_cmdline_options;
$lang->preprocess_code;
$lang->execute;
$lang->postprocess_output;
$lang->show_output;