jcraft--SFTP demo

import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Vector;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.ProgressMonitor;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpProgressMonitor;
import com.jcraft.jsch.SftpStatVFS;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;

public class Sftp {
    public static void main(String[] args) {
        try {
            JSch jsch = new JSch();
            
            String host = null;
            if (args.length > 0) {
                host = args[0];
            } else {
                host = JOptionPane.showInputDialog("Enter username@hostname",
                                                   System.getProperty("user.name") + "@localhost");
            }
            
            String user = host.substring(0, host.indexOf('@'));
            host = host.substring(host.indexOf('@') + 1);
            int port = 22;
            
            Session session = jsch.getSession(user, host, port);
            
            UserInfo userinfo = new MyUserInfo();
            session.setUserInfo(userinfo);            
            session.connect();
            
            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp channelSftp = (ChannelSftp)channel;
            
            InputStream in = System.in;
            PrintStream out = System.out;
            
            Vector cmds = new Vector();
            byte[] buf = new byte[1024];
            int i;
            String str;
            int level = 0;
            
            while (true) {
                out.print("sftp> ");
                cmds.removeAllElements();
                
                i = in.read(buf, 0, 1024);
                if (i <= 0) {
                    break;
                }
                i--;
                if (i > 0 && buf[i-1] == 0x0d) {
                    i--;
                }
                
                int s = 0;
                for (int ii = 0; ii < i; ii++) {
                    if (' ' == buf[ii]) {
                        if (ii - s > 0) {
                            cmds.addElement(new String(buf, s, ii - s));
                        }
                        
                        while (ii < i) {
                            if (' ' != buf[ii]) {
                                break;
                            }
                            ii++;
                        }
                        s = ii;
                    }
                }
                
                if (s < i) {
                    cmds.addElement(new String(buf, s, i - s));
                }
                
                if (0 == cmds.size()) {
                    continue;
                }
                
                String cmd = (String) cmds.elementAt(0);
                if (cmd.equals("quit")) {
                    channelSftp.quit();
                    break;
                }
                
                if (cmd.equals("exit")) {
                    channelSftp.exit();
                    break;
                }
                
                if (cmd.equals("rekey")) {
                    session.rekey();
                    continue;
                }
                
                if (cmd.equals("compression")) {
                    if (cmds.size() < 2) {
                        out.println("compression level: " + level);
                        continue;
                    }
                    
                    try {
                        level = Integer.parseInt((String)cmds.elementAt(1));
                        if (0 == level) {
                            session.setConfig("compression.s2c", "none");
                            session.setConfig("compression.c2s", "none");
                        } else {
                            session.setConfig("compression.s2c", "zlib@openssh.com,zlib,none");
                            session.setConfig("compression.c2s", "zlib@openssh.com,zlib,none");
                        }
                    } catch (Exception e) {}
                    session.rekey();
                    continue;
                }
                
                if (cmd.equals("cd") || cmd.equals("lcd")) {
                    if (cmds.size() < 2) {
                        continue;
                    }
                    String path = (String)cmds.elementAt(1);
                    
                    try {
                        if (cmd.equals("cd")) {
                            channelSftp.cd(path);
                        } else {
                            channelSftp.lcd(path);
                        }
                    } catch (Exception e) {
                        System.out.println(e.toString());
                    }
                    continue;
                }
                
                if (cmd.equals("rm") || cmd.equals("rmdir") || cmd.equals("mkdir")) {
                    if (cmds.size() < 2) {
                        continue;
                    }
                    
                    String path = (String)cmds.elementAt(1);
                    try {
                        if (cmd.equals("rm")) {
                            channelSftp.rm(path);
                        } else if (cmd.equals("rmdir")) {
                            channelSftp.rmdir(path);
                        } else {
                            channelSftp.mkdir(path);
                        }
                    } catch (Exception e) {
                        System.out.println(e.toString());
                    }
                    continue;
                }
                
                if (cmd.equals("chgrp") || cmd.equals("chown") || cmd.equals("chmod")) {
                    if (3 != cmds.size()) {
                        continue;
                    }
                    
                    String path = (String)cmds.elementAt(2);
                    int foo = 0;
                    if (cmd.equals("chmod")) {
                        byte[] bar = ((String)cmds.elementAt(1)).getBytes();
                        int k;
                        for (int j = 0; j < bar.length; j++) {
                            k = bar[j];
                            if (k < '0' || k > '7') {
                                foo = -1;
                                break;
                            }
                            foo <<= 3;
                            foo |= (k - '0');
                        }
                        if (-1 == foo) {
                            continue;
                        }
                    } else {
                        try {
                            foo = Integer.parseInt((String)cmds.elementAt(1));
                        } catch (Exception e) {
                            continue;
                        }
                    }
                    
                    try {
                        if (cmd.equals("chgrp")) {
                            channelSftp.chgrp(foo, path);
                        } else if (cmd.equals("chown")) {
                            channelSftp.chown(foo, path);
                        } else if (cmd.equals("chmod")) {
                            channelSftp.chmod(foo, path);
                        }
                    } catch (Exception e) {
                        System.out.println(e.toString());
                    }
                    continue;
                }
                
                if (cmd.equals("pwd") || cmd.equals("lpwd")) {
                    str = (cmd.equals("pwd") ? "Remote" : "Local");
                    str += " working directory: ";
                    if (cmd.equals("pwd")) {
                        str += channelSftp.pwd();
                    } else {
                        str += channelSftp.lpwd();
                    }
                    out.println(str);
                    continue;
                }
                
                if (cmd.equals("ls") || cmd.equals("dir")) {
                    String path = ".";
                    if (2 == cmds.size()) {
                        path = (String)cmds.elementAt(1);
                    }
                    
                    try {
                        Vector vv = channelSftp.ls(path);
                        if (null != vv) {
                            for (int ii = 0; ii < vv.size(); ii++) {
                                Object object = vv.elementAt(ii);
                                if (object instanceof LsEntry) {
                                    out.println(((LsEntry)object).getLongname());
                                }
                            }
                        }
                    } catch (Exception e) {
                        System.out.println(e.toString());
                    }
                    continue;
                }
                
                if (cmds.equals("lls") || cmds.equals("ldir")) {
                    String path = ".";
                    if (2 == cmds.size()) {
                        path = (String)cmds.elementAt(1);
                    }
                    
                    try {
                        File file = new File(path);
                        if (!file.exists()) {
                            out.println(path + ": No such file or directory");
                            continue;
                        }
                        
                        if (file.isDirectory()) {
                            String[] list = file.list();
                            for (int ii = 0; ii < list.length; ii++) {
                                out.println(list[ii]);
                            }
                            continue;
                        }
                        out.println(path);
                    } catch (Exception e) {
                        // TODO: handle exception
                        out.println(path);
                    }
                    continue;
                }
                
                if (cmd.equals("get") ||
                    cmd.equals("get-resume") || 
                    cmd.equals("get-append") ||
                    cmd.equals("put") || 
                    cmd.equals("put-resume") ||
                    cmd.equals("put-append")) {
                    
                    if (2 != cmds.size() && 3 != cmds.size()) {
                        continue;
                    }
                    
                    String p1 = (String)cmds.elementAt(1);
                    String p2 = ".";
                    
                    if (3 == cmds.size()) {
                        p2 = (String)cmds.elementAt(2);
                    }
                    
                    try {
                        SftpProgressMonitor monitor = new MyProgressMonitor();
                        if (cmd.startsWith("get")) {
                            int mode = ChannelSftp.OVERWRITE;
                            if (cmd.equals("get-resume")) {
                                mode = ChannelSftp.RESUME;
                            } else if (cmd.equals("get-append")) {
                                mode = ChannelSftp.APPEND;
                            }
                            channelSftp.get(p1, p2, monitor, mode);
                        } else {
                            int mode = ChannelSftp.OVERWRITE;
                            if (cmd.equals("put-resume")) {
                                mode = ChannelSftp.RESUME;
                            } else if (cmd.equals("put-append")) {
                                mode = ChannelSftp.APPEND;
                            }
                            channelSftp.put(p1, p2, monitor, mode);
                        }
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println(e.toString());
                    }
                    continue;
                }
                
                if (cmd.equals("ln") || cmd.equals("symlink") || cmd.equals("rename") || cmd.equals("hardlink")) {
                    if (3 != cmds.size()) {
                        continue;
                    }
                    String p1 = (String)cmds.elementAt(1);
                    String p2 = (String)cmds.elementAt(2);
                    
                    try {
                        if (cmd.equals("hardlink")) {
                            channelSftp.hardlink(p1, p2);
                        } else if (cmd.equals("rename")) {
                            channelSftp.rename(p1, p2);
                        } else {
                            channelSftp.symlink(p1, p2);
                        }
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println(e.toString());
                    }
                    continue;
                }
                
                if (cmd.equals("df")) {
                    if (cmds.size() > 2) {
                        continue;
                    }
                    String p1 = 1 == cmds.size() ? "." : (String)cmds.elementAt(1);
                    SftpStatVFS stat = channelSftp.statVFS(p1);
                    
                    long size = stat.getSize();
                    long used = stat.getUsed();
                    long avail = stat.getAvailForNonRoot();
                    long root_avail = stat.getAvail();
                    long capacity = stat.getCapacity();
                    
                    System.out.println("Size: " + size);
                    System.out.println("Used: " + used);
                    System.out.println("Avail: " + avail);
                    System.out.println("(root): " + root_avail);
                    System.out.println("%Capacity: " + capacity);
                    
                    continue;
                }
                
                if (cmd.equals("stat") || cmd.equals("lstat")) {
                    if (2 != cmds.size()) {
                        continue;
                    }
                    
                    String p1 = (String)cmds.elementAt(1);
                    SftpATTRS attrs = null;
                    
                    try {
                        if (cmd.equals("stat")) {
                            attrs = channelSftp.stat(p1);
                        } else {
                            attrs = channelSftp.lstat(p1);
                        }
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println(e.toString());
                    }
                    
                    if (null != attrs) {
                        out.println(attrs);
                    }
                    
                    continue;
                }
                
                if (cmd.equals("readlink")) {
                    if (2 != cmds.size()) {
                        continue;
                    }
                    
                    String p1 = (String)cmds.elementAt(1);
                    String filename = null;
                    
                    try {
                        filename = channelSftp.readlink(p1);
                        out.println(filename);
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println(e.toString());
                    }
                    
                    continue;
                }
                
                if (cmd.equals("realpath")) {
                    if (2 != cmds.size()) {
                        continue;
                    }
                    
                    String p1 = (String)cmds.elementAt(1);
                    String filename = null;
                    
                    try {
                        filename = channelSftp.realpath(p1);
                        out.println(filename);
                    } catch (Exception e) {
                        // TODO: handle exception
                        System.out.println(e.toString());
                    }
                    
                    continue;
                }
                
                if (cmd.equals("version")) {
                    out.println("SFTP protocol version " + channelSftp.version());
                    continue;
                }
                
                if (cmd.equals("help") || cmd.equals("?")) {
                    out.println(help);
                    continue;
                }
                
                out.println("unimplemented command: " + cmd);
            }
            session.disconnect();
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println(e);
        }
        System.exit(0);
    }
    
    public static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
        String passwd;
        JTextField passwordField = (JTextField)new JPasswordField(20);
        final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1,
                                                              GridBagConstraints.NORTHWEST, 
                                                              GridBagConstraints.NONE, 
                                                              new Insets(0, 0, 0, 0), 0, 0);
        Container panel;

        @Override
        public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt,
                boolean[] echo) {
            panel = new JPanel();
            panel.setLayout(new GridBagLayout());
            
            gbc.weightx = 1.0;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.gridx = 0;
            panel.add(new JLabel(instruction), gbc);
            gbc.gridy++;
            
            gbc.gridwidth = GridBagConstraints.RELATIVE;
            
            JTextField[] texts = new JTextField[prompt.length];
            for (int i = 0; i < prompt.length; i++) {
                gbc.fill = GridBagConstraints.NONE;
                gbc.gridx = 0;
                gbc.weightx = 1;
                panel.add(new JLabel(prompt[i]), gbc);
                
                gbc.gridx = 1;
                gbc.fill = GridBagConstraints.HORIZONTAL;
                gbc.weighty = 1;
                if (echo[i]) {
                    texts[i] = new JTextField(20);
                } else {
                    texts[i] = new JPasswordField(20);
                }
                panel.add(texts[i], gbc);
                gbc.gridy++;
            }
            
            if (JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(null, panel,
                                              destination + ": " + name,
                                              JOptionPane.OK_CANCEL_OPTION,
                                              JOptionPane.QUESTION_MESSAGE)) {
                String[] response = new String[prompt.length];
                for (int i = 0; i < prompt.length; i++) {
                    response[i] = texts[i].getText();
                }
                
                return response;
            } else {
                return null; // cancel
            }
        }

        @Override
        public String getPassphrase() {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public String getPassword() {
            // TODO Auto-generated method stub
            return passwd;
        }

        @Override
        public boolean promptPassphrase(String message) {
            // TODO Auto-generated method stub
            return true;
        }

        @Override
        public boolean promptPassword(String message) {
            Object[] ob = { passwordField };
            int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION);
            
            if (JOptionPane.OK_OPTION == result) {
                passwd = passwordField.getText();
                return true;
            } else {
                return false;
            }
        }

        @Override
        public boolean promptYesNo(String message) {
            Object[] options = { "yes", "no" };
            int foo = JOptionPane.showOptionDialog(null, message, "warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
            
            return 0 == foo;
        }

        @Override
        public void showMessage(String message) {
            // TODO Auto-generated method stub
            JOptionPane.showMessageDialog(null, message);
        }
        
    }
    
    public static class MyProgressMonitor implements SftpProgressMonitor {
        ProgressMonitor monitor;
        long count = 0;
        long max = 0;
        private long percent = -1;
        
        @Override
        public boolean count(long count) {
            this.count += count;
            
            if (percent >= this.count * 100 / max) {
                return true;
            }
            
            percent = this.count * 100 / max;
            
            monitor.setNote("Completed " + this.count + "(" + percent + "%) out of " + max + ".");
            monitor.setProgress((int)this.count);
            
            return !(monitor.isCanceled());
        }
        
        @Override
        public void end() {
            monitor.close();
        }
        
        @Override
        public void init(int op, String src, String dest, long max) {
            this.max = max;
            monitor = new ProgressMonitor(null, 
                                          ((SftpProgressMonitor.PUT == op) ? "put" : "get" + ": " + src), 
                                          "", 0, (int)max);
            count = 0;
            percent = -1;
            monitor.setProgress((int)this.count);
            monitor.setMillisToDecideToPopup(1000);
        }        
    }
    
    private static String help = "      Available commands:\n"+
            "      * means unimplemented command.\n"+
            "cd path                       Change remote directory to 'path'\n"+
            "lcd path                      Change local directory to 'path'\n"+
            "chgrp grp path                Change group of file 'path' to 'grp'\n"+
            "chmod mode path               Change permissions of file 'path' to 'mode'\n"+
            "chown own path                Change owner of file 'path' to 'own'\n"+
            "df [path]                     Display statistics for current directory or\n"+
            "                              filesystem containing 'path'\n"+
            "help                          Display this help text\n"+
            "get remote-path [local-path]  Download file\n"+
            "get-resume remote-path [local-path]  Resume to download file.\n"+
            "get-append remote-path [local-path]  Append remote file to local file\n"+
            "hardlink oldpath newpath      Hardlink remote file\n"+
            "*lls [ls-options [path]]      Display local directory listing\n"+
            "ln oldpath newpath            Symlink remote file\n"+
            "*lmkdir path                  Create local directory\n"+
            "lpwd                          Print local working directory\n"+
            "ls [path]                     Display remote directory listing\n"+
            "*lumask umask                 Set local umask to 'umask'\n"+
            "mkdir path                    Create remote directory\n"+
            "put local-path [remote-path]  Upload file\n"+
            "put-resume local-path [remote-path]  Resume to upload file\n"+
            "put-append local-path [remote-path]  Append local file to remote file.\n"+
            "pwd                           Display remote working directory\n"+
            "stat path                     Display info about path\n"+
            "exit                          Quit sftp\n"+
            "quit                          Quit sftp\n"+
            "rename oldpath newpath        Rename remote file\n"+
            "rmdir path                    Remove remote directory\n"+
            "rm path                       Delete remote file\n"+
            "symlink oldpath newpath       Symlink remote file\n"+
            "readlink path                 Check the target of a symbolic link\n"+
            "realpath path                 Canonicalize the path\n"+
            "rekey                         Key re-exchanging\n"+
            "compression level             Packet compression will be enabled\n"+
            "version                       Show SFTP version\n"+
            "?                             Synonym for help";
}

 

posted @ 2019-03-02 13:12  yixiu868  阅读(448)  评论(0编辑  收藏  举报