var mkdir = require("mkdirp") , fs = require("graceful-fs") , log = require("npmlog") , chownr = require("chownr") , npm = require("../npm.js") , inflight = require("inflight") // to maintain the cache dir's permissions consistently. var cacheStat = null module.exports = function getCacheStat (cb) { if (cacheStat) return cb(null, cacheStat) fs.stat(npm.cache, function (er, st) { if (er) return makeCacheDir(cb) if (!st.isDirectory()) { log.error("getCacheStat", "invalid cache dir %j", npm.cache) return cb(er) } return cb(null, cacheStat = st) }) } function makeCacheDir (cb) { cb = inflight("makeCacheDir", cb) if (!cb) { return log.verbose( "getCacheStat", "cache creation already in flight; waiting" ) } log.verbose("getCacheStat", "cache creation not in flight; initializing") if (!process.getuid) return mkdir(npm.cache, function (er) { log.verbose("makeCacheDir", "UID & GID are irrelevant on", process.platform) cacheStat = { uid : 0, gid : 0 } return cb(er, cacheStat) }) var uid = +process.getuid() , gid = +process.getgid() if (uid === 0) { if (process.env.SUDO_UID) uid = +process.env.SUDO_UID if (process.env.SUDO_GID) gid = +process.env.SUDO_GID } if (uid !== 0 || !process.env.HOME) { cacheStat = { uid : uid, gid : gid } return mkdir(npm.cache, afterMkdir) } fs.stat(process.env.HOME, function (er, st) { if (er) { log.error("makeCacheDir", "homeless?") return cb(er) } cacheStat = st log.silly("makeCacheDir", "cache dir uid, gid", [st.uid, st.gid]) return mkdir(npm.cache, afterMkdir) }) function afterMkdir (er, made) { if (er || !cacheStat || isNaN(cacheStat.uid) || isNaN(cacheStat.gid)) { return cb(er, cacheStat) } if (!made) return cb(er, cacheStat) // ensure that the ownership is correct. chownr(made, cacheStat.uid, cacheStat.gid, function (er) { return cb(er, cacheStat) }) } }