INSTALL:=libtool --mode=install install
COMPILE:=libtool --mode=compile ${CC} ${CFLAGS}
-HDRS:=types.h context.h strmd5.h attr.h known_attr.h
+HDRS:=types.h context.h strmd5.h attr.h known_attr.h backend.h
-SRCS:=context.c strmd5.c attr.c
+SRCS:=context.c strmd5.c attr.c utils.c
OBJS:=${SRCS:.c=.lo}
THROBJS:=${OBJS:.o=.thr.lo}
LIBS:=-L${globus_prefix}/lib -lcrypto_${nothrflavour}
clean:
rm -rvf *.o *.lo .libs lib*
rm -rvf log.xml project/ rpmbuild/ RPMS/ tgz/
+ rm -f glite jp
%.thr.lo: %.c
${COMPILE} ${GLOBUSTHRINC} -o $@ -c $<
--- /dev/null
+#ifndef GLITE_JP_BACKEND_H
+#define GLITE_JP_BACKEND_H
+
+/* do we need it?
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int glite_jppsbe_get_names(
+ glite_jp_context_t ctx,
+ const char *job,
+ const char * /* class */,
+ char ***names_out
+);
+
+int glite_jppsbe_destination_info(
+ glite_jp_context_t ctx,
+ const char *destination,
+ char **job_out,
+ char **class_out,
+ char **name_out
+);
+
+int glite_jppsbe_get_job_url(
+ glite_jp_context_t ctx,
+ const char *job,
+ const char * /* class */,
+ const char *name, /* optional within class */
+ char **url_out
+);
+
+int glite_jppsbe_open_file(
+ glite_jp_context_t ctx,
+ const char *job,
+ const char * /* class */,
+ const char *name, /* optional within class */
+ int mode,
+ void **handle_out
+);
+
+int glite_jppsbe_close_file(
+ glite_jp_context_t ctx,
+ void *handle
+);
+
+int glite_jppsbe_file_attrs(
+ glite_jp_context_t ctx,
+ void *handle,
+ struct stat *buf
+);
+
+int glite_jppsbe_pread(
+ glite_jp_context_t ctx,
+ void *handle,
+ void *buf,
+ size_t nbytes,
+ off_t offset,
+ ssize_t *nbytes_ret
+);
+
+int glite_jppsbe_pwrite(
+ glite_jp_context_t ctx,
+ void *handle,
+ void *buf,
+ size_t nbytes,
+ off_t offset
+);
+
+int glite_jppsbe_append(
+ glite_jp_context_t ctx,
+ void *handle,
+ void *buf,
+ size_t nbytes
+);
+
+int glite_jppsbe_is_metadata(
+ glite_jp_context_t ctx,
+ const char *attr
+);
+
+int glite_jppsbe_get_job_metadata(
+ glite_jp_context_t ctx,
+ const char *job,
+ glite_jp_attrval_t attrs_inout[]
+);
+
+int glite_jppsbe_query(
+ glite_jp_context_t ctx,
+ const glite_jp_query_rec_t query[],
+ char *attrs[],
+ void *arg,
+ int (*callback)(
+ glite_jp_context_t ctx,
+ const char *job,
+ const glite_jp_attrval_t metadata[],
+ void *arg
+ )
+);
+
+int glite_jppsbe_readline(
+ glite_jp_context_t ctx,
+ void *handle,
+ void **b,
+ char **line
+);
+
+char* glite_jpps_get_namespace(
+ const char* attr
+);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* GLITE_JP_BACKEND_H */
+
--- /dev/null
+#ifndef GLITE_JP_FILEPLUGIN_H
+#define GLITE_JP_FILEPLUGIN_H
+
+/** Methods of the file plugin. */
+
+typedef struct _glite_jpps_fplug_op_t {
+
+/** Open a file.
+\param[in] fpctx Context of the plugin, returned by its init.
+\param[in] bhandle Handle of the file via JPPS backend.
+\param[in] uri URI (type) of the opened file.
+\param[out] handle Handle to the opened file structure, to be passed to other plugin functions.
+*/
+ int (*open)(void *fpctx,void *bhandle,const char *uri,void **handle);
+/** Open from a string.
+\param[in] fpctx Context of the plugin, returned by its init.
+\param[in] str The string to use.
+\param[in] uri URI (type) of the string
+\param[in] ns namespace to handle
+\param[out] handle Handle to the opened file structure, to be passed to other plugin functions.
+*/
+
+ int (*open_str)(void *fpctx,const char *str,const char *uri,const char *ns,void **handle);
+
+/** Close the file. Free data associated to a handle */
+ int (*close)(void *fpctx,void *handle);
+
+/** "Preprocess" the file -- this function is called once after the file is commited */
+ int (*filecom)(void *fpctx,void *handle);
+
+/** Retrieve value(s) of an attribute.
+\param[in] fpctx Plugin context.
+\param[in] handle Handle of the opened file.
+\param[in] ns Namespace of queried attribute.
+\param[in] attr Queried attribute.
+\param[out] attrval GLITE_JP_ATTR_UNDEF-terminated list of value(s) of the attribute.
+ If there are more and there is an interpretation of their order
+ they must be sorted, eg. current value of tag is the last one.
+\retval 0 success
+\retval ENOSYS this attribute is not defined by this type of file
+\retval ENOENT no value is present
+*/
+ int (*attr)(void *fpctx,void *handle, const char *attr,glite_jp_attrval_t **attrval);
+
+/** File type specific operation.
+\param[in] fpctx Plugin context.
+\param[in] handle Handle of the opened file.
+\param[in] oper Code of the operation, specific for a concrete plugin.
+*/
+ int (*generic)(void *fpctx,void *handle,int oper,...);
+
+} glite_jpps_fplug_op_t;
+
+/** Data describing a plugin. */
+typedef struct _glite_jpps_fplug_data_t {
+ void *fpctx; /**< Context passed to plugin operations. */
+ char **uris; /**< NULL-terminated list of file types (URIs)
+ handled by the plugin. */
+ char **classes; /**< The same as uris but filesystem-friendly
+ (can be used to construct file names).*/
+ char **namespaces; /**< Which attribute namespaces this plugin handles. */
+
+ glite_jpps_fplug_op_t ops; /**< Plugin operations. */
+} glite_jpps_fplug_data_t;
+
+/** Initialisation function of the plugin.
+ Called after dlopen(), must be named "init".
+\param[in] ctx JPPS context
+\param[out] data filled-in plugin data
+*/
+
+typedef int (*glite_jpps_fplug_init_t)(
+ glite_jp_context_t ctx,
+ glite_jpps_fplug_data_t *plugin_data
+);
+
+
+
+
+/* XXX: not really public interface follows */
+
+int glite_jpps_fplug_load(glite_jp_context_t ctx,int argc,char **argv);
+int glite_jpps_fplug_lookup(glite_jp_context_t ctx,const char *uri, glite_jpps_fplug_data_t ***plugin_data);
+int glite_jpps_fplug_lookup_byclass(glite_jp_context_t, const char *class,glite_jpps_fplug_data_t ***plugin_data);
+
+#endif /* GLITE_JP_FILEPLUGIN_H */
--- /dev/null
+#include <getopt.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <limits.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "glite/jp/types.h"
+#include "glite/jp/context.h"
+#include "glite/jp/strmd5.h"
+#include "glite/jp/known_attr.h"
+#include "glite/jp/attr.h"
+
+/*
+#include "feed.h"
+#include "tags.h"
+*/
+
+#include "backend.h"
+
+
+typedef struct _rl_buffer_t {
+ char *buf;
+ size_t pos, size;
+ off_t offset;
+} rl_buffer_t;
+
+/*
+ * realloc the line to double size if needed
+ *
+ * \return 0 if failed, did nothing
+ * \return 1 if success
+ */
+int check_realloc_line(char **line, size_t *maxlen, size_t len) {
+ void *tmp;
+
+ if (len > *maxlen) {
+ *maxlen <<= 1;
+ tmp = realloc(*line, *maxlen);
+ if (!tmp) return 0;
+ *line = tmp;
+ }
+
+ return 1;
+}
+
+/*
+ * read next line from stream
+ *
+ * \return error code
+ */
+int glite_jppsbe_readline(
+ glite_jp_context_t ctx,
+ void *handle,
+ void **b,
+ char **line
+)
+{
+ size_t maxlen, len, i;
+ ssize_t nbytes;
+ int retval, z, end;
+ rl_buffer_t *buffer;
+
+ if (!*b) *b = calloc(1,sizeof *buffer);
+ buffer = *b;
+
+ maxlen = BUFSIZ;
+ i = 0;
+ len = 0;
+ *line = malloc(maxlen);
+ end = 0;
+
+ do {
+ /* read next portion */
+ if (buffer->pos >= buffer->size) {
+ buffer->pos = 0;
+ buffer->size = 0;
+ if ((retval = glite_jppsbe_pread(ctx, handle, buffer->buf, BUFSIZ, buffer->offset, &nbytes)) == 0) {
+ if (nbytes < 0) {
+ retval = EINVAL;
+ goto fail;
+ } else {
+ if (nbytes) {
+ buffer->size = (size_t)nbytes;
+ buffer->offset += nbytes;
+ } else end = 1;
+ }
+ } else goto fail;
+ }
+
+ /* we have buffer->size - buffer->pos bytes */
+ i = buffer->pos;
+ do {
+ if (i >= buffer->size) z = '\0';
+ else {
+ z = buffer->buf[i];
+ if (z == '\n') z = '\0';
+ }
+ len++;
+
+ if (!check_realloc_line(line, &maxlen, len)) {
+ retval = ENOMEM;
+ goto fail;
+ }
+ (*line)[len - 1] = z;
+ i++;
+ } while (z && i < buffer->size);
+ buffer->pos = i;
+ } while (len && (*line)[len - 1] != '\0');
+
+ if ((!len || !(*line)[0]) && end) {
+ free(*line);
+ *line = NULL;
+ }
+
+ return 0;
+
+fail:
+ free(*line);
+ *line = NULL;
+ return retval;
+}
+
+char* glite_jpps_get_namespace(const char* attr){
+ char* namespace = strdup(attr);
+ char* colon = strrchr(namespace, ':');
+ if (colon)
+ namespace[strrchr(namespace, ':') - namespace] = 0;
+ else
+ namespace[0] = 0;
+ return namespace;
+}
+
#include "strmd5.h"
+#include "types.h"
+#include "backend.h"
+
class Base64Test: public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(Base64Test);
return result.wasSuccessful() ? 0 : 1 ;
}
+/* fake to link */
+int glite_jppsbe_pread(
+ glite_jp_context_t ctx,
+ void *handle,
+ void *buf,
+ size_t nbytes,
+ off_t offset,
+ ssize_t *nbytes_ret
+)
+{
+ abort();
+}
#include "types.h"
#include "attr.h"
#include "context.h"
+#include "backend.h"
class TypePluginTest: public CppUnit::TestFixture
+
+/* fake to link */
+int glite_jppsbe_pread(
+ glite_jp_context_t ctx,
+ void *handle,
+ void *buf,
+ size_t nbytes,
+ off_t offset,
+ ssize_t *nbytes_ret
+)
+{
+ abort();
+}
+
+