"In the land of the blind, the one-eyed man is king"

Obsolete

This page describes Version 1 (now obsolete) of the Freenet Client Protocol Library (FCPLib) for historical purposes. See the Freenet page for details on my involvement.

What is the Freenet Client Protocol Library?

FCPLib (Freenet Client Protocol Library) aims to be a platform independent, but natively compiled set of functions for storing and retrieving information to and from Freenet. There are routines for storing documents to Freenet from the local disk, and other routines for moving data in memory to and from Freenet (for more information see the documentation for FCPTools, which is the package containing FCPLib).

It is written in ANSI C, checked by gcc when compiling the library on a Unix based system. To enable the greatest portability, the code is ANSI compliant (even though it is not checked by gcc with the -ansi switch) and compiled with GNU extensions disabled.

Supported Platforms

FCPLib is now routinely compiled on the following platforms:

FCPLib API Overview

Necessary Files

The necessary files depend on the platform:

On both platforms the FCPLib compiles into a static library. You must include this static module in your compiler's linking phase and put FCPlib.h in your project's include path.

Library Startup and Terminate Functions

fcpStartup(FILE *Logfile, int Verbosity)
fcpTerminate()

fcpStartup() allows a FILE pointer (which may be stdout or a locally opened file) where debugging messages may be sent. This must be the first function call to the FCPLib.

fcpTerminate() should be called before exiting.

Handle Create & Destroy Functions.

fcpCreateHFCP(char *Host, int Port, int Htl, int Optmask)
fcpInheritHFCP(hFCP *Handle)
fcpDestroyHFCP(hFCP *Handle)

These functions are to be called immediately after fcpStartup(), before any calls to the following functions: fcpOpenKey(), fcpPutKeyFromFile(), fcpGetKeyToFile().

fcpInheritHFCP() duplicates an FCP Handle. Call this function to prepare an FCP Handle with the same options as another one.

fcpDestroyHFCP() performs memory and file cleanup, and should be called before calling free() on the Handle.

File Based Functions

There are 2 functions for moving data between files and Freenet:

fcpPutKeyFromFile(hFCP *Handle, char *Key, char *KeyFile, char *MetaFile)
fcpGetKeyToFile(hFCP *Handle, char *Key, char *KeyFile, char *MetaFile)

fcpPutKeyFromFile() supports files larger than 1M and inserts them as splitfiles.

fcpGetGeyToFile() only supports single file chunks, which usually vary in Freenet from 200-1,000 kilobytes.

Memory Based Functions

Opening a Key

fcpOpenKey(hFCP *Handle, char *Key, int Mode)

This function opens a key in order to read from or write to, depending on the Mode parameter. Opening a key in Read Mode immediately prompts FCPLib to fetch the key and metadata, so that the next call to fcpReadKey() has data to return.

Reading & Writing

fcpWriteKey(hFCP *Handle, char *Buffer, int Length)
fcpWriteMetadta(hFCP *Handle, char *Buffer, int Length)

Once a key is opened for writing, this function writes a block of data to a temporary file that FCPLib later inserts into Freenet.

fcpReadKey(hFCP *Handle, char *Buffer, int Length)
fcpReadMetadata(hFCP *Handle, char *Buffer, int Length)

Once a key is opened for reading, this function reads from the temporary file that fcpOpenKey() retrieved the key into.

Closing a Key

fcpCloseKey(hFCP *Handle)

This function closes a key. When closing a key that has been opened in Write Mode, FCPLib inserts into Freenet the key and metadata stored in the temporary files.

FCPLib in Detail

Startup & Terminate Functions

fcpStartup

int fcpStartup(FILE *Logfile, int Verbosity)

Parameters: Logfile is a pointer to an opened FILE structure, or NULL to send logging information to stdout.

Returns: Zero on success, -1 on error.

Remarks

This must be the first function called out of all the FCPLib functions. On Windows it initializes Winsock, and then for all platforms initializes the log.

fcpTerminate

void fcpTerminate()

Remarks

This must be the last function to be called to FCPLib, especially before exiting a program. It closes the log, and on Windows calls the Winsock WSACleanup() function.

Create and Destroy Functions

fcpCreateHFCP

hFCP *fcpCreateHFCP(char *Host, int Port, int Htl, int Optmask)

Parameters: Host is a hostname or IP address of a Freenet node, Port is the node's listen port, Htl the hops to live for the FCP handle, and Optmask a series of possible flags.

Optmask Values:

Returns: A pointer to a malloc'ed hFCP structure.

Remarks

This function creates a new FCP Handle that must be free'd after use. Before freeing however, call fcpDestroyHFCP().

fcpInheritHFCP

hFCP *fcpInheritHFCP(hFCP *Handle)

Parameters: Handle is an already created hFCP structure.

Returns: A pointer to a malloc'ed hFCP structure.

Remarks

This functions basically creates a new FCP Handle and fills it with values from the Handle parameter. Before freeing however, call fcpDestroyHFCP().

fcpDestroyHFCP

void fcpDestroyHFCP(hFCP *Handle)

Parameters: Handle is an already created hFCP structure.

Remarks

This function disconnects the socket (if necessary), and destroys everything that's been malloc'ed and not yet free'd within the hFCP structure. It also deletes any temporary files still being held on disk.

File Based Functions

fcpPutKeyFromFile

int fcpPutKeyFromFile(hFCP *Handle, char *Key, char *KeyFile, char *MetaFile)

Parameters: Handle is an already created hFCP structure, Key a Freenet URI, KeyFile the local filename to insert into Freenet, and MetaFile is the local filename to insert as metadata.

Returns: Zero on success, -1 on error.

Remarks

Handle must already be created from a prior call to any of the fcpCreate functions. If the file is larger than EZFCP_DEFAULT_SPLITSIZE, the file is inserted into Freenet as an FEC encoded splitfile.

fcpGetKeyToFile

int fcpGetKeyToFile(hFCP *Handle, char *Key, char *KeyFile, char *MetaFile)

Parameters: Handle is an already created hFCP structure, Key a Freenet URI, KeyFile the local filename to write the Freenet document, and MetaFile is the local filename to write the document's metadata.

Returns: Zero on success, -1 on error.

Remarks

Handle must already be created from a prior call to any of the fcpCreate functions. The retrieving of splitfiles is currently not supported, which means this function assumes every URI parameter it receives is not FEC Encoded (in practical terms this means only the mapfile is retrieved).

Memory Based Functions

fcpOpenKey

int fcpOpenKey(hFCP *Handle, char *Key, int Mode)

Parameters: Handle is an already created hFCP structure, Key a Freenet URI, and Mode indicates either read or write.

MODE VALUES:

Returns: Zero on success, -1 on error.

Remarks

When a key is opened with Mode=FCP_MODE_O_READ, the key specified in Key is immediately retrieved and stored internally by FCPLib. Subsequent calls to fcpReadKey() return data from the retrieved temporary file.

When a key is opened with Mode=FCP_MODE_O_WRITE, calls to fcpWriteKey() write the key data to an internal temporary file. The key is written after a call to fcpCloseKey().

fcpReadKey

int fcpReadKey(hFCP *Handle, char *Buffer, int Length)
int fcpReadMetadata(hFCP *Handle, char *Buffer, int Length)

Parameters: Handle is an already created hFCP structure, Buffer points to an allocated block of memory. The function will read at most Length bytes.

Returns: Bytes read into Buffer, -1 on error.

Remarks

Function reads from the internal temporary file (which contains the data from the call to fcpOpenKey()) and returns no more than Length bytes.

fcpWriteKey

int fcpWriteKey(hFCP *Handle, char *Buffer, int Length)
int fcpWriteMetadata(hFCP *Handle, char *Buffer, int Length)

Parameters: Handle is an already created hFCP structure, Buffer points to an allocated block of memory. The function will write at most Length bytes.

Returns: Bytes read into Buffer, -1 on error.

Remarks

Function writes to the internal temporary file no more than Length bytes. Nothing is inserted into Freenet until the call to fcpCloseKey().

fcpCloseKey

int fcpCloseKey(hFCP *Handle)

Parameters: Handle is an already created hFCP structure.

Returns: Zero on success, -1 on error.

Remarks

When a key is opened in Write mode, this function will attempt to store the key into Freenet. The functions returns after the key is stored or if an error is encountered.

When a key is opened in Read mode, fcpCloseKey() simply cleans up temporary files and returns to the caller.

Other

fcpMakeSvkKeypair

int fcpMakeSvkKeypair(hFCP *Handle, char *PubKey, char *PrivKey, char *Entropy)

Parameters: Handle is an already created hFCP structure, PubKey points to an allocated block of memory to hold the public key, and PrivKey points to an allocated block of memory to hold the private key. Entropy is not currently used.

Returns: Zero on success, -1 on error.

Remarks

PubKey and PrivKey must be allocated with at least 28 bytes (27 for the key, 1 for the NULL character). Entropy should be set to NULL for now, until it is implemented.

Examples

For the sake of completion, each of the 4 different methods for moving data to and from Freenet is illustrated with the minimal C code required.

Storing Files To Freenet with fcpPutKeyFromFile

#include "FCPlib.h"

int main(int argc, char* argv[])
{
  hFCP *hfcp;

  /* set the log reporting to Verbose (user friendly output) */  
  if (fcpStartup(stdout, FCP_LOG_VERBOSE) != 0) return -1;

  /* Connect to localhost, port 8481, hops to live 3, and 0 for the optmask */
  hfcp = fcpCreateHFCP("127.0.0.1", 8481, 3, 0);

  /* insert the key. CHK@ means "calculate the CHK".
     NULL for no metadata */

  if (fcpPutKeyFromFile(hfcp, "CHK@", "/home/hapi/message.txt", NULL) != 0)
    return -1;

  /* call to delete temp files and free memory */
  fcpDestroyHFCP(hfcp);
  free(hfcp);

  /* The final shutdown for FCPLib */
  fcpTerminate();

  return 0;
}

Storing Files To Freenet with fcpWriteKey

#include "FCPlib.h"

int main(int argc, char* argv[])
{
  hFCP *hfcp;
  char  msg[65];

  /* set the log reporting to Verbose (user friendly output) */  
  if (fcpStartup(stdout, FCP_LOG_VERBOSE) != 0) return -1;

  /* Connect to localhost, port 8481, hops to live 3, and 0 for the optmask */
  hfcp = fcpCreateHFCP("127.0.0.1", 8481, 3, 0);

  /* open the key to prepare for writing */
  if (fcpOpenKey(hfcp, "KSK@message.txt", FCP_MODE_O_WRITE) != 0) return -1;

  strcpy(msg, "Hello World!);

  /* write the "message" */
  fcpWriteKey(hfcp, msg, strlen(msg));

  /* this call actually stores the key in Freenet. it will not return
     until the file has been stored (or an error occurs) */

  if (fcpCloseKey(hfcp) != 0) return -1;
    
  /* call to delete temp files and free memory */
  fcpDestroyHFCP(hfcp);
  free(hfcp);

  /* The final shutdown for FCPLib */
  fcpTerminate();

  return 0;
}

Retrieving Files From Freenet with fcpGetKeyToFile

#include "FCPlib.h"

int main(int argc, char* argv[])
{
  hFCP *hfcp;
  
  /* set the log reporting to Verbose (user friendly output) */  
  if (fcpStartup(stdout, FCP_LOG_VERBOSE) != 0) return -1;
  
  /* Connect to localhost, port 8481, hops to live 3,
     and 0 for the optmask */
  hfcp = fcpCreateHFCP("127.0.0.1", 8481, 3, 0);

  /* get the key and store it in the file message.txt.
     NULL for no metadata */

  if (fcpGetKeyToFile(hfcp, "KSK@message.txt", "/home/hapi/message.txt", NULL) != 0)
    return -1;

  /* call to delete temp files and free memory */
  fcpDestroyHFCP(hfcp);
  free(hfcp);

  /* The final shutdown for FCPLib */
  fcpTerminate();

  return 0;
}

Retrieving Files From Freenet with fcpReadKey

#include "FCPlib.h"

int main(int argc, char* argv[])
{
  hFCP *hfcp;
  int   bytes;
  char  buf[513];
  
  /* set the log reporting to Verbose (user friendly output) */  
  if (fcpStartup(stdout, FCP_LOG_VERBOSE) != 0) return -1;
  
  /* Connect to localhost, port 8481, hops to live 3,
     and 0 for the optmask */
  hfcp = fcpCreateHFCP("127.0.0.1", 8481, 3, 0);

  /* this call actually retrieves the key from Freenet;
     it will not return until the key is retrieved
     (or an error occurs) */
  if (fcpOpenKey(hfcp, "SSK@M7yZgrl8gwtAe1xEcR5Xyv4tFsoPAgM/fiw/7//", FCP_MODE_O_READ) != 0)
    return -1;
    
  /* ReadKey returns >0 whenever there's data left */
  while ((bytes = fcpReadKey(hfcp, buf,  512)) > 0) {
    buf[bytes] = 0;

    /* hope this is text only! */
    printf("buf: %s\n", buf);  
  }

  /* cleanup some tempfiles */    
  if (fcpCloseKey(hfcp) != 0) return -1;
    
  /* call to delete remaining temp files and free memory */
  fcpDestroyHFCP(hfcp);
  free(hfcp);

  /* The final shutdown for FCPLib */
  fcpTerminate();

  return 0;
}