diff --git a/headers.js b/headers.js index e168caa..992be10 100644 --- a/headers.js +++ b/headers.js @@ -198,6 +198,7 @@ exports.decode = function(buf) { var gid = decodeOct(buf, 116) var size = decodeOct(buf, 124) var mtime = decodeOct(buf, 136) + var type = toType(typeflag) var linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100) var uname = decodeStr(buf, 265, 32) var gname = decodeStr(buf, 297, 32) @@ -224,7 +225,7 @@ exports.decode = function(buf) { gid: gid, size: size, mtime: new Date(1000 * mtime), - type: toType(typeflag), + type: type, linkname: linkname, uname: uname, gname: gname, diff --git a/pack.js b/pack.js index eec3496..463448f 100644 --- a/pack.js +++ b/pack.js @@ -1,10 +1,13 @@ -var util = require('util') +var constants = require('constants') var eos = require('end-of-stream') -var headers = require('./headers') +var util = require('util') var Readable = require('readable-stream').Readable -var Writable = require('readable-stream').Writable var PassThrough = require('readable-stream').PassThrough +var Writable = require('readable-stream').Writable + +var headers = require('./headers') + var END_OF_TAR = new Buffer(1024) END_OF_TAR.fill(0) @@ -16,6 +19,18 @@ var overflow = function(self, size) { if (size) self.push(END_OF_TAR.slice(0, 512 - size)) } +function mode2type(mode) { + switch (mode & constants.S_IFMT) { + case constants.S_IFBLK: return 'block-device' + case constants.S_IFCHR: return 'character-device' + case constants.S_IFDIR: return 'directory' + case constants.S_IFIFO: return 'fifo' + case constants.S_IFLNK: return 'symlink' + } + + return 'file' +} + var Sink = function(to) { Writable.call(this) this.written = 0 @@ -81,7 +96,7 @@ Pack.prototype.entry = function(header, buffer, callback) { var self = this if (!header.size) header.size = 0 - if (!header.type) header.type = 'file' + if (!header.type) header.type = mode2type(header.mode) if (!header.mode) header.mode = header.type === 'directory' ? 0755 : 0644 if (!header.uid) header.uid = 0 if (!header.gid) header.gid = 0 @@ -96,15 +111,38 @@ Pack.prototype.entry = function(header, buffer, callback) { process.nextTick(callback) return new Void() } + + if (header.type === 'symlink' && !header.linkname) { + var stream = new Writable + var linkname = '' + + stream._write = function(data, enc, cb) { + linkname += data + cb() + } + eos(stream, function(err) { + if (err) { // stream was closed + self.destroy() + return callback(err) + } + + header.linkname = linkname + self._encode(header) + callback() + }) + + return stream + } + + this._encode(header) + if (header.type !== 'file' && header.type !== 'contigious-file') { - this._encode(header) process.nextTick(callback) return new Void() } var sink = new Sink(this) - this._encode(header) this._stream = sink eos(sink, function(err) {