Comparing version 0.1.17 to 0.1.18
@@ -169,9 +169,79 @@ | ||
// unless { clobber: false } in the props. | ||
mkdir(path.dirname(me._path), Writer.dirmode, function (er) { | ||
mkdir(path.dirname(me._path), Writer.dirmode, function (er, made) { | ||
// console.error("W created", path.dirname(me._path), er) | ||
if (er) return me.error(er) | ||
me._create() | ||
// later on, we have to set the mode and owner for these | ||
me._madeDir = made | ||
return me._create() | ||
}) | ||
} | ||
function endChmod (me, want, current, path, cb) { | ||
var wantMode = want.mode | ||
, chmod = want.follow || me.type !== "SymbolicLink" | ||
? "chmod" : "lchmod" | ||
if (!fs[chmod]) return cb() | ||
if (typeof wantMode !== "number") return cb() | ||
var curMode = current.mode & 0777 | ||
wantMode = wantMode & 0777 | ||
if (wantMode === curMode) return cb() | ||
fs[chmod](path, wantMode, cb) | ||
} | ||
function endChown (me, want, current, path, cb) { | ||
// Don't even try it unless root. Too easy to EPERM. | ||
if (process.platform === "win32") return cb() | ||
if (!process.getuid || !process.getuid() === 0) return cb() | ||
if (typeof want.uid !== "number" && | ||
typeof want.gid !== "number" ) return cb() | ||
if (current.uid === want.uid && | ||
current.gid === want.gid) return cb() | ||
var chown = (me.props.follow || me.type !== "SymbolicLink") | ||
? "chown" : "lchown" | ||
if (!fs[chown]) return cb() | ||
if (typeof want.uid !== "number") want.uid = current.uid | ||
if (typeof want.gid !== "number") want.gid = current.gid | ||
fs[chown](path, want.uid, want.gid, cb) | ||
} | ||
function endUtimes (me, want, current, path, cb) { | ||
if (!fs.utimes || process.platform === "win32") return cb() | ||
var utimes = (want.follow || me.type !== "SymbolicLink") | ||
? "utimes" : "lutimes" | ||
if (utimes === "lutimes" && !fs[utimes]) { | ||
utimes = "utimes" | ||
} | ||
if (!fs[utimes]) return cb() | ||
var curA = current.atime | ||
, curM = current.mtime | ||
, meA = want.atime | ||
, meM = want.mtime | ||
if (meA === undefined) meA = curA | ||
if (meM === undefined) meM = curM | ||
if (!isDate(meA)) meA = new Date(meA) | ||
if (!isDate(meM)) meA = new Date(meM) | ||
if (meA.getTime() === curA.getTime() && | ||
meM.getTime() === curM.getTime()) return cb() | ||
fs[utimes](path, meA, meM, cb) | ||
} | ||
// XXX This function is beastly. Break it up! | ||
Writer.prototype._finish = function () { | ||
@@ -224,84 +294,78 @@ var me = this | ||
function setProps (current) { | ||
// console.error(" W setprops", me._path) | ||
// mode | ||
var wantMode = me.props.mode | ||
, chmod = me.props.follow || me.type !== "SymbolicLink" | ||
? "chmod" : "lchmod" | ||
endChmod(me, me.props, current, me._path, next("chmod")) | ||
endChown(me, me.props, current, me._path, next("chown")) | ||
endUtimes(me, me.props, current, me._path, next("chown")) | ||
} | ||
if (fs[chmod] && typeof wantMode === "number") { | ||
wantMode = wantMode & 0777 | ||
todo ++ | ||
// console.error(" W chmod", wantMode.toString(8), me.basename, "\r") | ||
fs[chmod](me._path, wantMode, next(chmod)) | ||
} | ||
function next (what) { | ||
todo ++ | ||
return function (er) { | ||
// console.error(" W Finish", what, todo) | ||
if (errState) return | ||
if (er) { | ||
er.fstream_finish_call = what | ||
return me.error(errState = er) | ||
} | ||
if (--todo > 0) return | ||
if (done) return | ||
done = true | ||
// uid, gid | ||
// Don't even try it unless root. Too easy to EPERM. | ||
if (process.platform !== "win32" && | ||
process.getuid && process.getuid() === 0 && | ||
( typeof me.props.uid === "number" || | ||
typeof me.props.gid === "number" )) { | ||
var chown = (me.props.follow || me.type !== "SymbolicLink") | ||
? "chown" : "lchown" | ||
if (fs[chown]) { | ||
if (typeof me.props.uid !== "number") me.props.uid = current.uid | ||
if (typeof me.props.gid !== "number") me.props.gid = current.gid | ||
if (me.props.uid !== current.uid || me.props.gid !== current.gid) { | ||
todo ++ | ||
// console.error(" W chown", me.props.uid, me.props.gid, me.basename) | ||
fs[chown](me._path, me.props.uid, me.props.gid, next("chown")) | ||
// we may still need to set the mode/etc. on some parent dirs | ||
// that were created previously. delay end/close until then. | ||
if (!me._madeDir) return end() | ||
else endMadeDir(me, me._path, end) | ||
function end (er) { | ||
if (er) { | ||
er.fstream_finish_call = "setupMadeDir" | ||
return me.error(er) | ||
} | ||
// all the props have been set, so we're completely done. | ||
me.emit("end") | ||
me.emit("close") | ||
} | ||
} | ||
} | ||
} | ||
// atime, mtime. | ||
if (fs.utimes && process.platform !== "win32") { | ||
var utimes = (me.props.follow || me.type !== "SymbolicLink") | ||
? "utimes" : "lutimes" | ||
function endMadeDir (me, p, cb) { | ||
var made = me._madeDir | ||
// everything *between* made and path.dirname(me._path) | ||
// needs to be set up. Note that this may just be one dir. | ||
var d = path.dirname(p) | ||
if (utimes === "lutimes" && !fs[utimes]) { | ||
utimes = "utimes" | ||
} | ||
endMadeDir_(me, d, function (er) { | ||
if (er) return cb(er) | ||
if (d === made) { | ||
return cb() | ||
} | ||
endMadeDir(me, d, cb) | ||
}) | ||
} | ||
var curA = current.atime | ||
, curM = current.mtime | ||
, meA = me.props.atime | ||
, meM = me.props.mtime | ||
function endMadeDir_ (me, p, cb) { | ||
var dirProps = {} | ||
Object.keys(me.props).forEach(function (k) { | ||
dirProps[k] = me.props[k] | ||
if (meA === undefined) meA = curA | ||
if (meM === undefined) meM = curM | ||
if (!isDate(meA)) meA = new Date(meA) | ||
if (!isDate(meM)) meA = new Date(meM) | ||
if (meA.getTime() !== curA.getTime() || | ||
meM.getTime() !== curM.getTime()) { | ||
todo ++ | ||
// console.error(" W utimes", meA, meM, me.basename) | ||
fs[utimes](me._path, meA, meM, next("utimes")) | ||
} | ||
// only make non-readable dirs if explicitly requested. | ||
if (k === "mode" && me.type !== "Directory") { | ||
dirProps[k] = dirProps[k] | 0111 | ||
} | ||
}) | ||
// finally, handle the case if there was nothing to do. | ||
if (todo === 0) { | ||
// console.error(" W nothing to do", me.basename) | ||
next("nothing to do")() | ||
} | ||
} | ||
var todo = 3 | ||
, errState = null | ||
fs.stat(p, function (er, current) { | ||
if (er) return cb(errState = er) | ||
endChmod(me, dirProps, current, p, next) | ||
endChown(me, dirProps, current, p, next) | ||
endUtimes(me, dirProps, current, p, next) | ||
}) | ||
function next (what) { return function (er) { | ||
// console.error(" W Finish", what, todo) | ||
function next (er) { | ||
if (errState) return | ||
if (er) { | ||
er.fstream_finish_call = what | ||
return me.error(errState = er) | ||
} | ||
if (--todo > 0) return | ||
if (done) return | ||
done = true | ||
// all the props have been set, so we're completely done. | ||
me.emit("end") | ||
me.emit("close") | ||
}} | ||
if (er) return cb(errState = er) | ||
if (-- todo === 0) return cb() | ||
} | ||
} | ||
@@ -308,0 +372,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"description": "Advanced file system stream things", | ||
"version": "0.1.17", | ||
"version": "0.1.18", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
63354
1863