(err, attrs)
| 2263 | tryStat(null, { size: fileSize }); |
| 2264 | |
| 2265 | function tryStat(err, attrs) { |
| 2266 | if (err) { |
| 2267 | if (src !== fs) { |
| 2268 | // Try stat() for sftp servers that may not support fstat() for |
| 2269 | // whatever reason |
| 2270 | src.stat(srcPath, (err_, attrs_) => { |
| 2271 | if (err_) |
| 2272 | return onerror(err); |
| 2273 | tryStat(null, attrs_); |
| 2274 | }); |
| 2275 | return; |
| 2276 | } |
| 2277 | return onerror(err); |
| 2278 | } |
| 2279 | fsize = attrs.size; |
| 2280 | |
| 2281 | dst.open(dstPath, 'w', (err, destHandle) => { |
| 2282 | if (err) |
| 2283 | return onerror(err); |
| 2284 | |
| 2285 | dstHandle = destHandle; |
| 2286 | |
| 2287 | if (fsize <= 0) |
| 2288 | return onerror(); |
| 2289 | |
| 2290 | // Use less memory where possible |
| 2291 | while (bufsize > fsize) { |
| 2292 | if (concurrency === 1) { |
| 2293 | bufsize = fsize; |
| 2294 | break; |
| 2295 | } |
| 2296 | bufsize -= chunkSize; |
| 2297 | --concurrency; |
| 2298 | } |
| 2299 | |
| 2300 | readbuf = tryCreateBuffer(bufsize); |
| 2301 | if (readbuf instanceof Error) |
| 2302 | return onerror(readbuf); |
| 2303 | |
| 2304 | if (mode !== undefined) { |
| 2305 | dst.fchmod(dstHandle, mode, function tryAgain(err) { |
| 2306 | if (err) { |
| 2307 | // Try chmod() for sftp servers that may not support fchmod() |
| 2308 | // for whatever reason |
| 2309 | dst.chmod(dstPath, mode, (err_) => tryAgain()); |
| 2310 | return; |
| 2311 | } |
| 2312 | startReads(); |
| 2313 | }); |
| 2314 | } else { |
| 2315 | startReads(); |
| 2316 | } |
| 2317 | |
| 2318 | function onread(err, nb, data, dstpos, datapos, origChunkLen) { |
| 2319 | if (err) |
| 2320 | return onerror(err); |
| 2321 | |
| 2322 | datapos = datapos || 0; |
no test coverage detected
searching dependent graphs…