Added a full ctx-level TCP connector path for telnet:
packages/bare-os-booter/index.js Added ctx.bareOsTelnetConnect(host, port, opts) that prefers ctx.bare.bareTcp.createConnection, then new bareTcp.Socket(), with explicit diagnostics if unavailable. packages/bare-os-coreutils/src/telnet.js already preferred ctx.bareOsTelnetConnect, so it now uses this richer path first automatically. Added missing ssh command: New file: packages/bare-os-coreutils/src/ssh.js Supports -h/--help Delegates to ctx.bareOsRunSshCli when present Emits explicit nonzero unavailable/runtime diagnostics when absent Registered command: packages/bare-os-coreutils/lib/commands.mjs Hardened HDMS create mount visibility: packages/bare-os-booter/lib/hdms-manager.js hdms create now verifies mount visibility via getMountMap().has(label) and errors non-silently if missing. Success message now includes mount path (mounted=/mnt/<label>). Fixed parser/semantics and explicit failures: packages/bare-os-coreutils/src/kill.js -1 is now treated as a target (not misparsed as signal shorthand), so kill -TERM -1 is explicit/non-silent. packages/bare-os-coreutils/src/test.js Numeric test comparisons now emit diagnostic + exit 2 for empty integer operand cases (keeps existing non-decimal behavior stable). packages/bare-os-coreutils/src/crontab.js Explicitly rejects stdin/fd-style installs (-, /dev/fd/*, /proc/self/fd/*) with nonzero error. Updated ctx typings: packages/bare-os-booter/lib/bare-os-ctx.d.ts Added bareOsRunSshCli? Added bareOsTelnetConnect?
This commit is contained in:
@@ -201,6 +201,17 @@ async function run(ctx, argv) {
|
||||
}
|
||||
|
||||
const file = rest[0]
|
||||
if (
|
||||
file === '-' ||
|
||||
/^\/dev\/fd\/\d+$/i.test(file) ||
|
||||
/^\/proc\/self\/fd\/\d+$/i.test(file)
|
||||
) {
|
||||
ctx.console.error(
|
||||
'crontab: stdin/fd-based installs are not supported in this runtime; use a regular file path'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
try {
|
||||
const b = await vfs.readFile(file)
|
||||
if (b == null) {
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ function bareOsEmitRaw(ctx, chunk) {
|
||||
return false
|
||||
}
|
||||
|
||||
var BARE_OS_HELP_BIN_SPACED = "agent appctl arch awk baresay baretop base32 base64 basename basenc btop bundlebee cat chat chgrp chmod chown cksum clear cmp comm corestorectl cp crontab ctxbaredoctor curl cut date dd df dhtctl dhtscan dhttop diff dir dircolors dirname du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help holepunch-view holesail hostid hostname hrpc hypershell-board iconv id install join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill link ln locale logger login logname logout ls man md5sum meshdrop mkdir mkfifo mktemp mount mv nano nice nl nohup nproc numfmt od oidc-publish openssl openssl p2ping p2ptrace paste patch pathcap-verify pathchk pear-runtime-matrix peerctl peerdiscover peernote pkg-swarm-index pr printenv printf procstat ps pwd readlink realpath rev rm rmdir routeview savevault say sed seq setfacl sh sha1sum sha224sum sha256sum sha384sum sha512sum shuf sidecar sleep sort split ssh-keygen ssh-keygen sshd sshd stat sum swarmdoctor swarmmap swarmtop sync systemctl tac tail tar tar taskmesh tee telnet test theme time timeout touch tr true truncate trustctl tsort tty ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami whois xargs xattr yes"
|
||||
var BARE_OS_HELP_BIN_SPACED = "agent appctl arch awk baresay baretop base32 base64 basename basenc btop bundlebee cat chat chgrp chmod chown cksum clear cmp comm corestorectl cp crontab ctxbaredoctor curl cut date dd df dhtctl dhtscan dhttop diff dir dircolors dirname du echo edit env exit expand expr factor false find fmt fold getconf getfacl git git-pear grep groups hdms head help holepunch-view holesail hostid hostname hrpc hypershell-board iconv id install join journalctl jq kernel-boot-diff kernel-doctor kernel-explain kernel-fsck kernel-home-snapshot kernel-manifest-validate kernel-preflight kernel-triage kill link ln locale logger login logname logout ls man md5sum meshdrop mkdir mkfifo mktemp mount mv nano nice nl nohup nproc numfmt od oidc-publish openssl openssl p2ping p2ptrace paste patch pathcap-verify pathchk pear-runtime-matrix peerctl peerdiscover peernote pkg-swarm-index pr printenv printf procstat ps pwd readlink realpath rev rm rmdir routeview savevault say sed seq setfacl sh sha1sum sha224sum sha256sum sha384sum sha512sum shuf sidecar sleep sort split ssh ssh-keygen ssh-keygen sshd sshd stat sum swarmdoctor swarmmap swarmtop sync systemctl tac tail tar tar taskmesh tee telnet test theme time timeout touch tr true truncate trustctl tsort tty ulimit umount uname unexpand uniq unlink uptime users vdir wc wget which who whoami whois xargs xattr yes"
|
||||
async function run(ctx, argv) {
|
||||
ctx.console.log(
|
||||
'Bare OS — default user: guest | shell builtins: alias, barerc, cd, command, export, exit, login, logout, readonly, type, umask, unalias, unset, : | /bin: ' +
|
||||
|
||||
@@ -145,6 +145,10 @@ async function run(ctx, argv) {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if (a === '-1') {
|
||||
targets.push(a)
|
||||
continue
|
||||
}
|
||||
if (/^-[A-Za-z0-9]+$/.test(a) && a !== '-') {
|
||||
signal = a.slice(1)
|
||||
continue
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/* BARE_OS_BIN_API 1.0.0 — bump when staged /bin script semantics change (see developer guide). */
|
||||
/** Shared helpers for drive-resident /bin scripts (prepended before each command). */
|
||||
function bareStdin(ctx) {
|
||||
return typeof ctx.shellStdin === 'string' ? ctx.shellStdin : ''
|
||||
}
|
||||
|
||||
/** @param {number} mode @param {'file' | 'directory' | 'symlink'} type */
|
||||
function bareFormatModeString(mode, type) {
|
||||
const typeChar = type === 'directory' ? 'd' : type === 'symlink' ? 'l' : '-'
|
||||
const perm = mode & 0o777
|
||||
const r = (bit) => (perm & bit ? 'r' : '-')
|
||||
const w = (bit) => (perm & bit ? 'w' : '-')
|
||||
const x = (bit) => (perm & bit ? 'x' : '-')
|
||||
return (
|
||||
typeChar +
|
||||
r(0o400) +
|
||||
w(0o200) +
|
||||
x(0o100) +
|
||||
r(0o040) +
|
||||
w(0o020) +
|
||||
x(0o010) +
|
||||
r(0o004) +
|
||||
w(0o002) +
|
||||
x(0o001)
|
||||
)
|
||||
}
|
||||
|
||||
/** @param {number} mtimeMs @param {number} [nowMs] */
|
||||
function bareFormatLsMtime(mtimeMs, nowMs) {
|
||||
const now = nowMs != null ? nowMs : Date.now()
|
||||
const d = new Date(mtimeMs)
|
||||
const months = [
|
||||
'Jan',
|
||||
'Feb',
|
||||
'Mar',
|
||||
'Apr',
|
||||
'May',
|
||||
'Jun',
|
||||
'Jul',
|
||||
'Aug',
|
||||
'Sep',
|
||||
'Oct',
|
||||
'Nov',
|
||||
'Dec'
|
||||
]
|
||||
const mon = months[d.getMonth()]
|
||||
const day = String(d.getDate()).padStart(2, ' ')
|
||||
const sixMo = 180 * 24 * 3600 * 1000
|
||||
if (Math.abs(now - mtimeMs) > sixMo) {
|
||||
const yr = String(d.getFullYear()).padStart(4, ' ')
|
||||
return mon + ' ' + day + ' ' + yr
|
||||
}
|
||||
const hh = String(d.getHours()).padStart(2, '0')
|
||||
const mm = String(d.getMinutes()).padStart(2, '0')
|
||||
return mon + ' ' + day + ' ' + hh + ':' + mm
|
||||
}
|
||||
|
||||
/** @param {number} size */
|
||||
function barePosixBlocks(size) {
|
||||
return Math.ceil(Number(size) / 512) || 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw stdout for NUL/binary when **`process.stdout.write`** is missing.
|
||||
* If **`ctx.bareOsBinWrite(Uint8Array|string)`** is set (tests / host), use it.
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string | Uint8Array} chunk
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function bareOsEmitRaw(ctx, chunk) {
|
||||
if (typeof ctx.bareOsBinWrite === 'function') {
|
||||
const b4 = ctx.b4a
|
||||
const u8 =
|
||||
typeof chunk === 'string'
|
||||
? b4 && typeof b4.from === 'function'
|
||||
? b4.from(chunk)
|
||||
: new TextEncoder().encode(chunk)
|
||||
: chunk
|
||||
ctx.bareOsBinWrite(u8 instanceof Uint8Array ? u8 : new Uint8Array(u8))
|
||||
return true
|
||||
}
|
||||
const w = globalThis.process?.stdout?.write
|
||||
if (typeof w === 'function') {
|
||||
w.call(globalThis.process.stdout, chunk)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
async function run(ctx, argv) {
|
||||
const args = argv.slice(1)
|
||||
if (
|
||||
args.includes('-h') ||
|
||||
args.includes('--help') ||
|
||||
args.includes('-?')
|
||||
) {
|
||||
ctx.console.log(
|
||||
'Usage: ssh [user@]host [command]\n' +
|
||||
'Bare OS: ssh client support is host/runtime-dependent.\n' +
|
||||
'If unavailable, use telnet or start an ssh-enabled runtime.'
|
||||
)
|
||||
ctx.exitCode = 0
|
||||
return
|
||||
}
|
||||
if (typeof ctx.bareOsRunSshCli === 'function') {
|
||||
try {
|
||||
await ctx.bareOsRunSshCli(argv)
|
||||
if (ctx.exitCode == null) ctx.exitCode = 0
|
||||
} catch (e) {
|
||||
ctx.console.error('ssh: ' + ((e && e.message) || String(e)))
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
const target = String(args[0] || '').trim()
|
||||
if (!target) {
|
||||
ctx.console.error('ssh: missing destination (use ssh [user@]host)')
|
||||
ctx.exitCode = 1
|
||||
return
|
||||
}
|
||||
ctx.console.error(
|
||||
'ssh: client unavailable in this runtime (ctx.bareOsRunSshCli missing)'
|
||||
)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
|
||||
+12
-2
@@ -136,7 +136,12 @@ async function evalTest(ctx, args) {
|
||||
if (op === '-eq' || op === '-ne' || op === '-lt' || op === '-le' || op === '-gt' || op === '-ge') {
|
||||
const la = parseBareOsTestInt(a)
|
||||
const lb = parseBareOsTestInt(b)
|
||||
if (!Number.isFinite(la) || !Number.isFinite(lb)) return false
|
||||
if (!Number.isFinite(la) || !Number.isFinite(lb)) {
|
||||
if (String(a).trim() === '' || String(b).trim() === '') {
|
||||
throw new Error('test: integer expression expected')
|
||||
}
|
||||
return false
|
||||
}
|
||||
switch (op) {
|
||||
case '-eq':
|
||||
return la === lb
|
||||
@@ -230,5 +235,10 @@ async function run(ctx, argv) {
|
||||
}
|
||||
testArgs = testArgs.slice(0, -1)
|
||||
}
|
||||
ctx.exitCode = (await evalTest(ctx, testArgs)) ? 0 : 1
|
||||
try {
|
||||
ctx.exitCode = (await evalTest(ctx, testArgs)) ? 0 : 1
|
||||
} catch (e) {
|
||||
ctx.console.error((e && e.message) || String(e))
|
||||
ctx.exitCode = 2
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user