123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- // 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")
|