< back to phrasen|drescher
phrasen|drescher: The Plugin Writing Guide

The plugin API is very simple. What also implies, that the plugin developer has to do a lot of the work himself. The API generally requires mandatory functions to be declared. Each of the function will be called from p|d at a certain time. You can think of there are two sets of functions. Those, that are called from the main p|d process and those that are called by each p|d worker process. As for the latter, they are named with the prefix plugin_worker_. Please be aware, that the worker processes do not share the same memory. The advantage of that is, that the developer does not have to care for thread-safe programming.

Plugin Macros

There are a couple of macros that are required in each plugin:

PLUGIN_NAME(name); The name of the plugin. The filename of the plugin has to be used in p|d to chose a plugin. The plugin name specified here is only for pure information and will therefore only be shown in the usage message.
PLUGIN_AUTHOR(name); The author's name.
PLUGIN_VERSION(version); The version of the plugin.
PLUGIN_OPTIONS(list of options);
PLUGIN_NO_OPTIONS;
The list of options will include all plugin related command line options, their flags, parameters and description. The list expects the flag and it's attributes followed by the description and followed by the next flag, and so on ... For example:
PLUGIN_OPTIONS(
    "t text", "print's `text' on on the screen",
    "V"     , "shows the plugin's version number"
  );
If there are no command line options for this plugin use PLUGIN_NO_OPTIONS;
PLUGIN_INFO(additional information);
PLUGIN_NO_INFO;
There's an information text in each plugin's usage message. The text can contain whatever is helpful to know for the plugin's usage.
These three macros are for pure information.

PLUGIN_NAME("MyMacro");
PLUGIN_AUTHOR("Me");
PLUGIN_VERSION("1.0");
PLUGIN_OPTIONS("t text", "prints `text' on the screen");
PLUGIN_NO_INFO;

Plugin Functions
PLUGIN_FUNCTION plugin_get_opts(int opt, char *arg); The first function to be called during the command line parsing. Each command line option, that is not recognized by p|d itself, will be forwarded to this function. the `opt' parameter will hold the option character and `arg' will obviously be the following command line argument.
PLUGIN_FUNCTION plugin_init(int wnum); Once all options have been parsed, the init function is called with the number of workers as the argument.
PLUGIN_FUNCTION plugin_finish(); The function to be called at the very end, when p|d is terminated.
PLUGIN_FUNCTION plugin_worker_init(int wid); When p|d is forking all the worker processes the first function that will be invoked is this one. The argument `wid' is the unique worker id (an incrementing number from 0).
PLUGIN_FUNCTION plugin_worker_try_phrase(int wid, char *phrase); The heart of each plugin. This function is called for every worker, every time a new phrase has to be tested. `wid' if the worker's id and phrase the unique pass phrase. The function can return with three states:
  • PLUGIN_FAILURE: if a failure occurs (p|d will quit then)
  • PLUGIN_COMPLETED: if all work for this worker is done
  • PLUGIN_SUCCESS: normal return state (if no failure occurs)
PLUGIN_FUNCTION plugin_worker_finish(int wid); Similar to plugin_finish() but executed, when the worker process finishes.
Example Plugin
#include "../plugin.h"
#include "../utils.h"

PLUGIN_NAME("skel");
PLUGIN_AUTHOR("Nico Leidecker");
PLUGIN_VERSION("1.0");

PLUGIN_OPTIONS("t text", "prints `text' on the screen with each passphrase");
PLUGIN_NO_INFO;

static char *text = 0;

PLUGIN_FUNCTION plugin_get_opts(int opt, char *arg)
{
	switch (opt) {
		case 't':
				text = strdup(arg);
				break;
		default:
			return PLUGIN_RETURN_FAILURE;
	}
    return PLUGIN_RETURN_SUCCESS;
}

PLUGIN_FUNCTION plugin_init(int wnum)
{
	if (!text) {
		plugin_error_printf("please specify a text with -t.");
		return PLUGIN_RETURN_FAILURE;
	}
    return PLUGIN_RETURN_SUCCESS;
}

PLUGIN_FUNCTION plugin_finish()
{
    return PLUGIN_RETURN_SUCCESS;    
}

PLUGIN_FUNCTION plugin_worker_init(int wid)
{
    return PLUGIN_RETURN_SUCCESS;
}

PLUGIN_FUNCTION plugin_worker_try_phrase(int wid, char *phrase)
{
	plugin_verbose_printf("%s: %s\n", text, phrase);
	 
    return PLUGIN_RETURN_SUCCESS;
}

PLUGIN_FUNCTION plugin_worker_finish(int wid)
{
	return PLUGIN_RETURN_SUCCESS;
}