001package ssh;
002
003import grails.plugin.remotessh.SshConfig;
004
005import java.io.File;
006import java.io.FileOutputStream;
007import java.io.IOException;
008
009import ch.ethz.ssh2.ChannelCondition;
010import ch.ethz.ssh2.Connection;
011import ch.ethz.ssh2.SCPClient;
012import ch.ethz.ssh2.SFTPv3Client;
013import ch.ethz.ssh2.SFTPv3FileHandle;
014import ch.ethz.ssh2.Session;
015
016/**
017 * Called by IncludeUpdate class scps a folder to specified end server.
018 */
019public class RemoteSCPDir  {
020
021        String hostname = "";
022        String user = "";
023        Integer port=0;
024        String userpass="";
025        String localdir = "";
026        String remotedir = "";
027        String usercommand = "";
028        String output = "";
029        String characterSet="";
030        String permission = "";
031        
032        public RemoteSCPDir(String hostname, String localdir,String remotedir) {
033                this.hostname = hostname;
034                this.localdir = localdir;
035                this.remotedir = remotedir;
036        }
037        public RemoteSCPDir(String hostname, String user, String localdir,String remotedir) {
038                this.hostname = hostname;
039                this.user = user;
040                this.localdir = localdir;
041                this.remotedir = remotedir;
042        }
043        public RemoteSCPDir(String hostname, String user,String userpass, String localdir,String remotedir) {
044                this.hostname = hostname;
045                this.user = user;
046                this.userpass=userpass;
047                this.localdir = localdir;
048                this.remotedir = remotedir;
049        }
050        public RemoteSCPDir(String hostname, String localdir,String remotedir, Integer port) {
051                this.hostname = hostname;
052                this.localdir = localdir;
053                this.remotedir = remotedir;
054                this.port=port;
055        }
056        public RemoteSCPDir(String hostname, String user, String localdir,String remotedir, Integer port) {
057                this.hostname = hostname;
058                this.user = user;
059                this.localdir = localdir;
060                this.remotedir = remotedir;
061                this.port=port;
062        }
063        public RemoteSCPDir(String hostname, String user, String userpass, String localdir,String remotedir, Integer port,String charSet,String permission) {
064                this.hostname = hostname;
065                this.user = user;
066                this.userpass=userpass;
067                this.localdir = localdir;
068                this.remotedir = remotedir;
069                this.port=port;
070                this.characterSet=charSet;
071                this.permission=permission;
072        }
073
074        public RemoteSCPDir(String hostname, String user, String userpass, String localdir,String remotedir, Integer port,String charSet) {
075                this.hostname = hostname;
076                this.user = user;
077                this.userpass=userpass;
078                this.localdir = localdir;
079                this.remotedir = remotedir;
080                this.port=port;
081                this.characterSet=charSet;
082        }
083
084
085        public String Result(SshConfig ac) throws IOException{
086                Object sshuser=ac.getConfig("USER");
087                Object sshpass=ac.getConfig("PASS");
088                Object sshkey=ac.getConfig("KEY");
089                Object sshkeypass=ac.getConfig("KEYPASS");
090                Object sshport=ac.getConfig("PORT");
091                String charSet=ac.getConfig("CHARACTERSET").toString();
092                String perm=ac.getConfig("PERMISSION").toString();
093                //System.out.println("----"+sshuser.toString());
094                if (user.equals("")) {
095                        user = sshuser.toString();
096                }
097                if (userpass.equals("")) {
098                        userpass = sshpass.toString();
099                }
100                if (port==0) {
101                        String sps=sshport.toString();
102                        if (sps.matches("[0-9]+")) {
103                                port=Integer.parseInt(sps);
104                        }
105                }
106                if (this.characterSet.length()==0) {
107                        if (charSet.length()>0) {
108                                this.characterSet=charSet;
109                        } else {
110                                this.characterSet="UTF-8";
111                        }
112                }
113                if (this.permission.length()==0) {
114                        if (perm.length()>0) {
115                                this.permission=perm;
116                        } else {
117                                this.permission="0600";
118                        }
119                }
120                String username = user;
121                File keyfile = new File(sshkey.toString());
122                String keyfilePass = sshkeypass.toString();
123                        if (port==0){port=22; }
124                        Connection conn = new Connection(hostname,port);
125                        /* Now connect */
126                        conn.connect();
127                        /* Authenticate */
128                        boolean isAuthenticated=false;
129                        if (userpass.equals("")) {
130                                isAuthenticated = conn.authenticateWithPublicKey(username,
131                                                keyfile, keyfilePass);
132                        }else{
133                                isAuthenticated = conn.authenticateWithPassword(username,userpass);
134                        }
135                        if (isAuthenticated == false)
136                                throw new IOException("Authentication failed.");
137                        // Session sess = conn.openSession();
138                        // sess.execCommand("mkdir -p " + remotedir);
139                        putDir(conn, localdir, remotedir, permission,characterSet);
140                        conn.close();
141                        output = "" + localdir + " should now be copied to " + hostname
142                                        + ":" + remotedir + "<br>";
143                return output;
144        }
145
146        private static void putDir(Connection conn, String localDirectory,
147                        String remoteTargetDirectory, String permission,String characterSet) throws IOException {
148
149                File curDir = new File(localDirectory);
150                final String[] fileList = curDir.list();
151                for (String file : fileList) {
152                        final String fullFileName = localDirectory + "/" + file;
153                        if (new File(fullFileName).isDirectory()) {
154                                final String subDir = remoteTargetDirectory + "/" + file;
155                                Session sess = conn.openSession();
156                                sess.execCommand("mkdir " + subDir);
157                                sess.waitForCondition(ChannelCondition.EOF, 0);
158                                putDir(conn, fullFileName, subDir, permission,characterSet);
159                        } else {
160                                
161                                File actualFile = new File(fullFileName);
162                                FileOutputStream out =  null;
163                                try {
164                                        out = new FileOutputStream(remoteTargetDirectory+File.separator+actualFile.getName());
165                                        SFTPv3Client sFTPv3Client = new SFTPv3Client(conn);
166                                        if (characterSet!=null) {
167                                                sFTPv3Client.setCharset(characterSet);
168                                        }
169                                        SFTPv3FileHandle handle = sFTPv3Client.openFileRO(fullFileName);
170                                        byte[] cache = new byte[1024];
171                                        int i = 0;
172                                        int offset = 0;
173                                        while((i = sFTPv3Client.read(handle, offset, cache, 0, 1024)) != -1){
174                                                out.write(cache, 0, i);
175                                                offset += i;
176                                        }
177                                        sFTPv3Client.closeFile(handle);
178                                if (handle.isClosed()){
179                                            sFTPv3Client.close();
180                                } 
181                                } catch (IOException e) {
182                                        e.printStackTrace();
183                                } finally {
184                                        try {
185                                                if (out != null) {
186                                                        out.close();
187                                                }
188                                        } catch (IOException e) {
189                                                e.printStackTrace();
190                                        }
191                                }
192                        }
193                }
194        }
195}