chownr.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. module.exports = chownr
  2. chownr.sync = chownrSync
  3. var fs = require("fs")
  4. , path = require("path")
  5. function chownr (p, uid, gid, cb) {
  6. fs.readdir(p, function (er, children) {
  7. // any error other than ENOTDIR means it's not readable, or
  8. // doesn't exist. give up.
  9. if (er && er.code !== "ENOTDIR") return cb(er)
  10. if (er || !children.length) return fs.chown(p, uid, gid, cb)
  11. var len = children.length
  12. , errState = null
  13. children.forEach(function (child) {
  14. var pathChild = path.resolve(p, child);
  15. fs.lstat(pathChild, function(er, stats) {
  16. if (er)
  17. return cb(er)
  18. if (!stats.isSymbolicLink())
  19. chownr(pathChild, uid, gid, then)
  20. else
  21. then()
  22. })
  23. })
  24. function then (er) {
  25. if (errState) return
  26. if (er) return cb(errState = er)
  27. if (-- len === 0) return fs.chown(p, uid, gid, cb)
  28. }
  29. })
  30. }
  31. function chownrSync (p, uid, gid) {
  32. var children
  33. try {
  34. children = fs.readdirSync(p)
  35. } catch (er) {
  36. if (er && er.code === "ENOTDIR") return fs.chownSync(p, uid, gid)
  37. throw er
  38. }
  39. if (!children.length) return fs.chownSync(p, uid, gid)
  40. children.forEach(function (child) {
  41. var pathChild = path.resolve(p, child)
  42. var stats = fs.lstatSync(pathChild)
  43. if (!stats.isSymbolicLink())
  44. chownrSync(pathChild, uid, gid)
  45. })
  46. return fs.chownSync(p, uid, gid)
  47. }