CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes48downloads
index.js364 linesDownload Raw Back to tar-fs
1var chownr = require('chownr')2var tar = require('tar-stream')3var pump = require('pump')4var mkdirp = require('mkdirp-classic')5var fs = require('fs')6var path = require('path')7var os = require('os')8 9var win32 = os.platform() === 'win32'10 11var noop = function () {}12 13var echo = function (name) {14  return name15}16 17var normalize = !win32 ? echo : function (name) {18  return name.replace(/\\/g, '/').replace(/[:?<>|]/g, '_')19}20 21var statAll = function (fs, stat, cwd, ignore, entries, sort) {22  var queue = entries || ['.']23 24  return function loop (callback) {25    if (!queue.length) return callback()26    var next = queue.shift()27    var nextAbs = path.join(cwd, next)28 29    stat.call(fs, nextAbs, function (err, stat) {30      if (err) return callback(err)31 32      if (!stat.isDirectory()) return callback(null, next, stat)33 34      fs.readdir(nextAbs, function (err, files) {35        if (err) return callback(err)36 37        if (sort) files.sort()38        for (var i = 0; i < files.length; i++) {39          if (!ignore(path.join(cwd, next, files[i]))) queue.push(path.join(next, files[i]))40        }41 42        callback(null, next, stat)43      })44    })45  }46}47 48var strip = function (map, level) {49  return function (header) {50    header.name = header.name.split('/').slice(level).join('/')51 52    var linkname = header.linkname53    if (linkname && (header.type === 'link' || path.isAbsolute(linkname))) {54      header.linkname = linkname.split('/').slice(level).join('/')55    }56 57    return map(header)58  }59}60 61exports.pack = function (cwd, opts) {62  if (!cwd) cwd = '.'63  if (!opts) opts = {}64 65  var xfs = opts.fs || fs66  var ignore = opts.ignore || opts.filter || noop67  var map = opts.map || noop68  var mapStream = opts.mapStream || echo69  var statNext = statAll(xfs, opts.dereference ? xfs.stat : xfs.lstat, cwd, ignore, opts.entries, opts.sort)70  var strict = opts.strict !== false71  var umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask()72  var dmode = typeof opts.dmode === 'number' ? opts.dmode : 073  var fmode = typeof opts.fmode === 'number' ? opts.fmode : 074  var pack = opts.pack || tar.pack()75  var finish = opts.finish || noop76 77  if (opts.strip) map = strip(map, opts.strip)78 79  if (opts.readable) {80    dmode |= parseInt(555, 8)81    fmode |= parseInt(444, 8)82  }83  if (opts.writable) {84    dmode |= parseInt(333, 8)85    fmode |= parseInt(222, 8)86  }87 88  var onsymlink = function (filename, header) {89    xfs.readlink(path.join(cwd, filename), function (err, linkname) {90      if (err) return pack.destroy(err)91      header.linkname = normalize(linkname)92      pack.entry(header, onnextentry)93    })94  }95 96  var onstat = function (err, filename, stat) {97    if (err) return pack.destroy(err)98    if (!filename) {99      if (opts.finalize !== false) pack.finalize()100      return finish(pack)101    }102 103    if (stat.isSocket()) return onnextentry() // tar does not support sockets...104 105    var header = {106      name: normalize(filename),107      mode: (stat.mode | (stat.isDirectory() ? dmode : fmode)) & umask,108      mtime: stat.mtime,109      size: stat.size,110      type: 'file',111      uid: stat.uid,112      gid: stat.gid113    }114 115    if (stat.isDirectory()) {116      header.size = 0117      header.type = 'directory'118      header = map(header) || header119      return pack.entry(header, onnextentry)120    }121 122    if (stat.isSymbolicLink()) {123      header.size = 0124      header.type = 'symlink'125      header = map(header) || header126      return onsymlink(filename, header)127    }128 129    // TODO: add fifo etc...130 131    header = map(header) || header132 133    if (!stat.isFile()) {134      if (strict) return pack.destroy(new Error('unsupported type for ' + filename))135      return onnextentry()136    }137 138    var entry = pack.entry(header, onnextentry)139    if (!entry) return140 141    var rs = mapStream(xfs.createReadStream(path.join(cwd, filename), { start: 0, end: header.size > 0 ? header.size - 1 : header.size }), header)142 143    rs.on('error', function (err) { // always forward errors on destroy144      entry.destroy(err)145    })146 147    pump(rs, entry)148  }149 150  var onnextentry = function (err) {151    if (err) return pack.destroy(err)152    statNext(onstat)153  }154 155  onnextentry()156 157  return pack158}159 160var head = function (list) {161  return list.length ? list[list.length - 1] : null162}163 164var processGetuid = function () {165  return process.getuid ? process.getuid() : -1166}167 168var processUmask = function () {169  return process.umask ? process.umask() : 0170}171 172exports.extract = function (cwd, opts) {173  if (!cwd) cwd = '.'174  if (!opts) opts = {}175 176  var xfs = opts.fs || fs177  var ignore = opts.ignore || opts.filter || noop178  var map = opts.map || noop179  var mapStream = opts.mapStream || echo180  var own = opts.chown !== false && !win32 && processGetuid() === 0181  var extract = opts.extract || tar.extract()182  var stack = []183  var now = new Date()184  var umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask()185  var dmode = typeof opts.dmode === 'number' ? opts.dmode : 0186  var fmode = typeof opts.fmode === 'number' ? opts.fmode : 0187  var strict = opts.strict !== false188 189  if (opts.strip) map = strip(map, opts.strip)190 191  if (opts.readable) {192    dmode |= parseInt(555, 8)193    fmode |= parseInt(444, 8)194  }195  if (opts.writable) {196    dmode |= parseInt(333, 8)197    fmode |= parseInt(222, 8)198  }199 200  var utimesParent = function (name, cb) { // we just set the mtime on the parent dir again everytime we write an entry201    var top202    while ((top = head(stack)) && name.slice(0, top[0].length) !== top[0]) stack.pop()203    if (!top) return cb()204    xfs.utimes(top[0], now, top[1], cb)205  }206 207  var utimes = function (name, header, cb) {208    if (opts.utimes === false) return cb()209 210    if (header.type === 'directory') return xfs.utimes(name, now, header.mtime, cb)211    if (header.type === 'symlink') return utimesParent(name, cb) // TODO: how to set mtime on link?212 213    xfs.utimes(name, now, header.mtime, function (err) {214      if (err) return cb(err)215      utimesParent(name, cb)216    })217  }218 219  var chperm = function (name, header, cb) {220    var link = header.type === 'symlink'221 222    /* eslint-disable node/no-deprecated-api */223    var chmod = link ? xfs.lchmod : xfs.chmod224    var chown = link ? xfs.lchown : xfs.chown225    /* eslint-enable node/no-deprecated-api */226 227    if (!chmod) return cb()228 229    var mode = (header.mode | (header.type === 'directory' ? dmode : fmode)) & umask230 231    if (chown && own) chown.call(xfs, name, header.uid, header.gid, onchown)232    else onchown(null)233 234    function onchown (err) {235      if (err) return cb(err)236      if (!chmod) return cb()237      chmod.call(xfs, name, mode, cb)238    }239  }240 241  extract.on('entry', function (header, stream, next) {242    header = map(header) || header243    header.name = normalize(header.name)244    var name = path.join(cwd, path.join('/', header.name))245 246    if (ignore(name, header)) {247      stream.resume()248      return next()249    }250 251    var stat = function (err) {252      if (err) return next(err)253      utimes(name, header, function (err) {254        if (err) return next(err)255        if (win32) return next()256        chperm(name, header, next)257      })258    }259 260    var onsymlink = function () {261      if (win32) return next() // skip symlinks on win for now before it can be tested262      xfs.unlink(name, function () {263        var dst = path.resolve(path.dirname(name), header.linkname)264        if (!inCwd(dst, cwd)) return next(new Error(name + ' is not a valid symlink'))265 266        xfs.symlink(header.linkname, name, stat)267      })268    }269 270    var onlink = function () {271      if (win32) return next() // skip links on win for now before it can be tested272      xfs.unlink(name, function () {273        var srcpath = path.join(cwd, path.join('/', header.linkname))274 275        xfs.realpath(srcpath, function (err, dst) {276          if (err || !inCwd(dst, cwd)) return next(new Error(name + ' is not a valid hardlink'))277 278          xfs.link(dst, name, function (err) {279            if (err && err.code === 'EPERM' && opts.hardlinkAsFilesFallback) {280              stream = xfs.createReadStream(srcpath)281              return onfile()282            }283 284            stat(err)285          })286        })287      })288    }289 290    var onfile = function () {291      var ws = xfs.createWriteStream(name)292      var rs = mapStream(stream, header)293 294      ws.on('error', function (err) { // always forward errors on destroy295        rs.destroy(err)296      })297 298      pump(rs, ws, function (err) {299        if (err) return next(err)300        ws.on('close', stat)301      })302    }303 304    if (header.type === 'directory') {305      stack.push([name, header.mtime])306      return mkdirfix(name, {307        fs: xfs, own: own, uid: header.uid, gid: header.gid308      }, stat)309    }310 311    var dir = path.dirname(name)312 313    validate(xfs, dir, path.join(cwd, '.'), function (err, valid) {314      if (err) return next(err)315      if (!valid) return next(new Error(dir + ' is not a valid path'))316 317      mkdirfix(dir, {318        fs: xfs, own: own, uid: header.uid, gid: header.gid319      }, function (err) {320        if (err) return next(err)321 322        switch (header.type) {323          case 'file': return onfile()324          case 'link': return onlink()325          case 'symlink': return onsymlink()326        }327 328        if (strict) return next(new Error('unsupported type for ' + name + ' (' + header.type + ')'))329 330        stream.resume()331        next()332      })333    })334  })335 336  if (opts.finish) extract.on('finish', opts.finish)337 338  return extract339}340 341function validate (fs, name, root, cb) {342  if (name === root) return cb(null, true)343  fs.lstat(name, function (err, st) {344    if (err && err.code !== 'ENOENT') return cb(err)345    if (err || st.isDirectory()) return validate(fs, path.join(name, '..'), root, cb)346    cb(null, false)347  })348}349 350function mkdirfix (name, opts, cb) {351  mkdirp(name, { fs: opts.fs }, function (err, made) {352    if (!err && made && opts.own) {353      chownr(made, opts.uid, opts.gid, cb)354    } else {355      cb(err)356    }357  })358}359 360function inCwd (dst, cwd) {361  cwd = path.resolve(cwd)362  return cwd === dst || dst.startsWith(cwd + path.sep)363}364 
basant307/AI_Governance_Project · CoolFace