ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ftp_session.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file ftp_session.h
6 * @brief FTP client session driver: the two sockets the ftp.h codec deliberately does not own.
7 *
8 * ftp.h is pure bytes-on-the-wire. This is the other half: it drives a real control connection
9 * (`pc_client_*`) through the RFC 959 login -> TYPE I -> passive-mode -> transfer -> QUIT
10 * sequence, opens the second (data) connection the server names, and streams a payload across it.
11 *
12 * The payload is **pulled**, not pushed: the caller supplies a `pc_ftp_source` that fills a chunk at
13 * a given offset. So the bytes can come from anywhere - a file, a sensor log, or the core-dump
14 * partition (`pc_exc_coredump_read`) - without this owner knowing about any of them, and nothing
15 * ever has to fit in RAM at once.
16 *
17 * Blocking and synchronous, bounded by PC_FTP_TIMEOUT_MS per reply: an offload runs at boot or
18 * from a maintenance route, not from the request hot path.
19 *
20 * @author Douglas Quigg (dstroy0)
21 * @date 2026
22 */
23
24#ifndef PROTOCORE_FTP_SESSION_H
25#define PROTOCORE_FTP_SESSION_H
26
27#include "protocore_config.h"
28
29#if PC_ENABLE_FTP_SESSION
30
31#include <stddef.h>
32#include <stdint.h>
33
34/** @brief Where to connect and who to log in as. */
35struct FtpTarget
36{
37 const char *host; ///< server hostname or dotted-quad
38 uint16_t port; ///< control port, or 0 for the default 21
39 const char *user; ///< username, or nullptr for "anonymous"
40 const char *pass; ///< password, or nullptr for "" (anonymous)
41};
42
43/**
44 * @brief Fill up to @p cap bytes of the payload starting at @p offset.
45 *
46 * Called repeatedly with ascending offsets until the declared total is sent. Returning fewer than
47 * @p cap bytes ends the transfer early and fails it, so a source that cannot satisfy a chunk should
48 * return 0 rather than pad.
49 *
50 * @return bytes written into @p buf.
51 */
52typedef size_t (*pc_ftp_source)(void *ctx, size_t offset, uint8_t *buf, size_t cap);
53
54/**
55 * @brief Upload @p total bytes pulled from @p src to @p remote_path (RFC 959 STOR).
56 *
57 * Logs in, switches to binary (TYPE I), asks for a passive data port (EPSV, falling back to PASV
58 * for servers that predate RFC 2428), connects, streams the payload, then confirms the server's
59 * 226 transfer-complete before reporting success - a socket that merely accepted the bytes is not
60 * treated as a stored file.
61 *
62 * @return true only if the server confirmed the completed transfer.
63 */
64bool pc_ftp_store(const FtpTarget *target, const char *remote_path, size_t total, pc_ftp_source src, void *ctx);
65
66#endif // PC_ENABLE_FTP_SESSION
67
68#endif // PROTOCORE_FTP_SESSION_H
User-facing configuration for ProtoCore.