blob: e6fec4ae909c7c6628db95c56873b885a9bfd653 [file] [log] [blame]
James Kuszmaulcf324122023-01-14 14:07:17 -08001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <libssh/libssh.h>
8#include <libssh/sftp.h>
9
10#include <span>
11#include <stdexcept>
12#include <string>
13#include <string_view>
14#include <vector>
15
16namespace sftp {
17
18struct Attributes {
19 Attributes() = default;
20 explicit Attributes(sftp_attributes&& attr);
21
22 std::string name;
23 uint32_t flags = 0;
24 uint8_t type = 0;
25 uint64_t size = 0;
26};
27
28/**
29 * This is the exception that will be thrown if something goes wrong.
30 */
31class Exception : public std::runtime_error {
32 public:
33 explicit Exception(const std::string& msg) : std::runtime_error{msg} {}
34 explicit Exception(sftp_session sftp);
35
36 int err = 0;
37};
38
39class File {
40 public:
41 File() = default;
42 explicit File(sftp_file&& handle) : m_handle{handle} {}
43 ~File();
44
45 Attributes Stat() const;
46
47 void SetNonblocking() { sftp_file_set_nonblocking(m_handle); }
48 void SetBlocking() { sftp_file_set_blocking(m_handle); }
49
50 using AsyncId = uint32_t;
51
52 size_t Read(void* buf, uint32_t count);
53 AsyncId AsyncReadBegin(uint32_t len) const;
54 size_t AsyncRead(void* data, uint32_t len, AsyncId id);
55 size_t Write(std::span<const uint8_t> data);
56
57 void Seek(uint64_t offset);
58 uint64_t Tell() const;
59 void Rewind();
60
61 void Sync();
62
63 std::string_view GetName() const { return m_handle->name; }
64 uint64_t GetOffset() const { return m_handle->offset; }
65 bool IsEof() const { return m_handle->eof; }
66 bool IsNonblocking() const { return m_handle->nonblocking; }
67
68 private:
69 sftp_file m_handle{nullptr};
70};
71
72/**
73 * This class is a C++ implementation of the SshSessionController in
74 * wpilibsuite/deploy-utils. It handles connecting to an SSH server, running
75 * commands, and transferring files.
76 */
77class Session {
78 public:
79 /**
80 * Constructs a new session controller.
81 *
82 * @param host The hostname of the server to connect to.
83 * @param port The port that the sshd server is operating on.
84 * @param user The username to login as.
85 * @param pass The password for the given username.
86 */
87 Session(std::string_view host, int port, std::string_view user,
88 std::string_view pass);
89
90 /**
91 * Destroys the controller object. This also disconnects the session from the
92 * server.
93 */
94 ~Session();
95
96 /**
97 * Opens the SSH connection to the given host.
98 */
99 void Connect();
100
101 /**
102 * Disconnects the SSH connection.
103 */
104 void Disconnect();
105
106 /**
107 * Reads directory entries
108 *
109 * @param path remote path
110 * @return vector of file attributes
111 */
112 std::vector<Attributes> ReadDir(const std::string& path);
113
114 /**
115 * Unlinks (deletes) a file.
116 *
117 * @param filename filename
118 */
119 void Unlink(const std::string& filename);
120
121 /**
122 * Opens a file.
123 *
124 * @param filename filename
125 * @param accesstype O_RDONLY, O_WRONLY, or O_RDWR, combined with O_CREAT,
126 * O_EXCL, or O_TRUNC
127 * @param mode permissions to use if a new file is created
128 * @return File
129 */
130 File Open(const std::string& filename, int accesstype, mode_t mode);
131
132 private:
133 ssh_session m_session{nullptr};
134 sftp_session m_sftp{nullptr};
135 std::string m_host;
136
137 int m_port;
138
139 std::string m_username;
140 std::string m_password;
141};
142
143} // namespace sftp