summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2009-11-02 19:41:53 +0000
committerrandomdan <randomdan@localhost>2009-11-02 19:41:53 +0000
commit91d3c5f829804636ff9e1012132babe7226a97a5 (patch)
tree3a45e80f27be85c04dae2699bb5833859f94d2b4
parentAll basic funcs implemented, not tested (diff)
downloadnetfs-91d3c5f829804636ff9e1012132babe7226a97a5.tar.bz2
netfs-91d3c5f829804636ff9e1012132babe7226a97a5.tar.xz
netfs-91d3c5f829804636ff9e1012132babe7226a97a5.zip
Single msg read dir and reconnects
-rw-r--r--netfs/daemon.cpp73
-rw-r--r--netfs/daemonDirs.cpp14
-rw-r--r--netfs/fuse.cpp80
-rw-r--r--netfs/fuse.h13
-rw-r--r--netfs/fuseDirs.cpp7
-rw-r--r--netfs/msgtypes.cpp30
-rw-r--r--netfs/msgtypes.h18
7 files changed, 141 insertions, 94 deletions
diff --git a/netfs/daemon.cpp b/netfs/daemon.cpp
index b029316..4876a1a 100644
--- a/netfs/daemon.cpp
+++ b/netfs/daemon.cpp
@@ -21,8 +21,32 @@ void Sender::Send(DataPayloadPtr p)
r->write(host);
}
+class TempUserChange {
+ public:
+ TempUserChange(uid_t u, gid_t g) :
+ ogid(getegid()),
+ ouid(geteuid())
+ {
+ errno = 0;
+ setegid(g);
+ seteuid(u);
+ }
+ ~TempUserChange()
+ {
+ setegid(ogid);
+ seteuid(ouid);
+ }
+ private:
+ gid_t ogid;
+ uid_t ouid;
+};
+
#define TRYCLASS(cls) \
- if (type == cls::TypeID) { handle(p->data.as<TypedPayload<cls> >(), s); }
+ if (type == cls::TypeID) { \
+ TypedPayload<cls>::Ptr tp = p->data.as<TypedPayload<cls> >(); \
+ TempUserChange tuc(tp->data.uid, tp->data.gid); \
+ handle(tp, s); \
+ }
void
runDaemonOn(FILE * f, DaemonConfigPtr, DaemonGlobalStatePtr)
@@ -65,31 +89,32 @@ runDaemonOn(FILE * f, DaemonConfigPtr, DaemonGlobalStatePtr)
int main(int, char* [])
{
DaemonConfigPtr dc = DaemonConfig::Load("daemon.xml");
- struct addrinfo hints;
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE;
- struct addrinfo *result, *rp;
- int s = getaddrinfo(NULL, dc->tcpPort.c_str(), &hints, &result);
- if (s) {
- // Error
- }
- for (rp = result; rp != NULL; rp = rp->ai_next) {
- int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
- if (sfd == -1)
- continue;
- if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) {
- if (listen(sfd, 5)) {
- // Error
- }
- DaemonGlobalStatePtr dgs = new DaemonGlobalState();
- for (int newfd; (newfd = accept(sfd, NULL, NULL)) > 0; ) {
- runDaemonOn(fdopen(newfd, "a+"), dc, dgs);
+ DaemonGlobalStatePtr dgs = new DaemonGlobalState();
+ while (true) {
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ struct addrinfo *result, *rp;
+ if (getaddrinfo(NULL, dc->tcpPort.c_str(), &hints, &result) == 0) {
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (sfd == -1)
+ continue;
+ if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) {
+ if (listen(sfd, 5)) {
+ // Error
+ continue;
+ }
+ for (int newfd; (newfd = accept(sfd, NULL, NULL)) > 0; ) {
+ runDaemonOn(fdopen(newfd, "a+"), dc, dgs);
+ }
+ break;
+ }
+ close(sfd);
}
- break;
}
- close(sfd);
}
return 0;
}
diff --git a/netfs/daemonDirs.cpp b/netfs/daemonDirs.cpp
index 89b2426..20ab82d 100644
--- a/netfs/daemonDirs.cpp
+++ b/netfs/daemonDirs.cpp
@@ -37,27 +37,19 @@ handler(CloseDirRequest)
}
s.Send(r);
}
-typedef TypedPayload<ReadDirContent>::Ptr DirContPLPtr;
-typedef TypedPayload<ReadDirContent> DirContPL;
-typedef std::set<DirContPLPtr> DirContPLs;
handler(ReadDirRequest)
{
TypedPayload<ReadDirRequest::Reply> * r = new TypedPayload<ReadDirRequest::Reply>();
if (dirs.find(req->data.handle) != dirs.end()) {
errno = 0;
dirent * d;
- DirContPLs ds;
while ((d = readdir(dirs[req->data.handle])) && errno == 0) {
- DirContPLPtr dc = new DirContPL();
- dc->data.path = d->d_name;
- ds.insert(dc);
+ r->data.entries.push_back(ReadDirReply::Entry());
+ r->data.entries.back().path = d->d_name;
+ stat("/", &r->data.entries.back().val);
}
r->data.error = errno;
- r->data.count = ds.size();
s.Send(r);
- foreach(DirContPLs::const_iterator, ds, dir) {
- s.Send(*dir);
- }
}
else {
r->data.error = EBADF;
diff --git a/netfs/fuse.cpp b/netfs/fuse.cpp
index c540af1..ceb5cb3 100644
--- a/netfs/fuse.cpp
+++ b/netfs/fuse.cpp
@@ -4,6 +4,7 @@
#include <errno.h>
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
#include "fuse.h"
static FuseAppBase * fuseApp;
@@ -71,27 +72,32 @@ static void fuseDestroy(void * x)
NetFS::NetFS() :
f(NULL)
{
- struct addrinfo hints;
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE;
- struct addrinfo *result, *rp;
- int s = getaddrinfo("localhost", "4000", &hints, &result);
- if (s) {
- // Error
- }
- for (rp = result; rp != NULL; rp = rp->ai_next) {
- int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
- if (sfd == -1)
- // Error
- continue;
- if (connect(sfd, rp->ai_addr, rp->ai_addrlen)) {
- // Error
- continue;
+}
+void
+NetFS::connect()
+{
+ while (!f) {
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ struct addrinfo *result, *rp;
+ if (getaddrinfo("localhost", "4000", &hints, &result) == 0) {
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (sfd == -1)
+ // Error
+ continue;
+ if (::connect(sfd, rp->ai_addr, rp->ai_addrlen)) {
+ // Error
+ continue;
+ }
+ f = fdopen(sfd, "a+");
+ break;
+ }
}
- f = fdopen(sfd, "a+");
- break;
+ sleep(5);
}
}
NetFS::~NetFS()
@@ -103,20 +109,22 @@ NetFS::~NetFS()
DataPayloadPtr
NetFS::exchange(DataPayloadPtr dp)
{
- send(dp);
- return recv();
-}
-void
-NetFS::send(DataPayloadPtr dp)
-{
+ AutoMutex a(comms);
+ PacketPtr recvd;
PacketPtr sendme = new Packet(0, dp);
- sendme->write(f);
-}
-DataPayloadPtr
-NetFS::recv()
-{
- PacketPtr recvd = new Packet(f);
- return recvd->data;
+ connect();
+ while (true) {
+ try {
+ sendme->write(f);
+ recvd = new Packet(f);
+ return recvd->data;
+ }
+ catch (...) {
+ f = NULL;
+ connect();
+ }
+ }
+ return NULL;
}
template <class FuseApp>
@@ -165,7 +173,11 @@ int runFuseApp(int argc, char* argv[])
fuseCall<const char *, struct stat *, struct fuse_file_info *, &FuseAppBase::fgetattr>,
fuseCall<const char *, struct fuse_file_info *, int, struct flock *, &FuseAppBase::lock>,
fuseCall<const char *, const struct timespec [2], &FuseAppBase::utimens>,
- fuseCall<const char *, size_t, uint64_t *, &FuseAppBase::bmap>
+ fuseCall<const char *, size_t, uint64_t *, &FuseAppBase::bmap>,
+ NULL,
+ NULL,
+ NULL,
+ NULL
};
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
if (fuse_opt_parse(&args, fuseApp, fuse_opts,
diff --git a/netfs/fuse.h b/netfs/fuse.h
index dc0a124..f587da4 100644
--- a/netfs/fuse.h
+++ b/netfs/fuse.h
@@ -3,6 +3,7 @@
#include "fuseapp.h"
#include "comms.h"
+#include "threads.h"
class NetFS : public FuseAppBase
{
@@ -38,16 +39,10 @@ class NetFS : public FuseAppBase
NetFS();
~NetFS();
DataPayloadPtr exchange(DataPayloadPtr dp);
- void send(DataPayloadPtr dp);
- DataPayloadPtr recv();
- template <typename Type>
- SmartPointer<TypedPayload<Type> > recvType()
- {
- DataPayloadPtr p = this->recv();
- return p.as<TypedPayload<Type> >();
- }
private:
- FILE * f;
+ FILE * f;
+ void connect();
+ Mutex comms;
};
// this needs to go here to avoid circular includes regarding the net->exchange call
diff --git a/netfs/fuseDirs.cpp b/netfs/fuseDirs.cpp
index 17e4a3e..f756393 100644
--- a/netfs/fuseDirs.cpp
+++ b/netfs/fuseDirs.cpp
@@ -1,5 +1,6 @@
#include "fuse.h"
#include "msgtypes.h"
+#include "misc.h"
int
NetFS::opendir(const char * p, struct fuse_file_info * fi)
@@ -24,10 +25,8 @@ NetFS::readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct f
TypedPayloadReq<ReadDirRequest>::Ptr msg = new TypedPayloadReq<ReadDirRequest>(fuse_get_context());
msg->data.handle = fi->fh;
TypedPayload<ReadDirReply>::Ptr rep = msg->exchange(this);
- size_t cnt = rep->data.count;
- while (cnt--) {
- TypedPayload<ReadDirContent>::Ptr dir = recvType<ReadDirContent>();
- filler(buf, dir->data.path.c_str(), &dir->data.val, 0);
+ foreach (std::vector<ReadDirReply::Entry>::const_iterator, rep->data.entries, e) {
+ filler(buf, e->path.c_str(), &e->val, 0);
}
return -rep->data.error;
}
diff --git a/netfs/msgtypes.cpp b/netfs/msgtypes.cpp
index 9ac6b04..6ea3c80 100644
--- a/netfs/msgtypes.cpp
+++ b/netfs/msgtypes.cpp
@@ -1,5 +1,6 @@
#include "msgtypes.h"
#include "xfers.h"
+#include "misc.h"
MessageFactories & MsgFacs()
{
@@ -69,7 +70,6 @@ RequestBase::Read(FILE*f)
}
Xfer1(3, OpenDirRequest, RequestBase, path)
Xfer2(4, OpenDirReply, ContentBase, error, handle)
-Xfer2(5, ReadDirReply, ContentBase, error, count)
Xfer1(6, ReadDirRequest, RequestBase, handle)
Xfer2(7, AccessRequest, RequestBase, path, access)
Xfer1(8, SimpleInt, ContentBase, value)
@@ -77,7 +77,6 @@ Xfer1(9, GetAttrRequest, RequestBase, path)
Xfer2(10, GetAttrReply, ContentBase, res, val)
Xfer1(11, CloseDirRequest, RequestBase, handle)
Xfer1(12, CloseDirReply, ContentBase, error)
-Xfer2(13, ReadDirContent, ContentBase, path, val)
Xfer1(14, OpenRequest, RequestBase, path)
Xfer2(15, OpenReply, ContentBase, error, handle)
Xfer1(16, CloseRequest, RequestBase, handle)
@@ -101,6 +100,33 @@ Xfer1(33, FgetAttrRequest, RequestBase, handle)
Xfer2(34, CreateRequest, RequestBase, path, mode)
Xfer1(35, RmDirRequest, RequestBase, path)
+MSGTYPE(5, ReadDirReply)
+void
+ReadDirReply::Send(FILE*f) const
+{
+ ContentBase::Send(f);
+ *f << error;
+ *f << entries.size();
+ foreach (Entries::const_iterator, entries, e) {
+ *f << e->path;
+ *f << e->val;
+ }
+}
+void
+ReadDirReply::Read(FILE*f)
+{
+ ContentBase::Read(f);
+ *f >> error;
+ size_t count;
+ *f >> count;
+ entries.resize(count);
+ while (count) {
+ count -= 1;
+ *f >> entries[count].path;
+ *f >> entries[count].val;
+ }
+}
+
MSGTYPE(2, ReadReply)
ReadReply::~ReadReply()
{
diff --git a/netfs/msgtypes.h b/netfs/msgtypes.h
index 71909cc..0f7b3f0 100644
--- a/netfs/msgtypes.h
+++ b/netfs/msgtypes.h
@@ -5,6 +5,7 @@
#include "comms.h"
#include <map>
#include <string>
+#include <vector>
#include <sys/stat.h>
#include <stdint.h>
@@ -117,8 +118,14 @@ class CloseDirRequest : public RequestBase {
class ReadDirReply : public ContentBase {
public:
+ class Entry {
+ public:
+ std::string path;
+ struct stat val;
+ };
+ typedef std::vector<Entry> Entries;
int error;
- size_t count;
+ Entries entries;
const static uint16_t TypeID;
virtual void Send(FILE*) const;
virtual void Read(FILE*);
@@ -133,15 +140,6 @@ class ReadDirRequest : public RequestBase {
virtual void Read(FILE*);
};
-class ReadDirContent : public ContentBase {
- public:
- std::string path;
- struct stat val;
- const static uint16_t TypeID;
- virtual void Send(FILE*) const;
- virtual void Read(FILE*);
-};
-
class OpenReply : public ContentBase {
public:
int error;