2 #include "funfscodecs.h"
4 // Only used for cachefs message type translation
8 #include <wvistreamlist.h>
12 memcpy(&x, xinbuf.get(sizeof(x)), sizeof(x)); \
21 #define CHECKERROR() \
26 { RETURN(-errcode); } \
30 #define MAYBECHECKERROR() \
32 if (xinbuf.used() == sizeof(uint16)) \
48 #define CONTINUE_SELECT() \
50 context->continue_select(-1); \
51 } while (!context->alarm_was_ticking)
54 uint16
FunFS::jobid
= 1;
57 FunFS::FunFS(UniConf _cfg
)
58 : WvStreamClone(NULL
), mycloned((WvTCPConn
*)cloned
),
59 log("FunFS", WvLog::Info
), jobmap(255), cfg(_cfg
)
63 uses_continue_select
= true;
65 cloned
= new WvTCPConn(cfg
["Hostname"].get(), cfg
["Port"].getint());
66 WvIStreamList::globallist
.append(this, false);
68 setcallback(WvStreamCallback(this, &FunFS::line_mode_execute
), NULL
);
70 log("FunFS Initialized!\n");
75 terminate_continue_select();
77 log("FunFS Destructor!\n");
80 bool FunFS::isok() const
82 if (ok
&& cloned
&& mycloned
->isconnected() && !cloned
->isok())
84 log(WvLog::Error
, "Connection to %s lost!\n", *mycloned
->src());
87 else if (ok
&& cloned
&& !cloned
->isok())
89 log(WvLog::Error
, "Connecting to %s: %s\n", *mycloned
->src(),
96 size_t FunFS::write(WvStream
*job
, WvBuf
&inbuf
)
98 if (jobmap
.exists(jobid
))
100 log(WvLog::Error
, "Expiring job #%s\n", (int)jobid
);
101 jobmap
.remove(jobid
);
104 log("Adding a new job #%s\n", (int)jobid
);
106 jobmap
.add(jobid
, job
);
109 cloned
->write(SWAP16(&temp
), sizeof(temp
));
114 //fprintf(stderr, "writing %d bytes\n", inbuf.used());
115 size_t r
= cloned
->write(inbuf
);
123 void FunFS::line_mode_execute(WvStream
&, void *)
125 WvString line
= getline(2000);
129 log(WvLog::Error
, "Connection to %s timed out.\n", *mycloned
->src());
133 if (!strstr(line
.cstr(), "FunFS"))
135 log(WvLog::Error
, "%s is not a FunFS server.\n", *mycloned
->src());
139 // Switch to data mode
140 mycloned
->delay_output(true);
142 setcallback(WvStreamCallback(this, &FunFS::data_mode_execute
), NULL
);
145 void FunFS::data_mode_execute(WvStream
&, void *)
149 log(WvLog::Error
, "Oh-oh! Somebody was slacking on reads!\n");
159 log("FunFS::execute: replyid = %s, clength = %s\n", replyid
, clength
);
161 size_t r
= continue_read(-1, xinbuf
, clength
);
162 assert(r
== clength
);
170 void FunFS::got_reply(uint16 replyid
)
172 if (jobmap
.exists(replyid
))
174 // Wake up the guy who's reply this is
175 jobmap
[replyid
]->alarm(0);
179 } while (!alarm_was_ticking
);
181 jobmap
.remove(replyid
);
184 log(WvLog::Error
, "Unknown jobid %s!\n", (int)replyid
);
187 void FunFS::got_message()
190 int jobtype
= xinbuf
.getch();
191 WvString path
= xinbuf
.getstr(xinbuf
.strchr('\0'));
193 log(WvLog::Debug3
, "<BOB> got a message of type [%s], path = '%s'!\n",
199 messagecb(MT_GETATTR
, path
);
203 messagecb(MT_READLINK
, path
);
207 log(WvLog::Error
, "<BOB> unknown message type\n");
212 log(WvLog::Warning
, "<BOB> Discarding %s bytes.\n", xinbuf
.used());
219 /******************************************************************/
221 int FunFS::fs_getattr(CONTEXT
, PATH
, struct fuse_attr
*attr
)
225 xoutbuf
.putch(JT_GETATTR
);
228 write(context
, xoutbuf
);
234 decode_fuse_attr(xinbuf
, attr
);
239 int FunFS::fs_getdir(CONTEXT
, PATH
, WvFuseDirCb
&cb
)
241 xoutbuf
.putch(JT_GETDIR
);
244 write(context
, xoutbuf
);
252 while (xinbuf
.used())
254 decode_fuse_dirent(xinbuf
, &fde
);
261 int FunFS::fs_open(CONTEXT
, PATH
, int flags
)
263 xoutbuf
.putch(JT_OPEN
);
265 xoutbuf
.put(SWAP32(&flags
), 4);
267 write(context
, xoutbuf
);
278 int FunFS::fs_release(CONTEXT
, FD
)
280 // FIXME: this should not even wait for a responce
281 xoutbuf
.putch(JT_RELEASE
);
283 xoutbuf
.put(SWAP32(&fd
), 4);
285 write(context
, xoutbuf
);
292 int FunFS::fs_read(CONTEXT
, FD
, char *chbuf
, size_t size
, off_t offset
)
294 xoutbuf
.putch(JT_READ
);
296 xoutbuf
.put(SWAP32(&fd
), 4);
297 xoutbuf
.put(SWAP32(&size
), 4);
298 xoutbuf
.put(SWAP32(&offset
), 4);
300 write(context
, xoutbuf
);
304 size_t r
= xinbuf
.used();
305 memcpy(chbuf
, xinbuf
.get(r
), r
);
310 int FunFS::fs_readlink(CONTEXT
, PATH
, char *chbuf
, size_t size
)
314 xoutbuf
.putch(JT_READLINK
);
317 write(context
, xoutbuf
);
323 strncpy(chbuf
, xinbuf
.getstr(), size
);
328 int FunFS::fs_statfs(CONTEXT
, struct fuse_kstatfs
*fst
)
330 log(WvLog::Debug4
, "fs_statfs called\n");
332 xoutbuf
.putch(JT_STATFS
);
334 write(context
, xoutbuf
);
339 decode_fuse_kstatfs(xinbuf
, fst
);
344 int FunFS::fs_symlink(CONTEXT
, PATH
, WvStringParm to
)
347 log(WvLog::Error
, "fs_symlink not implemented!\n");
350 int res = symlink(path, to);
358 int FunFS::fs_truncate(CONTEXT
, FD
, off_t size
)
361 log(WvLog::Error
, "fs_truncate not implemented!\n");
364 int res = truncate(path, size);
372 int FunFS::fs_unlink(CONTEXT
, PATH
)
375 log(WvLog::Error
, "fs_unlink not implemented!\n");
378 int res = unlink(path);
386 int FunFS::fs_utime(CONTEXT
, PATH
, struct utimbuf
*utbuf
)
390 buf.putch(JT_READLINK);
391 buf.put(path, path.len() + 1);
397 uint32 actime = 0, modtime = 0;
404 utbuf->actime = actime;
405 utbuf->modtime = modtime;
410 fprintf(stderr, "Updating utime not implemented yet.\n");
417 int FunFS::fs_write(CONTEXT
, FD
, const char *buf
,
418 size_t size
, off_t offset
)
421 log(WvLog::Error
, "fs_write not implemented!\n");
427 fd = open(path, O_WRONLY);
431 res = pwrite(fd, buf, size, offset);
443 int FunFS::fs_chmod(CONTEXT
, PATH
, mode_t mode
)
446 log(WvLog::Error
, "fs_chmod not implemented!\n");
451 res = chmod(path, mode);
459 int FunFS::fs_chown(CONTEXT
, PATH
, uid_t uid
, gid_t gid
)
462 log(WvLog::Error
, "fs_chown not implemented!\n");
467 res = lchown(path, uid, gid);
475 int FunFS::fs_rename(CONTEXT
, PATH
, WvStringParm to
)
478 log(WvLog::Error
, "fs_rename not implemented!\n");
481 int res = rename(path, to);
490 int FunFS::fs_mkdir(CONTEXT
, PATH
, mode_t mode
)
493 log(WvLog::Error
, "fs_mkdir not implemented!\n");
498 res = mkdir(path, mode);
506 int FunFS::fs_mknod(CONTEXT
, PATH
, mode_t mode
, dev_t rdev
)
509 log(WvLog::Error
, "fs_mknod not implemented!\n");
512 int res = mknod(path, mode, rdev);
520 int FunFS::fs_link(CONTEXT
, PATH
, WvStringParm to
)
525 buf.put(path, path.len() + 1);
526 buf.put(to, to.len() + 1);
533 //READCLENGTH("link");
535 // For now we should always get an error.
543 int FunFS::fs_rmdir(CONTEXT
, PATH
)
546 log(WvLog::Error
, "fs_rmdir not implemented!\n");
549 int res = rmdir(path);