From 6857648056b8ab304537d5ebdc6715aba3e2f4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wierci=C5=84ski?= Date: Sun, 8 Sep 2019 23:38:24 +0200 Subject: [PATCH 1/2] Added new stat method to the smb2Client --- .gitignore | 1 + README.md | 9 ++++++ TODO.md | 1 - lib/api/stat.js | 72 +++++++++++++++++++++++++++++++++++++++++ lib/smb2.js | 1 + lib/tools/smb2-forge.js | 4 +-- package-lock.json | 13 ++++++++ package.json | 3 +- 8 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 lib/api/stat.js diff --git a/.gitignore b/.gitignore index 704aecb..f21aec7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules test.js +.vscode diff --git a/README.md b/README.md index e1ce82f..b20e031 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,15 @@ smb2Client.exists('path\\to\\my\\file.txt', function (err, exists) { }); ``` +### smb2Client.exists ( path, callback ) +Returns basic info about a file. Example: +```javascript +smb2Client.stat('path\\to\\my\\file.txt', function (err, stats) { + if (err) throw err; + console.log(`The size of a file is: ${stats.size} byte${stats.size === 1 ? '': 's'}.`); +}); +``` + ### smb2Client.unlink ( path, callback ) Asynchronous unlink(2). No arguments other than a possible exception are given to the completion callback. ```javascript diff --git a/TODO.md b/TODO.md index 410b87f..6065eb6 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,6 @@ ## New functions - fs.appendFile(filename, data, [options], callback) - fs.chmod(path, mode, callback) -- fs.stat(path, callback) - fs.watchFile(filename, [options], listener) - fs.unwatchFile(filename, [listener]) - fs.watch(filename, [options], [listener]) diff --git a/lib/api/stat.js b/lib/api/stat.js new file mode 100644 index 0000000..e1563c1 --- /dev/null +++ b/lib/api/stat.js @@ -0,0 +1,72 @@ +const FileTime = require('win32filetime'); +const SMB2Forge = require('../tools/smb2-forge'); +const SMB2Request = SMB2Forge.request; + +/* + * stat + * ====== + * + * return basic info about a file + * + * - try to open the file + * + * - process the file info + * + * - close the file + * + * returns stats in callback in similar format like fs.stat: + * { + * size: number; + * atimeMs: number; + * mtimeMs: number; + * ctimeMs: number; + * birthtimeMs: number; + * atime: Date; + * mtime: Date; + * ctime: Date; + * birthtime: Date; + * } + */ +module.exports = function (path, cb) { + if (!cb || typeof cb !== 'function') { + throw new Error('Callback must be a function'); + } + + var connection = this; + + SMB2Request('open', { path }, connection, function (err, fileInfo) { + if (err) cb(err); + else { + SMB2Request('close', fileInfo, connection, function (err) { + if (err) cb(err); + cb(null, translateResponse(fileInfo)); + }); + } + }); + +} + +function translateResponse(fileInfo) { + const atimeMs = convertToUnixTime(fileInfo['LastAccessTime']); + const mtimeMs = convertToUnixTime(fileInfo['LastWriteTime']); + const ctimeMs = convertToUnixTime(fileInfo['ChangeTime']); + const birthtimeMs = convertToUnixTime(fileInfo['CreationTime']); + return { + size: fileInfo['EndofFile'].readUInt32LE(), + + atimeMs, + mtimeMs, + ctimeMs, + birthtimeMs, + atime: new Date(atimeMs), + mtime: new Date(mtimeMs), + ctime: new Date(ctimeMs), + birthtime: new Date(birthtimeMs) + } +} + +function convertToUnixTime(buffer) { + const low = buffer.readUInt32LE(0); + const high = buffer.readUInt32LE(4); + return FileTime.toUnix({ low, high }); +} diff --git a/lib/smb2.js b/lib/smb2.js index c2d700b..bf10deb 100644 --- a/lib/smb2.js +++ b/lib/smb2.js @@ -88,6 +88,7 @@ var proto = SMB.prototype = {}; proto.close = require('./api/close'); proto.exists = SMB2Connection.requireConnect(require('./api/exists')); +proto.stat = SMB2Connection.requireConnect(require('./api/stat')); proto.rename = SMB2Connection.requireConnect(require('./api/rename')); diff --git a/lib/tools/smb2-forge.js b/lib/tools/smb2-forge.js index a3985fa..ebf7b1a 100644 --- a/lib/tools/smb2-forge.js +++ b/lib/tools/smb2-forge.js @@ -61,7 +61,7 @@ SMB2Forge.response = function(c){ message.parseBuffer(r); //debug if(c.debug){ - console.log('--response'); + console.log('--response', message.headers['Command']); console.log(r.toString('hex')); } // get the message id @@ -92,7 +92,7 @@ function sendNetBiosMessage(connection, message) { var smbRequest = message.getBuffer(connection); if(connection.debug){ - console.log('--request'); + console.log('--request', message.headers['Command']); console.log(smbRequest.toString('hex')); } diff --git a/package-lock.json b/package-lock.json index 0101846..07c8346 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,10 +4,23 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + }, "ntlm": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/ntlm/-/ntlm-0.1.3.tgz", "integrity": "sha1-O4FOvFMKHmzXEtzwz1kBVZMRlcE=" + }, + "win32filetime": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/win32filetime/-/win32filetime-1.0.2.tgz", + "integrity": "sha1-D41rmwXMnMr/6jsPT1BPhFRc9Fc=", + "requires": { + "long": "^3.1.0" + } } } } diff --git a/package.json b/package.json index 72d33c8..7cbfd3a 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "url": "https://github.com/bchelli/node-smb2" }, "dependencies": { - "ntlm": "^0.1.3" + "ntlm": "^0.1.3", + "win32filetime": "^1.0.2" }, "keywords": [ "SMB", From 6de96aea58cd101b58f6495367fea311aa25dc7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wierci=C5=84ski?= Date: Mon, 9 Sep 2019 20:27:58 +0200 Subject: [PATCH 2/2] correct header for stat description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b20e031..a7c6c0d 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ smb2Client.exists('path\\to\\my\\file.txt', function (err, exists) { }); ``` -### smb2Client.exists ( path, callback ) +### smb2Client.stat ( path, callback ) Returns basic info about a file. Example: ```javascript smb2Client.stat('path\\to\\my\\file.txt', function (err, stats) {