예제 #1
0
// utime
int fs_entry_utime( struct fs_core* core, char const* path, struct utimbuf* tb, uint64_t user, uint64_t volume ) {
   int err = 0;
   uint64_t parent_id = 0;
   char* parent_name = NULL;
   
   struct fs_entry* fent = fs_entry_resolve_path_and_parent_info( core, path, user, volume, true, &err, &parent_id, &parent_name );
   if( !fent || err ) {
      if( !err )
         err = -ENOMEM;

      return err;
   }

   // check permissions
   if( tb == NULL && !IS_WRITEABLE( fent->mode, fent->owner, fent->volume, user, volume ) ) {
      fs_entry_unlock( fent );
      return -EACCES;
   }
   if( tb != NULL && fent->owner != user ) {
      fs_entry_unlock( fent );
      return -EACCES;
   }

   if( tb != NULL ) {
      fent->mtime_sec = tb->modtime;
      fent->atime = tb->actime;
   }
   else {
      struct timespec ts;
      clock_gettime( CLOCK_REALTIME, &ts );

      fent->mtime_sec = ts.tv_sec;
      fent->mtime_nsec = ts.tv_nsec;
      fent->atime = fent->mtime_sec;
   }

   fent->atime = currentTimeSeconds();

   // post update
   struct md_entry up;
   fs_entry_to_md_entry( core, &up, fent, parent_id, parent_name );

   int rc = ms_client_update( core->ms, &fent->write_nonce, &up );
   if( rc != 0 ) {
      errorf("ms_client_update(%s) rc = %d\n", path, rc );
   }

   md_entry_free( &up );
   fs_entry_unlock( fent );
   return rc;
}
예제 #2
0
// open a directory, but fail-fast if we can't get path metadata
struct fs_dir_handle* fs_entry_opendir( struct fs_core* core, char const* fs_path, uint64_t user, uint64_t vol, int* err ) {

   // ensure path ends in /
   char path[PATH_MAX];
   strcpy( path, fs_path );

   md_sanitize_path( path );
   
   int rc = fs_entry_revalidate_path( core, path );
   if( rc != 0 ) {
      SG_error("fs_entry_revalidate_path(%s) rc = %d\n", path, rc );
      return NULL;
   }

   uint64_t parent_id = 0;
   char* parent_name = NULL;

   struct fs_entry* dir = fs_entry_resolve_path_and_parent_info( core, path, user, vol, true, err, &parent_id, &parent_name );
   if( dir == NULL ) {
      return NULL;
   }
   // make sure it's a directory
   if( dir->ftype != FTYPE_DIR ) {
      *err = -ENOTDIR;
      fs_entry_unlock( dir );
      return NULL;
   }

   // open this directory
   dir->open_count++;
   struct fs_dir_handle* dirh = fs_dir_handle_create( dir, path, parent_id, parent_name );
   rc = fs_dir_handle_open( dirh );
   if( rc != 0 ) {
      fs_dir_handle_destroy( dirh );
      free( dirh );
      dirh = NULL;
      *err = rc;
   }

   // release the directory
   fs_entry_unlock( dir );
   free( parent_name );
   
   return dirh;
}
예제 #3
0
// chmod
int fs_entry_chmod( struct fs_core* core, char const* path, uint64_t user, uint64_t volume, mode_t mode ) {
   int err = 0;
   uint64_t parent_id = 0;
   char* parent_name = NULL;
   
   struct fs_entry* fent = fs_entry_resolve_path_and_parent_info( core, path, user, volume, true, &err, &parent_id, &parent_name );
   if( !fent || err ) {
      if( !err )
         err = -ENOMEM;

      return err;
   }

   // can't chmod unless we own the file
   if( fent->owner != user ) {
      fs_entry_unlock( fent );
      free( parent_name );
      return -EPERM;
   }

   fent->mode = mode;
   
   // post update
   struct md_entry up;
   fs_entry_to_md_entry( core, &up, fent, parent_id, parent_name );

   int rc = ms_client_update( core->ms, &fent->write_nonce, &up );
   if( rc != 0 ) {
      errorf("ms_client_update(%s) rc = %d\n", path, rc );
   }

   md_entry_free( &up );
   fs_entry_unlock( fent );
   free( parent_name );

   return rc;
}