[examples] Stream based filelister daemon implementation;

v0.5.xx
Alexander Vdolainen 9 years ago
parent 6534dda8a0
commit f0c6a641ad

@ -46,4 +46,6 @@
#define FREE(x) { if (x) { free(x); x = NULL; } } #define FREE(x) { if (x) { free(x); x = NULL; } }
#define MAX_STREAMS INT_MAX #define MAX_STREAMS INT_MAX
#define DIRLIST_ID 1
#endif /*__SXMP_EXAMPLES_FILELIST_H__*/ #endif /*__SXMP_EXAMPLES_FILELIST_H__*/

@ -54,6 +54,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <tdata/usrtc.h> #include <tdata/usrtc.h>
#include <tdata/list.h>
#include <sexpr/sexp.h> #include <sexpr/sexp.h>
#include <sxmp/limits.h> #include <sxmp/limits.h>
#include <sxmp/sxmp.h> #include <sxmp/sxmp.h>
@ -119,6 +120,109 @@ static int __ping(void *m, sexp_t *sx)
return sxmsg_return((sxmsg_t*)m, SXE_SUCCESS); return sxmsg_return((sxmsg_t*)m, SXE_SUCCESS);
} }
/* dir listing stream */
typedef struct __dirlist_type {
DIR *dp;
struct dirent dent;
struct dirent *dres;
} dirlist_t;
static int dirlist_open(sxlink_t *link, struct sxstream_opened *stream,
const char *dirname)
{
dirlist_t *pslist = malloc(sizeof(dirlist_t));
if(!pslist) return SXE_ENOMEM;
else memset(pslist, 0, sizeof(dirlist_t));
if(!(pslist->dp = opendir(dirname ? dirname : "./"))) {
free(pslist);
return SXE_FAILED;
} else sxstream_opened_setpriv(stream, pslist);
return SXE_SUCCESS;
}
static int dirlist_close(struct sxstream_opened *stream)
{
dirlist_t *pslist = sxstream_opened_getpriv(stream);
list_head_t *llist = sxstream_opened_getelist(stream);
if(!pslist) return SXE_FAILED;
if(llist) sxstream_generic_slist_free(llist);
/* close dir and free strcuture */
if(pslist->dp) closedir(pslist->dp);
free(pslist);
return SXE_SUCCESS;
}
static inline const char *dump_type(struct dirent *d)
{
if(!d) return "nil";
switch(d->d_type) {
case DT_REG: return "regular";
case DT_DIR: return "directory";
case DT_BLK: return "block";
case DT_CHR: return "char";
case DT_FIFO: return "fifo";
case DT_LNK: return "link";
case DT_UNKNOWN: return "unknown";
default: return "another";
}
return "nil";
}
static size_t dirlist_read(struct sxstream_opened *stream, size_t sz, uint64_t off,
list_head_t **rlist)
{
dirlist_t *pslist = sxstream_opened_getpriv(stream);
list_head_t *llist_prev = sxstream_opened_getelist(stream);
list_head_t *llist_new = NULL;
if(!pslist || !llist_new) return -1;
/* read and fill new list */
if(readdir_r(pslist->dp, &(pslist->dent), &(pslist->dres)))
return -1;
/* if finished return 0 */
if(!pslist->dres) return 0;
/* allocate a new */
if(!(llist_new = sxstream_generic_slist_alloc())) return -1;
else { /* fill this list */
if(sxstream_generic_slist_additem(llist_new, pslist->dres->d_name)) {
__fail:
sxstream_generic_slist_free(llist_new);
return -1;
}
if(sxstream_generic_slist_additem(llist_new, dump_type(pslist->dres)))
goto __fail;
}
/* otherwise destroy last list */
sxstream_generic_slist_free(llist_prev);
*rlist = llist_new; /* assign new list */
return 1;
}
static struct sxstream_ops dirlist_ops = {
.s_open = dirlist_open,
.s_close = dirlist_close,
.s_eread = dirlist_read,
.s_ewrite = NULL,
};
static struct sxstream_description dirlist_stream = {
.stid = DIRLIST_ID,
.pcid = READONLY_CHANNEL,
.type = 0, /* just a simple one */
.flags = SXE_O_READ | SXE_O_TRUNC,
.ops = &dirlist_ops,
};
/* command line options helpers */ /* command line options helpers */
static void __help_print(FILE *fso, const char *fmtname) static void __help_print(FILE *fso, const char *fmtname)
{ {
@ -252,7 +356,6 @@ int main(int argc, char **argv)
/* ok, let's add stream functions */ /* ok, let's add stream functions */
opt = sxmp_rpclist_add_function(fulist, READONLY_CHANNEL, "ping", __ping); opt = sxmp_rpclist_add_function(fulist, READONLY_CHANNEL, "ping", __ping);
if(opt) { if(opt) {
__fail:
fprintf(stderr, "Failed to add functions to typed RPC channel\n Failure.\n"); fprintf(stderr, "Failed to add functions to typed RPC channel\n Failure.\n");
return opt; return opt;
} }
@ -260,6 +363,9 @@ int main(int argc, char **argv)
/* ok, setup it */ /* ok, setup it */
sxhub_set_rpcvalidator(sxmphub, __rettlist); sxhub_set_rpcvalidator(sxmphub, __rettlist);
/* setup our stream */
sxhub_stream_register(sxmphub, &dirlist_stream);
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
/* now we're ready to run the listen process */ /* now we're ready to run the listen process */

Loading…
Cancel
Save