New utils

This commit is contained in:
Raven Scott
2026-04-03 23:04:42 -04:00
parent eeef3da6e1
commit f42f50eb73
214 changed files with 17562 additions and 615 deletions
+61 -7
View File
@@ -87,7 +87,10 @@ function bareOsEmitRaw(ctx, chunk) {
return false
}
async function copyPath(ctx, from, to, recursive, followSymlink) {
async function copyPath(ctx, from, to, recursive, followSymlink, opts) {
const preserve = opts && opts.preserveTime
const update = opts && opts.update
const verbose = opts && opts.verbose
const st = await ctx.vfs.lstat(from)
if (!st) {
ctx.console.error('cp: ' + from + ': No such file')
@@ -97,6 +100,7 @@ async function copyPath(ctx, from, to, recursive, followSymlink) {
if (!followSymlink) {
const t = await ctx.vfs.readlink(from)
await ctx.vfs.symlink(t, to)
if (verbose) ctx.console.log("'" + from + "' -> '" + to + "'")
return true
}
const fst = await ctx.vfs.stat(from)
@@ -106,7 +110,19 @@ async function copyPath(ctx, from, to, recursive, followSymlink) {
ctx.console.error('cp: cannot read ' + from)
return false
}
await ctx.vfs.writeFile(to, buf)
if (update) {
const dst = await ctx.vfs.lstat(to)
if (dst && dst.mtimeMs >= fst.mtimeMs) {
if (verbose) ctx.console.log('skipped: ' + to)
return true
}
}
const wopts =
preserve && typeof fst.mtimeMs === 'number'
? { mtimeMs: fst.mtimeMs, ctimeMs: fst.ctimeMs }
: {}
await ctx.vfs.writeFile(to, buf, wopts)
if (verbose) ctx.console.log("'" + from + "' -> '" + to + "'")
return true
}
if (fst.type === 'directory') {
@@ -120,8 +136,10 @@ async function copyPath(ctx, from, to, recursive, followSymlink) {
if (n === '.bareos_empty') continue
const f = from.replace(/\/+$/, '') + '/' + n
const t = to.replace(/\/+$/, '') + '/' + n
if (!(await copyPath(ctx, f, t, true, followSymlink))) return false
if (!(await copyPath(ctx, f, t, true, followSymlink, opts)))
return false
}
if (verbose) ctx.console.log("'" + from + "' -> '" + to + "'")
return true
}
ctx.console.error('cp: cannot copy special file ' + from)
@@ -133,7 +151,19 @@ async function copyPath(ctx, from, to, recursive, followSymlink) {
ctx.console.error('cp: cannot read ' + from)
return false
}
await ctx.vfs.writeFile(to, buf)
if (update) {
const dst = await ctx.vfs.lstat(to)
if (dst && dst.mtimeMs >= st.mtimeMs) {
if (verbose) ctx.console.log('skipped: ' + to)
return true
}
}
const wopts =
preserve && typeof st.mtimeMs === 'number'
? { mtimeMs: st.mtimeMs, ctimeMs: st.ctimeMs }
: {}
await ctx.vfs.writeFile(to, buf, wopts)
if (verbose) ctx.console.log("'" + from + "' -> '" + to + "'")
return true
}
if (st.type === 'directory') {
@@ -147,8 +177,9 @@ async function copyPath(ctx, from, to, recursive, followSymlink) {
if (n === '.bareos_empty') continue
const f = from.replace(/\/+$/, '') + '/' + n
const t = to.replace(/\/+$/, '') + '/' + n
if (!(await copyPath(ctx, f, t, true, followSymlink))) return false
if (!(await copyPath(ctx, f, t, true, followSymlink, opts))) return false
}
if (verbose) ctx.console.log("'" + from + "' -> '" + to + "'")
return true
}
return false
@@ -157,6 +188,9 @@ async function copyPath(ctx, from, to, recursive, followSymlink) {
async function run(ctx, argv) {
let recursive = false
let followSymlink = false
let update = false
let verbose = false
let preserveTime = false
const paths = []
for (let i = 1; i < argv.length; i++) {
const a = argv[i]
@@ -172,6 +206,23 @@ async function run(ctx, argv) {
followSymlink = false
continue
}
if (a === '-u' || a === '--update') {
update = true
continue
}
if (a === '-v' || a === '--verbose') {
verbose = true
continue
}
if (a === '--preserve' || a === '-p') {
preserveTime = true
continue
}
if (a.startsWith('--preserve=')) {
const v = a.slice('--preserve='.length)
if (v === 'timestamps' || v === 'time' || v === 'all') preserveTime = true
continue
}
if (a === '--') {
paths.push(...argv.slice(i + 1))
break
@@ -184,7 +235,9 @@ async function run(ctx, argv) {
paths.push(a)
}
if (paths.length < 2) {
ctx.console.error('usage: cp [-R] [-L|-P] SOURCE... DEST')
ctx.console.error(
'usage: cp [-R] [-L|-P] [-u] [-v] [-p|--preserve[=timestamps]] SOURCE... DEST'
)
ctx.exitCode = 1
return
}
@@ -202,13 +255,14 @@ async function run(ctx, argv) {
ctx.exitCode = 1
return
}
const opts = { preserveTime, update, verbose }
for (const src of sources) {
const base = src.replace(/\/+$/, '').split('/').pop() || src
const target =
destIsDir || sources.length > 1
? dest.replace(/\/+$/, '') + '/' + base
: dest
if (!(await copyPath(ctx, src, target, recursive, followSymlink)))
if (!(await copyPath(ctx, src, target, recursive, followSymlink, opts)))
ctx.exitCode = 1
}
}