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 15 int 16 fuse_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 24 int 25 fuse_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 34 int 35 fuse_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 43 int 44 fuse_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 52 int 53 fuse_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 61 int 62 fuse_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 70 int 71 fuse_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 79 int 80 fuse_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 89 int 90 fuse_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 98 int 99 fuse_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 108 int 109 fuse_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 118 int 119 fuse_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 128 int 129 fuse_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 137 int 138 fuse_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 146 int 147 fuse_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 155 int 156 fuse_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 165 int 166 fuse_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 175 int 176 fuse_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 185 int 186 fuse_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 195 int 196 fuse_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 205 int 206 fuse_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 214 int 215 fuse_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 223 int 224 fuse_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 232 int 233 fuse_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 242 int 243 fuse_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 261 int 262 fuse_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 270 int 271 fuse_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 279 int 280 fuse_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 288 int 289 fuse_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 297 int 298 fuse_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 307 int 308 fuse_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 317 int 318 fuse_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 326 int 327 fuse_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 335 int 336 fuse_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 345 int 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 355 void 356 fuse_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 364 void 365 fuse_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 374 struct fuse_fs* 375 fuse_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