MY_FTP is a small but solid FTP server implementation built from scratch in C.
It handles real TCP client connections, anonymous authentication, filesystem navigation, and file transfers through both active and passive FTP data channels.
- 🔌 TCP control connection handling
- 👥 Multiple client support with
poll(2) - 🔐 Anonymous FTP authentication
- 🗂️ Root directory jail using real path validation
- 📁 Directory navigation and listing
- ⬇️ File download with
RETR - ⬆️ File upload with
STOR - 🔁 Active mode with
PORT - 🛰️ Passive mode with
PASV - 🧹 Clean process handling for transfer children
- 🛠️ Strict compilation flags:
-Wall -Wextra -Werror -std=gnu17
MY_FTP exposes a local directory as an FTP root and lets FTP clients interact with it using standard commands.
The server listens on a control port, receives FTP commands, opens a separate data connection when needed, and protects the configured root directory so clients cannot escape the FTP jail.
FTP Client
│
│ Control connection: USER, PASS, PWD, CWD, LIST, RETR, STOR...
▼
MY_FTP Server
│
├── Authentication state
├── Per-client working directory
├── Active / passive data connection state
└── Root path validation
│
▼
Exposed filesystem directorymakeThis creates the executable:
./myftpmake cleanmake remake debug./myftp <port> <path>| Argument | Description |
|---|---|
port |
TCP port used for the FTP control connection. Must be between 1 and 65535. |
path |
Root directory exposed to the anonymous FTP user. |
Example:
mkdir -p ftp_root
./myftp 2121 ./ftp_rootThen connect with an FTP client:
ftp localhost 2121Login credentials:
Username: Anonymous
Password: <empty>| Command | Description |
|---|---|
USER |
Accepts the Anonymous user. |
PASS |
Completes login when the password is empty. |
PWD |
Prints the current working directory. |
CWD |
Changes the current working directory. |
CDUP |
Moves to the parent directory. |
PASV |
Enables passive data transfer mode. |
PORT |
Enables active data transfer mode. |
LIST |
Lists files and directories over the data connection. |
RETR |
Downloads a file from the server. |
STOR |
Uploads a file to the server. |
NOOP |
Keeps the connection alive. |
QUIT |
Closes the FTP session. |
$ ./myftp 2121 ./ftp_rootIn another terminal:
$ ftp localhost 2121
Connected to localhost.
Name: Anonymous
Password:
230 User logged in, proceed.
ftp> pwd
257 "/"
ftp> passive
Passive mode on.
ftp> ls
150 File status okay; about to open data connection.
226 Closing data connection.
ftp> put hello.txt
ftp> get hello.txt
ftp> quit
221 GoodbyeMY_FTP-main/
├── include/
│ └── myftp.h
├── src/
│ ├── main.c
│ ├── client.c
│ ├── client_read.c
│ ├── data_connection.c
│ ├── write_reply.c
│ ├── commands/
│ │ ├── command_auth.c
│ │ ├── command_cwd.c
│ │ ├── command_dispatch.c
│ │ ├── command_list.c
│ │ ├── command_pasv.c
│ │ ├── command_port.c
│ │ ├── command_pwd.c
│ │ ├── command_retr.c
│ │ ├── command_stor.c
│ │ ├── command_utils.c
│ │ ├── list_path.c
│ │ ├── transfer_path.c
│ │ └── transfer_stream.c
│ └── server/
│ ├── server_accept.c
│ ├── server_children.c
│ ├── server_init.c
│ ├── server_poll.c
│ └── server_run.c
├── Makefile
└── README.md- Parse command-line arguments.
- Resolve the FTP root directory with
realpath. - Create and bind a TCP listening socket.
- Accept clients and send the FTP welcome reply.
- Poll connected clients for commands.
- Dispatch commands to dedicated handlers.
- Open active or passive data connections for transfers.
- Close and clean up client state on disconnect.
Each client keeps its own:
- control socket
- authentication state
- current working directory
- input buffer
- active mode address
- passive listening socket
- transfer process status
The server keeps users inside the configured root directory.
Path helper functions resolve target paths and verify that requested files or directories remain inside the FTP jail before performing navigation, listing, upload, or download operations.
| Target | Action |
|---|---|
make / make all |
Build myftp. |
make clean |
Remove object files. |
make fclean |
Remove object files and executable. |
make re |
Rebuild from scratch. |
make debug |
Rebuild with debug symbols. |
- Linux or Unix-like environment
gccmake- Standard C/POSIX networking headers
This project is a practical exercise in low-level network programming. It focuses on the core mechanics of FTP rather than external libraries or framework abstractions.
Useful areas to explore next:
DELE,MKD,RMD, andRNFR/RNTOcommand support- TLS support with FTPS
- Better logging
- Integration tests with an FTP client
- Configurable users and permissions
Made with C, sockets, and a lot of file descriptors. ⚡