1 /*
2 * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Distribution License v. 1.0 which is available at
6 * https://www.eclipse.org/org/documents/edl-v10.php.
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 */
10 package org.eclipse.jgit.transport;
11
12 import java.io.FileNotFoundException;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.OutputStream;
16 import java.util.Collection;
17 import java.util.concurrent.TimeUnit;
18
19 /**
20 * An interface providing FTP operations over a {@link RemoteSession}. All
21 * operations are supposed to throw {@link FtpException} for remote file system
22 * errors and other IOExceptions on connection errors.
23 *
24 * @since 5.2
25 */
26 public interface FtpChannel {
27
28 /**
29 * An {@link Exception} for reporting SFTP errors.
30 */
31 static class FtpException extends IOException {
32
33 private static final long serialVersionUID = 7176525179280330876L;
34
35 public static final int OK = 0;
36
37 public static final int EOF = 1;
38
39 public static final int NO_SUCH_FILE = 2;
40
41 public static final int NO_PERMISSION = 3;
42
43 public static final int UNSPECIFIED_FAILURE = 4;
44
45 public static final int PROTOCOL_ERROR = 5;
46
47 public static final int UNSUPPORTED = 8;
48
49 private final int status;
50
51 public FtpException(String message, int status) {
52 super(message);
53 this.status = status;
54 }
55
56 public FtpException(String message, int status, Throwable cause) {
57 super(message, cause);
58 this.status = status;
59 }
60
61 public int getStatus() {
62 return status;
63 }
64 }
65
66 /**
67 * Connects the {@link FtpChannel} to the remote end.
68 *
69 * @param timeout
70 * for establishing the FTP connection
71 * @param unit
72 * of the {@code timeout}
73 * @throws IOException
74 */
75 void connect(int timeout, TimeUnit unit) throws IOException;
76
77 /**
78 * Disconnects and {@link FtpChannel}.
79 */
80 void disconnect();
81
82 /**
83 * @return whether the {@link FtpChannel} is connected
84 */
85 boolean isConnected();
86
87 /**
88 * Changes the current remote directory.
89 *
90 * @param path
91 * target directory
92 * @throws IOException
93 * if the operation could not be performed remotely
94 */
95 void cd(String path) throws IOException;
96
97 /**
98 * @return the current remote directory path
99 * @throws IOException
100 */
101 String pwd() throws IOException;
102
103 /**
104 * Simplified remote directory entry.
105 */
106 interface DirEntry {
107 String getFilename();
108
109 long getModifiedTime();
110
111 boolean isDirectory();
112 }
113
114 /**
115 * Lists contents of a remote directory
116 *
117 * @param path
118 * of the directory to list
119 * @return the directory entries
120 * @throws IOException
121 */
122 Collection<DirEntry> ls(String path) throws IOException;
123
124 /**
125 * Deletes a directory on the remote file system. The directory must be
126 * empty.
127 *
128 * @param path
129 * to delete
130 * @throws IOException
131 */
132 void rmdir(String path) throws IOException;
133
134 /**
135 * Creates a directory on the remote file system.
136 *
137 * @param path
138 * to create
139 * @throws IOException
140 */
141 void mkdir(String path) throws IOException;
142
143 /**
144 * Obtain an {@link InputStream} to read the contents of a remote file.
145 *
146 * @param path
147 * of the file to read
148 *
149 * @return the stream to read from
150 * @throws IOException
151 */
152 InputStream get(String path) throws IOException;
153
154 /**
155 * Obtain an {@link OutputStream} to write to a remote file. If the file
156 * exists already, it will be overwritten.
157 *
158 * @param path
159 * of the file to read
160 *
161 * @return the stream to read from
162 * @throws IOException
163 */
164 OutputStream put(String path) throws IOException;
165
166 /**
167 * Deletes a file on the remote file system.
168 *
169 * @param path
170 * to delete
171 * @throws IOException
172 * if the file does not exist or could otherwise not be deleted
173 */
174 void rm(String path) throws IOException;
175
176 /**
177 * Deletes a file on the remote file system. If the file does not exist, no
178 * exception is thrown.
179 *
180 * @param path
181 * to delete
182 * @throws IOException
183 * if the file exist but could not be deleted
184 */
185 default void delete(String path) throws IOException {
186 try {
187 rm(path);
188 } catch (FileNotFoundException e) {
189 // Ignore; it's OK if the file doesn't exist
190 } catch (FtpException f) {
191 if (f.getStatus() == FtpException.NO_SUCH_FILE) {
192 return;
193 }
194 throw f;
195 }
196 }
197
198 /**
199 * Renames a file on the remote file system. If {@code to} exists, it is
200 * replaced by {@code from}. (POSIX rename() semantics)
201 *
202 * @param from
203 * original name of the file
204 * @param to
205 * new name of the file
206 * @throws IOException
207 * @see <a href=
208 * "http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html">stdio.h:
209 * rename()</a>
210 */
211 void rename(String from, String to) throws IOException;
212
213 }