]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/utils/tar.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / lib / utils / tar.js
diff --git a/org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/utils/tar.js b/org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/utils/tar.js
new file mode 100644 (file)
index 0000000..7656b5d
--- /dev/null
@@ -0,0 +1,291 @@
+// commands for packing and unpacking tarballs
+// this file is used by lib/cache.js
+
+var npm = require("../npm.js")
+  , fs = require("graceful-fs")
+  , writeFileAtomic = require("write-file-atomic")
+  , writeStreamAtomic = require("fs-write-stream-atomic")
+  , path = require("path")
+  , log = require("npmlog")
+  , uidNumber = require("uid-number")
+  , rm = require("./gently-rm.js")
+  , readJson = require("read-package-json")
+  , myUid = process.getuid && process.getuid()
+  , myGid = process.getgid && process.getgid()
+  , tar = require("tar")
+  , zlib = require("zlib")
+  , fstream = require("fstream")
+  , Packer = require("fstream-npm")
+  , lifecycle = require("./lifecycle.js")
+
+if (process.env.SUDO_UID && myUid === 0) {
+  if (!isNaN(process.env.SUDO_UID)) myUid = +process.env.SUDO_UID
+  if (!isNaN(process.env.SUDO_GID)) myGid = +process.env.SUDO_GID
+}
+
+exports.pack = pack
+exports.unpack = unpack
+
+function pack (tarball, folder, pkg, dfc, cb) {
+  log.verbose("tar pack", [tarball, folder])
+  if (typeof cb !== "function") cb = dfc, dfc = false
+
+  log.verbose("tarball", tarball)
+  log.verbose("folder", folder)
+
+  if (dfc) {
+    // do fancy crap
+    return lifecycle(pkg, "prepublish", folder, function (er) {
+      if (er) return cb(er)
+      pack_(tarball, folder, pkg, cb)
+    })
+  } else {
+    pack_(tarball, folder, pkg, cb)
+  }
+}
+
+function pack_ (tarball, folder, pkg, cb) {
+  new Packer({ path: folder, type: "Directory", isDirectory: true })
+    .on("error", function (er) {
+      if (er) log.error("tar pack", "Error reading " + folder)
+      return cb(er)
+    })
+
+    // By default, npm includes some proprietary attributes in the
+    // package tarball.  This is sane, and allowed by the spec.
+    // However, npm *itself* excludes these from its own package,
+    // so that it can be more easily bootstrapped using old and
+    // non-compliant tar implementations.
+    .pipe(tar.Pack({ noProprietary: !npm.config.get("proprietary-attribs") }))
+    .on("error", function (er) {
+      if (er) log.error("tar.pack", "tar creation error", tarball)
+      cb(er)
+    })
+    .pipe(zlib.Gzip())
+    .on("error", function (er) {
+      if (er) log.error("tar.pack", "gzip error "+tarball)
+      cb(er)
+    })
+    .pipe(writeStreamAtomic(tarball))
+    .on("error", function (er) {
+      if (er) log.error("tar.pack", "Could not write "+tarball)
+      cb(er)
+    })
+    .on("close", cb)
+}
+
+
+function unpack (tarball, unpackTarget, dMode, fMode, uid, gid, cb) {
+  log.verbose("tar", "unpack", tarball)
+  log.verbose("tar", "unpacking to", unpackTarget)
+  if (typeof cb !== "function") cb = gid, gid = null
+  if (typeof cb !== "function") cb = uid, uid = null
+  if (typeof cb !== "function") cb = fMode, fMode = npm.modes.file
+  if (typeof cb !== "function") cb = dMode, dMode = npm.modes.exec
+
+  uidNumber(uid, gid, function (er, uid, gid) {
+    if (er) return cb(er)
+    unpack_(tarball, unpackTarget, dMode, fMode, uid, gid, cb)
+  })
+}
+
+function unpack_ ( tarball, unpackTarget, dMode, fMode, uid, gid, cb ) {
+  rm(unpackTarget, function (er) {
+    if (er) return cb(er)
+    // gzip {tarball} --decompress --stdout \
+    //   | tar -mvxpf - --strip-components=1 -C {unpackTarget}
+    gunzTarPerm( tarball, unpackTarget
+               , dMode, fMode
+               , uid, gid
+               , function (er, folder) {
+      if (er) return cb(er)
+      readJson(path.resolve(folder, "package.json"), cb)
+    })
+  })
+}
+
+
+function gunzTarPerm (tarball, target, dMode, fMode, uid, gid, cb_) {
+  if (!dMode) dMode = npm.modes.exec
+  if (!fMode) fMode = npm.modes.file
+  log.silly("gunzTarPerm", "modes", [dMode.toString(8), fMode.toString(8)])
+
+  var cbCalled = false
+  function cb (er) {
+    if (cbCalled) return
+    cbCalled = true
+    cb_(er, target)
+  }
+
+  var fst = fs.createReadStream(tarball)
+
+  fst.on("open", function (fd) {
+    fs.fstat(fd, function (er, st) {
+      if (er) return fst.emit("error", er)
+      if (st.size === 0) {
+        er = new Error("0-byte tarball\n" +
+                       "Please run `npm cache clean`")
+        fst.emit("error", er)
+      }
+    })
+  })
+
+  // figure out who we're supposed to be, if we're not pretending
+  // to be a specific user.
+  if (npm.config.get("unsafe-perm") && process.platform !== "win32") {
+    uid = myUid
+    gid = myGid
+  }
+
+  function extractEntry (entry) {
+    log.silly("gunzTarPerm", "extractEntry", entry.path)
+    // never create things that are user-unreadable,
+    // or dirs that are user-un-listable. Only leads to headaches.
+    var originalMode = entry.mode = entry.mode || entry.props.mode
+    entry.mode = entry.mode | (entry.type === "Directory" ? dMode : fMode)
+    entry.mode = entry.mode & (~npm.modes.umask)
+    entry.props.mode = entry.mode
+    if (originalMode !== entry.mode) {
+      log.silly( "gunzTarPerm", "modified mode"
+               , [entry.path, originalMode, entry.mode])
+    }
+
+    // if there's a specific owner uid/gid that we want, then set that
+    if (process.platform !== "win32" &&
+        typeof uid === "number" &&
+        typeof gid === "number") {
+      entry.props.uid = entry.uid = uid
+      entry.props.gid = entry.gid = gid
+    }
+  }
+
+  var extractOpts = { type: "Directory", path: target, strip: 1 }
+
+  if (process.platform !== "win32" &&
+      typeof uid === "number" &&
+      typeof gid === "number") {
+    extractOpts.uid = uid
+    extractOpts.gid = gid
+  }
+
+  var sawIgnores = {}
+  extractOpts.filter = function () {
+    // symbolic links are not allowed in packages.
+    if (this.type.match(/^.*Link$/)) {
+      log.warn( "excluding symbolic link"
+              , this.path.substr(target.length + 1)
+              + " -> " + this.linkpath )
+      return false
+    }
+
+    // Note: This mirrors logic in the fs read operations that are
+    // employed during tarball creation, in the fstream-npm module.
+    // It is duplicated here to handle tarballs that are created
+    // using other means, such as system tar or git archive.
+    if (this.type === "File") {
+      var base = path.basename(this.path)
+      if (base === ".npmignore") {
+        sawIgnores[ this.path ] = true
+      } else if (base === ".gitignore") {
+        var npmignore = this.path.replace(/\.gitignore$/, ".npmignore")
+        if (sawIgnores[npmignore]) {
+          // Skip this one, already seen.
+          return false
+        } else {
+          // Rename, may be clobbered later.
+          this.path = npmignore
+          this._path = npmignore
+        }
+      }
+    }
+
+    return true
+  }
+
+
+  fst
+    .on("error", function (er) {
+      if (er) log.error("tar.unpack", "error reading "+tarball)
+      cb(er)
+    })
+    .on("data", function OD (c) {
+      // detect what it is.
+      // Then, depending on that, we'll figure out whether it's
+      // a single-file module, gzipped tarball, or naked tarball.
+      // gzipped files all start with 1f8b08
+      if (c[0] === 0x1F &&
+          c[1] === 0x8B &&
+          c[2] === 0x08) {
+        fst
+          .pipe(zlib.Unzip())
+          .on("error", function (er) {
+            if (er) log.error("tar.unpack", "unzip error "+tarball)
+            cb(er)
+          })
+          .pipe(tar.Extract(extractOpts))
+          .on("entry", extractEntry)
+          .on("error", function (er) {
+            if (er) log.error("tar.unpack", "untar error "+tarball)
+            cb(er)
+          })
+          .on("close", cb)
+      } else if (hasTarHeader(c)) {
+        // naked tar
+        fst
+          .pipe(tar.Extract(extractOpts))
+          .on("entry", extractEntry)
+          .on("error", function (er) {
+            if (er) log.error("tar.unpack", "untar error "+tarball)
+            cb(er)
+          })
+          .on("close", cb)
+      } else {
+        // naked js file
+        var jsOpts = { path: path.resolve(target, "index.js") }
+
+        if (process.platform !== "win32" &&
+            typeof uid === "number" &&
+            typeof gid === "number") {
+          jsOpts.uid = uid
+          jsOpts.gid = gid
+        }
+
+        fst
+          .pipe(fstream.Writer(jsOpts))
+          .on("error", function (er) {
+            if (er) log.error("tar.unpack", "copy error "+tarball)
+            cb(er)
+          })
+          .on("close", function () {
+            var j = path.resolve(target, "package.json")
+            readJson(j, function (er, d) {
+              if (er) {
+                log.error("not a package", tarball)
+                return cb(er)
+              }
+              writeFileAtomic(j, JSON.stringify(d) + "\n", cb)
+            })
+          })
+      }
+
+      // now un-hook, and re-emit the chunk
+      fst.removeListener("data", OD)
+      fst.emit("data", c)
+    })
+}
+
+function hasTarHeader (c) {
+  return c[257] === 0x75 && // tar archives have 7573746172 at position
+         c[258] === 0x73 && // 257 and 003030 or 202000 at position 262
+         c[259] === 0x74 &&
+         c[260] === 0x61 &&
+         c[261] === 0x72 &&
+
+       ((c[262] === 0x00 &&
+         c[263] === 0x30 &&
+         c[264] === 0x30) ||
+
+        (c[262] === 0x20 &&
+         c[263] === 0x20 &&
+         c[264] === 0x00))
+}