diff options
| author | randomdan <randomdan@localhost> | 2009-11-02 19:41:53 +0000 | 
|---|---|---|
| committer | randomdan <randomdan@localhost> | 2009-11-02 19:41:53 +0000 | 
| commit | 91d3c5f829804636ff9e1012132babe7226a97a5 (patch) | |
| tree | 3a45e80f27be85c04dae2699bb5833859f94d2b4 | |
| parent | All basic funcs implemented, not tested (diff) | |
| download | netfs-91d3c5f829804636ff9e1012132babe7226a97a5.tar.bz2 netfs-91d3c5f829804636ff9e1012132babe7226a97a5.tar.xz netfs-91d3c5f829804636ff9e1012132babe7226a97a5.zip  | |
Single msg read dir and reconnects
| -rw-r--r-- | netfs/daemon.cpp | 73 | ||||
| -rw-r--r-- | netfs/daemonDirs.cpp | 14 | ||||
| -rw-r--r-- | netfs/fuse.cpp | 80 | ||||
| -rw-r--r-- | netfs/fuse.h | 13 | ||||
| -rw-r--r-- | netfs/fuseDirs.cpp | 7 | ||||
| -rw-r--r-- | netfs/msgtypes.cpp | 30 | ||||
| -rw-r--r-- | netfs/msgtypes.h | 18 | 
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;  | 
