Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / fs-extra / lib / move / index.js
1 // most of this code was written by Andrew Kelley
2 // licensed under the BSD license: see
3 // https://github.com/andrewrk/node-mv/blob/master/package.json
4
5 // this needs a cleanup
6
7 var fs = require('graceful-fs')
8 var ncp = require('../copy/ncp')
9 var path = require('path')
10 var rimraf = require('rimraf')
11 var mkdirp = require('../mkdirs').mkdirs
12
13 function mv (source, dest, options, callback) {
14   if (typeof options === 'function') {
15     callback = options
16     options = {}
17   }
18
19   var shouldMkdirp = ('mkdirp' in options) ? options.mkdirp : true
20   var clobber = ('clobber' in options) ? options.clobber : false
21
22   var limit = options.limit || 16
23
24   if (shouldMkdirp) {
25     mkdirs()
26   } else {
27     doRename()
28   }
29
30   function mkdirs () {
31     mkdirp(path.dirname(dest), function (err) {
32       if (err) return callback(err)
33       doRename()
34     })
35   }
36
37   function doRename () {
38     if (clobber) {
39       fs.rename(source, dest, function (err) {
40         if (!err) return callback()
41
42         if (err.code === 'ENOTEMPTY' || err.code === 'EEXIST') {
43           rimraf(dest, function (err) {
44             if (err) return callback(err)
45             options.clobber = false // just clobbered it, no need to do it again
46             mv(source, dest, options, callback)
47           })
48           return
49         }
50
51         // weird Windows shit
52         if (err.code === 'EPERM') {
53           setTimeout(function () {
54             rimraf(dest, function (err) {
55               if (err) return callback(err)
56               options.clobber = false
57               mv(source, dest, options, callback)
58             })
59           }, 200)
60           return
61         }
62
63         if (err.code !== 'EXDEV') return callback(err)
64         moveAcrossDevice(source, dest, clobber, limit, callback)
65       })
66     } else {
67       fs.link(source, dest, function (err) {
68         if (err) {
69           if (err.code === 'EXDEV' || err.code === 'EISDIR' || err.code === 'EPERM') {
70             moveAcrossDevice(source, dest, clobber, limit, callback)
71             return
72           }
73           callback(err)
74           return
75         }
76         fs.unlink(source, callback)
77       })
78     }
79   }
80 }
81
82 function moveAcrossDevice (source, dest, clobber, limit, callback) {
83   fs.stat(source, function (err, stat) {
84     if (err) {
85       callback(err)
86       return
87     }
88
89     if (stat.isDirectory()) {
90       moveDirAcrossDevice(source, dest, clobber, limit, callback)
91     } else {
92       moveFileAcrossDevice(source, dest, clobber, limit, callback)
93     }
94   })
95 }
96
97 function moveFileAcrossDevice (source, dest, clobber, limit, callback) {
98   var outFlags = clobber ? 'w' : 'wx'
99   var ins = fs.createReadStream(source)
100   var outs = fs.createWriteStream(dest, {flags: outFlags})
101
102   ins.on('error', function (err) {
103     ins.destroy()
104     outs.destroy()
105     outs.removeListener('close', onClose)
106
107     // may want to create a directory but `out` line above
108     // creates an empty file for us: See #108
109     // don't care about error here
110     fs.unlink(dest, function () {
111       // note: `err` here is from the input stream errror
112       if (err.code === 'EISDIR' || err.code === 'EPERM') {
113         moveDirAcrossDevice(source, dest, clobber, limit, callback)
114       } else {
115         callback(err)
116       }
117     })
118   })
119
120   outs.on('error', function (err) {
121     ins.destroy()
122     outs.destroy()
123     outs.removeListener('close', onClose)
124     callback(err)
125   })
126
127   outs.once('close', onClose)
128   ins.pipe(outs)
129
130   function onClose () {
131     fs.unlink(source, callback)
132   }
133 }
134
135 function moveDirAcrossDevice (source, dest, clobber, limit, callback) {
136   var options = {
137     stopOnErr: true,
138     clobber: false,
139     limit: limit
140   }
141
142   function startNcp () {
143     ncp(source, dest, options, function (errList) {
144       if (errList) return callback(errList[0])
145       rimraf(source, callback)
146     })
147   }
148
149   if (clobber) {
150     rimraf(dest, function (err) {
151       if (err) return callback(err)
152       startNcp()
153     })
154   } else {
155     startNcp()
156   }
157 }
158
159 module.exports = {
160   move: mv
161 }