Seregon/zftpd

Zero-copy FTP/HTTP Daemon compatible with all POSIX systems

C/11.0 KB/No license
include/ftp_session.h
zftpd / include / ftp_session.h
1/*
2MIT License
3 
4Copyright (c) 2026 Seregon
5 
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12 
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15 
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24 
25/**
26 * @file ftp_session.h
27 * @brief FTP session management and lifecycle
28 *
29 * @author SeregonWar
30 * @version 1.0.0
31 * @date 2026-02-13
32 *
33 * DESIGN: Thread-per-client model with session pool
34 * THREADING: Each session runs in dedicated thread
35 *
36 */
37 
38#ifndef FTP_SESSION_H
39#define FTP_SESSION_H
40 
41#include "ftp_types.h"
42 
43/*===========================================================================*
44 * SESSION LIFECYCLE
45 *===========================================================================*/
46 
47/**
48 * @brief Initialize session structure
49 *
50 * @param session Session to initialize
51 * @param ctrl_fd Control socket descriptor
52 * @param client_addr Client address information
53 * @param session_id Unique session identifier
54 * @param root_path Server root directory
55 *
56 * @return FTP_OK on success, negative error code on failure
57 *
58 * @pre session != NULL
59 * @pre ctrl_fd >= 0
60 * @pre client_addr != NULL
61 * @pre root_path != NULL
62 *
63 * @post session->state == FTP_STATE_CONNECTED
64 * @post session->ctrl_fd == ctrl_fd
65 * @post All other file descriptors == -1
66 */
67ftp_error_t ftp_session_init(ftp_session_t *session,
68 int ctrl_fd,
69 const struct sockaddr_in *client_addr,
70 uint32_t session_id,
71 const char *root_path);
72 
73/**
74 * @brief Cleanup session resources
75 *
76 * @param session Session to cleanup
77 *
78 * @pre session != NULL
79 *
80 * @post All file descriptors closed
81 * @post Session state set to FTP_STATE_TERMINATING
82 *
83 * @note Thread-safety: Call only from session thread
84 */
85void ftp_session_cleanup(ftp_session_t *session);
86 
87/**
88 * @brief Session thread entry point
89 *
90 * WORKFLOW:
91 * 1. Send greeting (220)
92 * 2. Command processing loop
93 * 3. Cleanup and exit
94 *
95 * @param arg Session pointer (ftp_session_t*)
96 *
97 * @return NULL
98 *
99 * @pre arg != NULL
100 * @pre arg points to valid ftp_session_t
101 *
102 * @note This function runs in a separate thread
103 */
104void* ftp_session_thread(void *arg);
105 
106/*===========================================================================*
107 * REPLY SENDING
108 *===========================================================================*/
109 
110/**
111 * @brief Send FTP reply to client
112 *
113 * @param session Client session
114 * @param code FTP reply code
115 * @param message Reply message (NULL for default)
116 *
117 * @return FTP_OK on success, negative error code on failure
118 *
119 * @pre session != NULL
120 * @pre session->ctrl_fd >= 0
121 *
122 * @note Thread-safety: Safe (session not shared)
123 * @note Blocks until entire reply sent
124 */
125ftp_error_t ftp_session_send_reply(ftp_session_t *session,
126 ftp_reply_code_t code,
127 const char *message);
128 
129/**
130 * @brief Send multi-line reply to client
131 *
132 * Format:
133 * 123-First line
134 * Second line
135 * 123 Last line
136 *
137 * @param session Client session
138 * @param code FTP reply code
139 * @param lines Array of message lines
140 * @param count Number of lines
141 *
142 * @return FTP_OK on success, negative error code on failure
143 *
144 * @pre session != NULL
145 * @pre lines != NULL
146 * @pre count > 0
147 */
148ftp_error_t ftp_session_send_multiline_reply(ftp_session_t *session,
149 ftp_reply_code_t code,
150 const char **lines,
151 size_t count);
152 
153/*===========================================================================*
154 * DATA CONNECTION MANAGEMENT
155 *===========================================================================*/
156 
157/**
158 * @brief Open data connection
159 *
160 * Behavior depends on data_mode:
161 * - FTP_DATA_MODE_ACTIVE: Connect to client
162 * - FTP_DATA_MODE_PASSIVE: Accept from client
163 *
164 * @param session Client session
165 *
166 * @return FTP_OK on success, negative error code on failure
167 *
168 * @pre session != NULL
169 * @pre session->data_mode != FTP_DATA_MODE_NONE
170 *
171 * @post On success: session->data_fd >= 0
172 */
173ftp_error_t ftp_session_open_data_connection(ftp_session_t *session);
174 
175/**
176 * @brief Close data connection
177 *
178 * @param session Client session
179 *
180 * @pre session != NULL
181 *
182 * @post session->data_fd == -1
183 * @post session->pasv_fd == -1 (if passive mode)
184 * @post session->data_mode == FTP_DATA_MODE_NONE
185 */
186void ftp_session_close_data_connection(ftp_session_t *session);
187 
188/**
189 * @brief Send data via data connection
190 *
191 * @param session Client session
192 * @param buffer Data to send
193 * @param length Number of bytes to send
194 *
195 * @return Number of bytes sent, or negative error code
196 *
197 * @pre session != NULL
198 * @pre session->data_fd >= 0
199 * @pre buffer != NULL
200 * @pre length > 0
201 *
202 * @note May send less than requested (non-blocking)
203 */
204ssize_t ftp_session_send_data(ftp_session_t *session,
205 const void *buffer,
206 size_t length);
207 
208/**
209 * @brief Receive data via data connection
210 *
211 * @param session Client session
212 * @param buffer Output buffer
213 * @param length Buffer size
214 *
215 * @return Number of bytes received, or negative error code
216 *
217 * @pre session != NULL
218 * @pre session->data_fd >= 0
219 * @pre buffer != NULL
220 * @pre length > 0
221 *
222 * @note May receive less than requested
223 */
224ssize_t ftp_session_recv_data(ftp_session_t *session,
225 void *buffer,
226 size_t length);
227 
228/*===========================================================================*
229 * COMMAND PROCESSING
230 *===========================================================================*/
231 
232/**
233 * @brief Read command line from control connection
234 *
235 * Reads until CRLF sequence (\r\n).
236 *
237 * @param session Client session
238 * @param buffer Output buffer for command line
239 * @param size Size of output buffer
240 *
241 * @return Number of bytes read, or negative error code
242 * @retval >0 Command line read successfully
243 * @retval 0 Connection closed by client
244 * @retval <0 Error code
245 *
246 * @pre session != NULL
247 * @pre session->ctrl_fd >= 0
248 * @pre buffer != NULL
249 * @pre size >= FTP_CMD_BUFFER_SIZE
250 *
251 * @post buffer contains null-terminated command line (CRLF removed)
252 *
253 * @note Blocks until complete line received
254 */
255ssize_t ftp_session_read_command(ftp_session_t *session,
256 char *buffer,
257 size_t size);
258 
259/**
260 * @brief Process FTP command
261 *
262 * WORKFLOW:
263 * 1. Parse command line
264 * 2. Find command handler
265 * 3. Validate arguments
266 * 4. Execute command
267 *
268 * @param session Client session
269 * @param line Command line
270 *
271 * @return FTP_OK to continue, 1 to close session, negative on error
272 *
273 * @pre session != NULL
274 * @pre line != NULL
275 */
276int ftp_session_process_command(ftp_session_t *session, const char *line);
277 
278#endif /* FTP_SESSION_H */
279