#ifndef UnixFile_hpp
#define UnixFile_hpp


#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>    // neccessary for mode_t when using the glibc (?)

#include <string>

#include "File.hpp"
#include "Date.hpp"

using namespace std;

// Last changed: 1999-10-29
 
/**
  @short Represents Unix' file mode (access rights).
  For now, this class is used internally in class UnixFile only.
  */
class UnixFileMode {
  protected:      mode_t  filemode;             // Typ importiert!
  public:         
                  UnixFileMode() { }
                  UnixFileMode( mode_t fm);
                  string toString()  const;
                  mode_t getMode()  const { return filemode; }
};


/**
 *  @short Represents files/directories on Unix filesystems
 *
 *  This class' instances represent files that appear on an
 *  Unix filesystem, including all types like
 *  regular files, directories, symbolic links and
 *  other 'special' files.
 *  The file represented may or may not exist on the filesystem.
 *
 *  Instances are created by giving the file's access path.
 *  A special mode may be used: "AS_IS" for stating (symbolic) links 
 *  as they are (default) or "DEREF" for automatically 'dereferencing' a symbolic link.
 *  The file's existence and properties may be queried.
 *
 *  Most proporties are defined only on existing files. 
 *  Only the following properties may be queried in any case:
 *  File name, path, existance. 
 *  The actual meaning of some properties may depend on the operating system and/or the actual file type.
 *
 *  (Almost) all properties are cached by the respective instance.
 *  The properties are read initially on creation 
 *  and are updated on calls to sync().
 *
 *  @author Michael Weers
 *  @version 0.7.2 1999-01-22
 */
class File.html">UnixFile : public File {
                                            // class constants
  public: 
    static const  short int  AS_IS= 0, DEREF= 1;

    static const  char FILE='-', DIRECTORY='d', SYMLINK='l',
                       BLOCK_DEVICE='b', CHAR_DEVICE='c',
                       PIPE='p', SOCKET='s';

    /** The path separator */
    static const  char separator= '/';

    /** enumeration type for the internal state's values */
    enum State { NOT_EXISTING, ACCESS_DENIED, NORMAL};  
    
                                            // instance attributes
                  State state;
  protected:
                                    // internal mode (AS_IS or DEREF) 
                  short int  stat_mode;
                                        // file info attributes
                  string    fullname;                                            
                  char      type;
                  long int  size;

                  Date      status_change_time,
                            access_time,
                            modification_time;

                  int       owner,  group;

                  UnixFileMode fileMode;

                  /** Points to an object representing the linked-to file, if
                  if the instance represents a symbolic link, NULL otherwise. <P>
                  Important! That object still has the name and path from the 
                  the instance, because it was created with UnixFile(...,DEREF)
                  */
                  UnixFile* linkedFile;  

                                        // Constructors, assignment operator
  public:
                  UnixFile( const string& full_, 
                                const short int  mode= AS_IS );
                                
                  UnixFile( const UnixFile&);
                  UnixFile& operator= (const UnixFile&);
            
         virtual  ~UnixFile();

                                        // high level query functions

                  /** Queries if the file behaves as a container
                      for other files. Primarily this is true for direcories. 
                      On Unix filesystems,
                      this function also returns true if file is a symbolic
                      link to a direcory. */
         virtual  bool isNavigable()  const;      // overwrite        
         
                  /** true if the file is 'navigable' and something like 
                      a subdirectory of the directory it is contained in.*/
                  bool isSubNavigable()  const {
                    bool result= isNavigable();
                    if (result) {
                      string name;
                      if ( linkedFile!=NULL) 
                        name= linkedFile->getName(); // problem: name is still the link's one
                      else
                        name= getName();
                        
                      result= name != "." && name != "..";
                    }
                    return result;
                  }

                                        // general query functions

                  /** Queries the file's existence. 
                      @return  true if file exists (and information about it
                      could be obtained).
                  */
         virtual  bool exists()  const;           // overwrite
                  char getType()  const { return type; }

	 /** check for 'file equality' (same name and path) */
         virtual  bool equals( UnixFile& f)  const;
	          bool isAbsolute()  const;

         virtual  bool isDirectory()  const;      // overwrite
         virtual  bool isFile()  const;           // overwrite
         virtual  bool isLink()  const;
                  bool isBrokenLink()  const;
         
                  /** Returns if a regular file is an executable (applies on
                      regular files only */
                  bool isExecutable()  const;

                  bool isSpecialDirectory()  const {
                    string name= getName();
                    return name=="." || name=="..";
                  }

                  /** Returns the file's name (without path) */
         virtual  string getName()  const;          // overwrite

                  /** Returns the file's access path (without its own name).
                    The result is generally a pathname of the directory the file is
                    contained in.
                    Precisely, the result is access path part of the path specificaton
                    the object was created from, and if that was given as a relative path
                    the result is also a relative path. <P>
                    If the file has no path specification (the file is
                    contained in the current direcory), '.' is returned.
                    The parent of the root directory is '/' (by definition).
                    The result is never an empty string. */
         virtual  string getParent()  const;          // overwrite

                  /** Returns the file's complete path with name */
                  // proposed new name: getPath
         virtual  string getFullName()  const;      // overwrite
         virtual  string getPath()  const { return fullname; }
         
                  string getAbsolutePath()  const { 
                    return getCanonicalPath(getAbsolutePath( fullname)); }

                  /** Returns the file name extension or an empty string if the file has none */
         virtual  string getNameExtension()  const;

                  /** Returns the link name for symbolic links, as it is stored on the filesystem.*/
                  string getLinkName()  const;

                  long int getSize()  const;

                  /** Returns the file's mode (as an integer value)*/
                  mode_t getMode()  const { return fileMode.getMode(); }

                  string getAttributeString()  const;
                  
                  int getOwnerID()  const { return owner; }

                  /** Return the user name (login). An empty string indicates that
                  there is no name corresponding to the user ID. 
                  @param generate If true and no name is present, generate one. */
                  string getOwner( bool = false)  const;
                  string getOwnerName()  const;
                  
                  int getGroupID()  const { return group; }
                  string getGroup( bool = false)  const;
                  
                  const Date&  getLastModified()  const { return modification_time;}
                  const Date&  getLastAccessed()  const { return access_time; }
                  const Date&  getLastStatusChanged()  const { return status_change_time; }

                                        // control actions
                  void sync();

     static       string getAbsolutePath( const string& path);
     static       string getCanonicalPath( string path); 
}; // class UnixFile

#endif

Documentation generated by mw@nemea on Mit Nov 24 00:09:19 CET 1999