Пример #1
0
int fskit_test_mkdir_LR_recursive( struct fskit_core* core, char const* path, int depth ) {

   if( depth <= 0 ) {
      return 0;
   }

   fskit_debug("mkdir('%s')\n", path );
   
   int rc = fskit_mkdir( core, path, 0755, 0, 0 );
   if( rc != 0 ) {
      fskit_error("fskit_mkdir('%s') rc = %d\n", path, rc );
      return rc;
   }

   char* new_path_1 = fskit_fullpath( path, "L", NULL );
   char* new_path_2 = fskit_fullpath( path, "R", NULL );

   rc = fskit_test_mkdir_LR_recursive( core, new_path_1, depth - 1 );
   if( rc != 0 ) {
      fskit_error("fskit_test_mkdir_LR_recursive('%s') rc = %d\n", new_path_1, rc );

      free( new_path_1 );
      free( new_path_2 );
      return rc;
   }

   rc = fskit_test_mkdir_LR_recursive( core, new_path_2, depth - 1 );
   if( rc != 0 ) {
      fskit_error("fskit_test_mkdir_LR_recursive('%s') rc = %d\n", new_path_2, rc );

      free( new_path_1 );
      free( new_path_2 );
      return rc;
   }

   free( new_path_1 );
   free( new_path_2 );

   return 0;
}
Пример #2
0
// print out a tree to the given file stream
int fskit_print_tree( FILE* out, struct fskit_entry* root ) {

   struct fskit_entry* node = NULL;
   char* next_path = NULL;
   char type_str[10];
   int rc = 0;
   fskit_entry_set_itr itr;
   fskit_entry_set* child = NULL;

   vector< struct fskit_entry* > frontier;
   vector< char* > frontier_paths;

   frontier.push_back( root );
   frontier_paths.push_back( strdup(root->name) );

   while( frontier.size() > 0 ) {

      node = frontier[0];
      next_path = frontier_paths[0];

      frontier.erase( frontier.begin() );
      frontier_paths.erase( frontier_paths.begin() );

      fskit_type_to_string( node->type, type_str );

      fprintf( out, "%s: inode=%" PRIX64 " size=%jd mode=%o user=%" PRIu64 " group=%" PRIu64 " ctime=(%" PRId64 ".%" PRId32 ") mtime=(%" PRId64 ".%" PRId32 ") atime=(%" PRId64 ".%" PRId32 ") mem=%p \"%s\"\n",
                    type_str, node->file_id, node->size, node->mode, node->owner, node->group, node->ctime_sec, node->ctime_nsec, node->mtime_sec, node->mtime_nsec, node->atime_sec, node->atime_nsec, node, next_path );

      if( node->type == FSKIT_ENTRY_TYPE_DIR ) {

         if( node->children == NULL ) {
            fskit_error("ERR: children of %p == NULL\n", node );

            rc = -EINVAL;
            break;
         }

         // explore children
         for( child = fskit_entry_set_begin( node->children, &itr ); child != NULL; child = fskit_entry_set_next( &itr ) ) {

            char const* name = fskit_entry_set_name_at( &itr );
            struct fskit_entry* child = fskit_entry_set_child_at( &itr );

            if( child == NULL ) {
               continue;
            }
            if( strcmp(".", name) == 0 || strcmp("..", name) == 0 ) {
               continue;
            }

            frontier.push_back( child );
            frontier_paths.push_back( fskit_fullpath( next_path, child->name, NULL ) );
         }
      }

      free( next_path );
   }

   if( rc != 0 ) {

      for( unsigned int i = 0; i < frontier_paths.size(); i++ ) {

         if( frontier_paths.at(i) ) {
            free( frontier_paths.at(i) );
         }
      }

      frontier_paths.clear();
   }

   return rc;
}
Пример #3
0
Файл: fs.cpp Проект: 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;
}