nfs-ganesha 1.4
|
00001 /* 00002 FUSE: Filesystem in Userspace 00003 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> 00004 00005 This program can be distributed under the terms of the GNU GPL. 00006 See the file COPYING. 00007 00008 gcc -Wall `pkg-config fuse --cflags --libs` fusexmp.c -o fusexmp 00009 */ 00010 00011 #define FUSE_USE_VERSION 26 00012 00013 #ifdef HAVE_CONFIG_H 00014 #include <config.h> 00015 #endif 00016 00017 #include <ganesha_fuse_wrap.h> 00018 #include <stdio.h> 00019 #include <string.h> 00020 #include <unistd.h> 00021 #include <fcntl.h> 00022 #include <dirent.h> 00023 #include <errno.h> 00024 #include <sys/time.h> 00025 #ifdef HAVE_SETXATTR 00026 #include <sys/xattr.h> 00027 #endif 00028 00029 static int xmp_getattr(const char *path, struct stat *stbuf) 00030 { 00031 int res; 00032 00033 res = lstat(path, stbuf); 00034 if(res == -1) 00035 return -errno; 00036 00037 return 0; 00038 } 00039 00040 static int xmp_access(const char *path, int mask) 00041 { 00042 int res; 00043 00044 res = access(path, mask); 00045 if(res == -1) 00046 return -errno; 00047 00048 return 0; 00049 } 00050 00051 static int xmp_readlink(const char *path, char *buf, size_t size) 00052 { 00053 int res; 00054 00055 res = readlink(path, buf, size - 1); 00056 if(res == -1) 00057 return -errno; 00058 00059 buf[res] = '\0'; 00060 return 0; 00061 } 00062 00063 static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, 00064 off_t offset, struct fuse_file_info *fi) 00065 { 00066 DIR *dp; 00067 struct dirent *de; 00068 00069 (void)offset; 00070 (void)fi; 00071 00072 dp = opendir(path); 00073 if(dp == NULL) 00074 return -errno; 00075 00076 while((de = readdir(dp)) != NULL) 00077 { 00078 struct stat st; 00079 memset(&st, 0, sizeof(st)); 00080 st.st_ino = de->d_ino; 00081 st.st_mode = de->d_type << 12; 00082 if(filler(buf, de->d_name, &st, 0)) 00083 break; 00084 } 00085 00086 closedir(dp); 00087 return 0; 00088 } 00089 00090 static int xmp_mknod(const char *path, mode_t mode, dev_t rdev) 00091 { 00092 int res; 00093 00094 /* On Linux this could just be 'mknod(path, mode, rdev)' but this 00095 is more portable */ 00096 if(S_ISREG(mode)) 00097 { 00098 res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode); 00099 if(res >= 0) 00100 res = close(res); 00101 } 00102 else if(S_ISFIFO(mode)) 00103 res = mkfifo(path, mode); 00104 else 00105 res = mknod(path, mode, rdev); 00106 if(res == -1) 00107 return -errno; 00108 00109 return 0; 00110 } 00111 00112 static int xmp_mkdir(const char *path, mode_t mode) 00113 { 00114 int res; 00115 00116 res = mkdir(path, mode); 00117 if(res == -1) 00118 return -errno; 00119 00120 return 0; 00121 } 00122 00123 static int xmp_unlink(const char *path) 00124 { 00125 int res; 00126 00127 res = unlink(path); 00128 if(res == -1) 00129 return -errno; 00130 00131 return 0; 00132 } 00133 00134 static int xmp_rmdir(const char *path) 00135 { 00136 int res; 00137 00138 res = rmdir(path); 00139 if(res == -1) 00140 return -errno; 00141 00142 return 0; 00143 } 00144 00145 static int xmp_symlink(const char *from, const char *to) 00146 { 00147 int res; 00148 00149 res = symlink(from, to); 00150 if(res == -1) 00151 return -errno; 00152 00153 return 0; 00154 } 00155 00156 static int xmp_rename(const char *from, const char *to) 00157 { 00158 int res; 00159 00160 res = rename(from, to); 00161 if(res == -1) 00162 return -errno; 00163 00164 return 0; 00165 } 00166 00167 static int xmp_link(const char *from, const char *to) 00168 { 00169 int res; 00170 00171 res = link(from, to); 00172 if(res == -1) 00173 return -errno; 00174 00175 return 0; 00176 } 00177 00178 static int xmp_chmod(const char *path, mode_t mode) 00179 { 00180 int res; 00181 00182 res = chmod(path, mode); 00183 if(res == -1) 00184 return -errno; 00185 00186 return 0; 00187 } 00188 00189 static int xmp_chown(const char *path, uid_t uid, gid_t gid) 00190 { 00191 int res; 00192 00193 res = lchown(path, uid, gid); 00194 if(res == -1) 00195 return -errno; 00196 00197 return 0; 00198 } 00199 00200 static int xmp_truncate(const char *path, off_t size) 00201 { 00202 int res; 00203 00204 res = truncate(path, size); 00205 if(res == -1) 00206 return -errno; 00207 00208 return 0; 00209 } 00210 00211 static int xmp_utimens(const char *path, const struct timespec ts[2]) 00212 { 00213 int res; 00214 struct timeval tv[2]; 00215 00216 tv[0].tv_sec = ts[0].tv_sec; 00217 tv[0].tv_usec = ts[0].tv_nsec / 1000; 00218 tv[1].tv_sec = ts[1].tv_sec; 00219 tv[1].tv_usec = ts[1].tv_nsec / 1000; 00220 00221 res = utimes(path, tv); 00222 if(res == -1) 00223 return -errno; 00224 00225 return 0; 00226 } 00227 00228 static int xmp_open(const char *path, struct fuse_file_info *fi) 00229 { 00230 int res; 00231 00232 res = open(path, fi->flags); 00233 if(res == -1) 00234 return -errno; 00235 00236 close(res); 00237 return 0; 00238 } 00239 00240 static int xmp_read(const char *path, char *buf, size_t size, off_t offset, 00241 struct fuse_file_info *fi) 00242 { 00243 int fd; 00244 int res; 00245 00246 (void)fi; 00247 fd = open(path, O_RDONLY); 00248 if(fd == -1) 00249 return -errno; 00250 00251 res = pread(fd, buf, size, offset); 00252 if(res == -1) 00253 res = -errno; 00254 00255 close(fd); 00256 return res; 00257 } 00258 00259 static int xmp_write(const char *path, const char *buf, size_t size, 00260 off_t offset, struct fuse_file_info *fi) 00261 { 00262 int fd; 00263 int res; 00264 00265 (void)fi; 00266 fd = open(path, O_WRONLY); 00267 if(fd == -1) 00268 return -errno; 00269 00270 res = pwrite(fd, buf, size, offset); 00271 if(res == -1) 00272 res = -errno; 00273 00274 close(fd); 00275 return res; 00276 } 00277 00278 static int xmp_statfs(const char *path, struct statvfs *stbuf) 00279 { 00280 int res; 00281 00282 res = statvfs(path, stbuf); 00283 if(res == -1) 00284 return -errno; 00285 00286 return 0; 00287 } 00288 00289 static int xmp_release(const char *path, struct fuse_file_info *fi) 00290 { 00291 /* Just a stub. This method is optional and can safely be left 00292 unimplemented */ 00293 00294 (void)path; 00295 (void)fi; 00296 return 0; 00297 } 00298 00299 static int xmp_fsync(const char *path, int isdatasync, struct fuse_file_info *fi) 00300 { 00301 /* Just a stub. This method is optional and can safely be left 00302 unimplemented */ 00303 00304 (void)path; 00305 (void)isdatasync; 00306 (void)fi; 00307 return 0; 00308 } 00309 00310 #ifdef HAVE_SETXATTR 00311 /* xattr operations are optional and can safely be left unimplemented */ 00312 static int xmp_setxattr(const char *path, const char *name, const char *value, 00313 size_t size, int flags) 00314 { 00315 int res = lsetxattr(path, name, value, size, flags); 00316 if(res == -1) 00317 return -errno; 00318 return 0; 00319 } 00320 00321 static int xmp_getxattr(const char *path, const char *name, char *value, size_t size) 00322 { 00323 int res = lgetxattr(path, name, value, size); 00324 if(res == -1) 00325 return -errno; 00326 return res; 00327 } 00328 00329 static int xmp_listxattr(const char *path, char *list, size_t size) 00330 { 00331 int res = llistxattr(path, list, size); 00332 if(res == -1) 00333 return -errno; 00334 return res; 00335 } 00336 00337 static int xmp_removexattr(const char *path, const char *name) 00338 { 00339 int res = lremovexattr(path, name); 00340 if(res == -1) 00341 return -errno; 00342 return 0; 00343 } 00344 #endif /* HAVE_SETXATTR */ 00345 00346 static struct fuse_operations xmp_oper = { 00347 .getattr = xmp_getattr, 00348 .access = xmp_access, 00349 .readlink = xmp_readlink, 00350 .readdir = xmp_readdir, 00351 .mknod = xmp_mknod, 00352 .mkdir = xmp_mkdir, 00353 .symlink = xmp_symlink, 00354 .unlink = xmp_unlink, 00355 .rmdir = xmp_rmdir, 00356 .rename = xmp_rename, 00357 .link = xmp_link, 00358 .chmod = xmp_chmod, 00359 .chown = xmp_chown, 00360 .truncate = xmp_truncate, 00361 .utimens = xmp_utimens, 00362 .open = xmp_open, 00363 .read = xmp_read, 00364 .write = xmp_write, 00365 .statfs = xmp_statfs, 00366 .release = xmp_release, 00367 .fsync = xmp_fsync, 00368 #ifdef HAVE_SETXATTR 00369 .setxattr = xmp_setxattr, 00370 .getxattr = xmp_getxattr, 00371 .listxattr = xmp_listxattr, 00372 .removexattr = xmp_removexattr, 00373 #endif 00374 }; 00375 00376 int main(int argc, char *argv[]) 00377 { 00378 umask(0); 00379 return fuse_main(argc, argv, &xmp_oper, NULL); 00380 }