mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
261 lines
8.4 KiB
JavaScript
261 lines
8.4 KiB
JavaScript
/*
|
|
Copyright 2019 Intel Corporation
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
var readable = require('stream').Readable;
|
|
|
|
|
|
function loadUstarHeader(path, offset)
|
|
{
|
|
var fd = require('fs').openSync(path, 'rb');
|
|
var buffer = Buffer.alloc(512);
|
|
var result = require('fs').readSync(fd, buffer, 0, 512, offset);
|
|
require('fs').closeSync(fd);
|
|
|
|
var v = 0;
|
|
for (var i = 0; i < 512; ++i)
|
|
{
|
|
if (i >= 148 && i < 155)
|
|
{
|
|
v += 32;
|
|
}
|
|
else
|
|
{
|
|
v += buffer[i];
|
|
}
|
|
}
|
|
|
|
if (parseInt(buffer.slice(148, 148 + 8).toString(), 8) != (new Uint32Array([v]))[0])
|
|
{
|
|
return (null);
|
|
}
|
|
else
|
|
{
|
|
return (buffer);
|
|
}
|
|
}
|
|
|
|
function generateUstarHeader(path, basePath, uidtable, gidtable)
|
|
{
|
|
var ret = Buffer.alloc(512);
|
|
var stats = require('fs').statSync(path);
|
|
var name = process.platform == 'win32' ? path.split('\\').join('/') : path;
|
|
if (basePath) { name = name.substring(basePath.endsWith('/') ? basePath.length : (basePath.length + 1)); }
|
|
|
|
if (stats.isFile())
|
|
{
|
|
Buffer.from(stats.size.toString(8), 'binary').copy(ret, 124, 0, 12);
|
|
Object.defineProperty(ret, 'isFile', { value: true });
|
|
}
|
|
else
|
|
{
|
|
Buffer.from('0').copy(ret, 124, 0, 12);
|
|
Object.defineProperty(ret, 'isFile', { value: false });
|
|
name += '/';
|
|
}
|
|
|
|
Buffer.from(name, 'binary').copy(ret, 0, 0, 100);
|
|
ret[156] = stats.isFile() ? 48 : 53;
|
|
Buffer.from((Date.parse(stats.mtime) / 1000).toString(8), 'binary').copy(ret, 136, 0, 12);
|
|
Buffer.from('USTAR', 'binary').copy(ret, 257, 0, 5);
|
|
|
|
if (process.platform == 'win32')
|
|
{
|
|
// Windows Platforms, set UID/GID to 0
|
|
Buffer.from('0', 'binary').copy(ret, 108, 0, 8); // uid
|
|
Buffer.from('0', 'binary').copy(ret, 116, 0, 8); // gid
|
|
|
|
// Windows Platforms, set uname/gname to root/root
|
|
Buffer.from('root', 'binary').copy(ret, 265, 0, 32);
|
|
Buffer.from('root', 'binary').copy(ret, 297, 0, 32);
|
|
|
|
// Windows Platforms, set mode to (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
|
|
var m = require('fs').CHMOD_MODES;
|
|
Buffer.from((m.S_IRUSR | m.S_IWUSR | m.S_IRGRP | m.S_IWGRP | m.S_IROTH | m.S_IWOTH).toString(8), 'binary').copy(ret, 100, 0, 8);
|
|
}
|
|
else
|
|
{
|
|
// POSIX platforms, set the UID/GID
|
|
Buffer.from(stats.uid.toString(8), 'binary').copy(ret, 108, 0, 8); // uid
|
|
Buffer.from(stats.gid.toString(8), 'binary').copy(ret, 116, 0, 8); // gid
|
|
|
|
if (!uidtable[stats.uid]) { uidtable[stats.uid] = require('user-sessions').getUsername(stats.uid); }
|
|
if (!gidtable[stats.gid]) { gidtable[stats.gid] = require('user-sessions').getGroupname(stats.gid); }
|
|
|
|
Buffer.from(uidtable[stats.uid], 'binary').copy(ret, 265, 0, 32);
|
|
Buffer.from(gidtable[stats.gid], 'binary').copy(ret, 297, 0, 32);
|
|
|
|
// Set Mode
|
|
Buffer.from(stats.mode.toString(8), 'binary').copy(ret, 100, 0, 8);
|
|
}
|
|
|
|
|
|
var checksum = 0;
|
|
for (var i = 0; i < 8; ++i)
|
|
{
|
|
ret[148 + i] = 32; // Blank out the checksum, so we can calculate the checksum, then write it back
|
|
}
|
|
for (var i = 0; i < 512; ++i)
|
|
{
|
|
checksum += ret[i];
|
|
}
|
|
Buffer.from(checksum.toString(8), 'binary').copy(ret, 148, 0, 8); // Write the checksum
|
|
return (ret);
|
|
}
|
|
|
|
function encodeFiles(files, basePath)
|
|
{
|
|
var ret = new readable(
|
|
{
|
|
read: function read()
|
|
{
|
|
var bytesRead;
|
|
var ok = true;
|
|
if(this._fd == null)
|
|
{
|
|
if (this.files.length > 0)
|
|
{
|
|
var name = this.files.shift();
|
|
var header = generateUstarHeader(name, this._basePath, this._uidTable, this._gidTable);
|
|
if (header.isFile) { this._fd = require('fs').openSync(name, 'rb'); }
|
|
ok = this.push(header);
|
|
}
|
|
else
|
|
{
|
|
this.pause();
|
|
this.push(null);
|
|
return;
|
|
}
|
|
}
|
|
while(this._fd != null && ok)
|
|
{
|
|
bytesRead = require('fs').readSync(this._fd, this._buffer, 0, 512);
|
|
this._buffer.fill(0, bytesRead, 512);
|
|
if (bytesRead < 512)
|
|
{
|
|
require('fs').closeSync(this._fd);
|
|
this._fd = null;
|
|
}
|
|
ok = this.push(this._buffer);
|
|
}
|
|
}
|
|
});
|
|
ret.files = files;
|
|
ret._basePath = basePath;
|
|
ret._fd = null;
|
|
ret._buffer = Buffer.alloc(512);
|
|
ret._uidTable = {};
|
|
ret._gidTable = {};
|
|
return (ret);
|
|
}
|
|
|
|
function expandFolderPaths(folderPath, recurse, arr)
|
|
{
|
|
var files = require('fs').readdirSync(folderPath);
|
|
for(var f in files)
|
|
{
|
|
if(require('fs').statSync(folderPath + '/' + files[f]).isDirectory())
|
|
{
|
|
if (recurse)
|
|
{
|
|
arr.push(folderPath + '/' + files[f]);
|
|
expandFolderPaths(folderPath + '/' + files[f], recurse, arr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
arr.push(folderPath + '/' + files[f]);
|
|
}
|
|
}
|
|
}
|
|
|
|
function encodeFolder(folderPath, recurse)
|
|
{
|
|
var files = [];
|
|
expandFolderPaths(folderPath, recurse, files);
|
|
return (encodeFiles(files, folderPath));
|
|
}
|
|
|
|
function showHeader(path, offset)
|
|
{
|
|
do
|
|
{
|
|
var b = loadUstarHeader(path, offset);
|
|
if (b == null) { break; }
|
|
if (offset != null && isNaN(offset)) { process.exit();}
|
|
console.log('-----------------------------');
|
|
console.log('THIS Offset: ' + (offset == null ? 0 : offset));
|
|
var mtime = parseInt(b.slice(136, 136 + 12).toString(), 8) * 1000;
|
|
console.log('name: ' + b.slice(0, 100).toString());
|
|
console.log('size: ' + parseInt(b.slice(124, 124 + 12).toString(), 8));
|
|
console.log('mtime: ' + (new Date(mtime)).toString());
|
|
console.log('type: ' + String.fromCharCode(b[156]));
|
|
console.log('linkname: ' + b.slice(157, 257).toString());
|
|
console.log('magic: ' + b.slice(257, 257 + 6).toString());
|
|
console.log('version: ' + b.slice(263, 265).toString('hex'));
|
|
console.log('uname: ' + b.slice(265, 265 + 32).toString());
|
|
console.log('uid: ' + parseInt(b.slice(108, 108 + 8).toString(), 8));
|
|
console.log('gname: ' + b.slice(297, 297 + 32).toString());
|
|
console.log('gid: ' + parseInt(b.slice(116, 116 + 8).toString(), 8));
|
|
console.log('prefix: ' + b.slice(345, 345 + 155).toString());
|
|
console.log('mode: ' + b.slice(100, 100 + 8).toString());
|
|
console.log('checksum: ' + parseInt(b.slice(148, 148 + 8).toString(), 8).toString());
|
|
|
|
// Calculate Checksum
|
|
for (var i = 0; i < 8; ++i)
|
|
{
|
|
b[148 + i] = 32;
|
|
}
|
|
|
|
var v = 0;
|
|
for (var i = 0; i < 512; ++i)
|
|
{
|
|
v += b[i];
|
|
}
|
|
|
|
v = (new Uint32Array([v]))[0]
|
|
console.log('Computed Checksum: ' + v.toString());
|
|
console.log('');
|
|
if (String.fromCharCode(b[156]) == '5')
|
|
{
|
|
if(offset == null)
|
|
{
|
|
offset = 512;
|
|
}
|
|
else
|
|
{
|
|
offset += 512;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var filesize = parseInt(b.slice(124, 124 + 12).toString(), 8);
|
|
var recordskip = Math.floor(filesize / 512);
|
|
if (filesize % 512 != 0) { ++recordskip; }
|
|
if (offset == null)
|
|
{
|
|
offset = recordskip * 512;
|
|
}
|
|
else
|
|
{
|
|
offset += (recordskip * 512);
|
|
}
|
|
offset += 512;
|
|
}
|
|
} while (offset != null);
|
|
}
|
|
|
|
module.exports = { encodeFolder: encodeFolder, encodeFiles: encodeFiles, showHeader: showHeader };
|