107 lines
4.4 KiB
Plaintext
107 lines
4.4 KiB
Plaintext
from stdint import *
|
|
import stdlib
|
|
import string
|
|
import sys
|
|
import memhub
|
|
import win32.win32console as win32cmd
|
|
import lib.VLog as VLog
|
|
import lib.VFs as VFs
|
|
import lib.VDirs as VDirs
|
|
import lib.VGuid as VGuid
|
|
import lib.VCache as VCache
|
|
import lib.VJson as VJson
|
|
import lib.VProc as VProc
|
|
import lib.VPe as VPe
|
|
import lib.VScan as VScan
|
|
import lib.VCheck as VCheck
|
|
import lib.VGuard as VGuard
|
|
import lib.VCli as VCli
|
|
|
|
|
|
# ============================================================
|
|
# VET - Viper Environment Tool (entry point)
|
|
#
|
|
# Modes (see README): ver = single-exe check (dir table + .PRVERSN section + `--version` prefix);
|
|
# scan = resident disk scanner (interval via --sleep, default 10s; stdout is JSON only);
|
|
# confirm-watch = hidden heartbeat watchdog subcommand, auto-spawned by scan + --need-confirm;
|
|
# it only does sleep then waits on stdin for {"ok": 1}, aborting the parent on failure.
|
|
#
|
|
# This file only: console code page -> Log init -> main pool -> inject each module's `_mbuddy`
|
|
# -> init argv -> dispatch subcommand. All implementations live in lib/.
|
|
# ============================================================
|
|
|
|
define CODE_PAGE = 65001
|
|
define POOL_SIZE = 16777216 # MemBuddy main pool 16 MiB
|
|
|
|
|
|
export def main() -> int:
|
|
win32cmd.SetConsoleOutputCP(CODE_PAGE)
|
|
win32cmd.SetConsoleCP(CODE_PAGE)
|
|
|
|
VLog.LogInit()
|
|
|
|
# MemBuddy pool: sys._init_argv and all module allocations depend on it
|
|
arena: bytes = stdlib.malloc(POOL_SIZE)
|
|
if arena is None:
|
|
VLog.LogStr("[VET] FATAL: memory pool allocation failed\n")
|
|
return 1
|
|
mb: memhub.MemBuddy* = memhub.MemBuddy(arena, POOL_SIZE)
|
|
if mb is None:
|
|
VLog.LogStr("[VET] FATAL: MemBuddy initialization failed\n")
|
|
return 1
|
|
|
|
# Inject the same pool into every module that declares _mbuddy; missing one makes its
|
|
# _mbuddy point at zeroed static storage, so all allocs return None and it silently degrades.
|
|
VFs._mbuddy = mb
|
|
VDirs._mbuddy = mb
|
|
VGuid._mbuddy = mb
|
|
VCache._mbuddy = mb
|
|
VJson._mbuddy = mb
|
|
VScan._mbuddy = mb
|
|
VCheck._mbuddy = mb
|
|
VGuard._mbuddy = mb
|
|
sys._mbuddy = mb
|
|
|
|
sys._init_argv()
|
|
if sys._argc < 2 or sys._argv[1] is None:
|
|
VCli.PrintUsage()
|
|
return 1
|
|
Cmd: str = sys._argv[1]
|
|
|
|
if string.strcmp(Cmd, "ver") == 0:
|
|
# ver does not parse flags (target fixed at _argv[2]): --verbose in argv enables detail logs
|
|
if VCli.HasVerbose() != 0:
|
|
VLog.SetVerbose(1)
|
|
return VPe.RunVer()
|
|
# `--search-paths` may omit `scan` and sit in the subcommand slot; it is a pure query
|
|
# (no scan, no cache IO) with identical semantics. Set here, merged later by ParseScanArgs.
|
|
if string.strcmp(Cmd, "--search-paths") == 0:
|
|
VCli.SetSearchPathsImplicit()
|
|
if string.strcmp(Cmd, "scan") == 0 or string.strcmp(Cmd, "--search-paths") == 0:
|
|
# Args are parsed here because the watchdog lifecycle spans all of RunScan, so
|
|
# --need-confirm/--need-confirm-timeout must be known before entering it.
|
|
if VCli.ParseScanArgs() != 0:
|
|
return 1
|
|
# --verbose takes effect right after parsing, before watchdog/summary logs, so all
|
|
# later VLog.Verbose* calls gate on it (default off = quiet).
|
|
VLog.SetVerbose(VCli.Verbose())
|
|
# --search-paths: build the searched dir table, print it line by line to stderr, exit.
|
|
# Placed before SpawnWatchdog since it needs no scan/cache and must not start the watchdog.
|
|
if VCli.SearchPaths() != 0:
|
|
return VScan.RunSearchPathsQuery()
|
|
# --need-confirm > 0: spawn a separate watchdog subprocess (decoupled from scanning).
|
|
# Failure is fatal: an explicit heartbeat request must not silently run unconfirmed.
|
|
if VCli.NeedConfirm() > 0:
|
|
if VGuard.SpawnWatchdog(VCli.NeedConfirm(), VCli.NeedConfirmTimeout()) == 0:
|
|
VLog.LogStr("Error: heartbeat confirm watchdog launch failed, scan aborted\n")
|
|
return 1
|
|
RcScan: int = VScan.RunScan()
|
|
VGuard.StopWatchdog() # Always reap the watchdog on normal exit (incl. --once) to avoid orphans
|
|
return RcScan
|
|
# Hidden internal subcommand: heartbeat watchdog (not in usage; spawned by the scan branch)
|
|
if string.strcmp(Cmd, "confirm-watch") == 0:
|
|
return VGuard.RunConfirmWatch()
|
|
VLog.LogFmtS1("Error: unknown subcommand %s\n", Cmd)
|
|
VCli.PrintUsage()
|
|
return 1
|