/[hurdextras]/libfuse/netfs.c
ViewVC logotype

Diff of /libfuse/netfs.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.36 by stesie, Sat Dec 3 23:17:06 2005 UTC revision 1.37 by stesie, Sun Dec 4 18:20:44 2005 UTC
# Line 56  static int fuse_dirent_helper_compat(fus Line 56  static int fuse_dirent_helper_compat(fus
56                                       int type);                                       int type);
57    
58    
59    /* Check whether to allow access to a node, testing the allow_root and
60     * allow_other flag.  This does not check whether default permissions
61     * are okay to allow access.
62     *
63     * Return: 0 if access is to be granted, EPERM otherwise
64     *
65     * Sidenote: This function is mainly called from netfs_validate_stat which in
66     *           turn is called by any other of the netfs-operation-functions. This
67     *           is, we don't have to call this from all of the operation-functions
68     *           since netfs_validate_stat is called anyways!
69     */
70    static error_t
71    test_allow_root_or_other (struct iouser *cred)
72    {
73      FUNC_PROLOGUE("test_allow_root_or_other");
74    
75      /* if allow_other is set, access is okay in any case */
76      if(libfuse_params.allow_other)
77        FUNC_RETURN_FMT(0, "allow_other is set");
78    
79      unsigned int i;
80      uid_t proc_uid = getuid();
81      for(i = 0; i < cred->uids->num; i ++)
82        {
83          DEBUG("test_allow", "testing for uid=%d\n", cred->uids->ids[i]);
84    
85          if(cred->uids->ids[i] == 0 && libfuse_params.allow_root)
86            FUNC_RETURN_FMT(0, "allowing access for root");
87    
88          if(cred->uids->ids[i] == proc_uid)
89            FUNC_RETURN_FMT(0, "allowing access for owner");
90        }
91    
92      /* iouser is not the "filesystem-owner" and allow_other is not set,
93       * or iouser is root but allow_root is not set either */
94      FUNC_EPILOGUE(EPERM);
95    }
96    
97    
98    
99  /* Make sure that NP->nn_stat is filled with current information.  CRED  /* Make sure that NP->nn_stat is filled with current information.  CRED
100     identifies the user responsible for the operation.  */     identifies the user responsible for the operation.
101    
102       If the user `CRED' is not allowed to perform any operation (considering
103       the allow_root and allow_other flags), return EPERM. */
104  error_t  error_t
105  netfs_validate_stat (struct node *node, struct iouser *cred)  netfs_validate_stat (struct node *node, struct iouser *cred)
106  {  {
   (void) cred;  
   
107    FUNC_PROLOGUE_NODE("netfs_validate_stat", node);    FUNC_PROLOGUE_NODE("netfs_validate_stat", node);
108    error_t err = EOPNOTSUPP;    error_t err = EOPNOTSUPP;
109    
110      if(test_allow_root_or_other(cred))
111        FUNC_RETURN(EPERM);
112    
113    if(FUSE_OP_HAVE(getattr))    if(FUSE_OP_HAVE(getattr))
114      err = -FUSE_OP_CALL(getattr, node->nn->path, &node->nn_stat);      err = -FUSE_OP_CALL(getattr, node->nn->path, &node->nn_stat);
115    
# Line 98  error_t netfs_attempt_readlink (struct i Line 142  error_t netfs_attempt_readlink (struct i
142                                  char *buf)                                  char *buf)
143  {  {
144    FUNC_PROLOGUE_NODE("netfs_attempt_readlink", node);    FUNC_PROLOGUE_NODE("netfs_attempt_readlink", node);
145    error_t err = EOPNOTSUPP;    error_t err;
146    
147    if((err = netfs_validate_stat(node, user))    if((err = netfs_validate_stat(node, user))
148       || (err = fshelp_access(&node->nn_stat, S_IREAD, user)))       || (err = fshelp_access(&node->nn_stat, S_IREAD, user)))
# Line 106  error_t netfs_attempt_readlink (struct i Line 150  error_t netfs_attempt_readlink (struct i
150    
151    if(FUSE_OP_HAVE(readlink))    if(FUSE_OP_HAVE(readlink))
152      err = -FUSE_OP_CALL(readlink, node->nn->path, buf, INT_MAX);      err = -FUSE_OP_CALL(readlink, node->nn->path, buf, INT_MAX);
153      else
154        err = EOPNOTSUPP;
155    
156   out:   out:
157    FUNC_EPILOGUE(err);    FUNC_EPILOGUE(err);
# Line 121  netfs_attempt_create_file (struct iouser Line 167  netfs_attempt_create_file (struct iouser
167                             char *name, mode_t mode, struct node **node)                             char *name, mode_t mode, struct node **node)
168  {  {
169    FUNC_PROLOGUE("netfs_attempt_create_file");    FUNC_PROLOGUE("netfs_attempt_create_file");
170    error_t err = EOPNOTSUPP;    error_t err;
171    char *path = NULL;    char *path = NULL;
172    
   if(! FUSE_OP_HAVE(mknod))  
     goto out;  
   
173    if((err = netfs_validate_stat(dir, user))    if((err = netfs_validate_stat(dir, user))
174       || (err = fshelp_checkdirmod(&dir->nn_stat, NULL, user)))       || (err = fshelp_checkdirmod(&dir->nn_stat, NULL, user)))
175      goto out;      goto out;
176    
177      if(! FUSE_OP_HAVE(mknod))
178        {
179          err = EOPNOTSUPP;
180          goto out;
181        }
182    
183    if(! (path = malloc(strlen(dir->nn->path) + strlen(name) + 2)))    if(! (path = malloc(strlen(dir->nn->path) + strlen(name) + 2)))
184      {      {
185        err = ENOMEM;        err = ENOMEM;
# Line 196  error_t netfs_attempt_chown (struct ious Line 245  error_t netfs_attempt_chown (struct ious
245                               uid_t uid, uid_t gid)                               uid_t uid, uid_t gid)
246  {  {
247    FUNC_PROLOGUE_NODE("netfs_attempt_chown", node);    FUNC_PROLOGUE_NODE("netfs_attempt_chown", node);
248    error_t err = EOPNOTSUPP;    error_t err;
   
   if(! FUSE_OP_HAVE(chown))  
     goto out;  
249    
250    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
251       || (err = fshelp_isowner(&node->nn_stat, cred)))       || (err = fshelp_isowner(&node->nn_stat, cred)))
252      goto out;      goto out;
253    
254      if(! FUSE_OP_HAVE(chown))
255        {
256          err = EOPNOTSUPP;
257          goto out;
258        }
259    
260    /* FIXME, make sure, that user CRED is not able to change permissions    /* FIXME, make sure, that user CRED is not able to change permissions
261     * to somebody who is not. That is, don't allow $unpriv_user to change     * to somebody who is not. That is, don't allow $unpriv_user to change
262     * owner to e.g. root.     * owner to e.g. root.
# Line 225  error_t Line 277  error_t
277  netfs_attempt_statfs (struct iouser *cred, struct node *node,  netfs_attempt_statfs (struct iouser *cred, struct node *node,
278                        fsys_statfsbuf_t *st)                        fsys_statfsbuf_t *st)
279  {  {
   (void) cred;  
   
280    FUNC_PROLOGUE_NODE("netfs_attempt_statfs", node);    FUNC_PROLOGUE_NODE("netfs_attempt_statfs", node);
281    error_t err = EOPNOTSUPP;    error_t err;
282    
283    if(FUSE_OP_HAVE(statfs))    if(test_allow_root_or_other(cred))
284        err = EPERM;
285    
286      else if(FUSE_OP_HAVE(statfs))
287      err = -FUSE_OP_CALL(statfs, node->nn->path, st);      err = -FUSE_OP_CALL(statfs, node->nn->path, st);
288    
289      else
290        err = EOPNOTSUPP;
291    
292    FUNC_EPILOGUE(err);    FUNC_EPILOGUE(err);
293  }  }
294    
# Line 244  error_t netfs_attempt_mkdir (struct ious Line 300  error_t netfs_attempt_mkdir (struct ious
300                               char *name, mode_t mode)                               char *name, mode_t mode)
301  {  {
302    FUNC_PROLOGUE("netfs_attempt_mkdir");    FUNC_PROLOGUE("netfs_attempt_mkdir");
303    error_t err = EOPNOTSUPP;    error_t err;
304    char *path = NULL;    char *path = NULL;
305    
   if(! FUSE_OP_HAVE(mkdir))  
     goto out;  
   
306    if((err = netfs_validate_stat(dir, user))    if((err = netfs_validate_stat(dir, user))
307       || (err = fshelp_checkdirmod(&dir->nn_stat, NULL, user)))       || (err = fshelp_checkdirmod(&dir->nn_stat, NULL, user)))
308      goto out;      goto out;
309    
310      if(! FUSE_OP_HAVE(mkdir))
311        {
312          err = EOPNOTSUPP;
313          goto out;
314        }
315    
316    if(! (path = malloc(strlen(dir->nn->path) + strlen(name) + 2)))    if(! (path = malloc(strlen(dir->nn->path) + strlen(name) + 2)))
317      {      {
318        err = ENOMEM;        err = ENOMEM;
# Line 344  error_t netfs_attempt_chmod (struct ious Line 403  error_t netfs_attempt_chmod (struct ious
403                               mode_t mode)                               mode_t mode)
404  {  {
405    FUNC_PROLOGUE_NODE("netfs_attempt_chmod", node);    FUNC_PROLOGUE_NODE("netfs_attempt_chmod", node);
406    error_t err = EOPNOTSUPP;    error_t err;
   
   if(! FUSE_OP_HAVE(chmod))  
     goto out;  
407    
408    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
409       || (err = fshelp_isowner(&node->nn_stat, cred)))       || (err = fshelp_isowner(&node->nn_stat, cred)))
410      goto out;      goto out;
411    
412      if(! FUSE_OP_HAVE(chmod))
413        {
414          err = EOPNOTSUPP;
415          goto out;
416        }
417    
418    err = -FUSE_OP_CALL(chmod, node->nn->path, mode);    err = -FUSE_OP_CALL(chmod, node->nn->path, mode);
419    node->nn->may_need_sync = 1;    node->nn->may_need_sync = 1;
420        
# Line 368  error_t netfs_attempt_mkfile (struct iou Line 430  error_t netfs_attempt_mkfile (struct iou
430                                mode_t mode, struct node **node)                                mode_t mode, struct node **node)
431  {  {
432    FUNC_PROLOGUE("netfs_attempt_mkfile");    FUNC_PROLOGUE("netfs_attempt_mkfile");
433    error_t err = EOPNOTSUPP;    error_t err;
434    char name[20];    char name[20];
435    static int num = 0;    static int num = 0;
436    
437    if(FUSE_OP_HAVE(mknod))    if(! (err = netfs_validate_stat(dir, user)))
438      if(! (err = netfs_validate_stat(dir, user)))      err = fshelp_checkdirmod(&dir->nn_stat, NULL, user);
439        err = fshelp_checkdirmod(&dir->nn_stat, NULL, user);  
440      if(! err && ! FUSE_OP_HAVE(mknod))
441        err = EOPNOTSUPP;
442    
443    if(err)    if(err)
444      {      {
# Line 423  error_t netfs_attempt_mkfile (struct iou Line 487  error_t netfs_attempt_mkfile (struct iou
487     only after sync is completely finished.  */     only after sync is completely finished.  */
488  error_t netfs_attempt_syncfs (struct iouser *cred, int wait)  error_t netfs_attempt_syncfs (struct iouser *cred, int wait)
489  {  {
   (void) cred;   /* cannot use anything but translator's rights,  
                   * FIXME, maybe setuid/setgid? */  
490    (void) wait;   /* there's no such flag in libfuse */    (void) wait;   /* there's no such flag in libfuse */
491    
492    FUNC_PROLOGUE("netfs_attempt_syncfs");    FUNC_PROLOGUE("netfs_attempt_syncfs");
493    error_t err = fuse_sync_filesystem();    error_t err;
494    
495      if(test_allow_root_or_other(cred))
496        err = EPERM;
497      else
498        err = fuse_sync_filesystem();
499    
500    FUNC_EPILOGUE(err);    FUNC_EPILOGUE(err);
501  }  }
# Line 443  netfs_attempt_sync (struct iouser *cred, Line 510  netfs_attempt_sync (struct iouser *cred,
510    (void) wait;   /* there's no such flag in libfuse */    (void) wait;   /* there's no such flag in libfuse */
511    
512    FUNC_PROLOGUE_NODE("netfs_attempt_sync", node);    FUNC_PROLOGUE_NODE("netfs_attempt_sync", node);
513    error_t err = EOPNOTSUPP;    error_t err;
   
   if(! FUSE_OP_HAVE(fsync))  
     goto out;  
514    
515    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
516       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))
517      goto out;      goto out;
518    
519      if(! FUSE_OP_HAVE(fsync))
520        {
521          err = EOPNOTSUPP;
522          goto out;
523        }
524    
525    if(fuse_ops)    if(fuse_ops)
526      err = -fuse_ops->fsync(node->nn->path, 0, &node->nn->info);      err = -fuse_ops->fsync(node->nn->path, 0, &node->nn->info);
527    else    else
# Line 473  error_t netfs_attempt_unlink (struct iou Line 543  error_t netfs_attempt_unlink (struct iou
543                                char *name)                                char *name)
544  {  {
545    FUNC_PROLOGUE("netfs_attempt_unlink");    FUNC_PROLOGUE("netfs_attempt_unlink");
546    error_t err = EOPNOTSUPP;    error_t err;
547    struct node *node = NULL;    struct node *node = NULL;
548    
   if(! FUSE_OP_HAVE(unlink))  
     goto out;  
   
549    err = netfs_attempt_lookup(user, dir, name, &node);    err = netfs_attempt_lookup(user, dir, name, &node);
550    assert(dir != node);    assert(dir != node);
551    mutex_lock(&dir->lock); /* re-lock directory, since netfs_attempt_lookup    mutex_lock(&dir->lock); /* re-lock directory, since netfs_attempt_lookup
# Line 494  error_t netfs_attempt_unlink (struct iou Line 561  error_t netfs_attempt_unlink (struct iou
561       || (err = fshelp_checkdirmod(&dir->nn_stat, &node->nn_stat, user)))       || (err = fshelp_checkdirmod(&dir->nn_stat, &node->nn_stat, user)))
562      goto out;      goto out;
563    
564    err = -FUSE_OP_CALL(unlink, node->nn->path);    if(FUSE_OP_HAVE(unlink))
565        err = -FUSE_OP_CALL(unlink, node->nn->path);
566      else
567        err = EOPNOTSUPP;
568    
569    /* TODO free associated netnode. really?    /* TODO free associated netnode. really?
570     * FIXME, make sure nn->may_need_sync is set */     * FIXME, make sure nn->may_need_sync is set */
# Line 513  error_t netfs_attempt_set_size (struct i Line 583  error_t netfs_attempt_set_size (struct i
583                                  loff_t size)                                  loff_t size)
584  {  {
585    FUNC_PROLOGUE_NODE("netfs_attempt_set_size", node);    FUNC_PROLOGUE_NODE("netfs_attempt_set_size", node);
586    error_t err = EOPNOTSUPP;    error_t err;
   
   if(! FUSE_OP_HAVE(truncate))  
     goto out;  
587    
588    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
589       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))
590      goto out;      goto out;
591    
592    err = -FUSE_OP_CALL(truncate, node->nn->path, size);    if(FUSE_OP_HAVE(truncate))
593        err = -FUSE_OP_CALL(truncate, node->nn->path, size);
594      else
595        err = EOPNOTSUPP;
596    
597   out:   out:
598    FUNC_EPILOGUE(err);    FUNC_EPILOGUE(err);
# Line 536  error_t netfs_attempt_mkdev (struct ious Line 606  error_t netfs_attempt_mkdev (struct ious
606                               mode_t type, dev_t indexes)                               mode_t type, dev_t indexes)
607  {  {
608    FUNC_PROLOGUE_NODE("netfs_attempt_mkdev", node);    FUNC_PROLOGUE_NODE("netfs_attempt_mkdev", node);
609    error_t err = EOPNOTSUPP;    error_t err;
   
   if(! FUSE_OP_HAVE(mknod))  
     goto out;  
   
   /* we need to unlink the existing node, therefore, if unlink is not  
    * available, we cannot turn *node into a device.  
    */  
   if(! FUSE_OP_HAVE(unlink))  
     goto out;  
610    
611    /* check permissions    /* check permissions
612     * XXX, shall we check permissions of the parent directory as well,     * XXX, shall we check permissions of the parent directory as well,
613     * since we're going to unlink files?     * since we're going to unlink files?
614     */     */
   
615    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
616       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))
617      goto out;      goto out;
618    
619      /* check whether the operations are available at all */
620      if(! FUSE_OP_HAVE(mknod))
621        {
622          err = EOPNOTSUPP;
623          goto out;
624        }
625    
626      /* we need to unlink the existing node, therefore, if unlink is not
627       * available, we cannot turn *node into a device.
628       */
629      if(! FUSE_OP_HAVE(unlink))
630        {
631          err = EOPNOTSUPP;
632          goto out;
633        }
634    
635    /* unlink the already existing node, to be able to create the (new)    /* unlink the already existing node, to be able to create the (new)
636     * device file     * device file
637     */     */
# Line 697  error_t netfs_attempt_link (struct iouse Line 773  error_t netfs_attempt_link (struct iouse
773  {  {
774    FUNC_PROLOGUE_FMT("netfs_attempt_link", "link=%s/%s, to=%s",    FUNC_PROLOGUE_FMT("netfs_attempt_link", "link=%s/%s, to=%s",
775                      dir->nn->path, name, file->nn->path);                      dir->nn->path, name, file->nn->path);
776    error_t err = EOPNOTSUPP;    error_t err;
777    struct node *node = NULL;    struct node *node = NULL;
778    
   if(! FUSE_OP_HAVE(link))  
     goto out_nounlock;  
   
779    mutex_lock(&dir->lock);    mutex_lock(&dir->lock);
780    
781    if((err = netfs_attempt_lookup(user, dir, name, &node)))    if((err = netfs_attempt_lookup(user, dir, name, &node)))
# Line 715  error_t netfs_attempt_link (struct iouse Line 788  error_t netfs_attempt_link (struct iouse
788       || (err = fshelp_checkdirmod(&dir->nn_stat, &node->nn_stat, user)))       || (err = fshelp_checkdirmod(&dir->nn_stat, &node->nn_stat, user)))
789      goto out;      goto out;
790    
791      if(! FUSE_OP_HAVE(link)) {
792        err = EOPNOTSUPP;
793        goto out;
794      }
795    
796    if(! excl && FUSE_OP_HAVE(unlink))    if(! excl && FUSE_OP_HAVE(unlink))
797      /* EXCL is not set, therefore we may remove the target, i.e. call      /* EXCL is not set, therefore we may remove the target, i.e. call
798       * unlink on it.  Ignoring return value, as it's mostly not interesting,       * unlink on it.  Ignoring return value, as it's mostly not interesting,
# Line 766  error_t netfs_attempt_rmdir (struct ious Line 844  error_t netfs_attempt_rmdir (struct ious
844                               struct node *dir, char *name)                               struct node *dir, char *name)
845  {  {
846    FUNC_PROLOGUE("netfs_attempt_rmdir");    FUNC_PROLOGUE("netfs_attempt_rmdir");
847    error_t err = EOPNOTSUPP;    error_t err;
848    struct node *node = NULL;    struct node *node = NULL;
849    
   if(! FUSE_OP_HAVE(rmdir))  
     goto out_nounlock;  
   
850    err = netfs_attempt_lookup(user, dir, name, &node);    err = netfs_attempt_lookup(user, dir, name, &node);
851    assert(dir != node);    assert(dir != node);
852    mutex_lock(&dir->lock); /* netfs_attempt_lookup unlocked dir */    mutex_lock(&dir->lock); /* netfs_attempt_lookup unlocked dir */
# Line 783  error_t netfs_attempt_rmdir (struct ious Line 858  error_t netfs_attempt_rmdir (struct ious
858       || (err = fshelp_checkdirmod(&dir->nn_stat, &node->nn_stat, user)))       || (err = fshelp_checkdirmod(&dir->nn_stat, &node->nn_stat, user)))
859      goto out;      goto out;
860    
861    err = -FUSE_OP_CALL(rmdir, node->nn->path);    if(FUSE_OP_HAVE(rmdir))
862        err = -FUSE_OP_CALL(rmdir, node->nn->path);
863      else
864        err = EOPNOTSUPP;
865    
866    
867    /* TODO free associated netnode. really?    /* TODO free associated netnode. really?
868     * FIXME, make sure nn->may_need_sync is set */     * FIXME, make sure nn->may_need_sync is set */
# Line 818  error_t netfs_attempt_mksymlink (struct Line 897  error_t netfs_attempt_mksymlink (struct
897                                   char *name)                                   char *name)
898  {  {
899    FUNC_PROLOGUE_NODE("netfs_attempt_mksymlink", node);    FUNC_PROLOGUE_NODE("netfs_attempt_mksymlink", node);
900    error_t err = EOPNOTSUPP;    error_t err;
   
   /* we need to unlink the existing node, therefore, if unlink is not  
    * available, we cannot create symlinks  
    */  
   if(! FUSE_OP_HAVE(unlink))  
     goto out;  
   
   /* symlink function available? if not, fail. */  
   if(! FUSE_OP_HAVE(symlink))  
     goto out;  
901    
902    /* check permissions    /* check permissions
903     * XXX, shall we check permissions of the parent directory as well,     * XXX, shall we check permissions of the parent directory as well,
904     * since we're going to unlink files?     * since we're going to unlink files?
905     */     */
   
906    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
907       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))
908      goto out;      goto out;
909    
910      /* we need to unlink the existing node, therefore, if unlink is not
911       * available, we cannot create symlinks
912       */
913      if(! FUSE_OP_HAVE(unlink))
914        {
915          err = EOPNOTSUPP;
916          goto out;
917        }
918    
919      /* symlink function available? if not, fail. */
920      if(! FUSE_OP_HAVE(symlink))
921        {
922          err = EOPNOTSUPP;
923          goto out;
924        }
925    
926    /* try to remove the existing node (probably an anonymous file) */    /* try to remove the existing node (probably an anonymous file) */
927    if((err = -FUSE_OP_CALL(unlink, node->nn->path)))    if((err = -FUSE_OP_CALL(unlink, node->nn->path)))
928      goto out;      goto out;
# Line 863  error_t netfs_attempt_rename (struct iou Line 947  error_t netfs_attempt_rename (struct iou
947                                char *toname, int excl)                                char *toname, int excl)
948  {  {
949    FUNC_PROLOGUE("netfs_attempt_rename");    FUNC_PROLOGUE("netfs_attempt_rename");
950    error_t err = EOPNOTSUPP;    error_t err;
951    struct node *fromnode;    struct node *fromnode;
952    char *topath = NULL;    char *topath = NULL;
953    
   if(! FUSE_OP_HAVE(rename))  
     goto out_nounlock;  
   
954    if(! (topath = malloc(strlen(toname) + strlen(todir->nn->path) + 2)))    if(! (topath = malloc(strlen(toname) + strlen(todir->nn->path) + 2)))
955      {      {
956        err = ENOMEM;        err = ENOMEM;
# Line 896  error_t netfs_attempt_rename (struct iou Line 977  error_t netfs_attempt_rename (struct iou
977       || fshelp_checkdirmod(&todir->nn_stat, NULL, user))       || fshelp_checkdirmod(&todir->nn_stat, NULL, user))
978      goto out;      goto out;
979    
980      if(! FUSE_OP_HAVE(rename))
981        {
982          err = EOPNOTSUPP;
983          goto out;
984        }
985    
986    sprintf(topath, "%s/%s", todir->nn->path, toname);    sprintf(topath, "%s/%s", todir->nn->path, toname);
987    
988    if(! excl && FUSE_OP_HAVE(unlink))    if(! excl && FUSE_OP_HAVE(unlink))
# Line 938  error_t netfs_attempt_write (struct ious Line 1025  error_t netfs_attempt_write (struct ious
1025                               loff_t offset, size_t *len, void *data)                               loff_t offset, size_t *len, void *data)
1026  {  {
1027    FUNC_PROLOGUE_NODE("netfs_attempt_write", node);    FUNC_PROLOGUE_NODE("netfs_attempt_write", node);
1028    error_t err = EOPNOTSUPP;    error_t err;
   
   if(! FUSE_OP_HAVE(write))  
     goto out;  
1029    
1030    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
1031       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))       || (err = fshelp_access(&node->nn_stat, S_IWRITE, cred)))
1032      goto out;      goto out;
1033    
1034      if(! FUSE_OP_HAVE(write))
1035        {
1036          err = EOPNOTSUPP;
1037          goto out;
1038        }
1039    
1040    node->nn->info.writepage = 0; /* cannot distinct on the Hurd :( */    node->nn->info.writepage = 0; /* cannot distinct on the Hurd :( */
1041    
1042    int sz = fuse_ops ?    int sz = fuse_ops ?
# Line 971  netfs_attempt_utimes (struct iouser *cre Line 1061  netfs_attempt_utimes (struct iouser *cre
1061                        struct timespec *atime, struct timespec *mtime)                        struct timespec *atime, struct timespec *mtime)
1062  {  {
1063    FUNC_PROLOGUE_NODE("netfs_attempt_utimes", node);    FUNC_PROLOGUE_NODE("netfs_attempt_utimes", node);
1064    error_t err = EOPNOTSUPP;    error_t err;
   
   /* prepare utimebuf for FUSE_OP_HAVE(utime) call */  
   struct utimbuf utb;  
   utb.actime = atime ? atime->tv_sec : node->nn_stat.st_atime;  
   utb.modtime = mtime ? mtime->tv_sec : node->nn_stat.st_mtime;  
1065    
1066    /* test whether operation is supported and permission are sufficient */    /* test whether operation is supported and permission are sufficient */
   if(! FUSE_OP_HAVE(utime))  
     goto out;  
   
1067    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
1068       || (err = fshelp_isowner(&node->nn_stat, cred)))       || (err = fshelp_isowner(&node->nn_stat, cred)))
1069      goto out;      goto out;
1070    
1071      if(! FUSE_OP_HAVE(utime))
1072        {
1073          err = EOPNOTSUPP;
1074          goto out;
1075        }
1076    
1077      /* prepare utimebuf for FUSE_OP_HAVE(utime) call */
1078      struct utimbuf utb;
1079      utb.actime = atime ? atime->tv_sec : node->nn_stat.st_atime;
1080      utb.modtime = mtime ? mtime->tv_sec : node->nn_stat.st_mtime;
1081    
1082    err = -FUSE_OP_CALL(utime, node->nn->path, &utb);    err = -FUSE_OP_CALL(utime, node->nn->path, &utb);
1083    
1084    if (! err)    if (! err)
# Line 1012  error_t netfs_attempt_read (struct iouse Line 1105  error_t netfs_attempt_read (struct iouse
1105                              loff_t offset, size_t *len, void *data)                              loff_t offset, size_t *len, void *data)
1106  {  {
1107    FUNC_PROLOGUE_NODE("netfs_attempt_read", node);    FUNC_PROLOGUE_NODE("netfs_attempt_read", node);
1108    error_t err = EOPNOTSUPP;    error_t err;
   
   if(! FUSE_OP_HAVE(read))  
     goto out;  
1109    
1110    if((err = netfs_validate_stat(node, cred))    if((err = netfs_validate_stat(node, cred))
1111       || (err = fshelp_access(&node->nn_stat, S_IREAD, cred)))       || (err = fshelp_access(&node->nn_stat, S_IREAD, cred)))
1112      goto out;      goto out;
1113    
1114      if(! FUSE_OP_HAVE(read))
1115        {
1116          err = EOPNOTSUPP;
1117          goto out;
1118        }
1119    
1120    
1121    int sz = fuse_ops ?    int sz = fuse_ops ?
1122      (fuse_ops->read(node->nn->path, data, *len, offset, &node->nn->info)) :      (fuse_ops->read(node->nn->path, data, *len, offset, &node->nn->info)) :
1123      (fuse_ops_compat->read(node->nn->path, data, *len, offset));      (fuse_ops_compat->read(node->nn->path, data, *len, offset));
# Line 1187  netfs_get_dirents (struct iouser *cred, Line 1284  netfs_get_dirents (struct iouser *cred,
1284                          * i.e. never allocate any further memory */                          * i.e. never allocate any further memory */
1285    
1286    FUNC_PROLOGUE_NODE("netfs_get_dirents", dir);    FUNC_PROLOGUE_NODE("netfs_get_dirents", dir);
1287    error_t err = EOPNOTSUPP;    error_t err;
1288    fuse_dirh_t handle;    fuse_dirh_t handle;
1289    
   if(! FUSE_OP_HAVE(getdir))  
     goto out;  
   
1290    if((err = netfs_validate_stat(dir, cred))    if((err = netfs_validate_stat(dir, cred))
1291       || (err = fshelp_access(&dir->nn_stat, S_IREAD, cred))       || (err = fshelp_access(&dir->nn_stat, S_IREAD, cred))
1292       || (err = fshelp_access(&dir->nn_stat, S_IEXEC, cred)))       || (err = fshelp_access(&dir->nn_stat, S_IEXEC, cred)))
1293      goto out;      goto out;
1294    
1295      if(! FUSE_OP_HAVE(getdir))
1296        {
1297          err = EOPNOTSUPP;
1298          goto out;
1299        }
1300    
1301    if(! (handle = malloc(sizeof(struct fuse_dirhandle))))    if(! (handle = malloc(sizeof(struct fuse_dirhandle))))
1302      {      {
1303        err = ENOMEM; /* sorry, translator not available ... */        err = ENOMEM; /* sorry, translator not available ... */

Legend:
Removed from v.1.36  
changed lines
  Added in v.1.37

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26