Skip to content

Commit

Permalink
Merge branch 'scp'
Browse files Browse the repository at this point in the history
  • Loading branch information
conormcd committed Jan 31, 2016
2 parents 429cd40 + 86fbb78 commit 496f1aa
Show file tree
Hide file tree
Showing 9 changed files with 652 additions and 23 deletions.
4 changes: 4 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
machine:
java:
version: oraclejdk8

deployment:
all:
branch: /.*/
Expand Down
24 changes: 24 additions & 0 deletions doc/Primary-API.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
The primary public API for this library is the following set of functions:

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

If there are any breaking changes to the above-named functions after version
Expand Down Expand Up @@ -44,3 +46,25 @@ user=> (ssh/exec {:hostname "127.0.0.1"}
{:out "foo\nbar\n", :err "", :exit 0, :signal {:exit-signal nil, :err-msg nil,
:lang-tag nil}}
```

### Copy a file from a remote machine.

```clojure
user=> (require '[clj-libssh2.ssh :as ssh])
nil
user=> (ssh/scp-from {:hostname "127.0.0.1"} "/home/conor/.vimrc" ".vimrc")
{:local-path ".vimrc", :remote-path "/home/conor/.vimrc", :size 4525,
:remote-stat {:atime #object[java.time.Instant 0x3fc52110
"2016-01-30T23:16:16Z"], :ctime #object[java.time.Instant 0x6de7c794
"1970-01-01T00:00:00Z"], :gid 0, :mode 420, :mtime #object[java.time.Instant
0x3e81f5e4 "2016-01-30T17:58:11Z"], :size 4525, :uid 0}}
```

### Send a file to a remote machine.

```clojure
user=> (require '[clj-libssh2.ssh :as ssh])
nil
user=> (ssh/scp-to {:hostname "127.0.0.1"} "/home/conor/.vimrc" "/tmp/.vimrc")
nil
```
1 change: 1 addition & 0 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
:license {:name "BSD"
:url "https://github.com/conormcd/clj-libssh2/blob/master/LICENSE"}
:pedantic? :abort
:java-source-paths ["src-java"]
:dependencies [[org.clojure/clojure "1.7.0"]
[net.n01se/clojure-jna "1.0.0"]]
:profiles {:dev {:plugins [[lein-codox "0.9.1"]]}}
Expand Down
260 changes: 260 additions & 0 deletions src-java/clj_libssh2/struct/Stat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
package clj_libssh2.struct;

import java.time.Instant;
import java.util.Arrays;
import java.util.List;

import com.sun.jna.Platform;
import com.sun.jna.Structure;

/**
* A JNA mapping for struct stat.
*/
public abstract class Stat
extends Structure
{
/**
* Create a new struct stat. Since this structure varies between platforms
* the returned object may behave quite differently depending on the OS.
* While the returned object will expose all of its fields as public
* members it's advisable to only use the methods exposed in the Stat class
* itself.
*
* @return Stat An instance of this class which will map a struct stat from
* the underlying operating system.
*
* @throws UnsupportedPlatformException If we don't have an implementation
* for the current operating system.
*/
public static Stat newInstance() throws UnsupportedPlatformException {
switch (Platform.RESOURCE_PREFIX) {
case "darwin":
return new Darwin();
case "linux-x86-64":
return new Linux_X86_64();
default:
throw new UnsupportedPlatformException(Platform.RESOURCE_PREFIX);
}
}

/**
* Get the last access time of the described file.
*
* @return Instant The last access time.
*/
public abstract Instant getATime();

/**
* Get the time the status of the described file was changed.
*
* @return Instant The value of ctime for the described file.
*/
public abstract Instant getCTime();

/**
* The group ID assigned to the described file.
*
* @return int The file's GID.
*/
public abstract int getGroupID();

/**
* Get the permissions mask for the described file.
*
* @return int An integer with the same permissions mask as the file's.
*/
public abstract int getMode();

/**
* Get the last modification time of the described file.
*
* @return Instant The last time the file was modified.
*/
public abstract Instant getMTime();

/**
* Get the size of the file in bytes.
*
* @return int The size of the described file, in bytes.
*/
public abstract long getSize();

/**
* The UID of the user who owns the described file.
*
* @return int The user's UID.
*/
public abstract int getUserID();

/**
* The implementation of struct stat for OSX.
*/
public static class Darwin
extends Stat
{
public int st_dev; // dev_t
public short st_mode; // mode_t
public short st_nlink; // nlink_t
public long st_ino; // ino_t
public int st_uid; // uid_t
public int st_gid; // gid_t
public int st_rdev; // dev_t
public Timespec st_atimespec; // struct timespec
public Timespec st_mtimespec; // struct timespec
public Timespec st_ctimespec; // struct timespec
public Timespec st_birthtimespec; // struct timespec
public long st_size; // off_t
public long st_blocks; // blkcnt_t
public int st_blksize; // blksize_t
public int st_flags; // uint32_t
public int st_gen; // uint32_t
public int st_lspare; // int32_t
public long st_qspare_1; // int_64_t
public long st_qspare_2; // int_64_t

@Override
public Instant getATime() {
return st_atimespec.toInstant();
}

@Override
public Instant getCTime() {
return st_ctimespec.toInstant();
}

@Override
public int getGroupID() {
return st_gid;
}

@Override
public int getMode() {
return st_mode;
}

@Override
public Instant getMTime() {
return st_mtimespec.toInstant();
}

@Override
public long getSize() {
return st_size;
}

@Override
public int getUserID() {
return st_uid;
}

@Override
public List<String> getFieldOrder() {
return Arrays.asList(
"st_dev",
"st_mode",
"st_nlink",
"st_ino",
"st_uid",
"st_gid",
"st_rdev",
"st_atimespec",
"st_mtimespec",
"st_ctimespec",
"st_birthtimespec",
"st_size",
"st_blocks",
"st_blksize",
"st_flags",
"st_gen",
"st_lspare",
"st_qspare_1",
"st_qspare_2"
);
}
}

/**
* The implementation of struct stat for Linux x86_64. The names and
* mapping of the fields is from glibc.
*/
public static class Linux_X86_64
extends Stat
{
public long st_dev; // dev_t
public long st_ino; // ino_t
public long st_nlink; // nlink_t
public int st_mode; // mode_t
public int st_uid; // uid_t
public int st_gid; // gid_t
public int pad0; // int
public long st_rdev; // dev_t
public long st_size; // off_t
public long st_blksize; // blksize_t
public long st_blocks; // blkcnt_t
public Timespec st_atim; // struct timespec
public Timespec st_mtim; // struct timespec
public Timespec st_ctim; // struct timespec
public long reserved1; // __syscall_slong_t
public long reserved2; // __syscall_slong_t
public long reserved3; // __syscall_slong_t

@Override
public Instant getATime() {
return st_atim.toInstant();
}

@Override
public Instant getCTime() {
return st_ctim.toInstant();
}

@Override
public int getGroupID() {
return st_gid;
}

@Override
public int getMode() {
return st_mode;
}

@Override
public Instant getMTime() {
return st_mtim.toInstant();
}

@Override
public long getSize() {
return st_size;
}

@Override
public int getUserID() {
return st_uid;
}

@Override
public List<String> getFieldOrder() {
return Arrays.asList(
"st_dev",
"st_ino",
"st_nlink",
"st_mode",
"st_uid",
"st_gid",
"pad0",
"st_rdev",
"st_size",
"st_blksize",
"st_blocks",
"st_atim",
"st_mtim",
"st_ctim",
"reserved1",
"reserved2",
"reserved3"
);
}
}
}

39 changes: 39 additions & 0 deletions src-java/clj_libssh2/struct/Timespec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package clj_libssh2.struct;

import java.time.Instant;
import java.util.Arrays;
import java.util.List;

import com.sun.jna.Structure;

/**
* A struct timespec. This can represent instants in time with up to nanosecond
* precision depending on the underlying platform.
*/
public class Timespec
extends Structure
{
public long tv_sec;
public long tv_nsec;

@Override
public List<String> getFieldOrder() {
return Arrays.asList("tv_sec", "tv_nsec");
}

/**
* Re-interpret this struct as an {@link Instant} for more convenient use
* in Java/Clojure.
*
* @return Instant An {@link Instant} representing the same point in time
* as the underlying struct.
*/
public Instant toInstant() {
return Instant.ofEpochSecond(tv_sec, tv_nsec);
}

@Override
public String toString() {
return toInstant().toString();
}
}
13 changes: 13 additions & 0 deletions src-java/clj_libssh2/struct/UnsupportedPlatformException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package clj_libssh2.struct;

/**
* A marker exception for when we try to map a struct on a platform we
* don't support yet.
*/
public class UnsupportedPlatformException
extends Exception
{
public UnsupportedPlatformException(String message) {
super(message);
}
}
Loading

0 comments on commit 496f1aa

Please sign in to comment.