/* * * $Id: k3biso9660.h 619556 2007-01-03 17:38:12Z trueg $ * Copyright (C) 2003 Sebastian Trueg * * This file is part of the K3b project. * Copyright (C) 1998-2007 Sebastian Trueg * * This program is free software; you can redistribute it and/or modify * it under 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. * See the file "COPYING" for the exact licensing terms. */ #ifndef _K3B_ISO9660_H_ #define _K3B_ISO9660_H_ #include #include #include #include #include #include #include "k3b_export.h" namespace K3bDevice { class Device; } class K3bIso9660; class K3bIso9660Backend; struct iso_directory_record; struct el_torito_boot_descriptor; struct iso_primary_descriptor; typedef long sector_t; /** * Simplyfied primary descriptor which just contains the fields * used by K3b. */ class LIBK3B_EXPORT K3bIso9660SimplePrimaryDescriptor { public: /** * Creates an empty descriptor */ K3bIso9660SimplePrimaryDescriptor(); TQString volumeId; TQString systemId; TQString volumeSetId; TQString publisherId; TQString preparerId; TQString applicationId; int volumeSetSize; int volumeSetNumber; long logicalBlockSize; long long volumeSpaceSize; }; LIBK3B_EXPORT bool operator==( const K3bIso9660SimplePrimaryDescriptor& d1, const K3bIso9660SimplePrimaryDescriptor& d2 ); LIBK3B_EXPORT bool operator!=( const K3bIso9660SimplePrimaryDescriptor& d1, const K3bIso9660SimplePrimaryDescriptor& d2 ); /** * Base class for all entries in a K3bIso9660 archive. A lot has been copied * from KArchive. */ class LIBK3B_EXPORT K3bIso9660Entry { public: K3bIso9660Entry( K3bIso9660* archive, const TQString& isoName, const TQString& name, int access, int date, int adate, int cdate, const TQString& user, const TQString& group, const TQString& symlink ); virtual ~K3bIso9660Entry(); int adate() const { return m_adate; } int cdate() const { return m_cdate; } /** * Creation date of the file. * @return the creation date */ TQDateTime datetime() const; /** * Creation date of the file. * @return the creation date in seconds since 1970 */ int date() const { return m_date; } /** * Name of the file without path. * @return The file name without path. */ const TQString& name() const { return m_name; } /** * \return The raw name as saved in the ISO9660 tree */ const TQString& isoName() const { return m_isoName; } /** * The permissions and mode flags as returned by the stat() function * in st_mode. * @return the permissions */ mode_t permissions() const { return m_access; } /** * User who created the file. * @return the owner of the file */ const TQString& user() const { return m_user; } /** * Group of the user who created the file. * @return the group of the file */ const TQString& group() const { return m_group; } /** * Symlink if there is one. * @return the symlink, or TQString() */ const TQString& symlink() const { return m_symlink; } /** * Checks whether the entry is a file. * @return true if this entry is a file */ virtual bool isFile() const { return false; } /** * Checks whether the entry is a directory. * @return true if this entry is a directory */ virtual bool isDirectory() const { return false; } K3bIso9660* archive() const { return m_archive; } private: int m_adate; int m_cdate; TQString m_name; TQString m_isoName; int m_date; mode_t m_access; TQString m_user; TQString m_group; TQString m_symlink; K3bIso9660* m_archive; }; class LIBK3B_EXPORT K3bIso9660Directory : public K3bIso9660Entry { public: K3bIso9660Directory( K3bIso9660* archive, const TQString& isoName, const TQString& name, int access, int date, int adate, int cdate, const TQString& user, const TQString& group, const TQString& symlink, unsigned int pos = 0, unsigned int size = 0 ); ~K3bIso9660Directory(); /** * Returns a list of sub-entries. * @return the names of all entries in this directory (filenames, no path). */ TQStringList entries() const; /** * Returns the entry with the given name. * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc. * @return a pointer to the entry in the directory. */ K3bIso9660Entry* entry( const TQString& name ); /** * Returns the entry with the given name. * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc. * @return a pointer to the entry in the directory. */ const K3bIso9660Entry* entry( const TQString& name ) const; /** * Returns a list of sub-entries. * Searches for Iso9660 names. * @return the names of all entries in this directory (filenames, no path). */ TQStringList iso9660Entries() const; /** * Returns the entry with the given name. * Searches for Iso9660 names. * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc. * @return a pointer to the entry in the directory. */ K3bIso9660Entry* iso9660Entry( const TQString& name ); /** * Returns the entry with the given name. * Searches for Iso9660 names. * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc. * @return a pointer to the entry in the directory. */ const K3bIso9660Entry* iso9660Entry( const TQString& name ) const; /** * @internal * Adds a new entry to the directory. */ void addEntry( K3bIso9660Entry* ); /** * Checks whether this entry is a directory. * @return true, since this entry is a directory */ bool isDirectory() const { return true; } private: void expand(); TQDict m_entries; TQDict m_iso9660Entries; bool m_bExpanded; unsigned int m_startSector; unsigned int m_size; }; class LIBK3B_EXPORT K3bIso9660File : public K3bIso9660Entry { public: /** * @param pos start sector */ K3bIso9660File( K3bIso9660* archive, const TQString& isoName, const TQString& name, int access, int date, int adate, int cdate, const TQString& user, const TQString& group, const TQString& symlink, unsigned int pos, unsigned int size ); ~K3bIso9660File(); bool isFile() const { return true; } void setZF( char algo[2], char parms[2], int realsize ); int realsize() const { return m_realsize; } /** * @return size in bytes. */ unsigned int size() const { return m_size; } /** * Returnes the startSector of the file. */ unsigned int startSector() const { return m_startSector; } /** * Returnes the startOffset of the file in bytes. */ unsigned long long startPostion() const { return (unsigned long long)m_startSector * 2048; } /** * @param pos offset in bytes * @param len max number of bytes to read */ int read( unsigned int pos, char* data, int len ) const; /** * Copy this file to a url. */ bool copyTo( const TQString& url ) const; private: char m_algo[2]; char m_parms[2]; int m_realsize; unsigned int m_curpos; unsigned int m_startSector; unsigned int m_size; }; /** * This class is based on the KIso class by * Gy�gy Szombathelyi . * A lot has been changed and bugfixed. * The API has been improved to be useful. * * Due to the stupid TQt which does not support large files as default * we cannot use TQIODevice with DVDs! That's why we have our own * reading code which is not allowed by KArchive (which is limited to int * by the way... who the hell designed this?) * I also removed the KArchive inheritance because of the named reasons. * So this stuff contains a lot KArchive code which has been made usable. * * That does not mean that this class is well designed. No, it's not. :) * * Opening a K3bIso9660 object should be fast since creation of the directory * and file entries is not done until a call to K3bIso9660Directory::entries. */ class LIBK3B_EXPORT K3bIso9660 { public: /** * Creates an instance that operates on the given filename. * using the compression filter associated to given mimetype. * * @param filename is a local path (e.g. "/home/weis/myfile.tgz") */ K3bIso9660( const TQString& filename ); /** * Special case which always reads the TOC from the specified sector * thus supporting multisession CDs. */ K3bIso9660( K3bDevice::Device* dev, unsigned int startSector = 0 ); /** * @param fd open file descriptor */ K3bIso9660( int fd ); /** * Directly specify the backend to read from. * K3bIso9660 will take ownership of the backend and delete it. */ K3bIso9660( K3bIso9660Backend* ); /** * If the .iso is still opened, then it will be * closed automatically by the destructor. */ virtual ~K3bIso9660(); /** * Set where to start reading in the source. */ void setStartSector( unsigned int startSector ); /** * If set to true before opening K3bIso9660 will ignore RR and joliet extensions * and only create plain iso9660 names. */ void setPlainIso9660( bool ); bool plainIso9660() const; /** * Opens the archive for reading. * Parses the directory listing of the archive * and creates the K3bIso9660Directory/K3bIso9660File entries. */ bool open(); bool isOpen() const; /** * Closes everything. * This is also called in the destructor */ void close(); /** * @param sector startsector * @param len number of sectors * @return number of sectors read or -1 on error */ int read( unsigned int sector, char* data, int len ); /** * The name of the os file, as passed to the constructor * Null if you did not use the TQString constructor. */ const TQString& fileName() { return m_filename; } const K3bIso9660Directory* firstJolietDirEntry() const; const K3bIso9660Directory* firstRRDirEntry() const; const K3bIso9660Directory* firstIsoDirEntry() const; const K3bIso9660Directory* firstElToritoEntry() const; /** * @returns 0 if no joliet desc could be found * the joliet level (1-3) otherwise */ int jolietLevel() const { return m_joliet; } const K3bIso9660SimplePrimaryDescriptor& primaryDescriptor() const; void debug() const; private: /** * @internal */ void addBoot( struct el_torito_boot_descriptor* bootdesc ); void createSimplePrimaryDesc( struct iso_primary_descriptor* desc ); void debugEntry( const K3bIso9660Entry*, int depth ) const; int m_joliet; // only used for creation static int read_callback( char* buf, sector_t start, int len, void* udata ); static int isofs_callback( struct iso_directory_record* idr, void *udata ); K3bIso9660Directory *dirent; bool m_rr; friend class K3bIso9660Directory; private: TQString m_filename; class Private; Private * d; }; #endif