v. vanilla 2.0

restored/vanilla1.cpp

← All source files · Download this file

6,481 bytes · SHA256 2c5916feba3aee48a5d111e94cbdf66edcd9290702cd6370eedfe4c47c8c83b1

// Reconstructed Linux CLI; historical vanilla1.cpp supplied run FILE and CGI paths.
#include "script.h"
#include <iostream>
#include <locale>
#include <string>

int main(int argc,char** argv) {
    std::locale::global(std::locale::classic());
    vanilla::Source cli{"<cli>",0};
    try {
        vanilla::Options options;
        std::string file;
        std::size_t argumentBytes=0;
        for(int i=1;i<argc;++i) {
            std::string arg=argv[i];
            if(arg=="--") {
                if(file.empty()) vanilla::fail(cli,"-- requires run FILE first");
                for(++i;i<argc;++i) {
                    std::string text=argv[i]; argumentBytes+=text.size();
                    if(options.arguments.size()>=1024 || text.size()>vanilla::valueLimit || argumentBytes>vanilla::valueLimit)
                        vanilla::failLimit(cli,"CLI argument limit (1024 items, 1 MiB)");
                    options.arguments.push_back(std::move(text));
                }
                break;
            }
            if(arg == "--help") {
                std::cout << "Vanilla 1 Linux restoration 1.0\n"
                    "Usage: vanilla1 [--allow-files] [--allow-network] [--allow-listen] [--allow-db] [--max-steps N] run|test FILE [-- ARG ...]\n"
                    "  --help          Show this help\n"
                    "  --version       Show restoration version\n"
                    "  --allow-files   Enable file builtins; NOT an OS sandbox\n"
                    "  --allow-network Enable HTTP/S and TCP, including private networks; NOT a sandbox\n"
                    "  --allow-listen  Enable TCP listen; also requires --allow-network\n"
                    "  --dns-server IP:port  Socket DNS resolver override (IPv6 in brackets); requires network\n"
                    "  --tls-ca-file PATH    Socket TLS private CA bundle; replaces default trust; requires network\n"
                    "  --tls-cert-file PATH --tls-key-file PATH  TLS server PEM pair; requires network + listen\n"
                    "  --allow-db      Enable SQLite databases; NOT an OS sandbox\n"
                    "  --sql-config FILE  Private remote SQL profiles; also requires --allow-db + --allow-network\n"
                    "  test FILE       Run sorted test_* functions with isolated runtime state\n"
                    "  --max-steps N   Instruction budget (default 1000000; max 100000000)\n"
                    "  --cgi-worker   Internal buffered JSON protocol for the CGI gateway\n"
                    "Entry: function main 0 ... kill main. DLL unavailable; Apache CGI: gateway/vanilla1_cgi.py\n";
                vanilla::flushOutput(cli);
                return 0;
            }
            if(arg == "--version") {
                std::cout << "Vanilla 1 Linux restoration 1.0 (C++17)\n";
                vanilla::flushOutput(cli);
                return 0;
            }
            if(arg == "--allow-files") options.allowFiles=true;
            else if(arg == "--allow-db") options.allowDb=true;
            else if(arg=="--cgi-worker") options.webWorker=true;
            else if(arg=="--sql-config") {
                if(++i==argc || !argv[i][0] || !options.sqlConfig.empty()) vanilla::fail(cli,"--sql-config requires one nonempty file path");
                options.sqlConfig=argv[i];
            }
            else if(arg=="--allow-listen") options.allowListen=true;
            else if(arg=="--allow-network") options.allowNetwork=true;
            else if(arg=="--tls-cert-file" || arg=="--tls-key-file") {
                if(++i==argc || !argv[i][0]) vanilla::fail(cli,"TLS server option needs a nonempty value");
                auto& target=arg=="--tls-cert-file" ? options.tlsCertFile : options.tlsKeyFile;
                if(!target.empty()) vanilla::fail(cli,"duplicate TLS server option");
                target=argv[i];
            }
            else if(arg=="--dns-server" || arg=="--tls-ca-file") {
                if(++i==argc || !argv[i][0]) vanilla::fail(cli,"DNS/TLS option needs a nonempty value");
                if(arg=="--dns-server") options.dnsServer=argv[i]; else options.tlsCAFile=argv[i];
            }
            else if(arg == "--max-steps") {
                if(++i == argc) vanilla::fail(cli,"--max-steps needs an integer");
                options.maxSteps=static_cast<std::uint64_t>(vanilla::integer(argv[i],1,100000000,cli));
            } else if(arg == "run" || arg == "test") {
                options.testMode=arg=="test";
                if(!file.empty() || ++i == argc) vanilla::fail(cli,"usage: vanilla1 [options] run FILE");
                file=argv[i];
            } else if(arg == "cgi" || arg == "--cgi") vanilla::fail(cli,"CGI unavailable in Linux restoration");
            else vanilla::fail(cli,"unknown option: " + arg);
        }
        if(file.empty()) vanilla::fail(cli,"usage: vanilla1 [options] run FILE; CGI unavailable");
        if(!options.tlsCertFile.empty() || !options.tlsKeyFile.empty()) {
            if(options.tlsCertFile.empty() || options.tlsKeyFile.empty()) vanilla::fail(cli,"TLS server requires both --tls-cert-file and --tls-key-file");
            if(!options.allowNetwork || !options.allowListen) vanilla::fail(cli,"TLS server configuration requires --allow-network and --allow-listen");
        }
        vanilla::validateNetworkOptions(options,cli);
        if(options.webWorker) {
            if(options.testMode || !options.arguments.empty()) vanilla::fail(cli,"CGI worker does not accept test mode or script arguments");
            char chunk[4096];
            while(std::cin.read(chunk,sizeof(chunk)) || std::cin.gcount()) {
                options.webRequest.append(chunk,static_cast<std::size_t>(std::cin.gcount()));
                if(options.webRequest.size()>512*1024) vanilla::failLimit(cli,"CGI worker input limit (512 KiB)");
            }
            if(!std::cin.eof()) vanilla::fail(cli,"CGI worker input failed");
        }
        vanilla::vScript script(options);
        script.Load(file);
        if(options.testMode) return script.Test(file) ? 0 : 1;
        script.Run();
        if(options.webWorker) { std::cout << script.WebResponse(); vanilla::flushOutput(cli); }
        return 0;
    } catch(const vanilla::Error& e) {
        std::cerr << e.source.file << ':' << e.source.line << ": error: " << e.what() << '\n';
    } catch(const std::exception& e) {
        std::cerr << "<runtime>:0: error: " << e.what() << '\n';
    }
    return 1;
}