<< Back to tutorials

Quick Storage API in C with the SFTP

Published {$created} by Carsten Blum


Many IoT projects – whether it’s a small Arduino board, a Raspberry Pi, or an embedded sensor – need a reliable place to send their data. This often includes logs, measurements, or even images that should be stored securely without having to run and maintain your own server. This is where ftp cloud storage becomes the perfect fit: a simple, familiar protocol combined with modern security and cloud hosting.

By using SFTP with a library like libssh2, you can easily connect C programs running on your devices directly to the cloud. Your IoT hardware can continuously upload data to a central location, where developers, researchers, or businesses can process and analyze it — without worrying about firewalls, certificates, or GDPR compliance.

With ftpGrid, you get all the advantages: fast setup, secure encryption, and the ability to scale from a single prototype to thousands of IoT devices — all sending their files into the same trusted platform. In this tutorial, we will build a small example that creates a text file and uploads it to ftpGrid.


It is recommended to read our getting started with FTP/SFTP guide to create your account. To read more in-depth about ftpGrid managed FTP/SFTP cloud hosting checkout our guide to ftpGrid's cloud hosting.



Requirements

  • Linux or macOS environment

  • Development tools (gcc, make)

  • libssh2 installed (brew install libssh2 on macOS, sudo apt install libssh2-1-dev on Ubuntu/Debian)

  • An ftpGrid account with SFTP access


Prepare your environment

You need libssh2 to run this example, on MacOs or Linux the commands would look like this:


#On MacOS:
brew install libssh2

#On Debian, or variants like Ubuntu:
sudo apt install libssh2-1-dev


To keep the C example a little short, we're not gonna create the upload file, like we have in the other tutorials like the Java tutorial or the Go tutorial.


echo 'Hello from C and ftpGrid!' > hello.txt



Example C program

Create a file called sftp_example.c, and paste the below code into the file. Remember to change your username and password according to the ones you have created. If in doubt follow our onboarding to cloud storage guide.

#include <libssh2.h>
#include <libssh2_sftp.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

int main() {
    const char *hostname = "edge1.ftpgrid.com";
    const char *username = "PREFIX.username";
    const char *password = "password";
    const char *local_path = "hello.txt";
    const char *remote_path = "/hello.txt";
    int port = 22;

    // Initialize libssh2
    libssh2_init(0);

    // Create socket and connect
    struct hostent *host = gethostbyname(hostname);
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = *(unsigned long*)host->h_addr;
    if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
        fprintf(stderr, "Failed to connect to host %s\n", hostname);
        return 1;
    }

    // Create session
    LIBSSH2_SESSION *session = libssh2_session_init();
    libssh2_session_handshake(session, sock);

    // Authenticate
    if (libssh2_userauth_password(session, username, password)) {
        fprintf(stderr, "Authentication failed\n");
        return 1;
    }

    // Create SFTP session
    LIBSSH2_SFTP *sftp = libssh2_sftp_init(session);
    if (!sftp) {
        fprintf(stderr, "Unable to init SFTP session\n");
        return 1;
    }

    // Open remote file
    LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(sftp, remote_path, LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);

    if (!sftp_handle) {
        fprintf(stderr, "Unable to open remote file\n");
        return 1;
    }

    // Read local file
    FILE *local = fopen(local_path, "rb");
    if (!local) {
        fprintf(stderr, "Unable to open local file\n");
        return 1;
    }

    char buffer[1024];
    size_t nread;
    while ((nread = fread(buffer, 1, sizeof(buffer), local)) > 0) {
        char *ptr = buffer;
        while (nread > 0) {
            int rc = libssh2_sftp_write(sftp_handle, ptr, nread);
            if (rc < 0) break;
            ptr += rc;
            nread -= rc;
        }
    }

    fclose(local);
    libssh2_sftp_close(sftp_handle);
    libssh2_sftp_shutdown(sftp);
    libssh2_session_disconnect(session, "Normal Shutdown");
    libssh2_session_free(session);
    close(sock);
    libssh2_exit();

    printf("Uploaded %s to %s\n", local_path, remote_path);
    return 0;
}



Compile the program

To compile the program on Mac, when libssh2 is installed using brew, you need to use a rather complicated gcc command, the get all the external libraries in line


gcc sftp_example.c -o sftp_example \
  -I$(brew --prefix libssh2)/include \
  -L$(brew --prefix libssh2)/lib \
  -lssh2



Run the program

In the console you can now run your new C SFTP storage application like this.


#./sftp_example
Uploaded hello.txt to /hello.txt
#



Conclusion

With libssh2 you can integrate secure SFTP uploads directly into your C programs. This lets you use ftpGrid as a simple cloud storage API from even the lowest-level environments.

Perfect for embedded systems, IoT devices, or performance-critical applications that need direct control.



Signup now
© 2025 ftpGrid

ftpGrid ApS
Branebjerg 24
DK-5471
Gamby
Denmark

Looking for an all-in-one time tracking, timesheet, and invoicing solution - visit our Devanux sister company Nureti at https://nureti.com.

Preview Devanux’s upcoming project Pictoguide – a visual support tool designed to bring structure and clarity to people with ASD.