Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / ncp / lib / ncp.js
1 var fs = require('fs'),
2     path = require('path');
3
4 module.exports = ncp
5 ncp.ncp = ncp
6
7 function ncp (source, dest, options, callback) {
8   if (!callback) {
9     callback = options;
10     options = {};
11   }
12
13   var basePath = process.cwd(),
14       currentPath = path.resolve(basePath, source),
15       targetPath = path.resolve(basePath, dest),
16       filter = options.filter,
17       transform = options.transform,
18       clobber = options.clobber !== false,
19       errs = null,
20       started = 0,
21       finished = 0,
22       running = 0,
23       limit = options.limit || ncp.limit || 16;
24
25   limit = (limit < 1) ? 1 : (limit > 512) ? 512 : limit;
26
27   startCopy(currentPath);
28   
29   function startCopy(source) {
30     started++;
31     if (filter) {
32       if (filter instanceof RegExp) {
33         if (!filter.test(source)) {
34           return cb(true);
35         }
36       }
37       else if (typeof filter === 'function') {
38         if (!filter(source)) {
39           return cb(true);
40         }
41       }
42     }
43     return getStats(source);
44   }
45
46   function defer(fn) {
47     if (typeof(setImmediate) === 'function')
48       return setImmediate(fn);
49     return process.nextTick(fn);
50   }
51
52   function getStats(source) {
53     if (running >= limit) {
54       return defer(function () {
55         getStats(source);
56       });
57     }
58     running++;
59     fs.lstat(source, function (err, stats) {
60       var item = {};
61       if (err) {
62         return onError(err);
63       }
64
65       // We need to get the mode from the stats object and preserve it.
66       item.name = source;
67       item.mode = stats.mode;
68
69       if (stats.isDirectory()) {
70         return onDir(item);
71       }
72       else if (stats.isFile()) {
73         return onFile(item);
74       }
75       else if (stats.isSymbolicLink()) {
76         // Symlinks don't really need to know about the mode.
77         return onLink(source);
78       }
79     });
80   }
81
82   function onFile(file) {
83     var target = file.name.replace(currentPath, targetPath);
84     isWritable(target, function (writable) {
85       if (writable) {
86         return copyFile(file, target);
87       }
88       if(clobber)
89         rmFile(target, function () {
90           copyFile(file, target);
91         });
92     });
93   }
94
95   function copyFile(file, target) {
96     var readStream = fs.createReadStream(file.name),
97         writeStream = fs.createWriteStream(target, { mode: file.mode });
98     if(transform) {
99       transform(readStream, writeStream,file);
100     } else {
101       readStream.pipe(writeStream);
102     }
103     readStream.once('end', cb);
104   }
105
106   function rmFile(file, done) {
107     fs.unlink(file, function (err) {
108       if (err) {
109         return onError(err);
110       }
111       return done();
112     });
113   }
114
115   function onDir(dir) {
116     var target = dir.name.replace(currentPath, targetPath);
117     isWritable(target, function (writable) {
118       if (writable) {
119         return mkDir(dir, target);
120       }
121       copyDir(dir.name);
122     });
123   }
124
125   function mkDir(dir, target) {
126     fs.mkdir(target, dir.mode, function (err) {
127       if (err) {
128         return onError(err);
129       }
130       copyDir(dir.name);
131     });
132   }
133
134   function copyDir(dir) {
135     fs.readdir(dir, function (err, items) {
136       if (err) {
137         return onError(err);
138       }
139       items.forEach(function (item) {
140         startCopy(dir + '/' + item);
141       });
142       return cb();
143     });
144   }
145
146   function onLink(link) {
147     var target = link.replace(currentPath, targetPath);
148     fs.readlink(link, function (err, resolvedPath) {
149       if (err) {
150         return onError(err);
151       }
152       checkLink(resolvedPath, target);
153     });
154   }
155
156   function checkLink(resolvedPath, target) {
157     isWritable(target, function (writable) {
158       if (writable) {
159         return makeLink(resolvedPath, target);
160       }
161       fs.readlink(target, function (err, targetDest) {
162         if (err) {
163           return onError(err);
164         }
165         if (targetDest === resolvedPath) {
166           return cb();
167         }
168         return rmFile(target, function () {
169           makeLink(resolvedPath, target);
170         });
171       });
172     });
173   }
174
175   function makeLink(linkPath, target) {
176     fs.symlink(linkPath, target, function (err) {
177       if (err) {
178         return onError(err);
179       }
180       return cb();
181     });
182   }
183
184   function isWritable(path, done) {
185     fs.lstat(path, function (err, stats) {
186       if (err) {
187         if (err.code === 'ENOENT') return done(true);
188         return done(false);
189       }
190       return done(false);
191     });
192   }
193
194   function onError(err) {
195     if (options.stopOnError) {
196       return callback(err);
197     }
198     else if (!errs && options.errs) {
199       errs = fs.createWriteStream(options.errs);
200     }
201     else if (!errs) {
202       errs = [];
203     }
204     if (typeof errs.write === 'undefined') {
205         errs.push(err);
206     }
207     else { 
208         errs.write(err.stack + '\n\n');
209     }
210     return cb();
211   }
212
213   function cb(skipped) {
214     if (!skipped) running--;
215     finished++;
216     if ((started === finished) && (running === 0)) {
217       return errs ? callback(errs) : callback(null);
218     }
219   }
220 };
221
222