diff options
Diffstat (limited to 'libk3b/tools/k3biso9660.h')
-rw-r--r-- | libk3b/tools/k3biso9660.h | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/libk3b/tools/k3biso9660.h b/libk3b/tools/k3biso9660.h new file mode 100644 index 0000000..7fc52d9 --- /dev/null +++ b/libk3b/tools/k3biso9660.h @@ -0,0 +1,453 @@ +/* + * + * $Id: k3biso9660.h 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * 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 <sys/stat.h> +#include <sys/types.h> + +#include <qdatetime.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qdict.h> + +#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(); + + QString volumeId; + QString systemId; + QString volumeSetId; + QString publisherId; + QString preparerId; + QString 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 QString& isoName, + const QString& name, + int access, + int date, + int adate, + int cdate, + const QString& user, + const QString& group, + const QString& symlink ); + virtual ~K3bIso9660Entry(); + + int adate() const { return m_adate; } + int cdate() const { return m_cdate; } + + /** + * Creation date of the file. + * @return the creation date + */ + QDateTime 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 QString& name() const { return m_name; } + + /** + * \return The raw name as saved in the ISO9660 tree + */ + const QString& 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 QString& user() const { return m_user; } + + /** + * Group of the user who created the file. + * @return the group of the file + */ + const QString& group() const { return m_group; } + + /** + * Symlink if there is one. + * @return the symlink, or QString::null + */ + const QString& 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; + QString m_name; + QString m_isoName; + int m_date; + mode_t m_access; + QString m_user; + QString m_group; + QString m_symlink; + K3bIso9660* m_archive; +}; + + +class LIBK3B_EXPORT K3bIso9660Directory : public K3bIso9660Entry +{ + public: + K3bIso9660Directory( K3bIso9660* archive, + const QString& isoName, + const QString& name, + int access, + int date, + int adate, + int cdate, + const QString& user, + const QString& group, + const QString& 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). + */ + QStringList 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 QString& 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 QString& name ) const; + + /** + * Returns a list of sub-entries. + * Searches for Iso9660 names. + * @return the names of all entries in this directory (filenames, no path). + */ + QStringList 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 QString& 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 QString& 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(); + + QDict<K3bIso9660Entry> m_entries; + QDict<K3bIso9660Entry> 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 QString& isoName, + const QString& name, + int access, + int date, + int adate, + int cdate, + const QString& user, + const QString& group, + const QString& 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 QString& 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 <[email protected]>. + * A lot has been changed and bugfixed. + * The API has been improved to be useful. + * + * Due to the stupid Qt which does not support large files as default + * we cannot use QIODevice 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 QString& 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 QString constructor. + */ + const QString& 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: + QString m_filename; + + class Private; + Private * d; +}; + +#endif |