* New plugin API (terminate, return code for execute)

* PostgreSQL plugin
Initial
Stephane Bortzmeyer 20 years ago
parent a1d91e1af1
commit a1d6852155

@ -10,8 +10,12 @@ can safely return NULL.
void start (struct addrinfo *res)
Typically just stores the res structure for later use.
void execute ()
Connects and do whatever the protocol requires.
int execute ()
Connects and do whatever the protocol requires. It is called once
per iteration. It returns >=0 if it succeeds and -1 if it failed.
void terminate ()
Cleans everything. It is called after all iterations.
Start your plugin source code with:

@ -28,6 +28,7 @@ echoping \- tests a remote host with TCP or UDP
.RI [-m plugin]
.B hostname
[:port]
[plugin options...]
.SH DESCRIPTION
.LP
@ -126,7 +127,10 @@ or
(depending on your Unix). /usr/include/netinet/ip.h may contain
interesting constants for setting Type Of Service.
.IP -m\ plugin
Load the given plugin. Quite experimental.
Load the given plugin. Quite experimental. The documentation for a
plugin is in echoping_PLUGIN(1). The plugin-specific options appear
.B after
the hostname.
.SH EXAMPLES
.IP echoping\ \-v\ foobar.example.com
Tests the remote machine with TCP echo (one test).
@ -138,6 +142,9 @@ indicate the whole URL.
.IP echoping\ \-h\ http://www.example.com/\ cache.example.com:3128
Tests the remote Web proxy-cache and asks a Web page. Note that you must
indicate the whole URL.
.IP echoping\ -n\ 3\ -m\ whois\ foobar.example.com\ -r\ tao.example.org
Loads the whois plugin and query the host foobar.example.com. "-r
tao.example.org" are options specific to the whois plugin.
.IP echoping\ -u\ \-P\ 0xa0\ foobar.example.com
Sends several UDP Echo packets with an IP Precedence of 5.
.SH IP TYPE OF SERVICE OCTET

@ -460,6 +460,12 @@ main (argc, argv)
{
err_sys ("Cannot find execute in %s: %s", plugin_name, dl_result);
}
plugin_terminate = dlsym (plugin, "terminate");
dl_result = dlerror ();
if (dl_result)
{
err_sys ("Cannot find terminate in %s: %s", plugin_name, dl_result);
}
}
if (!udp && !ttcp)
{
@ -848,6 +854,7 @@ main (argc, argv)
if (plugin)
{
plugin_execute ();
/* TODO: do something with the return code */
}
else
{
@ -1369,19 +1376,21 @@ main (argc, argv)
}
} /* End of main loop */
printstats ();
if (successes >= 1)
exit (0);
else
exit (1);
/* It would be nice to clean here (OpenSSL, etc) */
/* Clean */
if (plugin)
plugin_terminate();
/* It would be nice to clean here for OpenSSL */
#ifdef GNUTLS
if (ssl)
{
gnutls_global_deinit ();
}
#endif
printstats ();
if (successes >= 1)
exit (0);
else
exit (1);
}
void

@ -127,8 +127,10 @@ typedef char * (*init_f) (const int argc, const char **argv);
init_f plugin_init;
typedef void (*start_f) (struct addrinfo *);
start_f plugin_start;
typedef void (*execute_f) ();
typedef int (*execute_f) ();
execute_f plugin_execute;
typedef void (*terminate_f) ();
terminate_f plugin_terminate;
#endif
#endif

@ -1,18 +1,23 @@
CCFLAGS=-DHAVE_CONFIG_H -Wall -O0 -g
CCDYNAMICFLAGS=${CCFLAGS} -fPIC
LDFLAGS=
LDDYNAMICFLAGS=${LDFLAGS} -shared
LDDYNAMICFLAGS=${LDFLAGS} -shared -lpq # TODO: add the flags only when necessary
PLUGINS=random.so whois.so
PLUGINS=random.so whois.so postgres
all: $(PLUGINS)
postgres: postgresql.so
%.o: %.c
${CC} ${CCDYNAMICFLAGS} -c -o $@ $<
%.so: %.o
${CC} ${LDDYNAMICFLAGS} -o $@ $<
test-postgresql: test-postgresql.o
${CC} -o $@ -l pq $<
clean:
-rm -f *.o *.so program

@ -0,0 +1,112 @@
/*
* PostgreSQL plugin.
*
* $Id$
*/
#define IN_PLUGIN
#include "../echoping.h"
#include <postgresql/libpq-fe.h>
const char *request = NULL;
int readall = FALSE;
poptContext postgresql_poptcon;
PGconn *conn;
PGresult *res;
char *conninfo;
void
postgresql_usage (const char *msg)
{
if (msg)
{
printf ("PostgreSQL plugin error: %s\n", msg);
}
poptPrintUsage (postgresql_poptcon, stdout, 0);
exit (1);
}
char *
init (const int argc, const char **argv)
{
int value;
char *msg = malloc (256);
/* popt variables */
struct poptOption options[] = {
{"conninfo", 'c', POPT_ARG_STRING, &conninfo, 0,
"Connection information for the Postgresql server. Something like 'host=foo dbname=bar''",
"request"},
{"request", 'r', POPT_ARG_STRING, &request, 0,
"Request/query (in SQL) to send to the Postgresql server. Only SELECT are supported.",
"request"},
{"readall", 'a', POPT_ARG_NONE, &readall, 0,
"Read all the data sent by the Postgresql server",
""},
POPT_AUTOHELP POPT_TABLEEND
};
postgresql_poptcon = poptGetContext (NULL, argc,
argv, options,
POPT_CONTEXT_KEEP_FIRST);
while ((value = poptGetNextOpt (postgresql_poptcon)) > 0)
{
if (value < -1)
{
sprintf (msg, "%s: %s",
poptBadOption (postgresql_poptcon, POPT_BADOPTION_NOALIAS),
poptStrerror (value));
postgresql_usage (msg);
}
}
if (request == NULL)
postgresql_usage ("Mandatory request missing");
if (conninfo == NULL)
postgresql_usage ("Mandatory connection information missing");
return NULL; /* We only use the conninfo, echoping does not see our hostname or port */
}
void
start (struct addrinfo *res)
{
conn = PQconnectdb (conninfo);
if (conn == NULL)
{
printf ("Cannot create connection\n");
exit (1);
}
if (PQstatus (conn) == CONNECTION_BAD)
{
printf ("Connection failed: %s\n", PQerrorMessage (conn));
exit (1);
}
}
int
execute ()
{
unsigned int row, column;
res = PQexec (conn, request);
if (PQresultStatus (res) != PGRES_TUPLES_OK)
{
printf ("Cannot run \"%s\": %s\n", request, PQresultErrorMessage (res));
return -1;
}
if (readall)
{
for (row = 0; row++; row < PQntuples (res))
{
for (column = 0; column++; column < PQnfields (res))
{
PQgetvalue (res, row, column);
/* TODO: test the return code */
}
}
}
return 0;
}
void
terminate ()
{
PQfinish (conn);
}

@ -22,8 +22,11 @@ void start ()
{
}
void
int
execute ()
{
usleep (rand () % 1000000);
return 1;
}
void terminate() {}

@ -77,7 +77,7 @@ start (struct addrinfo *res)
whois_server = *res;
}
void
int
execute ()
{
int nr = 0;
@ -102,4 +102,8 @@ execute ()
if (dump)
printf ("\n");
close (sockfd);
return 1;
}
void terminate() {
}

Loading…
Cancel
Save