1 /*
2 * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch>
3 * and other copyright owners as documented in the project's IP log.
4 *
5 * This program and the accompanying materials are made available
6 * under the terms of the Eclipse Distribution License v1.0 which
7 * accompanies this distribution, is reproduced below, and is
8 * available at http://www.eclipse.org/org/documents/edl-v10.php
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 *
24 * - Neither the name of the Eclipse Foundation, Inc. nor the
25 * names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior
27 * written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43 package org.eclipse.jgit.transport;
44
45 import java.io.FileNotFoundException;
46 import java.io.IOException;
47 import java.io.InputStream;
48 import java.io.OutputStream;
49 import java.util.Collection;
50 import java.util.concurrent.TimeUnit;
51
52 /**
53 * An interface providing FTP operations over a {@link RemoteSession}. All
54 * operations are supposed to throw {@link FtpException} for remote file system
55 * errors and other IOExceptions on connection errors.
56 *
57 * @since 5.2
58 */
59 public interface FtpChannel {
60
61 /**
62 * An {@link Exception} for reporting SFTP errors.
63 */
64 static class FtpException extends IOException {
65
66 private static final long serialVersionUID = 7176525179280330876L;
67
68 public static final int OK = 0;
69
70 public static final int EOF = 1;
71
72 public static final int NO_SUCH_FILE = 2;
73
74 public static final int NO_PERMISSION = 3;
75
76 public static final int UNSPECIFIED_FAILURE = 4;
77
78 public static final int PROTOCOL_ERROR = 5;
79
80 public static final int UNSUPPORTED = 8;
81
82 private final int status;
83
84 public FtpException(String message, int status) {
85 super(message);
86 this.status = status;
87 }
88
89 public FtpException(String message, int status, Throwable cause) {
90 super(message, cause);
91 this.status = status;
92 }
93
94 public int getStatus() {
95 return status;
96 }
97 }
98
99 /**
100 * Connects the {@link FtpChannel} to the remote end.
101 *
102 * @param timeout
103 * for establishing the FTP connection
104 * @param unit
105 * of the {@code timeout}
106 * @throws IOException
107 */
108 void connect(int timeout, TimeUnit unit) throws IOException;
109
110 /**
111 * Disconnects and {@link FtpChannel}.
112 */
113 void disconnect();
114
115 /**
116 * @return whether the {@link FtpChannel} is connected
117 */
118 boolean isConnected();
119
120 /**
121 * Changes the current remote directory.
122 *
123 * @param path
124 * target directory
125 * @throws IOException
126 * if the operation could not be performed remotely
127 */
128 void cd(String path) throws IOException;
129
130 /**
131 * @return the current remote directory path
132 * @throws IOException
133 */
134 String pwd() throws IOException;
135
136 /**
137 * Simplified remote directory entry.
138 */
139 interface DirEntry {
140 String getFilename();
141
142 long getModifiedTime();
143
144 boolean isDirectory();
145 }
146
147 /**
148 * Lists contents of a remote directory
149 *
150 * @param path
151 * of the directory to list
152 * @return the directory entries
153 * @throws IOException
154 */
155 Collection<DirEntry> ls(String path) throws IOException;
156
157 /**
158 * Deletes a directory on the remote file system. The directory must be
159 * empty.
160 *
161 * @param path
162 * to delete
163 * @throws IOException
164 */
165 void rmdir(String path) throws IOException;
166
167 /**
168 * Creates a directory on the remote file system.
169 *
170 * @param path
171 * to create
172 * @throws IOException
173 */
174 void mkdir(String path) throws IOException;
175
176 /**
177 * Obtain an {@link InputStream} to read the contents of a remote file.
178 *
179 * @param path
180 * of the file to read
181 *
182 * @return the stream to read from
183 * @throws IOException
184 */
185 InputStream get(String path) throws IOException;
186
187 /**
188 * Obtain an {@link OutputStream} to write to a remote file. If the file
189 * exists already, it will be overwritten.
190 *
191 * @param path
192 * of the file to read
193 *
194 * @return the stream to read from
195 * @throws IOException
196 */
197 OutputStream put(String path) throws IOException;
198
199 /**
200 * Deletes a file on the remote file system.
201 *
202 * @param path
203 * to delete
204 * @throws IOException
205 * if the file does not exist or could otherwise not be deleted
206 */
207 void rm(String path) throws IOException;
208
209 /**
210 * Deletes a file on the remote file system. If the file does not exist, no
211 * exception is thrown.
212 *
213 * @param path
214 * to delete
215 * @throws IOException
216 * if the file exist but could not be deleted
217 */
218 default void delete(String path) throws IOException {
219 try {
220 rm(path);
221 } catch (FileNotFoundException e) {
222 // Ignore; it's OK if the file doesn't exist
223 } catch (FtpException f) {
224 if (f.getStatus() == FtpException.NO_SUCH_FILE) {
225 return;
226 }
227 throw f;
228 }
229 }
230
231 /**
232 * Renames a file on the remote file system. If {@code to} exists, it is
233 * replaced by {@code from}. (POSIX rename() semantics)
234 *
235 * @param from
236 * original name of the file
237 * @param to
238 * new name of the file
239 * @throws IOException
240 * @see <a href=
241 * "http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html">stdio.h:
242 * rename()</a>
243 */
244 void rename(String from, String to) throws IOException;
245
246 }