//
// File: hzDirectory.h
//
// Legal Notice: This file is part of the HadronZoo C++ Class Library.
//
// Copyright 2025 HadronZoo Project (http://www.hadronzoo.com)
//
// The HadronZoo C++ Class Library is free software: You can redistribute it, and/or modify it under the terms of the GNU Lesser General Public License, as published by the Free
// Software Foundation, either version 3 of the License, or any later version.
//
// The HadronZoo C++ Class Library is distributed in the hope that it will be useful, 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.
//
// You should have received a copy of the GNU Lesser General Public License along with the HadronZoo C++ Class Library. If not, see http://www.gnu.org/licenses.
//
#ifndef hzDirectory_h
#define hzDirectory_h
// System includes
#include <sys/stat.h>
// Other HadronZoo includes
#include "hzChars.h"
#include "hzDate.h"
#include "hzChain.h"
#include "hzCodec.h"
#include "hzTmplArray.h"
#include "hzTmplList.h"
#include "hzTmplVect.h"
#include "hzTmplMapS.h"
#include "hzTmplMapM.h"
/*
** Definitions
*/
#define ISDIR S_ISDIR
typedef struct stat FSTAT ;
/*
** Control flags for directories & files for a filesystem state compare regime
*/
// Status flags
#define FSI_INERT 0x0000 // File or dir exists in both current and previous snapshot and has not changed.
#define FSI_MODIFY 0x0001 // File or dir exists in both current and previous snapshot but has changed.
#define FSI_CREATE 0x0002 // File or dir exists only in the current snapshot and is thus new.
#define FSI_DELETE 0x0004 // File or dir exists only in the previous snapshot and is thus deprecated.
class hzDirent
{
// Category: Filesystem
//
// Directory entry. Either file or directory
hzString m_parent ; // The parent directory
hzString m_Name ; // This will be full path if this is a dir, only the name if a file
uint64_t m_Size ; // Size in bytes (assuming 64 bit OS)
uint32_t m_Ctime ; // Date & time when file created
uint32_t m_Mtime ; // Date & time of last modification
uint32_t m_Inode ; // Inode value
uint32_t m_Mode ; // UNIX Permissions
uint16_t m_Owner ; // User Id of owner (unused under Windows)
uint16_t m_Group ; // Group Id of owner (unused under Windows)
uint16_t m_Links ; // Number of hard links
uint16_t m_Status ; // Appliction assigned value (eg version)
public:
hzDirent (void)
{
m_Size = 0 ;
m_Inode = m_Ctime = m_Mtime = m_Mode = 0 ;
m_Owner = m_Group = m_Links = m_Status = 0 ;
}
~hzDirent (void)
{
//m_Kinder.Clear() ;
}
// Set functions
void InitStat (const hzString& pardir, const hzString& name, FSTAT& fs) ;
void InitNorm ( const hzString& pardir,
const hzString& name,
uint64_t size,
uint32_t ino,
uint32_t ctime,
uint32_t mtime,
uint32_t mode,
uint32_t uid,
uint32_t gid,
uint32_t nlink) ;
// Set functions
void SetName (const char* name) { m_Name = name ; }
void SetName (hzString& name) { m_Name = name ; }
void SetCtime (hzXDate& d) { m_Ctime = d.AsEpoch() ; }
void SetMtime (hzXDate& d) { m_Mtime = d.AsEpoch() ; }
void SetCtime (uint32_t ctime) { m_Ctime = ctime ; }
void SetMtime (uint32_t mtime) { m_Mtime = mtime ; }
void SetSize (uint32_t nSize) { m_Size = nSize ; }
// Get functions
const hzString Path (void) const ;
const hzString strName (void) const { return m_Name ; }
const char* txtName (void) const { return *m_Name ; }
uint32_t Ctime (void) const { return m_Ctime ; }
uint32_t Mtime (void) const { return m_Mtime ; }
uint32_t Inode (void) const { return m_Inode ; }
uint32_t Mode (void) const { return m_Mode ; }
uint32_t Size (void) const { return m_Size ; }
uint16_t Owner (void) const { return m_Owner ; }
uint16_t Group (void) const { return m_Group ; }
uint16_t Nlink (void) const { return m_Links ; }
bool IsDir (void) const { return ISDIR(m_Mode) ? true : false ; }
// Set status functions
void MkInert (void) { m_Status = 0 ; }
void MkModify (void) { m_Status = FSI_MODIFY ; }
void MkCreate (void) { m_Status = FSI_CREATE ; }
void MkDelete (void) { m_Status = FSI_DELETE ; }
// Get status functions
bool IsInert (void) { return m_Status ? false : true ; }
bool IsModify (void) { return m_Status & FSI_MODIFY ? true : false ; }
bool IsCreate (void) { return m_Status & FSI_CREATE ? true : false ; }
bool IsDelete (void) { return m_Status & FSI_DELETE ? true : false ; }
bool IsChanged (void) { return m_Status & (FSI_MODIFY | FSI_CREATE) ? true : false ; }
// Operators
hzDirent& operator= (const hzDirent& op) ;
bool operator< (const hzDirent& op) const ;
bool operator> (const hzDirent& op) const ;
bool operator== (const hzDirent& op) const ;
// Stream operators
friend std::istream& operator>> (std::istream& is, hzDirent& de) ;
friend std::ostream& operator<< (std::ostream& os, const hzDirent& de) ;
} ;
class hzFileset
{
// Category: Filesystem
//
// The hzFileset (file set) class represents a snapshot of a file system subset. The directories and files in the subset can be for any purpose, e.g. webapp configs. hzFileset
// is implemented as a 1:1 map of pathnames to directories and a 1:many map of filenames to files. The directories and files are held as hzDirent instances.
//
// hzFileset is populated by importing a directory/file list or by file system scan. The scan is driven by a set of one or more roots, each of which is a starting point for a
// hierarchical scan.
hzChain m_Error ; // Report errors during scan
uint32_t m_nBlocs ; // No of block devices
uint32_t m_nChars ; // No of char devices
uint32_t m_nLinks ; // No of links
uint32_t m_nSocks ; // No of open sockets
uint64_t m_nBytes ; // Total bytes in all files on all disks
hzEcode _scan_r (hzDirent*, hzString& curdir) ;
void _clear (void) ;
public:
hzMapS<hzString,hzDirent*> m_dirs ; // Index of directories by name
hzMapM<hzString,hzDirent*> m_file ; // Index of files by name
hzList<hzString> m_Roots ; // Root directories
hzFileset (void)
{
_clear() ;
}
~hzFileset (void)
{
_clear() ;
}
hzEcode AddRoot (hzString& pathname)
{
if (pathname)
return m_Roots.Add(pathname) ;
return E_ARGUMENT ;
}
hzEcode Scan (void) ;
hzEcode Import (const char* cpFilename) ;
hzEcode Export (const char* cpFilename) ;
hzChain& Error (void) { return m_Error ; }
uint32_t TotalDirs (void) const { return m_dirs.Count() ; }
uint32_t TotalFiles (void) const { return m_file.Count() ; }
uint64_t TotalBytes (void) const { return m_nBytes ; }
} ;
/*
** Non member prototypes
*/
hzEcode GetCurrDir (hzString& Dir) ;
hzEcode GetAbsPath (hzString& abs, const char* rel) ;
hzEcode ReadDir (hzVect<hzDirent>& Dirs, hzVect<hzDirent>& Files, const char* cpPath = 0, const char* cpCriteria = 0) ;
hzEcode ReadDir (hzVect<hzDirent>& entries, const char* cpPath = 0, const char* cpCriteria = 0) ;
hzEcode ListDir (hzVect<hzString>& Dirs, hzVect<hzString>& Files, const char* cpPath = 0, const char* cpCriteria = 0) ;
hzEcode BlattDir (const char* dirname) ;
hzEcode Filecopy (const hzString& tgt, const hzString& src) ;
hzEcode Dircopy (const hzString& tgt, const hzString& src, bool bRecurse) ;
hzEcode Filemove (const hzString& tgt, const hzString& src) ;
// FindfilesStd (find files strictly conforming to the supplied criteria)
hzEcode FindfilesStd (hzArray<hzString>& files, const char* criteria) ;
// FindfilesTar (find files according to the tar interpretation of the supplied criteria)
hzEcode FindfilesTar (hzArray<hzString>& files, const char* criteria) ;
hzEcode AssertDir (const char* cpDir, uint32_t nPerms) ;
hzEcode DirExists (const char* dirname) ;
hzEcode TestFile (const char* pathname) ;
hzEcode OpenInputStrm (std::ifstream& is, const char* pathname) ;
#endif // hzDirectory_h