#include <stdio.h> #include <stdarg.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #ifdef WINDOWS #include <io.h> #else #include <dirent.h> #endif #include <errno.h> #include <malloc.h> #include "../wftk.h" #include "../wftk_internals.h" #include "../xmlapi/xmlobj.h" |
adaptor_info structure is used to pass adaptor info (duh) back to the
config module when it's building an adaptor instance. Here's what it contains:
static char *names[] =
{
"init",
"free",
"info",
"create",
"destroy",
"add",
"update",
"delete",
"get",
"query",
"first",
"next",
"rewind",
"prev",
"last",
"attach_open",
"attach_write",
"attach_close",
"attach_cancel",
"retrieve_open",
"retrieve_read",
"retrieve_close"
};
XML * LIST_localdir_init (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_free (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_info (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_create (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_destroy (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_add (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_update (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_delete (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_get (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_query (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_first (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_next (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_rewind (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_prev (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_last (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_attach_open (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_attach_write (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_attach_close (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_attach_cancel (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_retrieve_open (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_retrieve_read (WFTK_ADAPTOR * ad, va_list args);
XML * LIST_localdir_retrieve_close (WFTK_ADAPTOR * ad, va_list args);
static WFTK_API_FUNC vtab[] =
{
LIST_localdir_init,
LIST_localdir_free,
LIST_localdir_info,
LIST_localdir_create,
LIST_localdir_destroy,
LIST_localdir_add,
LIST_localdir_update,
LIST_localdir_delete,
LIST_localdir_get,
LIST_localdir_query,
LIST_localdir_first,
LIST_localdir_next,
LIST_localdir_rewind,
LIST_localdir_prev,
LIST_localdir_last,
LIST_localdir_attach_open,
LIST_localdir_attach_write,
LIST_localdir_attach_close,
LIST_localdir_attach_cancel,
LIST_localdir_retrieve_open,
LIST_localdir_retrieve_read,
LIST_localdir_retrieve_close
};
static struct wftk_adaptor_info _LIST_localdir_info =
{
22,
names,
vtab
};
|
struct wftk_adaptor_info * LIST_localdir_get_info ()
{
return & _LIST_localdir_info;
}
|
XML * LIST_localdir_init (WFTK_ADAPTOR * ad, va_list args)
{
const char * parms;
char * mark;
parms = xml_attrval (ad->parms, "parm");
xml_set (ad->parms, "defsuffix", ".xml");
if (!*parms) {
xml_set (ad->parms, "subdir", "");
return NULL;
}
xml_set (ad->parms, "spec", "localdir:?");
/* TODO: get current directory as basedir. */
mark = strchr (parms, ';');
if (!mark) {
xml_set (ad->parms, "subdir", parms);
return NULL;
}
xml_set (ad->parms, "subdir", "");
xml_attrncat (ad->parms, "subdir", parms, mark - parms);
parms = mark + 1;
mark = strchr (parms, ';');
if (mark) {
xml_set (ad->parms, "suffix", "");
xml_attrncat (ad->parms, "suffix", parms, mark - parms);
xml_set (ad->parms, "prefix", mark + 1);
} else {
xml_set (ad->parms, "suffix", parms);
}
if (mark = strchr (xml_attrval (ad->parms, "suffix"), ',')) {
xml_set (ad->parms, "multsuffix", "yes");
xml_set (ad->parms, "defsuffix", "");
xml_attrncat (ad->parms, "defsuffix", xml_attrval (ad->parms, "suffix"), mark - xml_attrval (ad->parms, "suffix"));
} else {
if (*xml_attrval (ad->parms, "multsuffix")) xml_set (ad->parms, "multsuffix", "");
xml_set (ad->parms, "defsuffix", xml_attrval (ad->parms, "suffix"));
}
return (XML *) 0;
}
XML * LIST_localdir_free (WFTK_ADAPTOR * ad, va_list args) { return (XML *) 0; }
|
XML * LIST_localdir_info (WFTK_ADAPTOR * ad, va_list args) {
XML * info;
info = xml_create ("info");
xml_set (info, "type", "list");
xml_set (info, "name", "localdir");
xml_set (info, "ver", "1.1.0");
xml_set (info, "compiled", __TIME__ " " __DATE__);
xml_set (info, "author", "Michael Roberts");
xml_set (info, "contact", "wftk@vivtek.com");
xml_set (info, "extra_functions", "0");
return (info);
}
|
XML * LIST_localdir_get (WFTK_ADAPTOR * ad, va_list args) {
XML * scratch = xml_create ("scratch");
XML * ret = NULL;
XML * list = NULL;
char * key;
FILE * file;
char * mark;
char * buf[128];
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
key = va_arg (args, char *);
xml_setf (ad->parms, "spec", "localdir:%s", xml_attrval (list, "id"));
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
xml_set (scratch, "dir", xml_attrval (ad->parms, "basedir"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (scratch, "dir", "/");
}
if (*xml_attrval (ad->parms, "prefix")) {
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "prefix"));
}
xml_attrcat (scratch, "dir", key);
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "defsuffix"));
file = fopen (xml_attrval (scratch, "dir"), "r");
if (file) {
ret = xml_parse_general (file, (XMLAPI_DATARETRIEVE) fread);
if (xml_is (ret, "xml-error")) {
xml_setf (ad->parms, "error",
"XML error in line %s of list item file %s: %s",
xml_attrval (ret, "line"),
xml_attrval (scratch, "dir"),
xml_attrval (ret, "message"));
xml_free (ret);
ret = NULL;
}
fclose (file);
}
if (ret) xml_set (ret, "key", key);
xml_free (scratch);
return ret;
}
|
void _LIST_localdir_scan (WFTK_ADAPTOR * ad, XML * list) {
#ifdef WINDOWS
long hFile;
struct _finddata_t c_file;
#else
DIR * dir;
struct dirent * entry;
#endif
char * cp;
char * mark;
const char * prefix;
int count = 0;
XML * scratch = xml_create ("s");
XML * record;
xml_set (list, "count", "0");
xml_replacecontent (list, NULL); /* Delete any existing contents. */
xml_set (scratch, "dir", xml_attrval (ad->parms, "basedir"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (scratch, "dir", "/");
}
prefix = xml_attrval (ad->parms, "prefix");
xml_setf (scratch, "spec", "%s%s*%s", xml_attrval (scratch, "dir"), prefix, xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes */
#ifdef WINDOWS
hFile = _findfirst (xml_attrval (scratch, "spec"), &c_file);
if (hFile < 0L) {
#else
if (!*xml_attrval (scratch, "dir")) xml_set (scratch, "dir", ".");
dir = opendir (xml_attrval (scratch, "dir"));
if (!dir) {
#endif
xml_free (scratch);
return;
}
#ifndef WINDOWS
entry = readdir (dir);
if (!entry) {
xml_free (scratch);
return;
}
#endif
do {
#ifndef WINDOWS
if (strlen (entry->d_name) < strlen (xml_attrval (ad->parms, "defsuffix"))) continue;
if (*prefix) if (strncmp (prefix, entry->d_name, strlen (prefix))) continue;
mark = entry->d_name + strlen (entry->d_name) - strlen (xml_attrval (ad->parms, "defsuffix"));
if (strcmp (mark, xml_attrval (ad->parms, "defsuffix"))) continue; /* TODO: multiple suffixes. */
#endif
count++;
record = xml_create ("record");
#ifdef WINDOWS
cp = strdup (c_file.name);
#else
cp = strdup (entry->d_name);
#endif
if (!*xml_attrval (ad->parms, "multsuffix")) {
mark = strchr (cp, '.');
if (mark) *mark = '\0';
}
xml_setf (record, "id", "%s", cp + strlen (xml_attrval (ad->parms, "prefix")));
free (cp);
xml_append (list, record);
#ifdef WINDOWS
} while (-1 != _findnext (hFile, &c_file));
#else
} while (entry = readdir (dir));
#endif
xml_setnum (list, "count", count);
xml_free (scratch);
#ifdef WINDOWS
_findclose (hFile);
#else
closedir (dir);
#endif
}
|
XML * LIST_localdir_query (WFTK_ADAPTOR * ad, va_list args)
{
XML * list;
XML * defn;
XML * scratch;
XML * cur;
XML * ret;
XML * sort;
XML * scan;
FILE * file;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
xml_setf (ad->parms, "spec", "localdir:%s", xml_attrval (list, "id"));
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
if (*xml_attrval (list, "order")) defn = xml_copy (list);
_LIST_localdir_scan (ad, list);
if (!*xml_attrval (list, "select") && !*xml_attrval (list, "order") && !*xml_attrval (list, "where")) return list;
/* If requested, we load the files -- note that we're not going to get sophisticated and select fields yet or anything. */
scratch = xml_create ("s");
xml_set (scratch, "dir", xml_attrval (ad->parms, "basedir"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (scratch, "dir", "/");
}
cur = xml_firstelem (list);
while (cur) {
xml_setf (scratch, "file", "%s%s%s%s", xml_attrval (scratch, "dir"), xml_attrval (scratch, "prefix"), xml_attrval (cur, "id"), xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes. */
file = fopen (xml_attrval (scratch, "file"), "r");
if (!file) {
cur = xml_nextelem (cur);
if (cur) {
xml_delete (xml_prevelem (cur));
} else {
xml_delete (xml_lastelem (list));
}
continue;
} else {
ret = xml_parse_general (file, (XMLAPI_DATARETRIEVE) fread);
xml_unset (ret, "key"); /* Long story. */
if (!xml_is (ret, "xml-error")) xml_copyinto (cur, ret);
xml_free (ret);
fclose (file);
}
cur = xml_nextelem (cur);
}
/* And now we sort the files as requested. */
if (*xml_attrval (list, "order")) {
xmlobj_list_sort (list, defn, xml_attrval (list, "order"));
xml_free (defn);
}
xml_free (scratch);
return list;
}
|
XML * LIST_localdir_first (WFTK_ADAPTOR * ad, va_list args) {
XML * list;
XML * ret;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
xml_setf (ad->parms, "spec", "localdir:%s", xml_attrval (list, "id"));
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
_LIST_localdir_scan (ad, list);
xml_set (list, "cur", "");
ret = xml_firstelem (list);
if (ret) xml_set_nodup (list, "cur", xml_getlocbuf (ret));
else xml_set (list, "cur", "EOF");
return (ret);
}
XML * LIST_localdir_next (WFTK_ADAPTOR * ad, va_list args) {
XML * list;
XML * cur;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
if (*xml_attrval (list, "cur")) {
if (!strcmp (xml_attrval (list, "cur"), "EOF")) return NULL;
cur = xml_loc (list, xml_attrval (list, "cur"));
if (cur) cur = xml_nextelem (cur);
if (cur) xml_set_nodup (list, "cur", xml_getlocbuf (cur));
else xml_set (list, "cur", "EOF");
return (cur);
}
cur = xml_firstelem (list);
if (cur) xml_set_nodup (list, "cur", xml_getlocbuf (cur));
else xml_set (list, "cur", "EOF");
return (cur);
}
XML * LIST_localdir_rewind (WFTK_ADAPTOR * ad, va_list args) {
XML * list;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
xml_set (list, "cur", "");
}
XML * LIST_localdir_prev (WFTK_ADAPTOR * ad, va_list args)
{
XML * list;
XML * cur;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
if (!*xml_attrval (list, "cur")) return NULL;
if (!strcmp (xml_attrval (list, "cur"), "EOF")) {
cur = xml_lastelem (list);
if (cur) xml_set_nodup (list, "cur", xml_getlocbuf (cur));
else xml_set (list, "cur", "");
return (cur);
}
cur = xml_loc (list, xml_attrval (list, "cur"));
if (cur) cur = xml_prevelem (cur);
if (cur) xml_set_nodup (list, "cur", xml_getlocbuf (cur));
else xml_set (list, "cur", "");
return (cur);
}
XML * LIST_localdir_last (WFTK_ADAPTOR * ad, va_list args)
{
XML * list;
XML * ret;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
xml_set (list, "cur", "EOF");
ret = xml_lastelem (list);
if (ret) xml_set_nodup (list, "cur", xml_getlocbuf (ret));
else xml_set (list, "cur", "");
return (ret);
}
|
XML * LIST_localdir_create (WFTK_ADAPTOR * ad, va_list args) { return 0; }
XML * LIST_localdir_destroy (WFTK_ADAPTOR * ad, va_list args) { return 0; }
|
XML * LIST_localdir_add (WFTK_ADAPTOR * ad, va_list args) {
XML * list;
XML * obj;
XML * mark;
XML * ret;
XML * scratch;
struct stat statbuf;
char timebuf[16]; /* Note: NO buffer overflow risk, since we know what's going into this puppy. */
struct tm * timeptr;
time_t julian;
FILE * file;
const char * keygen = NULL;
int temp;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
obj = va_arg (args, XML *);
if (!obj) {
xml_set (ad->parms, "error", "No object given.");
return (XML *) 0;
}
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
/* Check list for key-generation special. */
scratch = xml_create ("s");
xml_set (scratch, "dir", xml_attrval (ad->parms, "basedir"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (scratch, "dir", "/");
}
for (mark = xml_firstelem (list); mark; mark = xml_nextelem (mark)) if (!strcmp (xml_attrval (mark, "special"), "key")) break;
if (!mark) {
xml_set_nodup (obj, "key", xmlobj_getkey (obj, list));
if (!*xml_attrval (obj, "key")) { /* If no special key field but we still don't have a field, we have to choose a key field. */
mark = xml_loc (list, ".field[key]");
if (!mark) mark = xml_loc (list, ".field");
if (!mark) mark = xml_loc (obj, ".field[key]");
if (!mark) mark = xml_loc (obj, ".field");
/* At this point, the user has to live keylessly. I don't expect it to occur often. */
}
}
xml_set_nodup (obj, "key", xmlobj_getkey (obj, list));
if (mark && (!strcmp (xml_attrval (mark, "special"), "key") || !*xml_attrval (obj, "key"))) {
keygen = xml_attrval (mark, "id");
mark = xmlobj_is_field (obj, NULL, keygen);
if (!mark) {
mark = xml_create ("field");
xml_set (mark, "id", keygen);
xml_prepend_pretty (obj, mark);
}
time (&julian);
timeptr = localtime (&julian);
sprintf (timebuf, "%04d%02d%02d_%02d%02d%02d",
timeptr->tm_year + 1900, timeptr->tm_mon + 1, timeptr->tm_mday,
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
xml_setf (scratch, "key", "%s00", timebuf);
xml_setf (scratch, "file", "%s%s%s%s", xml_attrval (scratch, "dir"), xml_attrval (ad->parms, "prefix"), xml_attrval (scratch, "key"), xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes? */
temp = stat (xml_attrval (scratch, "file"), &statbuf);
while (stat (xml_attrval (scratch, "file"), &statbuf) != -1) { /* File exists already. */ /* TODO: probably some locking would help here... */
xml_setf (scratch, "key", "%s%d", timebuf, rand() * 100 / RAND_MAX);
xml_setf (scratch, "file", "%s%s%s%s", xml_attrval (scratch, "dir"), xml_attrval (ad->parms, "prefix"), xml_attrval (scratch, "key"), xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes? */
}
xmlobj_set (obj, NULL, keygen, xml_attrval (scratch, "key"));
xml_set (obj, "key", xml_attrval (scratch, "key"));
} else {
xml_setf (scratch, "file", "%s%s%s%s", xml_attrval (scratch, "dir"), xml_attrval (ad->parms, "prefix"), xml_attrval (obj, "key"), xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes? */
}
file = fopen (xml_attrval (scratch, "file"), "w");
if (!file) {
xml_setf (ad->parms, "error", "Object file %s cannot be opened for writing.", xml_attrval (scratch, "file"));
} else {
xml_write (file, obj);
fclose (file);
}
xml_free (scratch);
return NULL;
}
XML * LIST_localdir_update (WFTK_ADAPTOR * ad, va_list args) {
XML * list;
XML * obj;
const char * oldkey;
const char * key;
XML * mark;
XML * ret;
XML * scratch;
FILE * file;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
obj = va_arg (args, XML *);
if (!obj) {
xml_set (ad->parms, "error", "No object given.");
return (XML *) 0;
}
xml_setf (ad->parms, "spec", "localdir:%s", xml_attrval (list, "id"));
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
oldkey = xml_attrval (obj, "key");
key = xmlobj_getkey (obj, list);
scratch = xml_create ("s");
xml_set (scratch, "dir", xml_attrval (ad->parms, "basedir"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (scratch, "dir", "/");
}
xml_setf (scratch, "file", "%s%s%s%s", xml_attrval (scratch, "dir"), xml_attrval (ad->parms, "prefix"), key, xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes? */
file = fopen (xml_attrval (scratch, "file"), "w");
if (!file) {
xml_setf (ad->parms, "error", "Object file %s cannot be opened for writing.", xml_attrval (scratch, "file"));
} else {
xml_write (file, obj);
fclose (file);
if (*oldkey && strcmp (oldkey, key)) {
xml_setf (scratch, "delfile", "%s%s%s%s", xml_attrval (scratch, "dir"), xml_attrval (ad->parms, "prefix"), oldkey, xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes? */
unlink (xml_attrval (scratch, "delfile"));
}
}
free ((void *)key);
xml_free (scratch);
return NULL;
}
XML * LIST_localdir_delete (WFTK_ADAPTOR * ad, va_list args) {
XML * list;
XML * obj;
char * key;
XML * mark;
XML * ret;
XML * scratch;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
key = va_arg (args, char *);
if (!key) {
xml_set (ad->parms, "error", "No object given.");
return (XML *) 0;
}
xml_setf (ad->parms, "spec", "localdir:%s", xml_attrval (list, "id"));
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
scratch = xml_create ("s");
xml_set (scratch, "dir", xml_attrval (ad->parms, "basedir"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (scratch, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (scratch, "dir", "/");
}
xml_setf (scratch, "file", "%s%s%s%s", xml_attrval (scratch, "dir"), xml_attrval (ad->parms, "prefix"), key, xml_attrval (ad->parms, "defsuffix")); /* TODO: multiple suffixes? */
unlink (xml_attrval (scratch, "file"));
xml_free (scratch);
return NULL;
}
|
XML * LIST_localdir_attach_open (WFTK_ADAPTOR * ad, va_list args) {
XML * list;
char * key;
char * field;
char * filename;
char * ver;
struct stat statbuf;
XML * mark;
XML * ret;
void * sess;
FILE * file;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list descriptor given.");
return (XML *) 0;
}
key = va_arg (args, char *);
field = va_arg (args, char *);
filename = va_arg (args, char *);
ver = va_arg (args, char *);
if (!ver) ver = "0";
xml_setf (ad->parms, "spec", "localdir:%s", xml_attrval (list, "id"));
/* If we're not given a fieldname, then we'll just scan the list definition to find the first "document"-type field. */
if (!field) {
mark = xml_search (list, "field", "type", "document");
if (!mark) {
xml_set (ad->parms, "error", "No attachment field given and no default exists.");
return NULL;
}
field = (char *) xml_attrval (mark, "id");
}
ret = xml_create ("attachment-handle");
mark = xml_search (ad->session, "wftk-session", NULL, NULL);
if (mark) { /* Copy wftk session pointer into our attachment handle, because we'll be using that as a substitute repdef. */
sess = xml_getbin (mark);
mark = xml_create ("wftk-session");
xml_setbin (mark, sess, NULL);
xml_append (ret, mark);
}
xml_set (ret, "dir", xml_attrval (ad->parms, "basedir"));
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (ret, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (ret, "dir", "/");
}
xml_setf (ret, "adaptor", "localdir:%s", xml_attrval (ret, "dir"));
/* If we're supplied with a filename, then that file can't already exist in our controlled
directory. */
if (filename && *filename) {
xml_setf (ret, "location", filename);
xml_setf (ret, "file", "%s%s", xml_attrval (ret, "dir"), filename);
xml_set (ret, "tempfile", xml_attrval (ret, "file"));
if (stat (xml_attrval (ret, "file"), &statbuf) != -1) { /* File exists already. */
xml_setf (ad->parms, "error", "File %s is already present.", filename);
xml_free (ret);
return NULL;
}
} else {
xml_setf (ret, "location", "_att_%s_%s_%s.dat", key, field, ver);
xml_setf (ret, "file", "%s%s", xml_attrval (ret, "dir"), xml_attrval (ret, "location"));
xml_setf (ret, "tempfile", "%s_newatt_%s_%s_%s.dat", xml_attrval (ret, "dir"), key, field, ver);
}
file = fopen (xml_attrval (ret, "file"), "w");
if (!file) {
xml_setf (ad->parms, "error", "Unable to open file %s for writing.", xml_attrval (ret, "file"));
xml_free (ret);
return NULL;
}
xml_setbin (ret, file, (XML_SETBIN_FREE_FN *)fclose);
xml_set (ret, "content-type", "text/plain");
return (ret);
}
|
XML * LIST_localdir_attach_write (WFTK_ADAPTOR * ad, va_list args) {
void * buffer;
int size, number;
XML * handle;
if (!args) {
xml_set (ad->parms, "error", "No arguments given.");
return NULL;
}
buffer = va_arg (args, void *);
size = va_arg (args, int);
number = va_arg (args, int);
handle = va_arg (args, XML *);
xml_setnum (handle, "last-write", fwrite (buffer, size, number, xml_getbin(handle)));
return NULL;
}
XML * LIST_localdir_attach_cancel (WFTK_ADAPTOR * ad, va_list args) {
XML * handle;
if (!args) {
xml_set (ad->parms, "error", "No arguments given.");
return NULL;
}
handle = va_arg (args, XML *);
fclose (xml_getbin (handle));
unlink (xml_attrval (handle, "tempfile"));
return NULL;
}
XML * LIST_localdir_attach_close (WFTK_ADAPTOR * ad, va_list args) {
XML * handle;
if (!args) {
xml_set (ad->parms, "error", "No arguments given.");
return NULL;
}
handle = va_arg (args, XML *);
fclose (xml_getbin (handle));
rename (xml_attrval (handle, "tempfile"), xml_attrval (handle, "file"));
return NULL;
}
|
XML * LIST_localdir_retrieve_open (WFTK_ADAPTOR * ad, va_list args) {
XML * list = NULL;
XML * fld;
char * key;
char * field;
char * ver;
XML * mark;
XML * ret;
void * sess;
FILE * file;
WFTK_ADAPTOR * ad2;
if (args) list = va_arg (args, XML *);
if (!list) {
xml_set (ad->parms, "error", "No list given.");
return (XML *) 0;
}
key = va_arg (args, char *);
fld = va_arg (args, XML *);
xml_setf (ad->parms, "spec", "localdir:%s", xml_attrval (list, "id"));
ret = xml_create ("attachment-handle");
mark = xml_search (ad->session, "wftk-session", NULL, NULL);
if (mark) { /* Copy wftk session pointer into our attachment handle, because we'll be using that as a substitute repdef. */
sess = xml_getbin (mark);
mark = xml_create ("wftk-session");
xml_setbin (mark, sess, NULL);
xml_append (ret, mark);
}
xml_set (ret, "dir", xml_attrval (ad->parms, "basedir"));
if (!*xml_attrval (ad->parms, "subdir")) xml_set (ad->parms, "subdir", xml_attrval (list, "id"));
if (strcmp (xml_attrval (ad->parms, "subdir"), ".")) {
xml_attrcat (ret, "dir", xml_attrval (ad->parms, "subdir"));
xml_attrcat (ret, "dir", "/");
}
xml_setf (ret, "adaptor", "localdir:%s", xml_attrval (ret, "dir"));
if (fld) {
xml_set (ret, "location", xml_attrval (fld, "location"));
}
if (!*xml_attrval (ret, "location")) xml_setf (ret, "location", "_att_%s_%s_%s.dat", key, xml_attrval (fld, "id"), xml_attrval (fld, "ver"));
xml_setf (ret, "file", "%s%s", xml_attrval (ret, "dir"), xml_attrval (ret, "location"));
file = fopen (xml_attrval (ret, "file"), "r");
if (!file) {
xml_setf (ad->parms, "error", "Unable to open file %s for reading.", xml_attrval (ret, "location"));
xml_free (ret);
return NULL;
}
mark = xml_create ("reader");
xml_append (ret, mark);
xml_setbin (mark, (void *) fread, NULL);
xml_setbin (ret, file, (XML_SETBIN_FREE_FN *) fclose);
xml_set (ret, "content-type", "text/plain");
return (ret);
}
XML * LIST_localdir_retrieve_read (WFTK_ADAPTOR * ad, va_list args) {
void * buffer;
long size, number;
XML * handle;
XML * reader;
int bytes;
int (*read_fn) (void *, int, int, void *);
if (!args) {
xml_set (ad->parms, "error", "No arguments given.");
return NULL;
}
buffer = va_arg (args, void *);
size = va_arg (args, long);
number = va_arg (args, long);
handle = va_arg (args, XML *);
reader = xml_loc (handle, ".reader");
if (reader) read_fn = xml_getbin (reader);
else read_fn = fread;
bytes = (*read_fn) (buffer, size, number, xml_getbin(handle));
xml_setnum (handle, "last-read", bytes);
return NULL;
}
XML * LIST_localdir_retrieve_close (WFTK_ADAPTOR * ad, va_list args) {
XML * handle;
if (!args) {
xml_set (ad->parms, "error", "No arguments given.");
return NULL;
}
handle = va_arg (args, XML *);
fclose (xml_getbin (handle));
return NULL;
}
|
| This code and documentation are released under the terms of the GNU license. They are additionally copyright (c) 2001, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. This presentation was prepared with LPML. Try literate programming. You'll like it. |