Merge pull request #42 from NodeOS/master
Detect file type from 'mode' field & allow to stream symlinks content
This commit is contained in:
commit
e685cb179e
2 changed files with 46 additions and 7 deletions
|
@ -198,6 +198,7 @@ exports.decode = function(buf) {
|
||||||
var gid = decodeOct(buf, 116)
|
var gid = decodeOct(buf, 116)
|
||||||
var size = decodeOct(buf, 124)
|
var size = decodeOct(buf, 124)
|
||||||
var mtime = decodeOct(buf, 136)
|
var mtime = decodeOct(buf, 136)
|
||||||
|
var type = toType(typeflag)
|
||||||
var linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100)
|
var linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100)
|
||||||
var uname = decodeStr(buf, 265, 32)
|
var uname = decodeStr(buf, 265, 32)
|
||||||
var gname = decodeStr(buf, 297, 32)
|
var gname = decodeStr(buf, 297, 32)
|
||||||
|
@ -224,7 +225,7 @@ exports.decode = function(buf) {
|
||||||
gid: gid,
|
gid: gid,
|
||||||
size: size,
|
size: size,
|
||||||
mtime: new Date(1000 * mtime),
|
mtime: new Date(1000 * mtime),
|
||||||
type: toType(typeflag),
|
type: type,
|
||||||
linkname: linkname,
|
linkname: linkname,
|
||||||
uname: uname,
|
uname: uname,
|
||||||
gname: gname,
|
gname: gname,
|
||||||
|
|
50
pack.js
50
pack.js
|
@ -1,10 +1,13 @@
|
||||||
var util = require('util')
|
var constants = require('constants')
|
||||||
var eos = require('end-of-stream')
|
var eos = require('end-of-stream')
|
||||||
var headers = require('./headers')
|
var util = require('util')
|
||||||
|
|
||||||
var Readable = require('readable-stream').Readable
|
var Readable = require('readable-stream').Readable
|
||||||
var Writable = require('readable-stream').Writable
|
|
||||||
var PassThrough = require('readable-stream').PassThrough
|
var PassThrough = require('readable-stream').PassThrough
|
||||||
|
var Writable = require('readable-stream').Writable
|
||||||
|
|
||||||
|
var headers = require('./headers')
|
||||||
|
|
||||||
|
|
||||||
var END_OF_TAR = new Buffer(1024)
|
var END_OF_TAR = new Buffer(1024)
|
||||||
END_OF_TAR.fill(0)
|
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))
|
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) {
|
var Sink = function(to) {
|
||||||
Writable.call(this)
|
Writable.call(this)
|
||||||
this.written = 0
|
this.written = 0
|
||||||
|
@ -81,7 +96,7 @@ Pack.prototype.entry = function(header, buffer, callback) {
|
||||||
var self = this
|
var self = this
|
||||||
|
|
||||||
if (!header.size) header.size = 0
|
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.mode) header.mode = header.type === 'directory' ? 0755 : 0644
|
||||||
if (!header.uid) header.uid = 0
|
if (!header.uid) header.uid = 0
|
||||||
if (!header.gid) header.gid = 0
|
if (!header.gid) header.gid = 0
|
||||||
|
@ -96,15 +111,38 @@ Pack.prototype.entry = function(header, buffer, callback) {
|
||||||
process.nextTick(callback)
|
process.nextTick(callback)
|
||||||
return new Void()
|
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') {
|
if (header.type !== 'file' && header.type !== 'contigious-file') {
|
||||||
this._encode(header)
|
|
||||||
process.nextTick(callback)
|
process.nextTick(callback)
|
||||||
return new Void()
|
return new Void()
|
||||||
}
|
}
|
||||||
|
|
||||||
var sink = new Sink(this)
|
var sink = new Sink(this)
|
||||||
|
|
||||||
this._encode(header)
|
|
||||||
this._stream = sink
|
this._stream = sink
|
||||||
|
|
||||||
eos(sink, function(err) {
|
eos(sink, function(err) {
|
||||||
|
|
Loading…
Reference in a new issue