nfs-ganesha 1.4

fusexmp.c

Go to the documentation of this file.
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 }