"Fossies" - the Fresh Open Source Software Archive

Member "smbnetfs-0.6.3/src/function.c" (2 Mar 2019, 18095 Bytes) of package /linux/misc/smbnetfs-0.6.3.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "function.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.6.1_vs_0.6.2.

    1 #include "config.h"
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #include <string.h>
    5 #include <stddef.h>
    6 #include <errno.h>
    7 #include <fcntl.h>
    8 #include <dirent.h>
    9 #include <sys/statvfs.h>
   10 #include <sys/types.h>
   11 #include <time.h>
   12 #include <pthread.h>
   13 #include <libsmbclient.h>
   14 #include <glib.h>
   15 
   16 #include "common.h"
   17 #include "smbitem.h"
   18 #include "samba.h"
   19 #include "stat_workaround.h"
   20 #include "function.h"
   21 
   22 static int      function_free_space_size    = 0;
   23 static int      function_quiet_flag     = 1;
   24 static int      function_show_dollar_shares = 0;
   25 static int      function_show_hidden_hosts  = 0;
   26 static int      function_noexec_attr        = 0;
   27 
   28 
   29 int function_set_free_space_size(int blocks_count){
   30     DPRINTF(7, "blocks_count=%d\n", blocks_count);
   31     g_atomic_int_set(&function_free_space_size, blocks_count);
   32     return 1;
   33 }
   34 
   35 static int function_get_free_space_size(void){
   36     return g_atomic_int_get(&function_free_space_size);
   37 }
   38 
   39 int function_set_quiet_flag(int flag){
   40     DPRINTF(7, "flag=%d\n", flag);
   41     g_atomic_int_set(&function_quiet_flag, flag);
   42     return 1;
   43 }
   44 
   45 static inline int function_get_quiet_flag(void){
   46     return g_atomic_int_get(&function_quiet_flag);
   47 }
   48 
   49 int function_set_dollar_share_visibility(int flag){
   50     DPRINTF(7, "flag=%d\n", flag);
   51     g_atomic_int_set(&function_show_dollar_shares, flag);
   52     return 1;
   53 }
   54 
   55 static inline int function_get_dollar_share_visibility(void){
   56     return g_atomic_int_get(&function_show_dollar_shares);
   57 }
   58 
   59 int function_set_hidden_hosts_visibility(int flag){
   60     DPRINTF(7, "flag=%d\n", flag);
   61     g_atomic_int_set(&function_show_hidden_hosts, flag);
   62     return 1;
   63 }
   64 
   65 static inline int function_get_hidden_hosts_visibility(void){
   66     return g_atomic_int_get(&function_show_hidden_hosts);
   67 }
   68 
   69 int function_set_noexec_attr(int flag){
   70     DPRINTF(7, "flag=%d\n", flag);
   71     g_atomic_int_set(&function_noexec_attr, flag);
   72     return 1;
   73 }
   74 
   75 static inline int function_get_noexec_attr(void){
   76     return g_atomic_int_get(&function_noexec_attr);
   77 }
   78 
   79 static inline int function_check_xattr_name(const char *name){
   80     static char *xattr_name = "system.nt_sec_desc.";
   81     return (strncmp(name, xattr_name, strlen(xattr_name)) == 0);
   82 }
   83 
   84 static inline samba_fd function_get_fd(struct fuse_file_info *fi){
   85     return (samba_fd) fi->fh;
   86 }
   87 
   88 static inline void function_store_fd(struct fuse_file_info *fi, samba_fd fd){
   89     fi->fh = (uint64_t) fd;
   90 }
   91 
   92 static int function_open(const char *path, struct fuse_file_info *fi){
   93     samba_fd    fd;
   94 
   95     DPRINTF(5, "(%s, flags=%o, fh=%llx)\n", path, fi->flags, (long long) fi->fh);
   96     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
   97 
   98     if ((fd = samba_open(path, fi->flags, 0777)) == NULL) return -errno;
   99     function_store_fd(fi, fd);
  100     return 0;
  101 }
  102 
  103 static int function_read(const char *path, char *buf, size_t size, off_t offset,
  104             struct fuse_file_info *fi){
  105     int     result;
  106     samba_fd    fd;
  107 
  108     DPRINTF(5, "(%s, %zd, fh=%llx, offset=%lld, flags=%o)\n", path, size,
  109     (long long) fi->fh, (long long) offset, fi->flags);
  110 
  111     if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
  112     result = samba_read(fd, offset, buf, size);
  113     if (result == (ssize_t) (-1)) return -errno;
  114     return result;
  115 }
  116 
  117 static int function_write(const char *path, const char *buf, size_t size,
  118             off_t offset, struct fuse_file_info *fi){
  119     int     result;
  120     samba_fd    fd;
  121 
  122     DPRINTF(5, "(%s, %zd, fh=%llx, offset=%lld, flags=%o)\n", path, size,
  123     (long long) fi->fh, (long long) offset, fi->flags);
  124 
  125     if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
  126     result = samba_write(fd, offset, (char *) buf, size);
  127     if (result == (ssize_t) (-1)) return -errno;
  128     return result;
  129 }
  130 
  131 static int function_close(const char *path, struct fuse_file_info *fi){
  132     samba_fd    fd;
  133 
  134     DPRINTF(5, "(%s, fh=%llx, flags=%o)\n", path, (long long) fi->fh, fi->flags);
  135 
  136     if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
  137     if (samba_close(fd) != 0) return -errno;
  138     return 0;
  139 }
  140 
  141 static int function_unlink(const char *path){
  142     DPRINTF(5, "(%s)\n", path);
  143     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  144     if (samba_unlink(path) != 0) return -errno;
  145     return 0;
  146 }
  147 
  148 static int function_rename(const char *from, const char *to){
  149     DPRINTF(5, "(%s, %s)\n", from, to);
  150     if (smbitem_what_is(from) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  151     if (smbitem_what_is(to) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  152     if (samba_rename(from, to) != 0) return -errno;
  153     return 0;
  154 }
  155 
  156 static int function_opendir(const char *path, struct fuse_file_info *fi){
  157     samba_fd    fd;
  158 
  159     DPRINTF(5, "(%s, flags=%o, fh=%llx)\n", path, fi->flags, (long long) fi->fh);
  160     switch(smbitem_what_is(path)){
  161     case SMBITEM_SMBNETFS_DIR:
  162         function_store_fd(fi, (samba_fd) (-1));
  163         return 0;
  164 
  165     case SMBITEM_SMB_NAME:
  166     case SMBITEM_SMB_SHARE:
  167     case SMBITEM_SMB_SHARE_ITEM:
  168         if ((fd = samba_opendir(path)) == NULL) return -errno;
  169         function_store_fd(fi, fd);
  170         return 0;
  171 
  172     default:
  173         return -ENOTDIR;
  174     }
  175 }
  176 
  177 static int function_closedir(const char *path, struct fuse_file_info *fi){
  178     samba_fd    fd;
  179 
  180     DPRINTF(5, "(%s, fh=%llx, flags=%o)\n", path, (long long) fi->fh, fi->flags);
  181     if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
  182     if (fd == (samba_fd) (-1)) return 0;
  183     if (samba_closedir(fd) != 0) return -errno;
  184     return 0;
  185 }
  186 
  187 static int function_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
  188             off_t offset, struct fuse_file_info *fi){
  189     samba_fd        fd;
  190     int         error, rec_cnt;
  191     struct stat     st;
  192 
  193     (void) offset;
  194     DPRINTF(5, "(%s)\n", path);
  195 
  196     memset(&st, 0, sizeof(st));
  197     if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
  198     if (fd == (samba_fd) (-1)){
  199     int         i, show_hidden_hosts;
  200     struct smbitem      *dir;
  201 
  202     while(*path == '/') path++;
  203     if ((dir = smbitem_getdir(path)) == NULL) return -EBADF;
  204 
  205     error = EINVAL;
  206     st.st_mode = S_IFDIR;
  207     if (filler(buf, ".",  &st, 0)) goto error0;
  208     if (filler(buf, "..", &st, 0)) goto error0;
  209 
  210     show_hidden_hosts = function_get_hidden_hosts_visibility();
  211     for(i = 0; i < dir->child_cnt; i++){
  212         switch(dir->childs[i]->type){
  213         case SMBITEM_GROUP:
  214             st.st_mode = S_IFDIR;
  215             break;
  216         case SMBITEM_HOST:
  217             st.st_mode = S_IFDIR;
  218             if (!show_hidden_hosts && dir->childs[i]->is_hidden) continue;
  219             break;
  220         case SMBITEM_LINK:
  221             st.st_mode = S_IFLNK;
  222             break;
  223         default:
  224             goto error0;
  225         }
  226         if (filler(buf, dir->childs[i]->name,  &st, 0)) goto end;
  227     }
  228     error = 0;
  229 
  230       error0:
  231     smbitem_release_dir(dir);
  232     return -error;
  233     }
  234 
  235     rec_cnt = 0;
  236     while(*path == '/') path++;
  237 
  238     while(1){
  239     int             count;
  240     char                readdir_buf[4096];
  241     char                name[1024];
  242     char                link[1024];
  243     struct smb_conn_dirent_rec  *rec;
  244 
  245     count = samba_readdir(fd, readdir_buf, sizeof(readdir_buf));
  246     if (count == 0) break;
  247     if (count < 0){
  248         error = errno;
  249         goto end;
  250     }
  251 
  252     rec = (struct smb_conn_dirent_rec *) readdir_buf;
  253     for( ; count >= (int) sizeof(struct smb_conn_dirent_rec);
  254             count -= sizeof(struct smb_conn_dirent_rec)){
  255 
  256         if (strcmp(rec->d_name, "") == 0) goto next_record;
  257         if (strcmp(rec->d_name, ".") == 0) goto next_record;
  258         if (strcmp(rec->d_name, "..") == 0) goto next_record;
  259 
  260         switch(rec->smbc_type){
  261         case SMBC_WORKGROUP:
  262             error = EBADF;
  263             goto end;
  264 
  265         case SMBC_SERVER:
  266             st.st_mode = S_IFDIR;
  267             snprintf(name, sizeof(name), "%s/%s", path, rec->d_name);
  268             snprintf(link, sizeof(link), "../%s", rec->d_name);
  269             smbitem_mkgroup(path, SMBITEM_SAMBA_TREE);
  270             smbitem_mkhost(rec->d_name, path, 1, SMBITEM_SAMBA_TREE);
  271             smbitem_mklink(name, link, SMBITEM_SAMBA_TREE);
  272             break;
  273 
  274         case SMBC_FILE_SHARE:
  275             st.st_mode = S_IFDIR;
  276             if ((rec->d_name[strlen(rec->d_name) - 1] == '$') &&
  277             ! function_get_dollar_share_visibility())
  278                 goto next_record;
  279             break;
  280 
  281         case SMBC_DIR:
  282             st.st_mode = S_IFDIR;
  283             break;
  284 
  285         case SMBC_FILE:
  286             st.st_mode = S_IFREG;
  287             break;
  288 
  289         default:
  290             goto next_record;
  291         }
  292         if (rec_cnt == 0){
  293         struct stat st;
  294 
  295         error = EINVAL;
  296         memset(&st, 0, sizeof(st));
  297         st.st_mode = S_IFDIR;
  298         if (filler(buf, ".",  &st, 0)) goto end;
  299         if (filler(buf, "..", &st, 0)) goto end;
  300         rec_cnt += 2;
  301         }
  302         if (filler(buf, rec->d_name, &st, 0)){
  303         error = EINVAL;
  304         goto end;
  305         }
  306         rec_cnt++;
  307 
  308       next_record:
  309         rec++;
  310     }
  311     }
  312 
  313     if (rec_cnt == 0){
  314     error = EINVAL;
  315     st.st_mode = S_IFDIR;
  316     if (filler(buf, ".",  &st, 0)) goto end;
  317     if (filler(buf, "..", &st, 0)) goto end;
  318     rec_cnt += 2;
  319     }
  320     error = 0;
  321 
  322   end:
  323     return -error;
  324 }
  325 
  326 static int function_mkdir(const char *path, mode_t mode){
  327     DPRINTF(5, "(%s, %o)\n", path, mode);
  328     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  329     if (samba_mkdir(path, mode) != 0) return -errno;
  330     return 0;
  331 }
  332 
  333 static int function_rmdir(const char *path){
  334     DPRINTF(5, "(%s)\n", path);
  335     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  336     if (samba_rmdir(path) != 0) return -errno;
  337     return 0;
  338 }
  339 
  340 static int function_stat(const char *path, struct stat *stbuf){
  341     int         i, count;
  342     size_t      len;
  343     struct smbitem  *dir;
  344     char        buf[2048];
  345 
  346     DPRINTF(5, "(%s)\n", path);
  347     if (stat_workaround_is_name_ignored(path)) return -ENOENT;
  348     switch(smbitem_what_is(path)){
  349     case SMBITEM_SMBNETFS_DIR:
  350         while(*path == '/') path++;
  351 
  352         count = 2;
  353         if ((dir = smbitem_getdir(path)) == NULL) return -EINVAL;
  354         for(i = 0; i < dir->child_cnt; i++)
  355         switch(dir->childs[i]->type){
  356             case SMBITEM_HOST:
  357             case SMBITEM_GROUP:
  358             count++;
  359             break;
  360             default:
  361             break;
  362         }
  363         smbitem_release_dir(dir);
  364 
  365         memset(stbuf, 0, sizeof(struct stat));
  366         stbuf->st_mode = 0040777;   /* protection */
  367         stbuf->st_nlink = count;    /* number of hard links */
  368         stbuf->st_uid = 0;      /* user ID of owner */
  369         stbuf->st_gid = 0;      /* group ID of owner */
  370         stbuf->st_size = 0;     /* total size, in bytes */
  371         stbuf->st_blksize = 4096;   /* blocksize for filesystem I/O */
  372         return 0;
  373 
  374     case SMBITEM_SMBNETFS_LINK:
  375         DPRINTF(5, "link:(%s)\n", path);
  376         if (smbitem_readlink(path, buf, sizeof(buf)) != 0) return -EINVAL;
  377         len = strlen(buf);
  378 
  379         memset(stbuf, 0, sizeof(struct stat));
  380         stbuf->st_mode = 0120777;   /* protection */
  381         stbuf->st_nlink = 1;    /* number of hard links */
  382         stbuf->st_uid = 0;      /* user ID of owner */
  383         stbuf->st_gid = 0;      /* group ID of owner */
  384         stbuf->st_size = len;   /* total size, in bytes */
  385         stbuf->st_blksize = 4096;   /* blocksize for filesystem I/O */
  386         return 0;
  387 
  388     case SMBITEM_SMB_NAME:
  389     case SMBITEM_SMB_SHARE:
  390         memset(stbuf, 0, sizeof(struct stat));
  391         stbuf->st_mode = 0040777;   /* protection */
  392         stbuf->st_nlink = 2;    /* number of hard links */
  393         stbuf->st_uid = 0;      /* user ID of owner */
  394         stbuf->st_gid = 0;      /* group ID of owner */
  395         stbuf->st_size = 0;     /* total size, in bytes */
  396         stbuf->st_blksize = 4096;   /* blocksize for filesystem I/O */
  397         return 0;
  398 
  399     case SMBITEM_SMB_SHARE_ITEM:
  400         if (samba_stat(path, stbuf) != 0) return -errno;
  401         if (S_ISREG(stbuf->st_mode) && function_get_noexec_attr())
  402         stbuf->st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
  403         return 0;
  404 
  405     default:
  406         return -EINVAL;
  407     }
  408 }
  409 
  410 static int function_fstat(const char *path, struct stat *stbuf,
  411             struct fuse_file_info *fi){
  412     int         i, count;
  413     struct smbitem  *dir;
  414     samba_fd        fd;
  415 
  416     (void) path;
  417 
  418     DPRINTF(5, "(%s)\n", path);
  419     if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
  420     if (fd == (samba_fd) (-1)){
  421     /* SMBNETFS_DIR */
  422 
  423     while(*path == '/') path++;
  424 
  425     count = 2;
  426     if ((dir = smbitem_getdir(path)) == NULL) return -EBADF;
  427     for(i = 0; i < dir->child_cnt; i++)
  428         switch(dir->childs[i]->type){
  429         case SMBITEM_HOST:
  430         case SMBITEM_GROUP:
  431             count++;
  432             break;
  433         default:
  434             break;
  435         }
  436     smbitem_release_dir(dir);
  437 
  438     memset(stbuf, 0, sizeof(struct stat));
  439     stbuf->st_mode = 0040777;   /* protection */
  440     stbuf->st_nlink = count;    /* number of hard links */
  441     stbuf->st_uid = 0;      /* user ID of owner */
  442     stbuf->st_gid = 0;      /* group ID of owner */
  443     stbuf->st_size = 0;     /* total size, in bytes */
  444     stbuf->st_blksize = 4096;   /* blocksize for filesystem I/O */
  445     return 0;
  446     }
  447 
  448     if (samba_fstat(fd, stbuf) != 0) return -errno;
  449     if (S_ISREG(stbuf->st_mode) && function_get_noexec_attr())
  450     stbuf->st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
  451     return 0;
  452 }
  453 
  454 static int function_ftruncate(const char *path, off_t size,
  455             struct fuse_file_info *fi){
  456     samba_fd    fd;
  457 
  458     DPRINTF(5, "(%s, %lld)\n", path, (long long) size);
  459     if (size < 0) return -EINVAL;
  460     if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
  461     if (samba_ftruncate(fd, size) != 0) return -errno;
  462     return 0;
  463 }
  464 
  465 static int function_chmod(const char *path, mode_t mode){
  466     DPRINTF(5, "(%s, %o)\n", path, mode);
  467     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  468     if (samba_chmod(path, mode) != 0) return -errno;
  469     return 0;
  470 }
  471 
  472 static int function_utimes(const char *path, struct utimbuf *buffer){
  473     struct timeval  tbuf[2];
  474 
  475     DPRINTF(5, "(%s, %u)\n", path, (unsigned int)buffer->modtime);
  476     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  477 
  478     tbuf[0].tv_sec = buffer->actime;
  479     tbuf[0].tv_usec = 0;
  480     tbuf[1].tv_sec = buffer->modtime;
  481     tbuf[1].tv_usec = 0;
  482 
  483     if (samba_utimes(path, tbuf) != 0) return -errno;
  484     return 0;
  485 }
  486 
  487 /* libfuse does not support lsetxattr() and fsetxattr(), but samba does */
  488 static int function_setxattr(const char *path, const char *name,
  489                 const char *value, size_t size, int flags){
  490     DPRINTF(5, "(%s, name=%s, value=%s, size=%zd, flags=%o)\n", path,
  491     name, value, size, flags);
  492     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
  493     if (!function_check_xattr_name(name)) return -ENOTSUP;
  494     if (samba_setxattr(path, name, value, size, flags) != 0) return -errno;
  495     return 0;
  496 }
  497 
  498 /* libfuse does not support lgetxattr() and fgetxattr(), but samba does */
  499 static int function_getxattr(const char *path, const char *name,
  500                 char *value, size_t size){
  501     DPRINTF(5, "(%s, name=%s, size=%zd)\n", path, name, size);
  502     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
  503     if (!function_check_xattr_name(name)) return -ENOTSUP;
  504     if (samba_getxattr(path, name, value, size) != 0) return -errno;
  505     return 0;
  506 }
  507 
  508 /* libfuse does not support llistxattr() and flistxattr(), but samba does */
  509 static int function_listxattr(const char *path, char *list, size_t size){
  510     DPRINTF(5, "(%s, size=%zd)\n", path, size);
  511     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
  512     if (samba_listxattr(path, list, size) != 0) return -errno;
  513     return 0;
  514 }
  515 
  516 /* libfuse does not support lremovexattr() and fremovexattr(), but samba does */
  517 static int function_removexattr(const char *path, const char *name){
  518     DPRINTF(5, "(%s, name=%s)\n", path, name);
  519     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
  520     if (!function_check_xattr_name(name)) return -ENOTSUP;
  521     if (samba_removexattr(path, name) != 0) return -errno;
  522     return 0;
  523 }
  524 
  525 static int function_readlink(const char *path, char *buf, size_t size){
  526     DPRINTF(5, "(%s, %zd)\n", path, size);
  527     if (smbitem_what_is(path) != SMBITEM_SMBNETFS_LINK) return -EINVAL;
  528     if (smbitem_readlink(path, buf, size) != 0) return -EINVAL;
  529     return 0;
  530 }
  531 
  532 static int function_mknod(const char *path, mode_t mode, dev_t rdev){
  533     samba_fd    fd;
  534 
  535     (void) rdev;
  536 
  537     DPRINTF(5, "(%s, %o)\n", path, mode);
  538     if ((mode & S_IFMT) != S_IFREG) return -EPERM;
  539     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  540     if ((fd = samba_creat(path, mode)) == NULL) return -errno;
  541     if (samba_close(fd) != 0) return -errno;
  542     return 0;
  543 }
  544 
  545 static int function_chown(const char *path, uid_t uid, gid_t gid){
  546     (void) path;
  547     (void) uid;
  548     (void) gid;
  549 
  550     DPRINTF(5, "(%s, uid=%d, gid=%d)\n", path, uid, gid);
  551     if (function_get_quiet_flag()) return 0;
  552     else return -EPERM;
  553 }
  554 
  555 static int function_truncate(const char *path, off_t size){
  556     samba_fd    fd;
  557 
  558     DPRINTF(5, "(%s, %lld)\n", path, (long long) size);
  559     if (size < 0) return -EINVAL;
  560     if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
  561     if ((fd = samba_open(path, O_RDWR, 0777)) == NULL) return -errno;
  562     if (samba_ftruncate(fd, size) != 0){
  563     int error = errno;
  564     samba_close(fd);
  565     return -error;
  566     }
  567     if (samba_close(fd) != 0) return -errno;
  568     return 0;
  569 }
  570 
  571 static int function_statfs(const char *path, struct statvfs *stbuf){
  572     int free_space_blocks;
  573 
  574     DPRINTF(5, "(%s)\n", path);
  575 
  576     free_space_blocks = function_get_free_space_size();
  577     memset(stbuf, 0, sizeof(struct statvfs));
  578     stbuf->f_bsize = 4096;
  579     stbuf->f_frsize = 4096;
  580     if (free_space_blocks > 0){
  581     stbuf->f_blocks = free_space_blocks;
  582     stbuf->f_bfree = free_space_blocks;
  583     stbuf->f_bavail = free_space_blocks;
  584     stbuf->f_ffree = 32768;
  585     stbuf->f_favail = 32768;
  586     }
  587     stbuf->f_namemax = FILENAME_MAX;
  588     return 0;
  589 }
  590 
  591 struct fuse_operations smb_oper = {
  592     .open   = function_open,
  593     .read   = function_read,
  594     .write  = function_write,
  595     .release    = function_close,
  596     .unlink = function_unlink,
  597     .rename = function_rename,
  598     .opendir    = function_opendir,
  599     .releasedir = function_closedir,
  600     .readdir    = function_readdir,
  601     .mkdir  = function_mkdir,
  602     .rmdir  = function_rmdir,
  603     .getattr    = function_stat,
  604     .fgetattr   = function_fstat,
  605     .ftruncate  = function_ftruncate,
  606     .chmod  = function_chmod,
  607     .utime  = function_utimes,
  608     .setxattr   = function_setxattr,
  609     .getxattr   = function_getxattr,
  610     .listxattr  = function_listxattr,
  611     .removexattr= function_removexattr,
  612     .readlink   = function_readlink,
  613     .mknod  = function_mknod,
  614     .chown  = function_chown,
  615     .truncate   = function_truncate,
  616     .statfs = function_statfs,
  617 //    .init = function_init,    /* event.c */
  618 //    .destroy  = function_destroy, /* event.c */
  619 //    .fsyncdir = function_fsyncdir,
  620 //    .access   = function_access,
  621 };