Skip to content

Commit 496f1aa

Browse files
committed
Merge branch 'scp'
2 parents 429cd40 + 86fbb78 commit 496f1aa

File tree

9 files changed

+652
-23
lines changed

9 files changed

+652
-23
lines changed

circle.yml

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
machine:
2+
java:
3+
version: oraclejdk8
4+
15
deployment:
26
all:
37
branch: /.*/

doc/Primary-API.md

+24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
The primary public API for this library is the following set of functions:
44

55
- `clj-libssh2.ssh/exec` - Execute a command on the remote host.
6+
- `clj-libssh2.ssh/scp-from` - SCP a file from the remote host.
7+
- `clj-libssh2.ssh/scp-to` - SCP a file to the remote host.
68
- `clj-libssh2.ssh/with-session` - A convenience macro for managing sessions.
79

810
If there are any breaking changes to the above-named functions after version
@@ -44,3 +46,25 @@ user=> (ssh/exec {:hostname "127.0.0.1"}
4446
{:out "foo\nbar\n", :err "", :exit 0, :signal {:exit-signal nil, :err-msg nil,
4547
:lang-tag nil}}
4648
```
49+
50+
### Copy a file from a remote machine.
51+
52+
```clojure
53+
user=> (require '[clj-libssh2.ssh :as ssh])
54+
nil
55+
user=> (ssh/scp-from {:hostname "127.0.0.1"} "/home/conor/.vimrc" ".vimrc")
56+
{:local-path ".vimrc", :remote-path "/home/conor/.vimrc", :size 4525,
57+
:remote-stat {:atime #object[java.time.Instant 0x3fc52110
58+
"2016-01-30T23:16:16Z"], :ctime #object[java.time.Instant 0x6de7c794
59+
"1970-01-01T00:00:00Z"], :gid 0, :mode 420, :mtime #object[java.time.Instant
60+
0x3e81f5e4 "2016-01-30T17:58:11Z"], :size 4525, :uid 0}}
61+
```
62+
63+
### Send a file to a remote machine.
64+
65+
```clojure
66+
user=> (require '[clj-libssh2.ssh :as ssh])
67+
nil
68+
user=> (ssh/scp-to {:hostname "127.0.0.1"} "/home/conor/.vimrc" "/tmp/.vimrc")
69+
nil
70+
```

project.clj

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
:license {:name "BSD"
55
:url "https://github.com/conormcd/clj-libssh2/blob/master/LICENSE"}
66
:pedantic? :abort
7+
:java-source-paths ["src-java"]
78
:dependencies [[org.clojure/clojure "1.7.0"]
89
[net.n01se/clojure-jna "1.0.0"]]
910
:profiles {:dev {:plugins [[lein-codox "0.9.1"]]}}

src-java/clj_libssh2/struct/Stat.java

+260
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
package clj_libssh2.struct;
2+
3+
import java.time.Instant;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
import com.sun.jna.Platform;
8+
import com.sun.jna.Structure;
9+
10+
/**
11+
* A JNA mapping for struct stat.
12+
*/
13+
public abstract class Stat
14+
extends Structure
15+
{
16+
/**
17+
* Create a new struct stat. Since this structure varies between platforms
18+
* the returned object may behave quite differently depending on the OS.
19+
* While the returned object will expose all of its fields as public
20+
* members it's advisable to only use the methods exposed in the Stat class
21+
* itself.
22+
*
23+
* @return Stat An instance of this class which will map a struct stat from
24+
* the underlying operating system.
25+
*
26+
* @throws UnsupportedPlatformException If we don't have an implementation
27+
* for the current operating system.
28+
*/
29+
public static Stat newInstance() throws UnsupportedPlatformException {
30+
switch (Platform.RESOURCE_PREFIX) {
31+
case "darwin":
32+
return new Darwin();
33+
case "linux-x86-64":
34+
return new Linux_X86_64();
35+
default:
36+
throw new UnsupportedPlatformException(Platform.RESOURCE_PREFIX);
37+
}
38+
}
39+
40+
/**
41+
* Get the last access time of the described file.
42+
*
43+
* @return Instant The last access time.
44+
*/
45+
public abstract Instant getATime();
46+
47+
/**
48+
* Get the time the status of the described file was changed.
49+
*
50+
* @return Instant The value of ctime for the described file.
51+
*/
52+
public abstract Instant getCTime();
53+
54+
/**
55+
* The group ID assigned to the described file.
56+
*
57+
* @return int The file's GID.
58+
*/
59+
public abstract int getGroupID();
60+
61+
/**
62+
* Get the permissions mask for the described file.
63+
*
64+
* @return int An integer with the same permissions mask as the file's.
65+
*/
66+
public abstract int getMode();
67+
68+
/**
69+
* Get the last modification time of the described file.
70+
*
71+
* @return Instant The last time the file was modified.
72+
*/
73+
public abstract Instant getMTime();
74+
75+
/**
76+
* Get the size of the file in bytes.
77+
*
78+
* @return int The size of the described file, in bytes.
79+
*/
80+
public abstract long getSize();
81+
82+
/**
83+
* The UID of the user who owns the described file.
84+
*
85+
* @return int The user's UID.
86+
*/
87+
public abstract int getUserID();
88+
89+
/**
90+
* The implementation of struct stat for OSX.
91+
*/
92+
public static class Darwin
93+
extends Stat
94+
{
95+
public int st_dev; // dev_t
96+
public short st_mode; // mode_t
97+
public short st_nlink; // nlink_t
98+
public long st_ino; // ino_t
99+
public int st_uid; // uid_t
100+
public int st_gid; // gid_t
101+
public int st_rdev; // dev_t
102+
public Timespec st_atimespec; // struct timespec
103+
public Timespec st_mtimespec; // struct timespec
104+
public Timespec st_ctimespec; // struct timespec
105+
public Timespec st_birthtimespec; // struct timespec
106+
public long st_size; // off_t
107+
public long st_blocks; // blkcnt_t
108+
public int st_blksize; // blksize_t
109+
public int st_flags; // uint32_t
110+
public int st_gen; // uint32_t
111+
public int st_lspare; // int32_t
112+
public long st_qspare_1; // int_64_t
113+
public long st_qspare_2; // int_64_t
114+
115+
@Override
116+
public Instant getATime() {
117+
return st_atimespec.toInstant();
118+
}
119+
120+
@Override
121+
public Instant getCTime() {
122+
return st_ctimespec.toInstant();
123+
}
124+
125+
@Override
126+
public int getGroupID() {
127+
return st_gid;
128+
}
129+
130+
@Override
131+
public int getMode() {
132+
return st_mode;
133+
}
134+
135+
@Override
136+
public Instant getMTime() {
137+
return st_mtimespec.toInstant();
138+
}
139+
140+
@Override
141+
public long getSize() {
142+
return st_size;
143+
}
144+
145+
@Override
146+
public int getUserID() {
147+
return st_uid;
148+
}
149+
150+
@Override
151+
public List<String> getFieldOrder() {
152+
return Arrays.asList(
153+
"st_dev",
154+
"st_mode",
155+
"st_nlink",
156+
"st_ino",
157+
"st_uid",
158+
"st_gid",
159+
"st_rdev",
160+
"st_atimespec",
161+
"st_mtimespec",
162+
"st_ctimespec",
163+
"st_birthtimespec",
164+
"st_size",
165+
"st_blocks",
166+
"st_blksize",
167+
"st_flags",
168+
"st_gen",
169+
"st_lspare",
170+
"st_qspare_1",
171+
"st_qspare_2"
172+
);
173+
}
174+
}
175+
176+
/**
177+
* The implementation of struct stat for Linux x86_64. The names and
178+
* mapping of the fields is from glibc.
179+
*/
180+
public static class Linux_X86_64
181+
extends Stat
182+
{
183+
public long st_dev; // dev_t
184+
public long st_ino; // ino_t
185+
public long st_nlink; // nlink_t
186+
public int st_mode; // mode_t
187+
public int st_uid; // uid_t
188+
public int st_gid; // gid_t
189+
public int pad0; // int
190+
public long st_rdev; // dev_t
191+
public long st_size; // off_t
192+
public long st_blksize; // blksize_t
193+
public long st_blocks; // blkcnt_t
194+
public Timespec st_atim; // struct timespec
195+
public Timespec st_mtim; // struct timespec
196+
public Timespec st_ctim; // struct timespec
197+
public long reserved1; // __syscall_slong_t
198+
public long reserved2; // __syscall_slong_t
199+
public long reserved3; // __syscall_slong_t
200+
201+
@Override
202+
public Instant getATime() {
203+
return st_atim.toInstant();
204+
}
205+
206+
@Override
207+
public Instant getCTime() {
208+
return st_ctim.toInstant();
209+
}
210+
211+
@Override
212+
public int getGroupID() {
213+
return st_gid;
214+
}
215+
216+
@Override
217+
public int getMode() {
218+
return st_mode;
219+
}
220+
221+
@Override
222+
public Instant getMTime() {
223+
return st_mtim.toInstant();
224+
}
225+
226+
@Override
227+
public long getSize() {
228+
return st_size;
229+
}
230+
231+
@Override
232+
public int getUserID() {
233+
return st_uid;
234+
}
235+
236+
@Override
237+
public List<String> getFieldOrder() {
238+
return Arrays.asList(
239+
"st_dev",
240+
"st_ino",
241+
"st_nlink",
242+
"st_mode",
243+
"st_uid",
244+
"st_gid",
245+
"pad0",
246+
"st_rdev",
247+
"st_size",
248+
"st_blksize",
249+
"st_blocks",
250+
"st_atim",
251+
"st_mtim",
252+
"st_ctim",
253+
"reserved1",
254+
"reserved2",
255+
"reserved3"
256+
);
257+
}
258+
}
259+
}
260+
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package clj_libssh2.struct;
2+
3+
import java.time.Instant;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
7+
import com.sun.jna.Structure;
8+
9+
/**
10+
* A struct timespec. This can represent instants in time with up to nanosecond
11+
* precision depending on the underlying platform.
12+
*/
13+
public class Timespec
14+
extends Structure
15+
{
16+
public long tv_sec;
17+
public long tv_nsec;
18+
19+
@Override
20+
public List<String> getFieldOrder() {
21+
return Arrays.asList("tv_sec", "tv_nsec");
22+
}
23+
24+
/**
25+
* Re-interpret this struct as an {@link Instant} for more convenient use
26+
* in Java/Clojure.
27+
*
28+
* @return Instant An {@link Instant} representing the same point in time
29+
* as the underlying struct.
30+
*/
31+
public Instant toInstant() {
32+
return Instant.ofEpochSecond(tv_sec, tv_nsec);
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return toInstant().toString();
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package clj_libssh2.struct;
2+
3+
/**
4+
* A marker exception for when we try to map a struct on a platform we
5+
* don't support yet.
6+
*/
7+
public class UnsupportedPlatformException
8+
extends Exception
9+
{
10+
public UnsupportedPlatformException(String message) {
11+
super(message);
12+
}
13+
}

0 commit comments

Comments
 (0)