HEAD: remove ridiculous dependency of wvmapi (actually wvtnef) on evolution
[wvapps.git] / funfs / wvfuse.cc
blobfb8e69e25880a9425a70ab534760196fd59f2584
1 /*
2 * WvFUSE: A WvStreams library for FUSE.
3 * Copyright (C) 2002 Net Integration Technologies, Inc.
5 * This program can be distributed under the terms of the GNU GPL.
6 * See the file COPYING.
8 * This class implements the main FUSE functions: creating the filesystem,
9 * reading commands, creating objects to process the commands, maintaining
10 * nodes, etc.
13 #include "wvfuse.h"
14 #include "wvfusecmd.h"
16 #include <errno.h>
17 #include <unistd.h>
20 WvFuse::WvFuse(WvFS *_fs, UniConf &_cfg)
21 : WvFuseInoMgr(_cfg), fs(_fs), log("WvFuse", WvLog::Debug4), s(dup(0))
23 WvString realver = getenv(FUSE_KERNEL_VERSION_ENV);
24 WvString verstr(FUSE_KERNEL_VERSION);
26 if (realver != verstr)
27 log(WvLog::Warning, "FUSE version mismatch: using %s, kernel is %s\n",
28 realver, verstr);
30 fs_unmounted = false;
32 fs->set_message_callback(WvFSMessageCB(this, &WvFuse::message_handler));
34 append(&s, false);
38 WvFuse::~WvFuse()
40 log(WvLog::Info, "WvFuse dying.\n");
41 zap();
45 int WvFuse::getfd() const
47 return s.getfd();
51 void WvFuse::send_reply_raw(char *outbuf, size_t outsize)
53 fuse_out_header *out = (fuse_out_header *) outbuf;
54 log(WvLog::Debug5, " unique: %s error: %s (%s) outsize: %s\n", out->unique,
55 out->error, strerror(-out->error), outsize);
57 // We have to use uwrite here, because we don't want an
58 // unsuccessful write to buffer.
59 int res = s.uwrite(outbuf, outsize);
61 if (!res && geterr())
62 log(WvLog::Error, "Error writing to device.\n");
66 bool WvFuse::isok() const
68 if (fs_unmounted)
69 return false;
70 return WvStreamList::isok();
74 void WvFuse::do_invalidate(fino_t ino)
76 size_t outsize = sizeof(fuse_out_header) + sizeof(ino);
77 char *outbuf = new char[outsize];
79 fuse_out_header *out = (fuse_out_header *)outbuf;
81 out->unique = 0;
82 out->error = 0;
84 memcpy(outbuf + sizeof(fuse_out_header), &ino, sizeof(ino));
86 send_reply_raw(outbuf, outsize);
87 delete[] outbuf;
91 void WvFuse::message_handler(int type, WvStringParm path)
93 switch (type)
95 case FUSE_INVAL_FD:
97 log(WvLog::Debug2, "Got invalidation message for fd %s\n",
98 path);
99 fino_t ino = get_ino_by_fd(atoi(path.cstr()));
100 if (!ino)
101 log(WvLog::Error, "Bad invalidating message! (fd = %s)\n",
102 path);
103 else
104 do_invalidate(ino);
106 break;
107 case FUSE_INVAL_PATH:
109 log(WvLog::Debug2, "Got invalidation message for path %s\n", path);
110 fino_t ino = get_ino_by_path(path);
111 if (!ino)
112 log(WvLog::Error, "Bad invalidating message! (path = %s)\n",
113 path);
114 else
115 do_invalidate(ino);
117 break;
118 default:
119 log(WvLog::Warning, "Unhandler message type [%s]\n", type);
120 break;
125 void WvFuse::execute()
127 WvStreamList::execute();
128 if (s.select(0, true, false, false))
130 char *cmd = new char[FUSE_MAX_IN];
131 int res = s.read(cmd, FUSE_MAX_IN);
132 if (!res)
134 /* ENODEV means we got unmounted, so we silenty return failure */
135 if (s.geterr() != ENODEV)
137 log(WvLog::Error, "Error reading device\n");
138 /* BAD... This will happen again */
140 fs_unmounted = true;
141 delete cmd;
142 return;
145 if ((size_t) res < sizeof(fuse_in_header))
147 log(WvLog::Error, "Short read on fuse device\n");
148 /* Cannot happen */ /* Yeah, right! */
149 delete cmd;
150 return;
153 WvFuseCmd *fusecmd = new WvFuseCmd(this, fs, cmd);
154 append(fusecmd, true);