ezFCPlib
An Easy-to-use API for Freenet C/C++ Clients
Reference Manual

Contents

- Introduction
- Required Headers
- Establishment/Housekeeping Functions
- High-Level Freenet Key I/O Functions
- In-Freenet Key Index Functions
- Key Creation Functions
- Low Level Key Streaming Functions
- Error Code Descriptions
- Demo Program

Introduction

This document describes ezFCPlib, an API library for Freenet clients written in C or C++.

For Windows programmers, starting out with programming to Freenet can be daunting, to say the least. It certainly was for me. As a programmer who (due to a very welcome career change) hadn't coded for 7 years, I was very rusty. Worse, I had virtually no Windows API experience whatsoever.

I wish a library like this had been available when I'd started learning Freenet. It would have saved me countless frustrating hours.

Hopefully ezFCPlib will save you from suffering similar frustrations. Many programmers want to concentrate on user aspects of their programs - look-n-feel, interaction, features etc, without having to be dragged through the low-level entrails of the system they're coding to. It is especially for such programmers that this API is written.

I hope you find ezFCPlib to be simple and intuitive, fast to learn and understand, yet robust and flexible.
Have fun.

Kind Regards
David McNab
david@rebirthing.co.nz

1. Required Headers

- ezfcplib.h - all required constants, function prototypes, type definitions

2. Establishment/Housekeeping Funtions

- fcpStartup - Initialises the Freenet FCP interface, and does a test handshake
- fcpCreateHandle - create an FCP 'handle', needed for subsequent operations
- fcpDestroyHandle - destroys an FCP handle
- fcpSetHtl - sets an FCP handle's Hops To Live
- fcpRawMode - sets or resets automatic metadata handling

3. High-Level Freenet Key I/O Functions

- fcpGetKeyToMem - reads a key and its metadata into memory
- fcpPutKeyFromMem - write a key and/or metadata from memory
- fcpGetKeyToFile - reads a key and saves it to a file
- fcpPutKeyFromFile - inserts the contents of a file into Freenet

4. In-Freenet Key Index Functions

- fcpOpenKeyIndex - opens an in-freenet key index for reading
- fcpReadKeyIndex - reads the next key from the key index
- fcpWriteKeyIndex - writes an entry to an in-Freenet key index

5. Key Creation Functions

- fcpMakeChkFromMem - Creates a CHK value from data in memory
- fcpMakeChkFromFile - Creates a CHK value from data in a file
- fcpMakeSvkKeypair - Generates an SVK keypair

6. Low Level Key Streaming Functions

- fcpOpenKey - Opens a key for reading or writing
- fcpCloseKey - Closes a previously open key
- fcpReadKey - Reads an arbitrary number of bytes from a key
- fcpWriteKey - Writes an arbitrary number of bytes to a key

Establishment/Housekeeping Functions

int fcpStartup(char *host, int port, int defaultHtl, int rawMode)

Brief

> Starts up FCP interface, and handshakes with Freenet node.

Arguments

> host - ASCII string containing an internet hostname. This can be a domain name, or IP address string such as "12.212.33.5". If this argument is NULL, the host defaults to the local machine.

> port - port number on which Freenet is listening for FCP connections. Set this to zero to use the default FCP port number 8082.

> defaultHtl - default value to set for Hops To Live. Normal settings for htl are between 10 and 100. For writing to Freenet, this determines how deeply a key is inserted into Freenet.

> Lower values result in faster inserts, but inserted keys are less likely to be found by other nodes requesting them. High values can cause inserts to take up to an hour or more.

> For reading from Freenet, this determines how deeply to search into Freenet for the required key. Shorter values result in faster requests, but have a higher risk of failure with finding keys, especially new or unpopular keys.

> rawMode - by default, all incoming metadata is handled automatically, so that redirects are followed transparently.

Return Value

> 0 if successful, non-zero otherwise (see Error Codes)

Description

> This function should be called by the application's main thread as soon as possible after calling the required WSAStartup() function (refer Windows API docs on sockets)

HFCP *fcpCreateHandle()

Brief

> Creates an FCP 'handle', needed for subsequent FCP operations.

Arguments

> None

Return Value

> If successful, a pointer to an "FCP Handle", which is needed in all future operations on Freenet.
> If failed, NULL is returned.

Description

> An FCP handle is much like a FILE * pointer, used with fopen(), fprintf() etc. You need an FCP handle before you can do anything with Freenet.

> This function must not be called unless the calling process has already successfully called fcpCreate(). If you don't abide by this, the results will be unpredictable and potentially dangerous to your system. Worse, such effects can prove very hard to debug.

> Like FILE * handles, FCP handles can only operate on one Freenet key at a time. If you want to work with two or more keys at once, you will need to create that number of FCP handles.

> However, after you've finished working with a Freenet key, you don't have to destroy this handle. You can simply use it again and again, only destroying it when you're really finished with it.

> Note that these FCP handles are not necessarily intended to be created on a per-thread basis (although you're free to do this, and it may be the most convenient way for you). It's quite OK for a single thread to work with several handles, or even several threads to share the one handle (as long as they don't collide from simultaneously doing operations on that one handle).

void fcpDestroyHandle(HFCP *hfcp)

Brief

> Destroys an FCP handle that's no longer needed.

Arguments

> hfcp - pointer to an existing FCP handle.

Returns

> Nothing.

Description

> Frees up all dynamically-allocated memory resources used within an FCP handle, and destroys the FCP handle itself. If hfcp does not point to a valid FCP handle, calling this function will have unpredictable and dangerous results.

void fcpSetHtl(HFCP *hfcp, int htl)

Brief

> Sets a different HTL value for an individual FCP handle.

Arguments

> hfcp - pointer to an existing FCP handle.

> htl - Hops To Live value to set for this handle

Returns

> Nothing.

Description

> When you called fcpStartup(), you chose a 'default HTL' value. This will set the HTL for all FCP handles you subsequently create.

> But there may be times when you will want to set different HTL values for different FCP handles. That's what this function is for.

> HTL values should ideally be between 10 and 100. If the value is too low, any Freenet operations will barely scratch the surface of Freenet, and are apt to fail. However, they are fast. On the other hand, Freenet operations with high HTL values take a long time to complete, perhaps several minutes to an hour or even several hours, but give much more reliable results.

void fcpRawMode(HFCP *hfcp, int rawMode)

Brief

> Enables or disables "raw mode" for a given FCP handle.

Arguments

> hfcp - pointer to an existing FCP handle.

> rawMode - 1 to set the handle into 'raw mode, 0 to disable raw mode.

Returns

> Nothing

Description

> When you called fcpStartup(), you may choose to set raw mode, which disables automatic metadata handling for all FCP handles you subsequently create.

> But you may want to enable or disable auto metadata handling selectively for certain handles. That's what this function is for.

High-Level Freenet Key I/O Functions

int fcpGetKeyToMem(HFCP *hfcp, char *key, char **pData, char **pMetadata)

Brief

> Read a key and its metadata into memory

Arguments

> hfcp - an FCP handle, previously created by calling fcpCreateHandle()

> key - pointer to a char string containing a valid Freenet URI (eg 'freenet:KSK@AARDVARK')

> pData - pointer to a pointer to the received key data (see example below). If this argument is NULL, then the key's data will be discarded

> pMetadata - pointer to a pointer to the received key's metadata (again see example). If this argument is NULL, then the key's metadata will be discarded

Returns

> Size of the key in bytes if the key was successfully read;
> -1 if there was a failure (see error descriptions).

Description

> Retrieving a key from Freenet has never been this easy! This function will request a key from Freenet, using the default HTL (see fcpStartup() ), or the FCP handle's own HTL (see fcpSetHtl()).

> If the key can be retrieved, its entire contents and metadata will be written to memory, and locations of the data and metadata will be written to pData and pMetadata respectively.

> Note that the pData and pMetadata are malloc()ed. To prevent memory leaks, you should free() them when you're finished with them.

> It's quite acceptable to supply NULL pointers for both these arguments - this is a handy way to find out if a given key exists on Freenet.

> As regards Freenet metadata - metadata commands like redirects, date-based redirects and file splits are handled automagically and transparently.

> CAUTION - be careful with this function. Some Freenet keys can be up to a gigabyte or more in size. Using this function to retrieve such keys could have interesting effects on your system.

Example

>     #include <sys/types.h>
>     #include <winsock.h>
>     #include "ezfcplib.h"

>     int main(int argc, char *argv[])
>     {
>     	HFCP *hfcp;		// FCP handle pointer
>     	char *data;		// for Freenet key's data
>     	char *metadata;	// for Freenet key's metadata

>     	// Start up FCP interface
>     	if (fcpStartup("localhost", 8082, 60) != 0)
>     	{
>     		printf("fcpStartup failed\n");
>     		exit(1);
>     	}

>     	// Create an FCP handle
>     	if ((hfcp = fcpCreateHandle()) == NULL)
>     	{
>     		printf("Failed to create FCP handle\n");
>     		return -1;
>     	}

>     	// Try to fetch a key
>     	if (fcpGetKeyToMem(hfcp, "KSK@AARDVARK", &data, &metadata) != 0)
>     	{
>     		printf("Failed to retrieve 'KSK@AARDVARK'\n");
>     		fcpDestroyHandle(hfcp);
>     		exit(1);
>     	}

>     	// write key to stdout
>     	printf("Here is your key, Sir/Madam:\n");
>     	puts(data);

>     	// Finished with FCP handle
>     	fcpDestroyHandle(hfcp);

>     	exit(0);

>     }		// 'main()'

fcpPutKeyFromMem(HFCP *hfcp, char *name, char *data, char *metadata, char **pUri)

Brief

> Write a key and/or metadata from memory

Arguments

> hfcp - an FCP handle, previously created by calling fcpCreateHandle()

> name - URI to insert this key under. If NULL, then key is inserted as a CHK, whose name is returned in uri.

> data - location of raw key data in memory. If NULL, then key is created with no data.

> metadata - location in memory of key's metadata. If NULL, then key will be created with no metadata.

> uri - location into which the created key's name will be written (see example). If NULL, then the key's URI will be forgotten.

Returns

> 0 if key was inserted successfully, non-zero if failed (see errors).

Description

> This is a mindlessly easy way to create a Freenet key. Just create a key in memory, then call this function to insert it into Freenet.

Example

>     #include <sys/types.h>
>     #include <winsock.h>
>     #include "ezfcplib.h"

>     int main(int argc, char *argv[])
>     {
>     	HFCP *hfcp;
>     	char *data = "This is a freenet key";
>     	char uri[128];			// this is big enough for Freenet URIs.

>     	// Start up FCP interface
>     	if (fcpStartup("localhost", 8082, 60) != 0)
>     	{
>     		printf("fcpStartup failed\n");
>     		exit(1);
>     	}

>     	// Create an FCP handle
>     	if ((hfcp = fcpCreateHandle()) == NULL)
>     	{
>     		printf("Failed to create FCP handle\n");
>     		return -1;
>     	}

>     	// Try to insert a key
>     	if (fcpPutKeyFromMem(hfcp, "KSK@my-own-key", data, uri) != 0)
>     	{
>     		printf("Failed to insert KSK@my-own-key'\n");
>     		fcpDestroyHandle(hfcp);
>     		exit(1);
>     	}

>     	// write key's name to stdout
>     	printf("Key created successfully with URI '%s'\n", uri);

>     	// Finished with FCP handle
>     	fcpDestroyHandle(hfcp);

>     	exit(0);

>     }		// 'main()'

fcpGetKeyToFile(HFCP *hfcp, char *key, char *file, char **pMetadata)

Brief

> Read a key and saves it to a file.

Arguments

> hfcp - an FCP handle, previously created by calling fcpCreateHandle()

> key - pointer to a char string containing a valid Freenet URI (eg 'freenet:KSK@AARDVARK')

> file - string - a full pathname of a file to which to write the key's data. Note - all directories in the path must already exist.

> pMetadata - pointer to a pointer to the received key's metadata (again see example). If this argument is NULL, then the key's metadata will be discarded

Returns

> 0 if the key was successfully read; nonzero if there was a failure (see error descriptions).

Description

> Retrieving a key from Freenet has never been this easy! This function will request a key from Freenet, using the default HTL (see fcpStartup() ), or the FCP handle's own HTL (see fcpSetHtl()).

> If the key can be retrieved, its entire contents will be written, in binary form, to the file nominated by the caller, and the metadata will be written to memory, with the locations of this metadata being written to pMetadata.

> Note that pMetadata is malloc()ed. To prevent memory leaks, you should free() it when you're finished with it.

> As regards Freenet metadata - metadata commands like redirects, date-based redirects and file splits are handled automagically and transparently.

> CAUTION - be careful with this function. Some Freenet keys can be up to a gigabyte or more in size. Unless you basically know what kind of key you are retrieving, make sure you've got plenty of free disk space.

Example

>     #include <sys/types.h>
>     #include <winsock.h>
>     #include "ezfcplib.h"

>     int main(int argc, char *argv[])
>     {
>     	HFCP *hfcp;		// FCP handle pointer
>     	char *metadata;	// for Freenet key's metadata

>     	// Start up FCP interface
>     	if (fcpStartup("localhost", 8082, 60) != 0)
>     	{
>     		printf("fcpStartup failed\n");
>     		exit(1);
>     	}

>     	// Create an FCP handle
>     	if ((hfcp = fcpCreateHandle()) == NULL)
>     	{
>     		printf("Failed to create FCP handle\n");
>     		return -1;
>     	}

>     	// Try to fetch a key
>     	if (fcpGetKeyToMem(hfcp, "KSK@AARDVARK", "C:\\aardvark.txt", &metadata) != 0)
>     	{
>     		printf("Failed to retrieve 'KSK@AARDVARK'\n");
>     		fcpDestroyHandle(hfcp);
>     		exit(1);
>     	}

>     	// write key to stdout
>     	printf("Successfully retrieved key to c:\aardvark.html - metadata follows:\n");
>     	puts(metadata);

>     	// Finished with FCP handle
>     	fcpDestroyHandle(hfcp);

>     	exit(0);

>     }		// 'main()'

fcpPutKeyFromFile(HFCP *hfcp, char *name, char *file, char *metadata, char *uri)

Insert the contents of a file into Freenet

Brief

> Insert the contents of a file into Freenet

Arguments

> hfcp - an FCP handle, previously created by calling fcpCreateHandle()

> name - URI to insert this key under. If NULL, then key is inserted as a CHK, whose name is returned in uri.

> file - full pathname of a file to be inserted into Freenet. The syntax of this pathname must obey the requirements of the host operating system.

> metadata - location in memory of key's metadata. If NULL, then key will be created with no metadata.

> uri - location into which the created key's name will be written (see example). If NULL, then the key's URI will be forgotten.

Returns

> 0 if key was inserted successfully, non-zero if failed (see errors).

Description

> This is another mindlessly easy way to create a Freenet key.
> Just create a file, then call this function to insert it into Freenet.

Example

>     #include <sys/types.h>
>     #include <winsock.h>
>     #include <stdio.h>
>     #include "ezfcplib.h"

>     int main(int argc, char *argv[])
>     {
>     	FILE *fp;
>     	HFCP *hfcp;
>     	char uri[128];			// this is big enough for Freenet URIs.
>     	char *filename = "c:\\myfile.txt";

>     	// Start up FCP interface
>     	if (fcpStartup("localhost", 8082, 60) != 0)
>     	{
>     		printf("fcpStartup failed\n");
>     		exit(1);
>     	}

>     	// Create an FCP handle
>     	if ((hfcp = fcpCreateHandle()) == NULL)
>     	{
>     		printf("Failed to create FCP handle\n");
>     		return -1;
>     	}

>     	// Create a file
>     	if ((fp = fopen(filename, "wt")) == NULL)
>     	{
>     		printf("Failed to create file\n");
>     		exit(1);
>     	}
>     	fprintf(fp, "This is the first line of the file\n");
>     	fprintf(fp, "This is another line for the file\n");
>     	fclose(fp);

>     	// Try to insert the file as a key
>     	if (fcpPutKeyFromMem(hfcp, "KSK@my-own-key", filename, uri) != 0)
>     	{
>     		printf("Failed to insert KSK@my-own-key'\n");
>     		fcpDestroyHandle(hfcp);
>     		exit(1);
>     	}

>     	// write key's name to stdout
>     	printf("Key created successfully with URI '%s'\n", uri);

>     	// Finished with FCP handle
>     	fcpDestroyHandle(hfcp);

>     	exit(0);

>     }		// 'main()'

Key Index Function Descriptions

fcpOpenKeyIndex(HFCP *hfcp, char *name, char *date)

Brief

> Open an in-freenet key index for reading

Arguments

> hfcp - an FCP handle, previously created by calling fcpCreateHandle()

> name - name of key index to open

> date - date from which to read keys, in the format

Returns

> 0 if successful, non-zero otherwise (see errors)

Description

fcpReadKeyIndex(HFCP *hfcp)

Read the next key from a previously opened key index

fcpWriteKeyIndex(HFCP *hfcp, char *indexname, char *data)

Write an entry to an in-Freenet key index

Key Creation Functions

fcpMakeChkFromMem()

Create a CHK value from data in memory

fcpMakeChkFromFile()

Create a CHK value from data in a file

fcpMakeSvkKeypair()

Generate an SVK keypair

Low Level Key Key Streaming Functions

fcpOpenKey(HFCP *hfcp, char *key, int mode)

Brief

> Open a key for reading or writing (like Unix open())

Arguments

> hfcp - FCP 'handle', as previously created by calling fcpCreateHandle()

> key - text string containing a Freenet URI for the key to open.

> mode - flags indicating the modes under which the key is to be opened. These are:

> > _FCP_O_READ - open an existing Freenet key for reading
> > _FCP_O_WRITE - create a new Freenet key for writing
> > _FCP_O_RAW - disable automatic handling of metadata (enabled by default)

Returns

> 0 if the key was successfully opened
> nonzero if an error occurred

Description

> This layer of ezFCPlib provides a low-level streaming access to Freenet keys that strongly resembles the familiar Unix functions open()/close()/read()/write(). It is used by the higher-level ezFCPlib functions.

> The mode flags should be OR-ed together. However, please note that it is illegal to combine the _FCP_O_READ and _FCP_O_WRITE flags in the same operation - read/write access is not a concept which exists in Freenet, and will result in this function returning an error.

fcpCloseKey(HFCP *hfcp)

Close a previously open key (like Unix close())

fcpReadKey(HFCP *hfcp, char *buf, int count)

Brief

> Reads an arbitrary number of bytes from a key (like Unix read())

Arguments

> hfcp - an FCP handle, previously created by calling fcpCreateHandle()

> buf - pointer to a buffer that's large enough to hold the requested number of bytes

> count - number of bytes requested

Returns

> Number of bytes actually read, or -1 if a problem occurred

Description

> This function attempts to read an arbitrary number of bytes from a key which has been previously 'opened' via the fcpOpenKey() function.

fcpWriteKey()

Writes an arbitrary number of bytes to a key (like Unix write())

Error Codes

Demo Program

You should already have the source of this program with the library and header.