comparison src/ch/ethz/ssh2/SCPClient.java @ 290:9ae4ed7bb523 ganymed

start conversion from trilead to ganymed
author Carl Byington <carl@five-ten-sg.com>
date Fri, 18 Jul 2014 20:34:21 -0700
parents 91a31873c42a
children 855cdc3b2ced
comparison
equal deleted inserted replaced
289:d2ee20d9dff1 290:9ae4ed7bb523
227 sess = conn.openSession(); 227 sess = conn.openSession();
228 sess.execCommand(cmd, charsetName); 228 sess.execCommand(cmd, charsetName);
229 229
230 return new SCPInputStream(this, sess); 230 return new SCPInputStream(this, sess);
231 } 231 }
232 private void sendBytes(Session sess, byte[] data, String fileName, String mode) throws IOException {
233 OutputStream os = sess.getStdin();
234 InputStream is = new BufferedInputStream(sess.getStdout(), 512);
235 readResponse(is);
236 String cline = "C" + mode + " " + data.length + " " + fileName + "\n";
237 os.write(cline.getBytes("ISO-8859-1"));
238 os.flush();
239 readResponse(is);
240 os.write(data, 0, data.length);
241 os.write(0);
242 os.flush();
243 readResponse(is);
244 os.write("E\n".getBytes("ISO-8859-1"));
245 os.flush();
246 }
247
248 private void sendFiles(Session sess, String[] files, String[] remoteFiles, String mode) throws IOException {
249 byte[] buffer = new byte[8192];
250 OutputStream os = new BufferedOutputStream(sess.getStdin(), 40000);
251 InputStream is = new BufferedInputStream(sess.getStdout(), 512);
252 readResponse(is);
253
254 for (int i = 0; i < files.length; i++) {
255 File f = new File(files[i]);
256 long remain = f.length();
257 String remoteName;
258
259 if ((remoteFiles != null) && (remoteFiles.length > i) && (remoteFiles[i] != null))
260 remoteName = remoteFiles[i];
261 else
262 remoteName = f.getName();
263
264 String cline = "C" + mode + " " + remain + " " + remoteName + "\n";
265 os.write(cline.getBytes("ISO-8859-1"));
266 os.flush();
267 readResponse(is);
268 FileInputStream fis = null;
269
270 try {
271 fis = new FileInputStream(f);
272
273 while (remain > 0) {
274 int trans;
275
276 if (remain > buffer.length)
277 trans = buffer.length;
278 else
279 trans = (int) remain;
280
281 if (fis.read(buffer, 0, trans) != trans)
282 throw new IOException("Cannot read enough from local file " + files[i]);
283
284 os.write(buffer, 0, trans);
285 remain -= trans;
286 }
287 }
288 finally {
289 if (fis != null)
290 fis.close();
291 }
292
293 os.write(0);
294 os.flush();
295 readResponse(is);
296 }
297
298 os.write("E\n".getBytes("ISO-8859-1"));
299 os.flush();
300 }
301
302 private void receiveFiles(Session sess, OutputStream[] targets) throws IOException {
303 byte[] buffer = new byte[8192];
304 OutputStream os = new BufferedOutputStream(sess.getStdin(), 512);
305 InputStream is = new BufferedInputStream(sess.getStdout(), 40000);
306 os.write(0x0);
307 os.flush();
308
309 for (int i = 0; i < targets.length; i++) {
310 LenNamePair lnp = null;
311
312 while (true) {
313 int c = is.read();
314
315 if (c < 0)
316 throw new IOException("Remote scp terminated unexpectedly.");
317
318 String line = receiveLine(is);
319
320 if (c == 'T') {
321 /* Ignore modification times */
322 continue;
323 }
324
325 if ((c == 1) || (c == 2))
326 throw new IOException("Remote SCP error: " + line);
327
328 if (c == 'C') {
329 lnp = parseCLine(line);
330 break;
331 }
332
333 throw new IOException("Remote SCP error: " + ((char) c) + line);
334 }
335
336 os.write(0x0);
337 os.flush();
338 long remain = lnp.length;
339
340 while (remain > 0) {
341 int trans;
342
343 if (remain > buffer.length)
344 trans = buffer.length;
345 else
346 trans = (int) remain;
347
348 int this_time_received = is.read(buffer, 0, trans);
349
350 if (this_time_received < 0) {
351 throw new IOException("Remote scp terminated connection unexpectedly");
352 }
353
354 targets[i].write(buffer, 0, this_time_received);
355 remain -= this_time_received;
356 }
357
358 readResponse(is);
359 os.write(0x0);
360 os.flush();
361 }
362 }
363
364 private void receiveFiles(Session sess, String[] files, String target) throws IOException {
365 byte[] buffer = new byte[8192];
366 OutputStream os = new BufferedOutputStream(sess.getStdin(), 512);
367 InputStream is = new BufferedInputStream(sess.getStdout(), 40000);
368 os.write(0x0);
369 os.flush();
370
371 for (int i = 0; i < files.length; i++) {
372 LenNamePair lnp = null;
373
374 while (true) {
375 int c = is.read();
376
377 if (c < 0)
378 throw new IOException("Remote scp terminated unexpectedly.");
379
380 String line = receiveLine(is);
381
382 if (c == 'T') {
383 /* Ignore modification times */
384 continue;
385 }
386
387 if ((c == 1) || (c == 2))
388 throw new IOException("Remote SCP error: " + line);
389
390 if (c == 'C') {
391 lnp = parseCLine(line);
392 break;
393 }
394
395 throw new IOException("Remote SCP error: " + ((char) c) + line);
396 }
397
398 os.write(0x0);
399 os.flush();
400 File f = new File(target + File.separatorChar + lnp.filename);
401 FileOutputStream fop = null;
402
403 try {
404 fop = new FileOutputStream(f);
405 long remain = lnp.length;
406
407 while (remain > 0) {
408 int trans;
409
410 if (remain > buffer.length)
411 trans = buffer.length;
412 else
413 trans = (int) remain;
414
415 int this_time_received = is.read(buffer, 0, trans);
416
417 if (this_time_received < 0) {
418 throw new IOException("Remote scp terminated connection unexpectedly");
419 }
420
421 fop.write(buffer, 0, this_time_received);
422 remain -= this_time_received;
423 }
424 }
425 finally {
426 if (fop != null)
427 fop.close();
428 }
429
430 readResponse(is);
431 os.write(0x0);
432 os.flush();
433 }
434 }
435
436 /**
437 * Copy a local file to a remote directory, uses mode 0600 when creating the
438 * file on the remote side.
439 *
440 * @param localFile
441 * Path and name of local file.
442 * @param remoteTargetDirectory
443 * Remote target directory. Use an empty string to specify the
444 * default directory.
445 *
446 * @throws IOException
447 */
448 public void put(String localFile, String remoteTargetDirectory) throws IOException {
449 put(new String[] { localFile }, remoteTargetDirectory, "0600");
450 }
451
452 /**
453 * Copy a set of local files to a remote directory, uses mode 0600 when
454 * creating files on the remote side.
455 *
456 * @param localFiles
457 * Paths and names of local file names.
458 * @param remoteTargetDirectory
459 * Remote target directory. Use an empty string to specify the
460 * default directory.
461 *
462 * @throws IOException
463 */
464
465 public void put(String[] localFiles, String remoteTargetDirectory) throws IOException {
466 put(localFiles, remoteTargetDirectory, "0600");
467 }
468
469 /**
470 * Copy a local file to a remote directory, uses the specified mode when
471 * creating the file on the remote side.
472 *
473 * @param localFile
474 * Path and name of local file.
475 * @param remoteTargetDirectory
476 * Remote target directory. Use an empty string to specify the
477 * default directory.
478 * @param mode
479 * a four digit string (e.g., 0644, see "man chmod", "man open")
480 * @throws IOException
481 */
482 public void put(String localFile, String remoteTargetDirectory, String mode) throws IOException {
483 put(new String[] { localFile }, remoteTargetDirectory, mode);
484 }
485
486 /**
487 * Copy a local file to a remote directory, uses the specified mode and
488 * remote filename when creating the file on the remote side.
489 *
490 * @param localFile
491 * Path and name of local file.
492 * @param remoteFileName
493 * The name of the file which will be created in the remote
494 * target directory.
495 * @param remoteTargetDirectory
496 * Remote target directory. Use an empty string to specify the
497 * default directory.
498 * @param mode
499 * a four digit string (e.g., 0644, see "man chmod", "man open")
500 * @throws IOException
501 */
502 public void put(String localFile, String remoteFileName, String remoteTargetDirectory, String mode)
503 throws IOException {
504 put(new String[] { localFile }, new String[] { remoteFileName }, remoteTargetDirectory, mode);
505 }
506
507 /**
508 * Create a remote file and copy the contents of the passed byte array into
509 * it. Uses mode 0600 for creating the remote file.
510 *
511 * @param data
512 * the data to be copied into the remote file.
513 * @param remoteFileName
514 * The name of the file which will be created in the remote
515 * target directory.
516 * @param remoteTargetDirectory
517 * Remote target directory. Use an empty string to specify the
518 * default directory.
519 * @throws IOException
520 */
521
522 public void put(byte[] data, String remoteFileName, String remoteTargetDirectory) throws IOException {
523 put(data, remoteFileName, remoteTargetDirectory, "0600");
524 }
525
526 /**
527 * Create a remote file and copy the contents of the passed byte array into
528 * it. The method use the specified mode when creating the file on the
529 * remote side.
530 *
531 * @param data
532 * the data to be copied into the remote file.
533 * @param remoteFileName
534 * The name of the file which will be created in the remote
535 * target directory.
536 * @param remoteTargetDirectory
537 * Remote target directory. Use an empty string to specify the
538 * default directory.
539 * @param mode
540 * a four digit string (e.g., 0644, see "man chmod", "man open")
541 * @throws IOException
542 */
543 public void put(byte[] data, String remoteFileName, String remoteTargetDirectory, String mode) throws IOException {
544 Session sess = null;
545
546 if ((remoteFileName == null) || (remoteTargetDirectory == null) || (mode == null))
547 throw new IllegalArgumentException("Null argument.");
548
549 if (mode.length() != 4)
550 throw new IllegalArgumentException("Invalid mode.");
551
552 for (int i = 0; i < mode.length(); i++)
553 if (Character.isDigit(mode.charAt(i)) == false)
554 throw new IllegalArgumentException("Invalid mode.");
555
556 remoteTargetDirectory = remoteTargetDirectory.trim();
557 remoteTargetDirectory = (remoteTargetDirectory.length() > 0) ? remoteTargetDirectory : ".";
558 String cmd = "scp -t -d " + remoteTargetDirectory;
559
560 try {
561 sess = conn.openSession();
562 sess.execCommand(cmd);
563 sendBytes(sess, data, remoteFileName, mode);
564 }
565 catch (IOException e) {
566 throw(IOException) new IOException("Error during SCP transfer.").initCause(e);
567 }
568 finally {
569 if (sess != null)
570 sess.close();
571 }
572 }
573
574 /**
575 * Copy a set of local files to a remote directory, uses the specified mode
576 * when creating the files on the remote side.
577 *
578 * @param localFiles
579 * Paths and names of the local files.
580 * @param remoteTargetDirectory
581 * Remote target directory. Use an empty string to specify the
582 * default directory.
583 * @param mode
584 * a four digit string (e.g., 0644, see "man chmod", "man open")
585 * @throws IOException
586 */
587 public void put(String[] localFiles, String remoteTargetDirectory, String mode) throws IOException {
588 put(localFiles, null, remoteTargetDirectory, mode);
589 }
590
591 public void put(String[] localFiles, String[] remoteFiles, String remoteTargetDirectory, String mode)
592 throws IOException {
593 Session sess = null;
594
595 /*
596 * remoteFiles may be null, indicating that the local filenames shall be
597 * used
598 */
599
600 if ((localFiles == null) || (remoteTargetDirectory == null) || (mode == null))
601 throw new IllegalArgumentException("Null argument.");
602
603 if (mode.length() != 4)
604 throw new IllegalArgumentException("Invalid mode.");
605
606 for (int i = 0; i < mode.length(); i++)
607 if (Character.isDigit(mode.charAt(i)) == false)
608 throw new IllegalArgumentException("Invalid mode.");
609
610 if (localFiles.length == 0)
611 return;
612
613 remoteTargetDirectory = remoteTargetDirectory.trim();
614 remoteTargetDirectory = (remoteTargetDirectory.length() > 0) ? remoteTargetDirectory : ".";
615 String cmd = "scp -t -d " + remoteTargetDirectory;
616
617 for (int i = 0; i < localFiles.length; i++) {
618 if (localFiles[i] == null)
619 throw new IllegalArgumentException("Cannot accept null filename.");
620 }
621
622 try {
623 sess = conn.openSession();
624 sess.execCommand(cmd);
625 sendFiles(sess, localFiles, remoteFiles, mode);
626 }
627 catch (IOException e) {
628 throw(IOException) new IOException("Error during SCP transfer.").initCause(e);
629 }
630 finally {
631 if (sess != null)
632 sess.close();
633 }
634 }
635
636 /**
637 * Download a file from the remote server to a local directory.
638 *
639 * @param remoteFile
640 * Path and name of the remote file.
641 * @param localTargetDirectory
642 * Local directory to put the downloaded file.
643 *
644 * @throws IOException
645 */
646 public void get(String remoteFile, String localTargetDirectory) throws IOException {
647 get(new String[] { remoteFile }, localTargetDirectory);
648 }
649
650 /**
651 * Download a file from the remote server and pipe its contents into an
652 * <code>OutputStream</code>. Please note that, to enable flexible usage
653 * of this method, the <code>OutputStream</code> will not be closed nor
654 * flushed.
655 *
656 * @param remoteFile
657 * Path and name of the remote file.
658 * @param target
659 * OutputStream where the contents of the file will be sent to.
660 * @throws IOException
661 */
662 public void get(String remoteFile, OutputStream target) throws IOException {
663 get(new String[] { remoteFile }, new OutputStream[] { target });
664 }
665
666 private void get(String remoteFiles[], OutputStream[] targets) throws IOException {
667 Session sess = null;
668
669 if ((remoteFiles == null) || (targets == null))
670 throw new IllegalArgumentException("Null argument.");
671
672 if (remoteFiles.length != targets.length)
673 throw new IllegalArgumentException("Length of arguments does not match.");
674
675 if (remoteFiles.length == 0)
676 return;
677
678 String cmd = "scp -f";
679
680 for (int i = 0; i < remoteFiles.length; i++) {
681 if (remoteFiles[i] == null)
682 throw new IllegalArgumentException("Cannot accept null filename.");
683
684 String tmp = remoteFiles[i].trim();
685
686 if (tmp.length() == 0)
687 throw new IllegalArgumentException("Cannot accept empty filename.");
688
689 cmd += (" " + tmp);
690 }
691
692 try {
693 sess = conn.openSession();
694 sess.execCommand(cmd);
695 receiveFiles(sess, targets);
696 }
697 catch (IOException e) {
698 throw(IOException) new IOException("Error during SCP transfer.").initCause(e);
699 }
700 finally {
701 if (sess != null)
702 sess.close();
703 }
704 }
705
706 /**
707 * Download a set of files from the remote server to a local directory.
708 *
709 * @param remoteFiles
710 * Paths and names of the remote files.
711 * @param localTargetDirectory
712 * Local directory to put the downloaded files.
713 *
714 * @throws IOException
715 */
716 public void get(String remoteFiles[], String localTargetDirectory) throws IOException {
717 Session sess = null;
718
719 if ((remoteFiles == null) || (localTargetDirectory == null))
720 throw new IllegalArgumentException("Null argument.");
721
722 if (remoteFiles.length == 0)
723 return;
724
725 String cmd = "scp -f";
726
727 for (int i = 0; i < remoteFiles.length; i++) {
728 if (remoteFiles[i] == null)
729 throw new IllegalArgumentException("Cannot accept null filename.");
730
731 String tmp = remoteFiles[i].trim();
732
733 if (tmp.length() == 0)
734 throw new IllegalArgumentException("Cannot accept empty filename.");
735
736 cmd += (" " + tmp);
737 }
738
739 try {
740 sess = conn.openSession();
741 sess.execCommand(cmd);
742 receiveFiles(sess, remoteFiles, localTargetDirectory);
743 }
744 catch (IOException e) {
745 throw(IOException) new IOException("Error during SCP transfer.").initCause(e);
746 }
747 finally {
748 if (sess != null)
749 sess.close();
750 }
751 }
232 } 752 }
753
754