Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-01-13 20:33:27 +0400
committerisaacs <i@izs.me>2012-01-13 20:41:06 +0400
commitc18fe966ddbeb66c8a9b9aa8ab4899166e6986f5 (patch)
tree8650e7575caff9d05e04352b78669dd81d21230d /node_modules/tar
parentb7ff884870958221eb52c5a600c101fab4c26781 (diff)
check in node_modules
Diffstat (limited to 'node_modules/tar')
-rw-r--r--node_modules/tar/.npmignore5
-rw-r--r--node_modules/tar/.travis.yml3
-rw-r--r--node_modules/tar/README.md50
-rw-r--r--node_modules/tar/lib/buffer-entry.js30
-rw-r--r--node_modules/tar/lib/entry-writer.js169
-rw-r--r--node_modules/tar/lib/entry.js212
-rw-r--r--node_modules/tar/lib/extended-header-writer.js192
-rw-r--r--node_modules/tar/lib/extended-header.js139
-rw-r--r--node_modules/tar/lib/extract.js64
-rw-r--r--node_modules/tar/lib/global-header-writer.js14
-rw-r--r--node_modules/tar/lib/header.js385
-rw-r--r--node_modules/tar/lib/pack.js226
-rw-r--r--node_modules/tar/lib/parse.js270
-rw-r--r--node_modules/tar/package.json26
-rw-r--r--node_modules/tar/tar.js172
15 files changed, 1957 insertions, 0 deletions
diff --git a/node_modules/tar/.npmignore b/node_modules/tar/.npmignore
new file mode 100644
index 000000000..856407ebe
--- /dev/null
+++ b/node_modules/tar/.npmignore
@@ -0,0 +1,5 @@
+.*.swp
+node_modules
+examples/extract/
+test/tmp/
+test/fixtures/symlink
diff --git a/node_modules/tar/.travis.yml b/node_modules/tar/.travis.yml
new file mode 100644
index 000000000..2d26206d5
--- /dev/null
+++ b/node_modules/tar/.travis.yml
@@ -0,0 +1,3 @@
+language: node_js
+node_js:
+ - 0.6
diff --git a/node_modules/tar/README.md b/node_modules/tar/README.md
new file mode 100644
index 000000000..7cfe3bbca
--- /dev/null
+++ b/node_modules/tar/README.md
@@ -0,0 +1,50 @@
+# node-tar
+
+Tar for Node.js.
+
+## Goals of this project
+
+1. Be able to parse and reasonably extract the contents of any tar file
+ created by any program that creates tar files, period.
+
+ At least, this includes every version of:
+
+ * bsdtar
+ * gnutar
+ * solaris posix tar
+ * Joerg Schilling's star ("Schilly tar")
+
+2. Create tar files that can be extracted by any of the following tar
+ programs:
+
+ * bsdtar/libarchive version 2.6.2
+ * gnutar 1.15 and above
+ * SunOS Posix tar
+ * Joerg Schilling's star ("Schilly tar")
+
+3. 100% test coverage. Speed is important. Correctness is slightly
+ more important.
+
+4. Create the kind of tar interface that Node users would want to use.
+
+5. Satisfy npm's needs for a portable tar implementation with a
+ JavaScript interface.
+
+6. No excuses. No complaining. No tolerance for failure.
+
+## But isn't there already a tar.js?
+
+Yes, there are a few. This one is going to be better, and it will be
+fanatically maintained, because npm will depend on it.
+
+That's why I need to write it from scratch. Creating and extracting
+tarballs is such a large part of what npm does, I simply can't have it
+be a black box any longer.
+
+## Didn't you have something already? Where'd it go?
+
+It's in the "old" folder. It's not functional. Don't use it.
+
+It was a useful exploration to learn the issues involved, but like most
+software of any reasonable complexity, node-tar won't be useful until
+it's been written at least 3 times.
diff --git a/node_modules/tar/lib/buffer-entry.js b/node_modules/tar/lib/buffer-entry.js
new file mode 100644
index 000000000..5322a28ab
--- /dev/null
+++ b/node_modules/tar/lib/buffer-entry.js
@@ -0,0 +1,30 @@
+// just like the Entry class, but it buffers the contents
+//
+// XXX It would be good to set a maximum BufferEntry filesize,
+// since it eats up memory. In normal operation,
+// these are only for long filenames or link names, which are
+// rarely very big.
+
+module.exports = BufferEntry
+
+var inherits = require("inherits")
+ , Entry = require("./entry.js")
+
+function BufferEntry () {
+ Entry.apply(this, arguments)
+ this._buffer = new Buffer(this.props.size)
+ this._offset = 0
+ this.body = ""
+ this.on("end", function () {
+ this.body = this._buffer.toString().slice(0, -1)
+ })
+}
+
+// collect the bytes as they come in.
+BufferEntry.prototype.write = function (c) {
+ c.copy(this._buffer, this._offset)
+ this._offset += c.length
+ Entry.prototype.write.call(this, c)
+}
+
+inherits(BufferEntry, Entry)
diff --git a/node_modules/tar/lib/entry-writer.js b/node_modules/tar/lib/entry-writer.js
new file mode 100644
index 000000000..8e09042d0
--- /dev/null
+++ b/node_modules/tar/lib/entry-writer.js
@@ -0,0 +1,169 @@
+module.exports = EntryWriter
+
+var tar = require("../tar.js")
+ , TarHeader = require("./header.js")
+ , Entry = require("./entry.js")
+ , inherits = require("inherits")
+ , BlockStream = require("block-stream")
+ , ExtendedHeaderWriter
+ , Stream = require("stream").Stream
+ , EOF = {}
+
+inherits(EntryWriter, Stream)
+
+function EntryWriter (props) {
+ var me = this
+
+ if (!(me instanceof EntryWriter)) {
+ return new EntryWriter(props)
+ }
+
+ Stream.apply(this)
+
+ me.writable = true
+ me.readable = true
+
+ me._stream = new BlockStream(512)
+
+ me._stream.on("data", function (c) {
+ me.emit("data", c)
+ })
+
+ me._stream.on("drain", function () {
+ me.emit("drain")
+ })
+
+ me._stream.on("end", function () {
+ me.emit("end")
+ me.emit("close")
+ })
+
+ me.props = props
+ if (props.type === "Directory") {
+ props.size = 0
+ }
+ props.ustar = "ustar\0"
+ props.ustarver = "00"
+ me.path = props.path
+
+ me._buffer = []
+ me._didHeader = false
+ me._meta = false
+
+ me.on("pipe", function () {
+ me._process()
+ })
+}
+
+EntryWriter.prototype.write = function (c) {
+ // console.error(".. ew write")
+ if (this._ended) return this.emit("error", new Error("write after end"))
+ this._buffer.push(c)
+ this._process()
+ this._needDrain = this._buffer.length > 0
+ return !this._needDrain
+}
+
+EntryWriter.prototype.end = function (c) {
+ // console.error(".. ew end")
+ if (c) this._buffer.push(c)
+ this._buffer.push(EOF)
+ this._ended = true
+ this._process()
+ this._needDrain = this._buffer.length > 0
+}
+
+EntryWriter.prototype.pause = function () {
+ // console.error(".. ew pause")
+ this._paused = true
+ this.emit("pause")
+}
+
+EntryWriter.prototype.resume = function () {
+ // console.error(".. ew resume")
+ this._paused = false
+ this.emit("resume")
+ this._process()
+}
+
+EntryWriter.prototype.add = function (entry) {
+ // console.error(".. ew add")
+ if (!this.parent) return this.emit("error", new Error("no parent"))
+
+ // make sure that the _header and such is emitted, and clear out
+ // the _currentEntry link on the parent.
+ if (!this._ended) this.end()
+
+ return this.parent.add(entry)
+}
+
+EntryWriter.prototype._header = function () {
+ // console.error(".. ew header")
+ if (this._didHeader) return
+ this._didHeader = true
+
+ var headerBlock = TarHeader.encode(this.props)
+
+ if (this.props.needExtended && !this._meta) {
+ var me = this
+
+ ExtendedHeaderWriter = ExtendedHeaderWriter ||
+ require("./extended-header-writer.js")
+
+ ExtendedHeaderWriter(this.props)
+ .on("data", function (c) {
+ me.emit("data", c)
+ })
+ .on("error", function (er) {
+ me.emit("error", er)
+ })
+ .end()
+ }
+
+ // console.error(".. .. ew headerBlock emitting")
+ this.emit("data", headerBlock)
+ this.emit("header")
+}
+
+EntryWriter.prototype._process = function () {
+ // console.error(".. .. ew process")
+ if (!this._didHeader && !this._meta) {
+ this._header()
+ }
+
+ if (this._paused || this._processing) {
+ // console.error(".. .. .. paused=%j, processing=%j", this._paused, this._processing)
+ return
+ }
+
+ this._processing = true
+
+ var buf = this._buffer
+ for (var i = 0; i < buf.length; i ++) {
+ // console.error(".. .. .. i=%d", i)
+
+ var c = buf[i]
+
+ if (c === EOF) this._stream.end()
+ else this._stream.write(c)
+
+ if (this._paused) {
+ // console.error(".. .. .. paused mid-emission")
+ this._processing = false
+ if (i < buf.length) {
+ this._needDrain = true
+ this._buffer = buf.slice(i + 1)
+ }
+ return
+ }
+ }
+
+ // console.error(".. .. .. emitted")
+ this._buffer.length = 0
+ this._processing = false
+
+ // console.error(".. .. .. emitting drain")
+ this.emit("drain")
+}
+
+EntryWriter.prototype.destroy = function () {}
diff --git a/node_modules/tar/lib/entry.js b/node_modules/tar/lib/entry.js
new file mode 100644
index 000000000..4fc331eb9
--- /dev/null
+++ b/node_modules/tar/lib/entry.js
@@ -0,0 +1,212 @@
+// A passthrough read/write stream that sets its properties
+// based on a header, extendedHeader, and globalHeader
+//
+// Can be either a file system object of some sort, or
+// a pax/ustar metadata entry.
+
+module.exports = Entry
+
+var TarHeader = require("./header.js")
+ , tar = require("../tar")
+ , assert = require("assert").ok
+ , Stream = require("stream").Stream
+ , inherits = require("inherits")
+ , fstream = require("fstream").Abstract
+
+function Entry (header, extended, global) {
+ Stream.call(this)
+ this.readable = true
+ this.writable = true
+
+ this._needDrain = false
+ this._paused = false
+ this._reading = false
+ this._ending = false
+ this._ended = false
+ this._remaining = 0
+ this._queue = []
+ this._index = 0
+ this._queueLen = 0
+
+ this._read = this._read.bind(this)
+
+ this.props = {}
+ this._header = header
+ this._extended = extended || {}
+
+ // globals can change throughout the course of
+ // a file parse operation. Freeze it at its current state.
+ this._global = {}
+ var me = this
+ Object.keys(global || {}).forEach(function (g) {
+ me._global[g] = global[g]
+ })
+
+ this._setProps()
+}
+
+inherits(Entry, Stream,
+{ write: function (c) {
+ if (this._ending) this.error("write() after end()", null, true)
+ if (this._remaining === 0) {
+ this.error("invalid bytes past eof")
+ }
+
+ // often we'll get a bunch of \0 at the end of the last write,
+ // since chunks will always be 512 bytes when reading a tarball.
+ if (c.length > this._remaining) {
+ c = c.slice(0, this._remaining)
+ }
+ this._remaining -= c.length
+
+ // put it on the stack.
+ var ql = this._queueLen
+ this._queue.push(c)
+ this._queueLen ++
+
+ this._read()
+
+ // either paused, or buffered
+ if (this._paused || ql > 0) {
+ this._needDrain = true
+ return false
+ }
+
+ return true
+ }
+
+, end: function (c) {
+ if (c) this.write(c)
+ this._ending = true
+ this._read()
+ }
+
+, pause: function () {
+ this._paused = true
+ this.emit("pause")
+ }
+
+, resume: function () {
+ // console.error(" Tar Entry resume", this.path)
+ this.emit("resume")
+ this._paused = false
+ this._read()
+ return this._queueLen - this._index > 1
+ }
+
+ // This is bound to the instance
+, _read: function () {
+ // console.error(" Tar Entry _read", this.path)
+
+ if (this._paused || this._reading || this._ended) return
+
+ // set this flag so that event handlers don't inadvertently
+ // get multiple _read() calls running.
+ this._reading = true
+
+ // have any data to emit?
+ if (this._index < this._queueLen) {
+ var chunk = this._queue[this._index ++]
+ this.emit("data", chunk)
+ }
+
+ // check if we're drained
+ if (this._index >= this._queueLen) {
+ this._queue.length = this._queueLen = this._index = 0
+ if (this._needDrain) {
+ this._needDrain = false
+ this.emit("drain")
+ }
+ if (this._ending) {
+ this._ended = true
+ this.emit("end")
+ }
+ }
+
+ // if the queue gets too big, then pluck off whatever we can.
+ // this should be fairly rare.
+ var mql = this._maxQueueLen
+ if (this._queueLen > mql && this._index > 0) {
+ mql = Math.min(this._index, mql)
+ this._index -= mql
+ this._queueLen -= mql
+ this._queue = this._queue.slice(mql)
+ }
+
+ this._reading = false
+ }
+
+, _setProps: function () {
+ // props = extended->global->header->{}
+ var header = this._header
+ , extended = this._extended
+ , global = this._global
+ , props = this.props
+
+ // first get the values from the normal header.
+ var fields = tar.fields
+ for (var f = 0; fields[f] !== null; f ++) {
+ var field = fields[f]
+ , val = header[field]
+ if (typeof val !== "undefined") props[field] = val
+ }
+
+ // next, the global header for this file.
+ // numeric values, etc, will have already been parsed.
+ ;[global, extended].forEach(function (p) {
+ Object.keys(p).forEach(function (f) {
+ if (typeof p[f] !== "undefined") props[f] = p[f]
+ })
+ })
+
+ // no nulls allowed in path or linkpath
+ ;["path", "linkpath"].forEach(function (p) {
+ if (props.hasOwnProperty(p)) {
+ props[p] = props[p].split("\0")[0]
+ }
+ })
+
+
+ // set date fields to be a proper date
+ ;["mtime", "ctime", "atime"].forEach(function (p) {
+ if (props.hasOwnProperty(p)) {
+ props[p] = new Date(props[p] * 1000)
+ }
+ })
+
+ // set the type so that we know what kind of file to create
+ var type
+ switch (tar.types[props.type]) {
+ case "OldFile":
+ case "ContiguousFile":
+ type = "File"
+ break
+
+ case "GNUDumpDir":
+ type = "Directory"
+ break
+
+ case undefined:
+ type = "Unknown"
+ break
+
+ case "Link":
+ case "SymbolicLink":
+ case "CharacterDevice":
+ case "BlockDevice":
+ case "Directory":
+ case "FIFO":
+ default:
+ type = tar.types[props.type]
+ }
+
+ this.type = type
+ this.path = props.path
+ this.size = props.size
+
+ // size is special, since it signals when the file needs to end.
+ this._remaining = props.size
+ }
+, warn: fstream.warn
+, error: fstream.error
+})
diff --git a/node_modules/tar/lib/extended-header-writer.js b/node_modules/tar/lib/extended-header-writer.js
new file mode 100644
index 000000000..a130c5b16
--- /dev/null
+++ b/node_modules/tar/lib/extended-header-writer.js
@@ -0,0 +1,192 @@
+
+module.exports = ExtendedHeaderWriter
+
+var inherits = require("inherits")
+ , EntryWriter = require("./entry-writer.js")
+
+inherits(ExtendedHeaderWriter, EntryWriter)
+
+var tar = require("../tar.js")
+ , path = require("path")
+ , inherits = require("inherits")
+ , TarHeader = require("./header.js")
+
+// props is the props of the thing we need to write an
+// extended header for.
+// Don't be shy with it. Just encode everything.
+function ExtendedHeaderWriter (props) {
+ // console.error(">> ehw ctor")
+ var me = this
+
+ if (!(me instanceof ExtendedHeaderWriter)) {
+ return new ExtendedHeaderWriter(props)
+ }
+
+ me.fields = props
+
+ var p =
+ { path : ("PaxHeader" + path.join("/", props.path || ""))
+ .replace(/\\/g, "/").substr(0, 100)
+ , mode : props.mode || 0666
+ , uid : props.uid || 0
+ , gid : props.gid || 0
+ , size : 0 // will be set later
+ , mtime : props.mtime || Date.now() / 1000
+ , type : "x"
+ , linkpath : ""
+ , ustar : "ustar\0"
+ , ustarver : "00"
+ , uname : props.uname || ""
+ , gname : props.gname || ""
+ , devmaj : props.devmaj || 0
+ , devmin : props.devmin || 0
+ }
+
+
+ EntryWriter.call(me, p)
+ // console.error(">> ehw props", me.props)
+ me.props = p
+
+ me._meta = true
+}
+
+ExtendedHeaderWriter.prototype.end = function () {
+ // console.error(">> ehw end")
+ var me = this
+
+ if (me._ended) return
+ me._ended = true
+
+ me._encodeFields()
+
+ if (me.props.size === 0) {
+ // nothing to write!
+ me._ready = true
+ me._stream.end()
+ return
+ }
+
+ me._stream.write(TarHeader.encode(me.props))
+ me.body.forEach(function (l) {
+ me._stream.write(l)
+ })
+ me._ready = true
+
+ // console.error(">> ehw _process calling end()", me.props)
+ this._stream.end()
+}
+
+ExtendedHeaderWriter.prototype._encodeFields = function () {
+ // console.error(">> ehw _encodeFields")
+ this.body = []
+ if (this.fields.prefix) {
+ this.fields.path = this.fields.prefix + "/" + this.fields.path
+ this.fields.prefix = ""
+ }
+ encodeFields(this.fields, "", this.body, this.fields.noProprietary)
+ var me = this
+ this.body.forEach(function (l) {
+ me.props.size += l.length
+ })
+}
+
+function encodeFields (fields, prefix, body, nop) {
+ // console.error(">> >> ehw encodeFields")
+ // "%d %s=%s\n", <length>, <keyword>, <value>
+ // The length is a decimal number, and includes itself and the \n
+ // Numeric values are decimal strings.
+
+ Object.keys(fields).forEach(function (k) {
+ var val = fields[k]
+ , numeric = tar.numeric[k]
+
+ if (prefix) k = prefix + "." + k
+
+ // already including NODETAR.type, don't need File=true also
+ if (k === fields.type && val === true) return
+
+ switch (k) {
+ // don't include anything that's always handled just fine
+ // in the normal header, or only meaningful in the context
+ // of nodetar
+ case "mode":
+ case "cksum":
+ case "ustar":
+ case "ustarver":
+ case "prefix":
+ case "basename":
+ case "dirname":
+ case "needExtended":
+ case "block":
+ case "filter":
+ return
+
+ case "rdev":
+ if (val === 0) return
+ break
+
+ case "nlink":
+ case "dev": // Truly a hero among men, Creator of Star!
+ case "ino": // Speak his name with reverent awe! It is:
+ k = "SCHILY." + k
+ break
+
+ default: break
+ }
+
+ if (val && typeof val === "object" &&
+ !Buffer.isBuffer(val)) encodeFields(val, k, body, nop)
+ else if (val === null || val === undefined) return
+ else body.push.apply(body, encodeField(k, val, nop))
+ })
+
+ return body
+}
+
+function encodeField (k, v, nop) {
+ // lowercase keys must be valid, otherwise prefix with
+ // "NODETAR."
+ if (k.charAt(0) === k.charAt(0).toLowerCase()) {
+ var m = k.split(".")[0]
+ if (!tar.knownExtended[m]) k = "NODETAR." + k
+ }
+
+ // no proprietary
+ if (nop && k.charAt(0) !== k.charAt(0).toLowerCase()) {
+ return []
+ }
+
+ if (typeof val === "number") val = val.toString(10)
+
+ var s = new Buffer(" " + k + "=" + v + "\n")
+ , digits = Math.floor(Math.log(s.length) / Math.log(10)) + 1
+
+ // console.error("1 s=%j digits=%j s.length=%d", s.toString(), digits, s.length)
+
+ // if adding that many digits will make it go over that length,
+ // then add one to it. For example, if the string is:
+ // " foo=bar\n"
+ // then that's 9 characters. With the "9", that bumps the length
+ // up to 10. However, this is invalid:
+ // "10 foo=bar\n"
+ // but, since that's actually 11 characters, since 10 adds another
+ // character to the length, and the length includes the number
+ // itself. In that case, just bump it up again.
+ if (s.length + digits >= Math.pow(10, digits)) digits += 1
+ // console.error("2 s=%j digits=%j s.length=%d", s.toString(), digits, s.length)
+
+ var len = digits + s.length
+ // console.error("3 s=%j digits=%j s.length=%d len=%d", s.toString(), digits, s.length, len)
+ var lenBuf = new Buffer("" + len)
+ if (lenBuf.length + s.length !== len) {
+ throw new Error("Bad length calculation\n"+
+ "len="+len+"\n"+
+ "lenBuf="+JSON.stringify(lenBuf.toString())+"\n"+
+ "lenBuf.length="+lenBuf.length+"\n"+
+ "digits="+digits+"\n"+
+ "s="+JSON.stringify(s.toString())+"\n"+
+ "s.length="+s.length)
+ }
+
+ return [lenBuf, s]
+}
diff --git a/node_modules/tar/lib/extended-header.js b/node_modules/tar/lib/extended-header.js
new file mode 100644
index 000000000..4346d6c59
--- /dev/null
+++ b/node_modules/tar/lib/extended-header.js
@@ -0,0 +1,139 @@
+// An Entry consisting of:
+//
+// "%d %s=%s\n", <length>, <keyword>, <value>
+//
+// The length is a decimal number, and includes itself and the \n
+// \0 does not terminate anything. Only the length terminates the string.
+// Numeric values are decimal strings.
+
+module.exports = ExtendedHeader
+
+var Entry = require("./entry.js")
+ , inherits = require("inherits")
+ , tar = require("../tar.js")
+ , numeric = tar.numeric
+ , keyTrans = { "SCHILY.dev": "dev"
+ , "SCHILY.ino": "ino"
+ , "SCHILY.nlink": "nlink" }
+
+function ExtendedHeader () {
+ Entry.apply(this, arguments)
+ this.on("data", this._parse)
+ this.fields = {}
+ this._position = 0
+ this._fieldPos = 0
+ this._state = SIZE
+ this._sizeBuf = []
+ this._keyBuf = []
+ this._valBuf = []
+ this._size = -1
+ this._key = ""
+}
+
+inherits(ExtendedHeader, Entry, { _parse: parse })
+
+var s = 0
+ , states = ExtendedHeader.states = {}
+ , SIZE = states.SIZE = s++
+ , KEY = states.KEY = s++
+ , VAL = states.VAL = s++
+ , ERR = states.ERR = s++
+
+Object.keys(states).forEach(function (s) {
+ states[states[s]] = states[s]
+})
+
+states[s] = null
+
+// char code values for comparison
+var _0 = "0".charCodeAt(0)
+ , _9 = "9".charCodeAt(0)
+ , point = ".".charCodeAt(0)
+ , a = "a".charCodeAt(0)
+ , Z = "Z".charCodeAt(0)
+ , a = "a".charCodeAt(0)
+ , z = "z".charCodeAt(0)
+ , space = " ".charCodeAt(0)
+ , eq = "=".charCodeAt(0)
+ , cr = "\n".charCodeAt(0)
+
+function parse (c) {
+ if (this._state === ERR) return
+
+ for ( var i = 0, l = c.length
+ ; i < l
+ ; this._position++, this._fieldPos++, i++) {
+ // console.error("top of loop, size="+this._size)
+
+ var b = c[i]
+
+ if (this._size >= 0 && this._fieldPos > this._size) {
+ error(this, "field exceeds length="+this._size)
+ return
+ }
+
+ switch (this._state) {
+ case ERR: return
+
+ case SIZE:
+ // console.error("parsing size, b=%d, rest=%j", b, c.slice(i).toString())
+ if (b === space) {
+ this._state = KEY
+ // this._fieldPos = this._sizeBuf.length
+ this._size = parseInt(new Buffer(this._sizeBuf).toString(), 10)
+ this._sizeBuf.length = 0
+ continue
+ }
+ if (b < _0 || b > _9) {
+ error(this, "expected [" + _0 + ".." + _9 + "], got " + b)
+ return
+ }
+ this._sizeBuf.push(b)
+ continue
+
+ case KEY:
+ // can be any char except =, not > size.
+ if (b === eq) {
+ this._state = VAL
+ this._key = new Buffer(this._keyBuf).toString()
+ if (keyTrans[this._key]) this._key = keyTrans[this._key]
+ this._keyBuf.length = 0
+ continue
+ }
+ this._keyBuf.push(b)
+ continue
+
+ case VAL:
+ // field must end with cr
+ if (this._fieldPos === this._size - 1) {
+ // console.error("finished with "+this._key)
+ if (b !== cr) {
+ error(this, "expected \\n at end of field")
+ return
+ }
+ var val = new Buffer(this._valBuf).toString()
+ if (numeric[this._key]) {
+ val = parseFloat(val)
+ }
+ this.fields[this._key] = val
+
+ this._valBuf.length = 0
+ this._state = SIZE
+ this._size = -1
+ this._fieldPos = -1
+ continue
+ }
+ this._valBuf.push(b)
+ continue
+ }
+ }
+}
+
+function error (me, msg) {
+ msg = "invalid header: " + msg
+ + "\nposition=" + me._position
+ + "\nfield position=" + me._fieldPos
+
+ me.error(msg)
+ me.state = ERR
+}
diff --git a/node_modules/tar/lib/extract.js b/node_modules/tar/lib/extract.js
new file mode 100644
index 000000000..e45974c72
--- /dev/null
+++ b/node_modules/tar/lib/extract.js
@@ -0,0 +1,64 @@
+// give it a tarball and a path, and it'll dump the contents
+
+module.exports = Extract
+
+var tar = require("../tar.js")
+ , fstream = require("fstream")
+ , inherits = require("inherits")
+ , path = require("path")
+
+function Extract (opts) {
+ if (!(this instanceof Extract)) return new Extract(opts)
+ tar.Parse.apply(this)
+
+ // have to dump into a directory
+ opts.type = "Directory"
+ opts.Directory = true
+
+ if (typeof opts !== "object") {
+ opts = { path: opts }
+ }
+
+ // better to drop in cwd? seems more standard.
+ opts.path = opts.path || path.resolve("node-tar-extract")
+ opts.type = "Directory"
+ opts.Directory = true
+
+ this._fst = fstream.Writer(opts)
+
+ this.pause()
+ var me = this
+
+ // Hardlinks in tarballs are relative to the root
+ // of the tarball. So, they need to be resolved against
+ // the target directory in order to be created properly.
+ me.on("entry", function (entry) {
+ if (entry.type !== "Link") return
+ entry.linkpath = entry.props.linkpath =
+ path.join(opts.path, path.join("/", entry.props.linkpath))
+ })
+
+ this._fst.on("ready", function () {
+ me.pipe(me._fst, { end: false })
+ me.resume()
+ })
+
+ // this._fst.on("end", function () {
+ // console.error("\nEEEE Extract End", me._fst.path)
+ // })
+
+ this._fst.on("close", function () {
+ // console.error("\nEEEE Extract End", me._fst.path)
+ me.emit("end")
+ me.emit("close")
+ })
+}
+
+inherits(Extract, tar.Parse)
+
+Extract.prototype._streamEnd = function () {
+ var me = this
+ if (!me._ended) me.error("unexpected eof")
+ me._fst.end()
+ // my .end() is coming later.
+}
diff --git a/node_modules/tar/lib/global-header-writer.js b/node_modules/tar/lib/global-header-writer.js
new file mode 100644
index 000000000..0bfc7b80a
--- /dev/null
+++ b/node_modules/tar/lib/global-header-writer.js
@@ -0,0 +1,14 @@
+module.exports = GlobalHeaderWriter
+
+var ExtendedHeaderWriter = require("./extended-header-writer.js")
+ , inherits = require("inherits")
+
+inherits(GlobalHeaderWriter, ExtendedHeaderWriter)
+
+function GlobalHeaderWriter (props) {
+ if (!(this instanceof GlobalHeaderWriter)) {
+ return new GlobalHeaderWriter(props)
+ }
+ ExtendedHeaderWriter.call(this, props)
+ this.props.type = "g"
+}
diff --git a/node_modules/tar/lib/header.js b/node_modules/tar/lib/header.js
new file mode 100644
index 000000000..05b237c0c
--- /dev/null
+++ b/node_modules/tar/lib/header.js
@@ -0,0 +1,385 @@
+// parse a 512-byte header block to a data object, or vice-versa
+// If the data won't fit nicely in a simple header, then generate
+// the appropriate extended header file, and return that.
+
+module.exports = TarHeader
+
+var tar = require("../tar.js")
+ , fields = tar.fields
+ , fieldOffs = tar.fieldOffs
+ , fieldEnds = tar.fieldEnds
+ , fieldSize = tar.fieldSize
+ , numeric = tar.numeric
+ , assert = require("assert").ok
+ , space = " ".charCodeAt(0)
+ , slash = "/".charCodeAt(0)
+ , bslash = process.platform === "win32" ? "\\".charCodeAt(0) : null
+
+function TarHeader (block) {
+ if (!(this instanceof TarHeader)) return new TarHeader(block)
+ if (block) this.decode(block)
+}
+
+TarHeader.prototype =
+ { decode : decode
+ , encode: encode
+ , calcSum: calcSum
+ , checkSum: checkSum
+ }
+
+TarHeader.parseNumeric = parseNumeric
+TarHeader.encode = encode
+TarHeader.decode = decode
+
+// note that this will only do the normal ustar header, not any kind
+// of extended posix header file. If something doesn't fit comfortably,
+// then it will set obj.needExtended = true, and set the block to
+// the closest approximation.
+function encode (obj) {
+ if (!obj && !(this instanceof TarHeader)) throw new Error(
+ "encode must be called on a TarHeader, or supplied an object")
+
+ obj = obj || this
+ var block = obj.block = new Buffer(512)
+
+ // if the object has a "prefix", then that's actually an extension of
+ // the path field.
+ if (obj.prefix) {
+ // console.error("%% header encoding, got a prefix", obj.prefix)
+ obj.path = obj.prefix + "/" + obj.path
+ // console.error("%% header encoding, prefixed path", obj.path)
+ obj.prefix = ""
+ }
+
+ obj.needExtended = false
+
+ if (obj.mode) {
+ if (typeof obj.mode === "string") obj.mode = parseInt(obj.mode, 8)
+ obj.mode = obj.mode & 0777
+ }
+
+ for (var f = 0; fields[f] !== null; f ++) {
+ var field = fields[f]
+ , off = fieldOffs[f]
+ , end = fieldEnds[f]
+ , ret
+
+ switch (field) {
+ case "cksum":
+ // special, done below, after all the others
+ break
+
+ case "prefix":
+ // special, this is an extension of the "path" field.
+ // console.error("%% header encoding, skip prefix later")
+ break
+
+ case "type":
+ // convert from long name to a single char.
+ var type = obj.type || "0"
+ if (type.length > 1) {
+ type = tar.types[obj.type]
+ if (!type) type = "0"
+ }
+ writeText(block, off, end, type)
+ break
+
+ case "path":
+ // uses the "prefix" field if > 100 bytes, but <= 255
+ var pathLen = Buffer.byteLength(obj.path)
+ , pathFSize = fieldSize[fields.path]
+ , prefFSize = fieldSize[fields.prefix]
+
+ // paths between 100 and 255 should use the prefix field.
+ // longer than 255
+ if (pathLen > pathFSize &&
+ pathLen <= pathFSize + prefFSize) {
+ // need to find a slash somewhere in the middle so that
+ // path and prefix both fit in their respective fields
+ var searchStart = pathLen - 1 - pathFSize
+ , searchEnd = prefFSize
+ , found = false
+ , pathBuf = new Buffer(obj.path)
+
+ for ( var s = searchStart
+ ; (s <= searchEnd)
+ ; s ++ ) {
+ if (pathBuf[s] === slash || pathBuf[s] === bslash) {
+ found = s
+ break
+ }
+ }
+
+ if (found !== false) {
+ prefix = pathBuf.slice(0, found).toString("utf8")
+ path = pathBuf.slice(found + 1).toString("utf8")
+
+ ret = writeText(block, off, end, path)
+ off = fieldOffs[fields.prefix]
+ end = fieldEnds[fields.prefix]
+ // console.error("%% header writing prefix", off, end, prefix)
+ ret = writeText(block, off, end, prefix) || ret
+ break
+ }
+ }
+
+ // paths less than 100 chars don't need a prefix
+ // and paths longer than 255 need an extended header and will fail
+ // on old implementations no matter what we do here.
+ // Null out the prefix, and fallthrough to default.
+ // console.error("%% header writing no prefix")
+ var poff = fieldOffs[fields.prefix]
+ , pend = fieldEnds[fields.prefix]
+ writeText(block, poff, pend, "")
+ // fallthrough
+
+ // all other fields are numeric or text
+ default:
+ ret = numeric[field]
+ ? writeNumeric(block, off, end, obj[field])
+ : writeText(block, off, end, obj[field] || "")
+ break
+ }
+ obj.needExtended = obj.needExtended || ret
+ }
+
+ var off = fieldOffs[fields.cksum]
+ , end = fieldEnds[fields.cksum]
+
+ writeNumeric(block, off, end, calcSum.call(this, block))
+
+ return block
+}
+
+// if it's a negative number, or greater than will fit,
+// then use write256.
+var MAXNUM = { 12: 077777777777
+ , 11: 07777777777
+ , 8 : 07777777
+ , 7 : 0777777 }
+function writeNumeric (block, off, end, num) {
+ var writeLen = end - off
+ , maxNum = MAXNUM[writeLen] || 0
+
+ num = num || 0
+ // console.error(" numeric", num)
+
+ if (num instanceof Date ||
+ Object.prototype.toString.call(num) === "[object Date]") {
+ num = num.getTime() / 1000
+ }
+
+ if (num > maxNum || num < 0) {
+ write256(block, off, end, num)
+ // need an extended header if negative or too big.
+ return true
+ }
+
+ // god, tar is so annoying
+ // if the string is small enough, you should put a space
+ // between the octal string and the \0, but if it doesn't
+ // fit, then don't.
+ var numStr = Math.floor(num).toString(8)
+ if (num < MAXNUM[writeLen - 1]) numStr += " "
+
+ // pad with "0" chars
+ if (numStr.length < writeLen) {
+ numStr = (new Array(writeLen - numStr.length).join("0")) + numStr
+ }
+
+ if (numStr.length !== writeLen - 1) {
+ throw new Error("invalid length: " + JSON.stringify(numStr) + "\n" +
+ "expected: "+writeLen)
+ }
+ block.write(numStr, off, writeLen, "utf8")
+ block[end - 1] = 0
+}
+
+function write256 (block, off, end, num) {
+ var buf = block.slice(off, end)
+ var positive = num >= 0
+ buf[0] = positive ? 0x80 : 0xFF
+
+ // get the number as a base-256 tuple
+ if (!positive) num *= -1
+ var tuple = []
+ do {
+ var n = num % 256
+ tuple.push(n)
+ num = (num - n) / 256
+ } while (num)
+
+ var bytes = tuple.length
+
+ var fill = buf.length - bytes
+ for (var i = 1; i < fill; i ++) {
+ buf[i] = positive ? 0 : 0xFF
+ }
+
+ // tuple is a base256 number, with [0] as the *least* significant byte
+ // if it's negative, then we need to flip all the bits once we hit the
+ // first non-zero bit. The 2's-complement is (0x100 - n), and the 1's-
+ // complement is (0xFF - n).
+ var zero = true
+ for (i = bytes; i > 0; i --) {
+ var byte = tuple[bytes - i]
+ if (positive) buf[fill + i] = byte
+ else if (zero && byte === 0) buf[fill + i] = 0
+ else if (zero) {
+ zero = false
+ buf[fill + i] = 0x100 - byte
+ } else buf[fill + i] = 0xFF - byte
+ }
+}
+
+function writeText (block, off, end, str) {
+ // strings are written as utf8, then padded with \0
+ var strLen = Buffer.byteLength(str)
+ , writeLen = Math.min(strLen, end - off)
+ // non-ascii fields need extended headers
+ // long fields get truncated
+ , needExtended = strLen !== str.length || strLen > writeLen
+
+ // write the string, and null-pad
+ if (writeLen > 0) block.write(str, off, writeLen, "utf8")
+ for (var i = off + writeLen; i < end; i ++) block[i] = 0
+
+ return needExtended
+}
+
+function calcSum (block) {
+ block = block || this.block
+ assert(Buffer.isBuffer(block) && block.length === 512)
+
+ if (!block) throw new Error("Need block to checksum")
+
+ // now figure out what it would be if the cksum was " "
+ var sum = 0
+ , start = fieldOffs[fields.cksum]
+ , end = fieldEnds[fields.cksum]
+
+ for (var i = 0; i < fieldOffs[fields.cksum]; i ++) {
+ sum += block[i]
+ }
+
+ for (var i = start; i < end; i ++) {
+ sum += space
+ }
+
+ for (var i = end; i < 512; i ++) {
+ sum += block[i]
+ }
+
+ return sum
+}
+
+
+function checkSum (block) {
+ var sum = calcSum.call(this, block)
+ block = block || this.block
+
+ var cksum = block.slice(fieldOffs[fields.cksum], fieldEnds[fields.cksum])
+ cksum = parseNumeric(cksum)
+
+ return cksum === sum
+}
+
+function decode (block) {
+ block = block || this.block
+ assert(Buffer.isBuffer(block) && block.length === 512)
+
+ this.block = block
+ this.cksumValid = this.checkSum()
+
+ var prefix = null
+
+ // slice off each field.
+ for (var f = 0; fields[f] !== null; f ++) {
+ var field = fields[f]
+ , val = block.slice(fieldOffs[f], fieldEnds[f])
+
+ switch (field) {
+ case "ustar":
+ // if not ustar, then everything after that is just padding.
+ if (val.toString() !== "ustar\0") {
+ this.ustar = false
+ return
+ } else {
+ // console.error("ustar:", val, val.toString())
+ this.ustar = val.toString()
+ }
+ break
+
+ // prefix is special, since it might signal the xstar header
+ case "prefix":
+ var atime = parseNumeric(val.slice(131, 131 + 12))
+ , ctime = parseNumeric(val.slice(131 + 12, 131 + 12 + 12))
+ if ((val[130] === 0 || val[130] === space) &&
+ typeof atime === "number" &&
+ typeof ctime === "number" &&
+ val[131 + 12] === space &&
+ val[131 + 12 + 12] === space) {
+ this.atime = atime
+ this.ctime = ctime
+ val = val.slice(0, 130)
+ }
+ prefix = val.toString("utf8").replace(/\0+$/, "")
+ // console.error("%% header reading prefix", prefix)
+ break
+
+ // all other fields are null-padding text
+ // or a number.
+ default:
+ if (numeric[field]) {
+ this[field] = parseNumeric(val)
+ } else {
+ this[field] = val.toString("utf8").replace(/\0+$/, "")
+ }
+ break
+ }
+ }
+
+ // if we got a prefix, then prepend it to the path.
+ if (prefix) {
+ this.path = prefix + "/" + this.path
+ // console.error("%% header got a prefix", this.path)
+ }
+}
+
+function parse256 (buf) {
+ // first byte MUST be either 80 or FF
+ // 80 for positive, FF for 2's comp
+ var positive
+ if (buf[0] === 0x80) positive = true
+ else if (buf[0] === 0xFF) positive = false
+ else return null
+
+ // build up a base-256 tuple from the least sig to the highest
+ var zero = false
+ , tuple = []
+ for (var i = buf.length - 1; i > 0; i --) {
+ var byte = buf[i]
+ if (positive) tuple.push(byte)
+ else if (zero && byte === 0) tuple.push(0)
+ else if (zero) {
+ zero = false
+ tuple.push(0x100 - byte)
+ } else tuple.push(0xFF - byte)
+ }
+
+ for (var sum = 0, i = 0, l = tuple.length; i < l; i ++) {
+ sum += tuple[i] * Math.pow(256, i)
+ }
+
+ return positive ? sum : -1 * sum
+}
+
+function parseNumeric (f) {
+ if (f[0] & 0x80) return parse256(f)
+
+ var str = f.toString("utf8").split("\0")[0].trim()
+ , res = parseInt(str, 8)
+
+ return isNaN(res) ? null : res
+}
+
diff --git a/node_modules/tar/lib/pack.js b/node_modules/tar/lib/pack.js
new file mode 100644
index 000000000..ed44686c8
--- /dev/null
+++ b/node_modules/tar/lib/pack.js
@@ -0,0 +1,226 @@
+// pipe in an fstream, and it'll make a tarball.
+// key-value pair argument is global extended header props.
+
+module.exports = Pack
+
+var EntryWriter = require("./entry-writer.js")
+ , Stream = require("stream").Stream
+ , path = require("path")
+ , inherits = require("inherits")
+ , GlobalHeaderWriter = require("./global-header-writer.js")
+ , collect = require("fstream").collect
+ , eof = new Buffer(512)
+
+for (var i = 0; i < 512; i ++) eof[i] = 0
+
+inherits(Pack, Stream)
+
+function Pack (props) {
+ // console.error("-- p ctor")
+ var me = this
+ if (!(me instanceof Pack)) return new Pack(props)
+
+ if (props) me._noProprietary = props.noProprietary
+ else me._noProprietary = false
+
+ me._global = props
+
+ me.readable = true
+ me.writable = true
+ me._buffer = []
+ // console.error("-- -- set current to null in ctor")
+ me._currentEntry = null
+ me._processing = false
+
+ me._pipeRoot = null
+ me.on("pipe", function (src) {
+ if (src.root === me._pipeRoot) return
+ me._pipeRoot = src
+ src.on("end", function () {
+ me._pipeRoot = null
+ })
+ me.add(src)
+ })
+}
+
+Pack.prototype.addGlobal = function (props) {
+ // console.error("-- p addGlobal")
+ if (this._didGlobal) return
+ this._didGlobal = true
+
+ var me = this
+ GlobalHeaderWriter(props)
+ .on("data", function (c) {
+ me.emit("data", c)
+ })
+ .end()
+}
+
+Pack.prototype.add = function (stream) {
+ if (this._global && !this._didGlobal) this.addGlobal(this._global)
+
+ if (this._ended) return this.emit("error", new Error("add after end"))
+
+ collect(stream)
+ this._buffer.push(stream)
+ this._process()
+ this._needDrain = this._buffer.length > 0
+ return !this._needDrain
+}
+
+Pack.prototype.pause = function () {
+ this._paused = true
+ if (this._currentEntry) this._currentEntry.pause()
+ this.emit("pause")
+}
+
+Pack.prototype.resume = function () {
+ this._paused = false
+ if (this._currentEntry) this._currentEntry.resume()
+ this.emit("resume")
+ this._process()
+}
+
+Pack.prototype.end = function () {
+ this._ended = true
+ this._buffer.push(eof)
+ this._process()
+}
+
+Pack.prototype._process = function () {
+ var me = this
+ if (me._paused || me._processing) {
+ return
+ }
+
+ var entry = me._buffer.shift()
+
+ if (!entry) {
+ if (me._needDrain) {
+ me.emit("drain")
+ }
+ return
+ }
+
+ if (entry.ready === false) {
+ // console.error("-- entry is not ready", entry)
+ me._buffer.unshift(entry)
+ entry.on("ready", function () {
+ // console.error("-- -- ready!", entry)
+ me._process()
+ })
+ return
+ }
+
+ me._processing = true
+
+ if (entry === eof) {
+ // need 2 ending null blocks.
+ me.emit("data", eof)
+ me.emit("data", eof)
+ me.emit("end")
+ me.emit("close")
+ return
+ }
+
+ // Change the path to be relative to the root dir that was
+ // added to the tarball.
+ //
+ // XXX This should be more like how -C works, so you can
+ // explicitly set a root dir, and also explicitly set a pathname
+ // in the tarball to use. That way we can skip a lot of extra
+ // work when resolving symlinks for bundled dependencies in npm.
+
+ var root = path.dirname((entry.root || entry).path)
+ var wprops = {}
+
+ Object.keys(entry.props).forEach(function (k) {
+ wprops[k] = entry.props[k]
+ })
+
+ if (me._noProprietary) wprops.noProprietary = true
+
+ wprops.path = path.relative(root, entry.path)
+
+ // actually not a matter of opinion or taste.
+ if (process.platform === "win32") {
+ wprops.path = wprops.path.replace(/\\/g, "/")
+ }
+
+ switch (wprops.type) {
+ // sockets not supported
+ case "Socket":
+ return
+
+ case "Directory":
+ wprops.path += "/"
+ wprops.size = 0
+ break
+ case "Link":
+ var lp = path.resolve(path.dirname(entry.path), entry.linkpath)
+ wprops.linkpath = path.relative(root, lp) || "."
+ wprops.size = 0
+ break
+ case "SymbolicLink":
+ var lp = path.resolve(path.dirname(entry.path), entry.linkpath)
+ wprops.linkpath = path.relative(path.dirname(entry.path), lp) || "."
+ wprops.size = 0
+ break
+ }
+
+ // console.error("-- new writer", wprops)
+ // if (!wprops.type) {
+ // // console.error("-- no type?", entry.constructor.name, entry)
+ // }
+
+ // console.error("-- -- set current to new writer", wprops.path)
+ var writer = me._currentEntry = EntryWriter(wprops)
+
+ writer.parent = me
+
+ // writer.on("end", function () {
+ // // console.error("-- -- writer end", writer.path)
+ // })
+
+ writer.on("data", function (c) {
+ me.emit("data", c)
+ })
+
+ writer.on("header", function () {
+ Buffer.prototype.toJSON = function () {
+ return this.toString().split(/\0/).join(".")
+ }
+ // console.error("-- -- writer header %j", writer.props)
+ if (writer.props.size === 0) nextEntry()
+ })
+ writer.on("close", nextEntry)
+
+ var ended = false
+ function nextEntry () {
+ if (ended) return
+ ended = true
+
+ // console.error("-- -- writer close", writer.path)
+ // console.error("-- -- set current to null", wprops.path)
+ me._currentEntry = null
+ me._processing = false
+ me._process()
+ }
+
+ writer.on("error", function (er) {
+ // console.error("-- -- writer error", writer.path)
+ me.emit("error", er)
+ })
+
+ // if it's the root, then there's no need to add its entries,
+ // or data, since they'll be added directly.
+ if (entry === me._pipeRoot) {
+ // console.error("-- is the root, don't auto-add")
+ writer.add = null
+ }
+
+ entry.pipe(writer)
+}
+
+Pack.prototype.destroy = function () {}
+Pack.prototype.write = function () {}
diff --git a/node_modules/tar/lib/parse.js b/node_modules/tar/lib/parse.js
new file mode 100644
index 000000000..884e73dba
--- /dev/null
+++ b/node_modules/tar/lib/parse.js
@@ -0,0 +1,270 @@
+
+// A writable stream.
+// It emits "entry" events, which provide a readable stream that has
+// header info attached.
+
+module.exports = Parse.create = Parse
+
+var stream = require("stream")
+ , Stream = stream.Stream
+ , BlockStream = require("block-stream")
+ , tar = require("../tar.js")
+ , TarHeader = require("./header.js")
+ , Entry = require("./entry.js")
+ , BufferEntry = require("./buffer-entry.js")
+ , ExtendedHeader = require("./extended-header.js")
+ , assert = require("assert").ok
+ , inherits = require("inherits")
+ , fstream = require("fstream")
+
+// reading a tar is a lot like reading a directory
+// However, we're actually not going to run the ctor,
+// since it does a stat and various other stuff.
+// This inheritance gives us the pause/resume/pipe
+// behavior that is desired.
+inherits(Parse, fstream.Reader)
+
+function Parse () {
+ var me = this
+ if (!(me instanceof Parse)) return new Parse()
+
+ // doesn't apply fstream.Reader ctor?
+ // no, becasue we don't want to stat/etc, we just
+ // want to get the entry/add logic from .pipe()
+ Stream.apply(me)
+
+ me.writable = true
+ me.readable = true
+ me._stream = new BlockStream(512)
+ me.position = 0
+
+ me._stream.on("error", function (e) {
+ me.emit("error", e)
+ })
+
+ me._stream.on("data", function (c) {
+ me._process(c)
+ })
+
+ me._stream.on("end", function () {
+ me._streamEnd()
+ })
+
+ me._stream.on("drain", function () {
+ me.emit("drain")
+ })
+}
+
+// overridden in Extract class, since it needs to
+// wait for its DirWriter part to finish before
+// emitting "end"
+Parse.prototype._streamEnd = function () {
+ var me = this
+ if (!me._ended) me.error("unexpected eof")
+ me.emit("end")
+}
+
+// a tar reader is actually a filter, not just a readable stream.
+// So, you should pipe a tarball stream into it, and it needs these
+// write/end methods to do that.
+Parse.prototype.write = function (c) {
+ if (this._ended) {
+ // gnutar puts a LOT of nulls at the end.
+ // you can keep writing these things forever.
+ // Just ignore them.
+ for (var i = 0, l = c.length; i > l; i ++) {
+ if (c[i] !== 0) return this.error("write() after end()")
+ }
+ return
+ }
+ return this._stream.write(c)
+}
+
+Parse.prototype.end = function (c) {
+ this._ended = true
+ return this._stream.end(c)
+}
+
+// don't need to do anything, since we're just
+// proxying the data up from the _stream.
+// Just need to override the parent's "Not Implemented"
+// error-thrower.
+Parse.prototype._read = function () {}
+
+Parse.prototype._process = function (c) {
+ assert(c && c.length === 512, "block size should be 512")
+
+ // one of three cases.
+ // 1. A new header
+ // 2. A part of a file/extended header
+ // 3. One of two or more EOF null blocks
+
+ if (this._entry) {
+ var entry = this._entry
+ entry.write(c)
+ if (entry._remaining === 0) {
+ entry.end()
+ this._entry = null
+ }
+ } else {
+ // either zeroes or a header
+ var zero = true
+ for (var i = 0; i < 512 && zero; i ++) {
+ zero = c[i] === 0
+ }
+
+ // eof is *at least* 2 blocks of nulls, and then the end of the
+ // file. you can put blocks of nulls between entries anywhere,
+ // so appending one tarball to another is technically valid.
+ // ending without the eof null blocks is not allowed, however.
+ if (zero) {
+ this._ended = this._eofStarted
+ this._eofStarted = true
+ } else {
+ this._ended = this._eofStarted = false
+ this._startEntry(c)
+ }
+
+ }
+
+ this.position += 512
+}
+
+// take a header chunk, start the right kind of entry.
+Parse.prototype._startEntry = function (c) {
+ var header = new TarHeader(c)
+ , self = this
+ , entry
+ , ev
+ , EntryType
+ , onend
+ , meta = false
+
+ if (null === header.size || !header.cksumValid) {
+ var e = new Error("invalid tar file")
+ e.header = header
+ e.tar_file_offset = this.position
+ e.tar_block = this.position / 512
+ this.emit("error", e)
+ }
+
+ switch (tar.types[header.type]) {
+ case "File":
+ case "OldFile":
+ case "Link":
+ case "SymbolicLink":
+ case "CharacterDevice":
+ case "BlockDevice":
+ case "Directory":
+ case "FIFO":
+ case "ContiguousFile":
+ case "GNUDumpDir":
+ // start a file.
+ // pass in any extended headers
+ // These ones consumers are typically most interested in.
+ EntryType = Entry
+ ev = "entry"
+ break
+
+ case "GlobalExtendedHeader":
+ // extended headers that apply to the rest of the tarball
+ EntryType = ExtendedHeader
+ onend = function () {
+ self._global = self._global || {}
+ Object.keys(entry.fields).forEach(function (k) {
+ self._global[k] = entry.fields[k]
+ })
+ }
+ ev = "globalExtendedHeader"
+ meta = true
+ break
+
+ case "ExtendedHeader":
+ case "OldExtendedHeader":
+ // extended headers that apply to the next entry
+ EntryType = ExtendedHeader
+ onend = function () {
+ self._extended = entry.fields
+ }
+ ev = "extendedHeader"
+ meta = true
+ break
+
+ case "NextFileHasLongLinkpath":
+ // set linkpath=<contents> in extended header
+ EntryType = BufferEntry
+ onend = function () {
+ self._extended = self._extended || {}
+ self._extended.linkpath = entry.body
+ }
+ ev = "longLinkpath"
+ meta = true
+ break
+
+ case "NextFileHasLongPath":
+ case "OldGnuLongPath":
+ // set path=<contents> in file-extended header
+ EntryType = BufferEntry
+ onend = function () {
+ self._extended = self._extended || {}
+ self._extended.path = entry.body
+ }
+ ev = "longPath"
+ meta = true
+ break
+
+ default:
+ // all the rest we skip, but still set the _entry
+ // member, so that we can skip over their data appropriately.
+ // emit an event to say that this is an ignored entry type?
+ EntryType = Entry
+ ev = "ignoredEntry"
+ break
+ }
+
+ var global, extended
+ if (meta) {
+ global = extended = null
+ } else {
+ var global = this._global
+ var extended = this._extended
+
+ // extendedHeader only applies to one entry, so once we start
+ // an entry, it's over.
+ this._extended = null
+ }
+ entry = new EntryType(header, extended, global)
+ entry.meta = meta
+
+ // only proxy data events of normal files.
+ if (!meta) {
+ entry.on("data", function (c) {
+ me.emit("data", c)
+ })
+ }
+
+ if (onend) entry.on("end", onend)
+
+ this._entry = entry
+ var me = this
+
+ entry.on("pause", function () {
+ me.pause()
+ })
+
+ entry.on("resume", function () {
+ me.resume()
+ })
+
+ if (this.listeners("*").length) {
+ this.emit("*", ev, entry)
+ }
+
+ this.emit(ev, entry)
+
+ // Zero-byte entry. End immediately.
+ if (entry.props.size === 0) {
+ entry.end()
+ this._entry = null
+ }
+}
diff --git a/node_modules/tar/package.json b/node_modules/tar/package.json
new file mode 100644
index 000000000..0836977a1
--- /dev/null
+++ b/node_modules/tar/package.json
@@ -0,0 +1,26 @@
+{
+ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
+ "name": "tar",
+ "description": "tar for node",
+ "version": "0.1.11",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/node-tar.git"
+ },
+ "main": "tar.js",
+ "scripts": {
+ "test": "rm -rf test/tmp; tap test/*.js"
+ },
+ "engines": {
+ "node": "~0.5.9 || 0.6 || 0.7 || 0.8"
+ },
+ "dependencies": {
+ "inherits": "1.x",
+ "block-stream": "*",
+ "fstream": "~0.1.8"
+ },
+ "devDependencies": {
+ "tap": "0.x",
+ "rimraf": "1.x"
+ }
+}
diff --git a/node_modules/tar/tar.js b/node_modules/tar/tar.js
new file mode 100644
index 000000000..b9dbca489
--- /dev/null
+++ b/node_modules/tar/tar.js
@@ -0,0 +1,172 @@
+// 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
+ , 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")