Esempio n. 1
0
File: stat.c Progetto: jaromil/fskit
// stat an inode directly
// fill in the stat buffer, but do NOT call the user route
// always succeeds
// NOTE: fent must be read-locked
int fskit_entry_fstat( struct fskit_entry* fent, struct stat* sb ) {
   
   // fill in defaults
   sb->st_dev = 0;
   sb->st_ino = fent->file_id;
   sb->st_mode = fskit_fullmode( fent->type, fent->mode );
   sb->st_nlink = fent->link_count;
   sb->st_uid = fent->owner;
   sb->st_gid = fent->group;
   sb->st_rdev = fent->dev;
   sb->st_size = fent->size;
   sb->st_blksize = 0;
   sb->st_blocks = 0;

   sb->st_atim.tv_sec = fent->atime_sec;
   sb->st_atim.tv_nsec = fent->atime_nsec;

   sb->st_mtim.tv_sec = fent->mtime_sec;
   sb->st_mtim.tv_nsec = fent->mtime_nsec;

   sb->st_ctim.tv_sec = fent->ctime_sec;
   sb->st_ctim.tv_nsec = fent->ctime_nsec;

   return 0;
}
Esempio n. 2
0
File: fs.cpp Progetto: 8l/vdev
// readdir: equivocate about which devices exist, depending on who's asking
// omit entries if the ACLs forbid them
int vdevfs_readdir( struct fskit_core* core, struct fskit_match_group* grp, struct fskit_entry* fent, struct fskit_dir_entry** dirents, size_t num_dirents ) {
   
   int rc = 0;
   struct fskit_entry* child = NULL;
   
   // entries to omit in the listing
   vector<int> omitted_idx;
   
   pid_t pid = 0;
   uid_t uid = 0;
   gid_t gid = 0;
   
   struct vdevfs* vdev = (struct vdevfs*)fskit_core_get_user_data( core );
   struct fskit_fuse_state* fs_state = fskit_fuse_get_state();
   
   struct stat sb;
   struct pstat ps;
   char* child_path = NULL;
   
   pid = fskit_fuse_get_pid();
   uid = fskit_fuse_get_uid( fs_state );
   gid = fskit_fuse_get_gid( fs_state );
   
   vdev_debug("vdevfs_readdir(%s, %zu) from user %d group %d task %d\n", grp->path, num_dirents, uid, gid, pid );
   
   // see who's asking
   rc = pstat( pid, &ps, 0 );
   if( rc != 0 ) { 
      
      vdev_error("pstat(%d) rc = %d\n", pid, rc );
      return -EIO;
   }
   
   for( unsigned int i = 0; i < num_dirents; i++ ) {
      
      // skip . and ..
      if( strcmp(dirents[i]->name, ".") == 0 || strcmp(dirents[i]->name, "..") == 0 ) {
         continue;
      }
      
      // find the associated fskit_entry
      child = fskit_dir_find_by_name( fent, dirents[i]->name );
      
      if( child == NULL ) {
         // strange, shouldn't happen...
         continue;
      }
      
      fskit_entry_rlock( child );
      
      // construct a stat buffer from what we actually need 
      memset( &sb, 0, sizeof(struct stat) );
      
      sb.st_uid = child->owner;
      sb.st_gid = child->group;
      sb.st_mode = fskit_fullmode( child->type, child->mode );
      
      child_path = fskit_fullpath( grp->path, child->name, NULL );
      if( child_path == NULL ) {
         
         // can't continue; OOM
         fskit_entry_unlock( child );
         rc = -ENOMEM;
         break;
      }
      
      // filter it 
      rc = vdev_acl_apply_all( vdev->config, vdev->acls, vdev->num_acls, child_path, &ps, uid, gid, &sb );
      if( rc < 0 ) {
         
         vdev_error("vdev_acl_apply_all('%s', uid=%d, gid=%d, pid=%d) rc = %d\n", child_path, uid, gid, pid, rc );
         rc = -EIO;
      }
      else if( rc == 0 || (sb.st_mode & 0777) == 0 ) {
         
         // omit this one 
         vdev_debug("Filter '%s'\n", child->name );
         omitted_idx.push_back( i );
         
         rc = 0;
      }
      else {
         
         // success; matched
         rc = 0;
      }
      
      fskit_entry_unlock( child );
      
      free( child_path );
      
      // error?
      if( rc != 0 ) {
         break;
      }
   }
   
   // skip ACL'ed entries
   for( unsigned int i = 0; i < omitted_idx.size(); i++ ) {
      
      fskit_readdir_omit( dirents, omitted_idx[i] );
   }
   
   return rc;
}