1/* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include "fuse_fs.h" 7 8#include <string.h> 9 10#include <new> 11 12#include "Debug.h" 13 14 15int 16fuse_fs_getattr(struct fuse_fs* fs, const char* path, struct stat* buf) 17{ 18 if (fs->ops.getattr == NULL) 19 return ENOSYS; 20 return fs->ops.getattr(path, buf); 21} 22 23 24int 25fuse_fs_fgetattr(struct fuse_fs* fs, const char* path, struct stat* buf, 26 struct fuse_file_info* fi) 27{ 28 if (fs->ops.fgetattr == NULL) 29 return ENOSYS; 30 return fs->ops.fgetattr(path, buf, fi); 31} 32 33 34int 35fuse_fs_rename(struct fuse_fs* fs, const char* oldpath, const char* newpath) 36{ 37 if (fs->ops.rename == NULL) 38 return ENOSYS; 39 return fs->ops.rename(oldpath, newpath); 40} 41 42 43int 44fuse_fs_unlink(struct fuse_fs* fs, const char* path) 45{ 46 if (fs->ops.unlink == NULL) 47 return ENOSYS; 48 return fs->ops.unlink(path); 49} 50 51 52int 53fuse_fs_rmdir(struct fuse_fs* fs, const char* path) 54{ 55 if (fs->ops.rmdir == NULL) 56 return ENOSYS; 57 return fs->ops.rmdir(path); 58} 59 60 61int 62fuse_fs_symlink(struct fuse_fs* fs, const char* linkname, const char* path) 63{ 64 if (fs->ops.symlink == NULL) 65 return ENOSYS; 66 return fs->ops.symlink(linkname, path); 67} 68 69 70int 71fuse_fs_link(struct fuse_fs* fs, const char* oldpath, const char* newpath) 72{ 73 if (fs->ops.link == NULL) 74 return ENOSYS; 75 return fs->ops.link(oldpath, newpath); 76} 77 78 79int 80fuse_fs_release(struct fuse_fs* fs, const char* path, 81 struct fuse_file_info* fi) 82{ 83 if (fs->ops.release == NULL) 84 return 0; 85 return fs->ops.release(path, fi); 86} 87 88 89int 90fuse_fs_open(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) 91{ 92 if (fs->ops.open == NULL) 93 return 0; 94 return fs->ops.open(path, fi); 95} 96 97 98int 99fuse_fs_read(struct fuse_fs* fs, const char* path, char *buf, size_t size, 100 off_t off, struct fuse_file_info* fi) 101{ 102 if (fs->ops.read == NULL) 103 return ENOSYS; 104 return fs->ops.read(path, buf, size, off, fi); 105} 106 107 108int 109fuse_fs_write(struct fuse_fs* fs, const char* path, const char* buf, 110 size_t size, off_t off, struct fuse_file_info* fi) 111{ 112 if (fs->ops.write == NULL) 113 return ENOSYS; 114 return fs->ops.write(path, buf, size, off, fi); 115} 116 117 118int 119fuse_fs_fsync(struct fuse_fs* fs, const char* path, int datasync, 120 struct fuse_file_info* fi) 121{ 122 if (fs->ops.fsync == NULL) 123 return ENOSYS; 124 return fs->ops.fsync(path, datasync, fi); 125} 126 127 128int 129fuse_fs_flush(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) 130{ 131 if (fs->ops.flush == NULL) 132 return ENOSYS; 133 return fs->ops.flush(path, fi); 134} 135 136 137int 138fuse_fs_statfs(struct fuse_fs* fs, const char* path, struct statvfs* buf) 139{ 140 if (fs->ops.statfs == NULL) 141 return 0; 142 return fs->ops.statfs(path, buf); 143} 144 145 146int 147fuse_fs_opendir(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi) 148{ 149 if (fs->ops.opendir == NULL) 150 return 0; 151 return fs->ops.opendir(path, fi); 152} 153 154 155int 156fuse_fs_readdir(struct fuse_fs* fs, const char* path, void* buf, 157 fuse_fill_dir_t filler, off_t off, struct fuse_file_info* fi) 158{ 159 if (fs->ops.readdir == NULL) 160 return ENOSYS; 161 return fs->ops.readdir(path, buf, filler, off, fi); 162} 163 164 165int 166fuse_fs_fsyncdir(struct fuse_fs* fs, const char* path, int datasync, 167 struct fuse_file_info* fi) 168{ 169 if (fs->ops.fsyncdir == NULL) 170 return ENOSYS; 171 return fs->ops.fsyncdir(path, datasync, fi); 172} 173 174 175int 176fuse_fs_releasedir(struct fuse_fs* fs, const char* path, 177 struct fuse_file_info* fi) 178{ 179 if (fs->ops.releasedir == NULL) 180 return 0; 181 return fs->ops.releasedir(path, fi); 182} 183 184 185int 186fuse_fs_create(struct fuse_fs* fs, const char* path, mode_t mode, 187 struct fuse_file_info* fi) 188{ 189 if (fs->ops.create == NULL) 190 return ENOSYS; 191 return fs->ops.create(path, mode, fi); 192} 193 194 195int 196fuse_fs_lock(struct fuse_fs* fs, const char* path, struct fuse_file_info* fi, 197 int cmd, struct flock* lock) 198{ 199 if (fs->ops.lock == NULL) 200 return ENOSYS; 201 return fs->ops.lock(path, fi, cmd, lock); 202} 203 204 205int 206fuse_fs_chmod(struct fuse_fs* fs, const char* path, mode_t mode) 207{ 208 if (fs->ops.chmod == NULL) 209 return ENOSYS; 210 return fs->ops.chmod(path, mode); 211} 212 213 214int 215fuse_fs_chown(struct fuse_fs* fs, const char* path, uid_t uid, gid_t gid) 216{ 217 if (fs->ops.chown == NULL) 218 return ENOSYS; 219 return fs->ops.chown(path, uid, gid); 220} 221 222 223int 224fuse_fs_truncate(struct fuse_fs* fs, const char* path, off_t size) 225{ 226 if (fs->ops.truncate == NULL) 227 return ENOSYS; 228 return fs->ops.truncate(path, size); 229} 230 231 232int 233fuse_fs_ftruncate(struct fuse_fs* fs, const char* path, off_t size, 234 struct fuse_file_info* fi) 235{ 236 if (fs->ops.ftruncate == NULL) 237 return ENOSYS; 238 return fs->ops.ftruncate(path, size, fi); 239} 240 241 242int 243fuse_fs_utimens(struct fuse_fs* fs, const char* path, 244 const struct timespec tv[2]) 245{ 246 if (fs->ops.utimens != NULL) 247 return fs->ops.utimens(path, tv); 248 249 if (fs->ops.utime != NULL) { 250 utimbuf timeBuffer = { 251 tv[0].tv_sec, // access time 252 tv[1].tv_sec // modification time 253 }; 254 return fs->ops.utime(path, &timeBuffer); 255 } 256 257 return ENOSYS; 258} 259 260 261int 262fuse_fs_access(struct fuse_fs* fs, const char* path, int mask) 263{ 264 if (fs->ops.access == NULL) 265 return ENOSYS; 266 return fs->ops.access(path, mask); 267} 268 269 270int 271fuse_fs_readlink(struct fuse_fs* fs, const char* path, char* buf, size_t len) 272{ 273 if (fs->ops.readlink == NULL) 274 return ENOSYS; 275 return fs->ops.readlink(path, buf, len); 276} 277 278 279int 280fuse_fs_mknod(struct fuse_fs* fs, const char* path, mode_t mode, dev_t rdev) 281{ 282 if (fs->ops.mknod == NULL) 283 return ENOSYS; 284 return fs->ops.mknod(path, mode, rdev); 285} 286 287 288int 289fuse_fs_mkdir(struct fuse_fs* fs, const char* path, mode_t mode) 290{ 291 if (fs->ops.mkdir == NULL) 292 return ENOSYS; 293 return fs->ops.mkdir(path, mode); 294} 295 296 297int 298fuse_fs_setxattr(struct fuse_fs* fs, const char* path, const char* name, 299 const char* value, size_t size, int flags) 300{ 301 if (fs->ops.setxattr == NULL) 302 return ENOSYS; 303 return fs->ops.setxattr(path, name, value, size, flags); 304} 305 306 307int 308fuse_fs_getxattr(struct fuse_fs* fs, const char* path, const char* name, 309 char* value, size_t size) 310{ 311 if (fs->ops.getxattr == NULL) 312 return ENOSYS; 313 return fs->ops.getxattr(path, name, value, size); 314} 315 316 317int 318fuse_fs_listxattr(struct fuse_fs* fs, const char* path, char* list, size_t size) 319{ 320 if (fs->ops.listxattr == NULL) 321 return ENOSYS; 322 return fs->ops.listxattr(path, list, size); 323} 324 325 326int 327fuse_fs_removexattr(struct fuse_fs* fs, const char* path, const char* name) 328{ 329 if (fs->ops.removexattr == NULL) 330 return ENOSYS; 331 return fs->ops.removexattr(path, name); 332} 333 334 335int 336fuse_fs_bmap(struct fuse_fs* fs, const char* path, size_t blocksize, 337 uint64_t* idx) 338{ 339 if (fs->ops.bmap == NULL) 340 return ENOSYS; 341 return fs->ops.bmap(path, blocksize, idx); 342} 343 344 345int fuse_fs_ioctl(struct fuse_fs *fs, const char *path, int cmd, void *arg, 346 struct fuse_file_info *fi, unsigned int flags, void *data) 347{ 348 if (fs->ops.ioctl == NULL) 349 return ENOSYS; 350 351 return fs->ops.ioctl(path, cmd, arg, fi, flags, data); 352} 353 354 355void 356fuse_fs_init(struct fuse_fs* fs, struct fuse_conn_info* conn) 357{ 358 if (fs->ops.init == NULL) 359 return; 360 fs->ops.init(conn); 361} 362 363 364void 365fuse_fs_destroy(struct fuse_fs* fs) 366{ 367 if (fs->ops.destroy != NULL) 368 fs->ops.destroy(fs->userData); 369 370 delete fs; 371} 372 373 374struct fuse_fs* 375fuse_fs_new(const struct fuse_operations* ops, size_t opSize, void* userData) 376{ 377 if (sizeof(fuse_operations) < opSize) { 378 ERROR(("fuse_fs_new(): Client FS built with newer library version!\n")); 379 return NULL; 380 } 381 382 fuse_fs* fs = new(std::nothrow) fuse_fs; 383 if (fs == NULL) 384 return NULL; 385 386 memset(&fs->ops, 0, sizeof(fuse_operations)); 387 memcpy(&fs->ops, ops, opSize); 388 389 fs->userData = userData; 390 391 return fs; 392} 393 394