Skip to content

YetAnotherFactsEnjoyer/MY_FTP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 

Repository files navigation

🚀 MY_FTP

A lightweight FTP server written in C

C Build Protocol Status


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.


✨ Highlights

  • 🔌 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

🧠 What It Does

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 directory

📦 Build

make

This creates the executable:

./myftp

Clean build files

make clean

Fully rebuild

make re

Debug build

make debug

🚀 Usage

./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_root

Then connect with an FTP client:

ftp localhost 2121

Login credentials:

Username: Anonymous
Password: <empty>

🕹️ Supported FTP Commands

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.

🧪 Example Session

$ ./myftp 2121 ./ftp_root

In 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 Goodbye

🏗️ Project Structure

MY_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

⚙️ Architecture

Server lifecycle

  1. Parse command-line arguments.
  2. Resolve the FTP root directory with realpath.
  3. Create and bind a TCP listening socket.
  4. Accept clients and send the FTP welcome reply.
  5. Poll connected clients for commands.
  6. Dispatch commands to dedicated handlers.
  7. Open active or passive data connections for transfers.
  8. Close and clean up client state on disconnect.

Client state

Each client keeps its own:

  • control socket
  • authentication state
  • current working directory
  • input buffer
  • active mode address
  • passive listening socket
  • transfer process status

🔒 Filesystem Safety

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.


🧰 Makefile Targets

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.

✅ Requirements

  • Linux or Unix-like environment
  • gcc
  • make
  • Standard C/POSIX networking headers

🧑‍💻 Development Notes

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, and RNFR / RNTO command 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. ⚡

```

About

My own FTP implementation in C

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors