<commit_before>/*
   fskit: a library for creating multi-threaded in-RAM filesystems
   Copyright (C) 2014  <NAME>

   This program is dual-licensed: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License version 3 or later as
   published by the Free Software Foundation. For the terms of this
   license, see LICENSE.LGPLv3+ or <http://www.gnu.org/licenses/>.

   You are free to use this program under the terms of the GNU Lesser General
   Public License, but WITHOUT ANY WARRANTY; without even the implied
   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the GNU Lesser General Public License for more details.

   Alternatively, you are free to use this program under the terms of the
   Internet Software Consortium License, but WITHOUT ANY WARRANTY; without
   even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   For the terms of this license, see LICENSE.ISC or
   <http://www.isc.org/downloads/software-support-policy/isc-license/>.
*/

#include <fskit/stat.h>
#include <fskit/route.h>

#include "fskit_private/private.h"

// NOTE: fent cannot be locked
int fskit_do_user_stat( struct fskit_core* core, char const* fs_path, struct fskit_entry* fent, struct stat* sb ) {

   int rc = 0;
   int cbrc = 0;
   char name[FSKIT_FILESYSTEM_NAMEMAX+1];
   
   struct fskit_route_dispatch_args dargs;

   memset( name, 0, FSKIT_FILESYSTEM_NAMEMAX+1 );
   fskit_basename( fs_path, name );
   
   fskit_route_stat_args( &dargs, name, sb );

   rc = fskit_route_call_stat( core, fs_path, fent, &dargs, &cbrc );

   if( rc == -EPERM || rc == -ENOSYS ) {
      // no stat defined
      return 0;
   }
   else if( rc != 0 || cbrc != 0 ) {
       
      fskit_error("fskit_route_call_stat rc = %d, cbrc = %d\n", rc, cbrc );
   }

   return cbrc;
}

// stat a path.
// fill in the stat buffer on success.
// return the usual path resolution errors.
int fskit_stat( struct fskit_core* core, char const* fs_path, uint64_t user, uint64_t group, struct stat* sb ) {

   int rc = 0;

   // ref this entry, so it won't disappear on stat
   struct fskit_entry* fent = fskit_entry_ref( core, fs_path, &rc );
   if( fent == NULL ) {
      
      return rc;
   }
   
   // stat it
   rc = fskit_fstat( core, fs_path, fent, sb );
<commit_msg>Indicate in the user route to stat that fent doesn't exist<commit_after>/*
   fskit: a library for creating multi-threaded in-RAM filesystems
   Copyright (C) 2014  <NAME>

   This program is dual-licensed: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License version 3 or later as
   published by the Free Software Foundation. For the terms of this
   license, see LICENSE.LGPLv3+ or <http://www.gnu.org/licenses/>.

   You are free to use this program under the terms of the GNU Lesser General
   Public License, but WITHOUT ANY WARRANTY; without even the implied
   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   See the GNU Lesser General Public License for more details.

   Alternatively, you are free to use this program under the terms of the
   Internet Software Consortium License, but WITHOUT ANY WARRANTY; without
   even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   For the terms of this license, see LICENSE.ISC or
   <http://www.isc.org/downloads/software-support-policy/isc-license/>.
*/

#include <fskit/stat.h>
#include <fskit/route.h>

#include "fskit_private/private.h"

// NOTE: fent cannot be locked (or, it can be NULL)
int fskit_do_user_stat( struct fskit_core* core, char const* fs_path, struct fskit_entry* fent, struct stat* sb ) {

   int rc = 0;
   int cbrc = 0;
   char name[FSKIT_FILESYSTEM_NAMEMAX+1];
   
   struct fskit_route_dispatch_args dargs;

   memset( name, 0, FSKIT_FILESYSTEM_NAMEMAX+1 );
   fskit_basename( fs_path, name );
   
   fskit_route_stat_args( &dargs, name, sb, true );

   rc = fskit_route_call_stat( core, fs_path, fent, &dargs, &cbrc );

   if( rc == -EPERM || rc == -ENOSYS ) {
      // no stat defined
      return 0;
   }
   else if( rc != 0 || cbrc != 0 ) {
       
      fskit_error("fskit_route_call_stat rc = %d, cbrc = %d\n", rc, cbrc );
   }

   return cbrc;
}

// stat a path.
// fill in the stat buffer on success.
// return the usual path resolution errors.
int fskit_stat( struct fskit_core* core, char const* fs_path, uint64_t user, uint64_t group, struct stat* sb ) {

   int rc = 0;

   // ref this entry, so it won't disappear on stat
   struct fskit_entry* fent = fskit_entry_ref( core, fs_path, &rc );
   if( fent == NULL ) {
      
      // doesn't exist, but maybe the FS implementation will add it... 
      rc = fskit_do_user_stat( core, fs_path, NULL, sb );
      return rc;
   }
   
   // stat it
   rc = fskit_fstat( core, fs_path, fent, sb );

{'fraction_non_alphanumeric': 0.08950617283950617, 'fraction_numerical': 0.007818930041152264, 'mean_word_length': 3.1618150684931505, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1016663', 'n_tokens_mistral': 1648, 'n_tokens_neox': 1585, 'n_words': 604}