Seregon/zftpd

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

C/11.0 KB/No license
include/ftp_server.h
zftpd / include / ftp_server.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_server.h
27 * @brief FTP server main loop and session management
28 *
29 * @author SeregonWar
30 * @version 1.0.0
31 * @date 2026-02-13
32 *
33 * ARCHITECTURE: Single listener thread + thread-per-client sessions
34 * CONCURRENCY: Fixed session pool (FTP_MAX_SESSIONS)
35 *
36 */
37 
38#ifndef FTP_SERVER_H
39#define FTP_SERVER_H
40 
41#include "ftp_types.h"
42 
43/*===========================================================================*
44 * SERVER LIFECYCLE
45 *===========================================================================*/
46 
47/**
48 * @brief Initialize FTP server
49 *
50 * @param ctx Server context to initialize
51 * @param bind_ip IP address to bind to ("0.0.0.0" for all interfaces)
52 * @param port Port number to listen on
53 * @param root_path Server root directory path
54 *
55 * @return FTP_OK on success, negative error code on failure
56 * @retval FTP_OK Server initialized successfully
57 * @retval FTP_ERR_INVALID_PARAM Invalid parameters
58 * @retval FTP_ERR_SOCKET_CREATE Socket creation failed
59 * @retval FTP_ERR_SOCKET_BIND Bind failed (port in use?)
60 * @retval FTP_ERR_SOCKET_LISTEN Listen failed
61 *
62 * @pre ctx != NULL
63 * @pre bind_ip != NULL
64 * @pre port > 0
65 * @pre root_path != NULL
66 *
67 * @post ctx->listen_fd >= 0
68 * @post ctx->running == 0 (call ftp_server_start to begin)
69 * @post All sessions initialized
70 */
71ftp_error_t ftp_server_init(ftp_server_context_t *ctx,
72 const char *bind_ip,
73 uint16_t port,
74 const char *root_path);
75 
76/**
77 * @brief Start FTP server (begin accepting connections)
78 *
79 * Creates accept thread and begins processing connections.
80 *
81 * @param ctx Server context
82 *
83 * @return FTP_OK on success, negative error code on failure
84 *
85 * @pre ctx != NULL
86 * @pre ctx->listen_fd >= 0
87 *
88 * @post ctx->running == 1
89 * @post Accept thread is running
90 *
91 * @note Non-blocking: returns immediately
92 */
93ftp_error_t ftp_server_start(ftp_server_context_t *ctx);
94 
95/**
96 * @brief Stop FTP server (graceful shutdown)
97 *
98 * Signals server to stop accepting connections and waits
99 * for all active sessions to complete.
100 *
101 * @param ctx Server context
102 *
103 * @pre ctx != NULL
104 *
105 * @post ctx->running == 0
106 * @post All sessions terminated
107 *
108 * @note Blocking: waits for all threads to exit
109 */
110void ftp_server_stop(ftp_server_context_t *ctx);
111 
112/**
113 * @brief Cleanup server resources
114 *
115 * @param ctx Server context
116 *
117 * @pre ctx != NULL
118 * @pre Server stopped (running == 0)
119 *
120 * @post All resources freed
121 * @post Listen socket closed
122 */
123void ftp_server_cleanup(ftp_server_context_t *ctx);
124 
125/*===========================================================================*
126 * SERVER CONTROL
127 *===========================================================================*/
128 
129/**
130 * @brief Check if server is running
131 *
132 * @param ctx Server context
133 *
134 * @return 1 if running, 0 if not
135 *
136 * @pre ctx != NULL
137 */
138int ftp_server_is_running(const ftp_server_context_t *ctx);
139 
140/**
141 * @brief Get number of active sessions
142 *
143 * @param ctx Server context
144 *
145 * @return Number of active sessions
146 *
147 * @pre ctx != NULL
148 */
149uint32_t ftp_server_get_active_sessions(const ftp_server_context_t *ctx);
150 
151/**
152 * @brief Get server statistics
153 *
154 * @param ctx Server context
155 * @param total_conn Output: Total connections
156 * @param bytes_sent Output: Total bytes sent
157 * @param bytes_received Output: Total bytes received
158 *
159 * @pre ctx != NULL
160 * @pre At least one output parameter != NULL
161 */
162void ftp_server_get_stats(const ftp_server_context_t *ctx,
163 uint64_t *total_conn,
164 uint64_t *bytes_sent,
165 uint64_t *bytes_received);
166 
167/*===========================================================================*
168 * SESSION POOL MANAGEMENT (called by session threads)
169 *===========================================================================*/
170 
171/**
172 * @brief Release a session slot back to the server pool.
173 *
174 * MUST be called by the session thread as the very last action before it
175 * returns, AFTER ftp_session_cleanup() has closed all file descriptors.
176 *
177 * WHY THIS EXISTS:
178 * ftp_server_stop() blocks on (active_sessions > 0). Without this call
179 * active_sessions is never decremented, causing an infinite loop that
180 * prevents orderly PS5 shutdown and leads to SIGKILL → forced M2 unmount
181 * → kernel panic.
182 *
183 * @param ctx Owning server context (session->server_ctx)
184 * @param session Session to release
185 *
186 * @pre ctx != NULL
187 * @pre session != NULL
188 * @pre Called only from the session's own thread
189 * @pre ftp_session_cleanup() already called (all FDs closed)
190 *
191 * @post session->state == FTP_STATE_INIT (slot is reusable)
192 * @post ctx->active_sessions decremented by 1
193 *
194 * @note Thread-safety: Protected internally by ctx->session_lock
195 */
196void ftp_server_release_session(ftp_server_context_t *ctx,
197 ftp_session_t *session);
198 
199#endif /* FTP_SERVER_H */
200