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.
		
		
		
		
		
			
		
			
				
					
					
						
							174 lines
						
					
					
						
							4.0 KiB
						
					
					
				
			
		
		
	
	
							174 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")
 |