tripwire-open-source/src/fco/fconame.h

233 lines
9.2 KiB
C++

//
// The developer of the original code and/or files is Tripwire, Inc.
// Portions created by Tripwire, Inc. are copyright (C) 2000-2018 Tripwire,
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
// reserved.
//
// This program is free software. The contents of this file are subject
// to the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version. You may redistribute it and/or modify it
// only in compliance with the GNU General Public License.
//
// This program is distributed in the hope that it will be useful.
// However, this program is distributed AS-IS WITHOUT ANY
// WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
// FOR A PARTICULAR PURPOSE. Please see the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// Nothing in the GNU General Public License or any other license to use
// the code or files shall permit you to use Tripwire's trademarks,
// service marks, or other intellectual property without Tripwire's
// prior written consent.
//
// If you have any questions, please contact Tripwire, Inc. at either
// info@tripwire.org or www.tripwire.org.
//
///////////////////////////////////////////////////////////////////////////////
// fconame.h
//
// cFCOName -- represents the name of an FCO
#ifndef __FCONAME_H
#define __FCONAME_H
#ifndef __SERIALIZABLE_H
#include "core/serializable.h"
#endif
#ifndef __FCONAMEINFO_H
#include "fconameinfo.h"
#endif
///////////////////////////////////////////////////////////////////////////////
// class cFCOName -- How we name a FCO. The implementation has ended up being
// a wrapper around a standard string.
///////////////////////////////////////////////////////////////////////////////
class cFCONameTblNode;
class cFCONameIter;
class cFCOName_i;
class cFCOName : public iTypedSerializable
{
DECLARE_TYPEDSERIALIZABLE()
public:
typedef cFCONameIter iterator;
explicit cFCOName(iFCONameInfo* iNI = NULL);
cFCOName(const cFCOName& rhs);
explicit cFCOName(const TSTRING& rhs, iFCONameInfo* iNI = NULL);
explicit cFCOName(const TCHAR* rhs, iFCONameInfo* iNI = NULL);
// these ctors are explicit because it is expensive to create these things, so we don't want to
// do it unexpectedly
virtual ~cFCOName();
cFCOName& operator = (const cFCOName& rhs);
cFCOName& operator = (const TSTRING& rhs);
cFCOName& operator = (const TCHAR* rhs);
bool operator < (const cFCOName& rhs) const;
// defines an arbitrary order for cFCONames. This is so that names can
// be stored in trees and other ordered data structures in order to facilitate
// fast lookups.
bool operator == (const cFCOName& rhs) const;
bool operator != (const cFCOName& rhs) const;
bool IsEqual (const cFCOName& rhs) const;
// both of these are synonyms for (GetRelationship(rhs) == REL_EQUAL)
TSTRING AsString() const;
// return a string representation of the string
bool IsCaseSensitive() const;
void SetCaseSensitive(bool val);
// determines how name comparisons are done. If two cFCONames are compared who are
// both case insensitive, a case insensitive compare is done. If both are case sensitive,
// a case sensitive compare is done. If one is and one isn't case sensitive (? TODO: what
// is the right thing to do in this case? ASSERT(0)? do a case sensitive compare??)
TCHAR GetDelimiter() const;
void SetDelimiter(TCHAR delimiter);
// defines what the path-delimiting character is
void Push(const TSTRING& str);
// pushes the named string onto the end of the path. A delimiter is implicitely placed between the old end
// and the new string. if debug is defined, it is asserted that the new string does not contain the
// delimiting character
const TCHAR* Pop();
// removes the last part of the path from the name and returns it. ASSERTS and returns an undefined value if
// the path is empty
const TCHAR* PopFront();
// removes the first part of the path from the name and returns it. ASSERTS and returns an undefined value if
// the path is empty
void Clear();
// removes all elements from the name; after this, GetSize() == 0.
const TCHAR* GetShortName() const;
// this will return the final string in the vector. It will assert that the name is not empty.
int GetSize() const;
// returns the number of path items (strings between delimiters) that are in the fco name. It is always equal
// to the number of delimiters in the path plus one.
enum Relationship
{
REL_BELOW, // an fco is below another (/etc/passwd is below /etc)
REL_ABOVE, // an fco is above another (/etc is above /etc/passwd)
REL_EQUAL, // the fcos are equal (/etc/passwd is equal to /etc/passwd)
REL_UNRELATED // the fcos are unrelated (/var/spool/mail is unrelated to /var/log/pig.log)
};
Relationship GetRelationship(const cFCOName& rhs) const;
// returns the relationship of _this_ name to the one passed in (ie -- if REL_BELOW is returned,
// this fco name is below the one passed in)
virtual void Read (iSerializer* pSerializer, int32 version = 0); // throw (eSerializer, eArchive)
virtual void Write(iSerializer* pSerializer) const; // throw (eSerializer, eArchive)
//////////////////////////////////
// Debugging method
//////////////////////////////////
static void ClearNameTable();
// this method should _only_ be called when the program is exiting, and you are positively sure you
// will not be using or creating any more cFCONames. Violating this rule will result in unpredictable
// results. This clears out the cFCOName internal name table, making memory leaks easier to find.
protected:
friend class cFCOName_i;
friend class cFCONameIter;
void ParseString(const TCHAR* str);
// helper function that takes the pathname pointer to by str and fills out mpPathName
void CopyOnModify();
// if the fconame is modified and mpPathName is shared by more than one object, this will
// release mpPathName and create a new one, so we don't change any other object's data
void SetNameInfo(iFCONameInfo* pNI);
// sets the delimiter and case sensitiveness to the name info's
cFCOName_i* mpPathName;
TCHAR mDelimiter; // the delimiting character in names (ie -- in file systems, it is '/')
bool mbCaseSensitive; // determines whether name compares are case sensitive of not
// this is what type of structure holds the elements of the name
//
typedef std::vector<cFCONameTblNode*> ListType;
#ifdef DEBUG
TSTRING mDebugStrName; // so we can see this guy's value in the debug window
#endif
};
//-----------------------------------------------------------------------------
// cFCONameIter
//-----------------------------------------------------------------------------
class cFCONameIter_i;
class cFCONameIter
{
public:
explicit cFCONameIter(const cFCOName& name);
~cFCONameIter();
int GetSize() const; // returns the number of entries in the fco name
void SeekBegin();
void Next();
void Prev();
bool Done() const;
int Index() const;
// return the current offset from the beginning of the short name list
void SeekTo( int index );
// seeks to the given index. asserts that the index is appropriate for the
// current fco name.
const TCHAR* GetName() const;
private:
void operator=(const cFCONameIter& rhs); // not impl
cFCONameIter(const cFCONameIter& rhs); // not impl
// the data...
//
const cFCOName& mName;
cFCOName::ListType::const_iterator mIter;
};
//#############################################################################
// inline implementation
inline bool cFCOName::IsCaseSensitive() const
{
return mbCaseSensitive;
}
inline void cFCOName::SetCaseSensitive(bool val)
{
mbCaseSensitive = val;
}
inline TCHAR cFCOName::GetDelimiter() const
{
return mDelimiter;
}
inline void cFCOName::SetDelimiter(TCHAR delimiter)
{
mDelimiter = delimiter;
}
///////////////////////////////////////////////////////////////////////////////
// IsEqual
///////////////////////////////////////////////////////////////////////////////
inline bool cFCOName::IsEqual(const cFCOName& rhs) const
{
return (GetRelationship(rhs) == cFCOName::REL_EQUAL);
}
inline bool cFCOName::operator==(const cFCOName& rhs) const
{
return IsEqual(rhs);
}
inline bool cFCOName::operator!=(const cFCOName& rhs) const
{
return (! IsEqual(rhs));
}
#endif //__FCONAME_H