You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.0 KiB
173 lines
4.0 KiB
// field paths that every tar file must have. |
|
// header is padded to 512 bytes. |
|
var f = 0 |
|
, fields = {} |
|
, path = fields.path = f++ |
|
, mode = fields.mode = f++ |
|
, uid = fields.uid = f++ |
|
, gid = fields.gid = f++ |
|
, size = fields.size = f++ |
|
, mtime = fields.mtime = f++ |
|
, cksum = fields.cksum = f++ |
|
, type = fields.type = f++ |
|
, linkpath = fields.linkpath = f++ |
|
, headerSize = 512 |
|
, blockSize = 512 |
|
, fieldSize = [] |
|
|
|
fieldSize[path] = 100 |
|
fieldSize[mode] = 8 |
|
fieldSize[uid] = 8 |
|
fieldSize[gid] = 8 |
|
fieldSize[size] = 12 |
|
fieldSize[mtime] = 12 |
|
fieldSize[cksum] = 8 |
|
fieldSize[type] = 1 |
|
fieldSize[linkpath] = 100 |
|
|
|
// "ustar\0" may introduce another bunch of headers. |
|
// these are optional, and will be nulled out if not present. |
|
|
|
var ustar = fields.ustar = f++ |
|
, ustarver = fields.ustarver = f++ |
|
, uname = fields.uname = f++ |
|
, gname = fields.gname = f++ |
|
, devmaj = fields.devmaj = f++ |
|
, devmin = fields.devmin = f++ |
|
, prefix = fields.prefix = f++ |
|
, fill = fields.fill = f++ |
|
|
|
// terminate fields. |
|
fields[f] = null |
|
|
|
fieldSize[ustar] = 6 |
|
fieldSize[ustarver] = 2 |
|
fieldSize[uname] = 32 |
|
fieldSize[gname] = 32 |
|
fieldSize[devmaj] = 8 |
|
fieldSize[devmin] = 8 |
|
fieldSize[prefix] = 155 |
|
fieldSize[fill] = 12 |
|
|
|
// nb: prefix field may in fact be 130 bytes of prefix, |
|
// a null char, 12 bytes for atime, 12 bytes for ctime. |
|
// |
|
// To recognize this format: |
|
// 1. prefix[130] === ' ' or '\0' |
|
// 2. atime and ctime are octal numeric values |
|
// 3. atime and ctime have ' ' in their last byte |
|
|
|
var fieldEnds = {} |
|
, fieldOffs = {} |
|
, fe = 0 |
|
for (var i = 0; i < f; i ++) { |
|
fieldOffs[i] = fe |
|
fieldEnds[i] = (fe += fieldSize[i]) |
|
} |
|
|
|
// build a translation table of field paths. |
|
Object.keys(fields).forEach(function (f) { |
|
if (fields[f] !== null) fields[fields[f]] = f |
|
}) |
|
|
|
// different values of the 'type' field |
|
// paths match the values of Stats.isX() functions, where appropriate |
|
var types = |
|
{ 0: "File" |
|
, "\0": "OldFile" // like 0 |
|
, "": "OldFile" |
|
, 1: "Link" |
|
, 2: "SymbolicLink" |
|
, 3: "CharacterDevice" |
|
, 4: "BlockDevice" |
|
, 5: "Directory" |
|
, 6: "FIFO" |
|
, 7: "ContiguousFile" // like 0 |
|
// posix headers |
|
, g: "GlobalExtendedHeader" // k=v for the rest of the archive |
|
, x: "ExtendedHeader" // k=v for the next file |
|
// vendor-specific stuff |
|
, A: "SolarisACL" // skip |
|
, D: "GNUDumpDir" // like 5, but with data, which should be skipped |
|
, I: "Inode" // metadata only, skip |
|
, K: "NextFileHasLongLinkpath" // data = link path of next file |
|
, L: "NextFileHasLongPath" // data = path of next file |
|
, M: "ContinuationFile" // skip |
|
, N: "OldGnuLongPath" // like L |
|
, S: "SparseFile" // skip |
|
, V: "TapeVolumeHeader" // skip |
|
, X: "OldExtendedHeader" // like x |
|
} |
|
|
|
Object.keys(types).forEach(function (t) { |
|
types[types[t]] = types[types[t]] || t |
|
}) |
|
|
|
// values for the mode field |
|
var modes = |
|
{ suid: 04000 // set uid on extraction |
|
, sgid: 02000 // set gid on extraction |
|
, svtx: 01000 // set restricted deletion flag on dirs on extraction |
|
, uread: 0400 |
|
, uwrite: 0200 |
|
, uexec: 0100 |
|
, gread: 040 |
|
, gwrite: 020 |
|
, gexec: 010 |
|
, oread: 4 |
|
, owrite: 2 |
|
, oexec: 1 |
|
, all: 07777 |
|
} |
|
|
|
var numeric = |
|
{ mode: true |
|
, uid: true |
|
, gid: true |
|
, size: true |
|
, mtime: true |
|
, devmaj: true |
|
, devmin: true |
|
, cksum: true |
|
, atime: true |
|
, ctime: true |
|
, dev: true |
|
, ino: true |
|
, nlink: true |
|
} |
|
|
|
Object.keys(modes).forEach(function (t) { |
|
modes[modes[t]] = modes[modes[t]] || t |
|
}) |
|
|
|
var knownExtended = |
|
{ atime: true |
|
, charset: true |
|
, comment: true |
|
, ctime: true |
|
, gid: true |
|
, gname: true |
|
, linkpath: true |
|
, mtime: true |
|
, path: true |
|
, realtime: true |
|
, security: true |
|
, size: true |
|
, uid: true |
|
, uname: true } |
|
|
|
|
|
exports.fields = fields |
|
exports.fieldSize = fieldSize |
|
exports.fieldOffs = fieldOffs |
|
exports.fieldEnds = fieldEnds |
|
exports.types = types |
|
exports.modes = modes |
|
exports.numeric = numeric |
|
exports.headerSize = headerSize |
|
exports.blockSize = blockSize |
|
exports.knownExtended = knownExtended |
|
|
|
exports.Pack = require("./lib/pack.js") |
|
exports.Parse = require("./lib/parse.js") |
|
exports.Extract = require("./lib/extract.js")
|
|
|