UNPKG

@ccos/package_maker

Version:

Coocaa WebOS APP Command-Line Tools.

221 lines (212 loc) 8.13 kB
import path from 'path'; import fs from 'fs'; let currTimeStamp = 0; function numberToOctalString(number, maxlength) { let octStr = number.toString(8); if (octStr.length < maxlength) { let fillSize = maxlength - octStr.length; let prefix = ''; for (let i = 0; i < fillSize; i++) { prefix = prefix + '0'; } octStr = prefix + octStr; } return octStr; } function writeTarHeader(tarFileHandler, shortPath, isDir, fileSize) { let nameBuf = Buffer.from(shortPath, 'utf8'); const header = Buffer.alloc(512); header.fill(0); if (nameBuf.length > 99) { // long name //console.log('longname: ' + shortPath); // let longNameLength = nameBuf.length + 1; //=====fill header========== // name const longLinkFlagBuf = Buffer.from('././@LongLink', 'utf8'); header.fill(longLinkFlagBuf, 0, longLinkFlagBuf.length); // file mode const file_mode = Buffer.from('0000644', 'utf8'); header.fill(file_mode, 0x0064, 0x0064 + file_mode.length); // owner user ID const uid = Buffer.from('0000000', 'utf8'); header.fill(uid, 0x006C, 0x006C + uid.length); // owner group ID const gid = Buffer.from('0000000', 'utf8'); header.fill(gid, 0x0074, 0x0074 + gid.length); // length of file in bytes const filesize = Buffer.from(numberToOctalString(longNameLength, 11), 'utf8'); header.fill(filesize, 0x007C, 0x007C + filesize.length); // modify time of file const modifytime = Buffer.from(numberToOctalString(0, 11), 'utf8'); header.fill(modifytime, 0x0088, 0x0088 + modifytime.length); // type of file const filetype = Buffer.from('L', 'utf8'); header.fill(filetype, 0x009C, 0x009C + filetype.length); // USTAR const ustar = Buffer.from('ustar ', 'utf8'); header.fill(ustar, 0x0101, 0x0101 + ustar.length); // checksum const dummy_checksum = Buffer.from(' ', 'utf8'); header.fill(dummy_checksum, 0x0094, 0x0094 + dummy_checksum.length); let curSum = 0; for (let i = 0; i < 512; i++) { curSum += header.readUInt8(i); } const checksum = Buffer.from(numberToOctalString(curSum, 7), 'utf8'); header.fill(checksum, 0x0094, 0x0094 + checksum.length); // fs.writeSync(tarFileHandler, header, 0, 512, null); // //写入文件名 // const a1 = parseInt(longNameLength / 512); const a2 = longNameLength % 512; let blockCount = a1; if (a2 != 0) { blockCount ++; } let longNameBuffer = Buffer.alloc(512 * blockCount); longNameBuffer.fill(0); longNameBuffer.fill(nameBuf, 0, nameBuf.length); fs.writeSync(tarFileHandler, longNameBuffer, 0, 512 * blockCount, null); // let newShortName = '@PathCut/_pc_root/' + shortPath; newShortName = newShortName.substring(0, 100); nameBuf = Buffer.from(newShortName, 'utf8'); } //=====fill header========== // name header.fill(nameBuf, 0, nameBuf.length); // file mode const file_mode = Buffer.from('0000777', 'utf8'); header.fill(file_mode, 0x0064, 0x0064 + file_mode.length); // owner user ID const uid = Buffer.from('0000000', 'utf8'); header.fill(uid, 0x006C, 0x006C + uid.length); // owner group ID const gid = Buffer.from('0000000', 'utf8'); header.fill(gid, 0x0074, 0x0074 + gid.length); // length of file in bytes const filesize = Buffer.from(numberToOctalString(fileSize, 11), 'utf8'); header.fill(filesize, 0x007C, 0x007C + filesize.length); // modify time of file const modifytime = Buffer.from(numberToOctalString(currTimeStamp, 11), 'utf8'); header.fill(modifytime, 0x0088, 0x0088 + modifytime.length); // type of file const filetype = Buffer.from(isDir ? '5' : '0', 'utf8'); header.fill(filetype, 0x009C, 0x009C + filetype.length); // USTAR const ustar = Buffer.from('ustar ', 'utf8'); header.fill(ustar, 0x0101, 0x0101 + ustar.length); // checksum const dummy_checksum = Buffer.from(' ', 'utf8'); header.fill(dummy_checksum, 0x0094, 0x0094 + dummy_checksum.length); let curSum = 0; for (let i = 0; i < 512; i++) { curSum += header.readUInt8(i); } const checksum = Buffer.from(numberToOctalString(curSum, 7), 'utf8'); header.fill(checksum, 0x0094, 0x0094 + checksum.length); // fs.writeSync(tarFileHandler, header, 0, 512, null); } function addItem(tarFileHandler, fromInfo, fileSize) { if (fromInfo.isDir) { // // 插入tar内容 if (fromInfo.shortPath != '') { writeTarHeader(tarFileHandler, fromInfo.shortPath, true, 0); } //console.log('tar增加目录:' + fromInfo.fullPath); //console.log(' 内部路径:' + fromInfo.shortPath); // const subItems = fs.readdirSync(fromInfo.fullPath); for (const subName of subItems) { let subFullPath = path.join(fromInfo.fullPath, subName); let subShortPath = fromInfo.shortPath + subName; const stats = fs.statSync(subFullPath); if (stats.isDirectory()) { subShortPath = subShortPath + '/'; let subInfo = { isDir: true, fullPath: subFullPath, shortPath: subShortPath, }; addItem(tarFileHandler, subInfo, 0); } else if (stats.isFile()) { let subInfo = { isDir: false, fullPath: subFullPath, shortPath: subShortPath, }; addItem(tarFileHandler, subInfo, stats.size); } //只处理目录与普通文件 } } else { // ////console.log('tar增加文件:' + fromInfo.fullPath); ////console.log(' 内部路径:' + fromInfo.shortPath); // // 写入tar 头 writeTarHeader(tarFileHandler, fromInfo.shortPath, false, fileSize); if (fileSize == 0) { return 0; } // 下面将文件内容写入到 tar 里面 const fd = fs.openSync(fromInfo.fullPath, 'r'); if (!fd) { console.error('cannot open file: ' + fromInfo.fullPath); return -1; } let readSize = 0; let buffer = Buffer.alloc(32768); let writeTotal = 0; while (true) { readSize = fs.readSync(fd, buffer, 0, 32768, null); if (readSize > 0) { fs.writeSync(tarFileHandler, buffer, 0, readSize, null); writeTotal += readSize; } else { break; } } // 下面做512字节对齐 let outSize = writeTotal % 512; if (outSize > 0) { outSize = 512 - outSize; buffer.fill(0); fs.writeSync(tarFileHandler, buffer, 0, outSize, null); } // // fs.closeSync(fd); } return 0; } function makeTarFile(tarSourceFullPath, tarFileName) { //console.log('start path = ' + tarSourceFullPath); currTimeStamp = new Date().getTime(); currTimeStamp = parseInt(currTimeStamp / 1000); const tarFileHandler = fs.openSync(tarFileName, 'w'); if (!tarFileHandler) { console.error('cannot open file: ' + tarFileName); return -1; } let rootInfo = { isDir: true, fullPath: tarSourceFullPath, shortPath: '', }; addItem(tarFileHandler, rootInfo, 0); // fs.closeSync(tarFileHandler); return 0; } export default { makeTarFile };