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
			| 
								 
											4 years ago
										 
									 | 
							
								// 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")
							 |