保誠-保戶業務員媒合平台
HelenHuang
2022-06-09 9bdb95c9e34cef640534e5e5a1e2225a80442000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
'use strict'
 
const BB = require('bluebird')
 
const chownr = BB.promisify(require('chownr'))
const mkdirp = BB.promisify(require('mkdirp'))
const inflight = require('promise-inflight')
const inferOwner = require('infer-owner')
 
// Memoize getuid()/getgid() calls.
// patch process.setuid/setgid to invalidate cached value on change
const self = { uid: null, gid: null }
const getSelf = () => {
  if (typeof self.uid !== 'number') {
    self.uid = process.getuid()
    const setuid = process.setuid
    process.setuid = (uid) => {
      self.uid = null
      process.setuid = setuid
      return process.setuid(uid)
    }
  }
  if (typeof self.gid !== 'number') {
    self.gid = process.getgid()
    const setgid = process.setgid
    process.setgid = (gid) => {
      self.gid = null
      process.setgid = setgid
      return process.setgid(gid)
    }
  }
}
 
module.exports.chownr = fixOwner
function fixOwner (cache, filepath) {
  if (!process.getuid) {
    // This platform doesn't need ownership fixing
    return BB.resolve()
  }
 
  getSelf()
  if (self.uid !== 0) {
    // almost certainly can't chown anyway
    return BB.resolve()
  }
 
  return BB.resolve(inferOwner(cache)).then(owner => {
    const { uid, gid } = owner
 
    // No need to override if it's already what we used.
    if (self.uid === uid && self.gid === gid) {
      return
    }
 
    return inflight(
      'fixOwner: fixing ownership on ' + filepath,
      () => chownr(
        filepath,
        typeof uid === 'number' ? uid : self.uid,
        typeof gid === 'number' ? gid : self.gid
      ).catch({ code: 'ENOENT' }, () => null)
    )
  })
}
 
module.exports.chownr.sync = fixOwnerSync
function fixOwnerSync (cache, filepath) {
  if (!process.getuid) {
    // This platform doesn't need ownership fixing
    return
  }
  const { uid, gid } = inferOwner.sync(cache)
  getSelf()
  if (self.uid === uid && self.gid === gid) {
    // No need to override if it's already what we used.
    return
  }
  try {
    chownr.sync(
      filepath,
      typeof uid === 'number' ? uid : self.uid,
      typeof gid === 'number' ? gid : self.gid
    )
  } catch (err) {
    // only catch ENOENT, any other error is a problem.
    if (err.code === 'ENOENT') {
      return null
    }
    throw err
  }
}
 
module.exports.mkdirfix = mkdirfix
function mkdirfix (cache, p, cb) {
  // we have to infer the owner _before_ making the directory, even though
  // we aren't going to use the results, since the cache itself might not
  // exist yet.  If we mkdirp it, then our current uid/gid will be assumed
  // to be correct if it creates the cache folder in the process.
  return BB.resolve(inferOwner(cache)).then(() => {
    return mkdirp(p).then(made => {
      if (made) {
        return fixOwner(cache, made).then(() => made)
      }
    }).catch({ code: 'EEXIST' }, () => {
      // There's a race in mkdirp!
      return fixOwner(cache, p).then(() => null)
    })
  })
}
 
module.exports.mkdirfix.sync = mkdirfixSync
function mkdirfixSync (cache, p) {
  try {
    inferOwner.sync(cache)
    const made = mkdirp.sync(p)
    if (made) {
      fixOwnerSync(cache, made)
      return made
    }
  } catch (err) {
    if (err.code === 'EEXIST') {
      fixOwnerSync(cache, p)
      return null
    } else {
      throw err
    }
  }
}