Skip to content

Commit

Permalink
fixing tar: 1. no longer infinite loop when enqueuing multiple jobs 2…
Browse files Browse the repository at this point in the history
…. added type option (directories) 3. allows dates for mtime options 4. added a couple utility methods
  • Loading branch information
dmcaulay committed Jun 26, 2012
1 parent 8961d61 commit 13fa00c
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 34 deletions.
63 changes: 40 additions & 23 deletions lib/tar.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@
this.emit('data', header);
this.written += header.length;

if (size == 0) {
this.dequeueNextJob();
return callback();
}

// if it's a string/Buffer, we can just write it out to the stream
if (typeof input === 'string' || input instanceof Buffer) {
this.emit('data', input);
Expand All @@ -112,32 +117,14 @@

tape.processing = false;

if (queue.length > 0) {
process.nextTick(function () {
var job = queue.shift();

if (typeof job.input === 'object' && typeof job.input.resume === 'function') {
job.input.resume();
}

tape.append(job.filepath, job.input, job.opts, job.cb);
});
}
tape.dequeueNextJob();

return callback();
});
}
};

Tar.prototype.append = function (filepath, input, opts, callback) {
var data,
mode,
mtime,
uid,
gid,
size,
tape = this;

if (typeof opts === 'function') {
callback = opts;
opts = {};
Expand All @@ -154,7 +141,7 @@
}

if (this.processing || queue.length) {
if (typeof input === 'object' && typeof input.pause === 'function') {
if (input && typeof input === 'object' && typeof input.pause === 'function') {
input.pause();
}

Expand All @@ -165,15 +152,30 @@
cb: callback
});
return;
}
}
this.processAppend(filepath, input, opts, callback);
};

Tar.prototype.processAppend = function (filepath, input, opts, callback) {
var data,
mode,
mtime,
uid,
gid,
size,
type,
tape = this;

opts = opts || {};

mode = typeof opts.mode === 'number' ? opts.mode : parseInt('777', 8) & 0xfff;
mtime = typeof opts.mtime === 'number' ? opts.mtime : parseInt(+new Date() / 1000);
uid = typeof opts.uid === 'number' ? opts.uid : 0;
gid = typeof opts.gid === 'number' ? opts.gid : 0;
size = typeof opts.size === 'number' ? opts.size : input.length;
mtime = utils.calculateTarDate(opts.mtime, new Date());
utils.fileTypeToIndex(opts.type, function(err, index) {
type = err ? '0' : index.toString();
});

// if you give me a stream, you must tell me how big it is
// since the header comes first, the only other solution is to
Expand All @@ -196,7 +198,7 @@
size: utils.pad(size, 11),
mtime: utils.pad(mtime, 11),
checksum: ' ',
type: '0', // just a file
type: type,
ustar: 'ustar ',
owner: '',
group: ''
Expand All @@ -215,6 +217,21 @@
this.writeData(callback, this.createHeader(data), input, size);
}
};

Tar.prototype.dequeueNextJob = function() {
var tape = this;
if (queue.length > 0) {
process.nextTick(function () {
var job = queue.shift();

if (job.input && typeof job.input === 'object' && typeof job.input.resume === 'function') {
job.input.resume();
}

tape.processAppend(job.filepath, job.input, job.opts, job.cb);
});
}
};

module.exports = Tar;
}());
21 changes: 10 additions & 11 deletions lib/untar.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
(function () {
"use strict";

var utils = require('./utils');

var Stream = require('stream').Stream,
headerFormat = require('./header').structure,
buffer,
totalRead = 0,
recordSize = 512,
fileStream,
leftToRead,
fileTypes = [
'normal', 'hard-link', 'symbolic-link', 'character-special', 'block-special', 'directory', 'fifo', 'contiguous-file'
];
leftToRead;

function filterDecoder(input) {
var filter = [];
Expand All @@ -28,13 +27,13 @@
}

input.forEach(function (i) {
var index = fileTypes.indexOf(i);
if (index < 0) {
console.error('Filetype not valid. Ignoring input:', i);
return;
}

filter.push(index);
utils.fileTypeToIndex(i, function(err, index) {
if (err) {
console.error(err + " Ignoring input:" + i);
} else {
filter.push(index);
}
});
});

return filter;
Expand Down
32 changes: 32 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
(function () {
"use strict";

var util = require('util'),
fileTypes = [
'normal', 'hard-link', 'symbolic-link', 'character-special', 'block-special', 'directory', 'fifo', 'contiguous-file'
];

function fileTypeToIndex(fileType, callback) {
var index = fileTypes.indexOf(fileType);
if (index < 0) {
callback('Invalid fileType.', index);
} else {
callback(null, index);
}
}

function convertToTarDate(date) {
return parseInt(date/1000);
}

function calculateTarDate(input, defaultDate) {
if (typeof input === 'number') {
return input;
} else if (util.isDate(input)) {
return convertToTarDate(input);
} else if (typeof defaultDate == 'number') {
return defaultDate;
} else {
return convertToTarDate(defaultDate);
}
}

function clean(length) {
var i, buffer = new Buffer(length);
for (i = 0; i < length; i += 1) {
Expand Down Expand Up @@ -36,6 +66,8 @@
});
}

module.exports.fileTypeToIndex = fileTypeToIndex;
module.exports.calculateTarDate = calculateTarDate;
module.exports.clean = clean;
module.exports.pad = pad;
module.exports.readAll = readAll;
Expand Down

0 comments on commit 13fa00c

Please sign in to comment.