Blame include/cdio++/iso9660.hpp

Packit dd8086
/*
Packit dd8086
    Copyright (C) 2006, 2008, 2011-2012, 2016-2017 Rocky Bernstein <rocky@gnu.org>
Packit dd8086
Packit dd8086
    This program is free software: you can redistribute it and/or modify
Packit dd8086
    it under the terms of the GNU General Public License as published by
Packit dd8086
    the Free Software Foundation, either version 3 of the License, or
Packit dd8086
    (at your option) any later version.
Packit dd8086
Packit dd8086
    This program is distributed in the hope that it will be useful,
Packit dd8086
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit dd8086
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit dd8086
    GNU General Public License for more details.
Packit dd8086
Packit dd8086
    You should have received a copy of the GNU General Public License
Packit dd8086
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit dd8086
*/
Packit dd8086
Packit dd8086
/** \file iso9660.hpp
Packit dd8086
 *
Packit dd8086
 *  \brief C++ class for libcdio: the CD Input and Control
Packit dd8086
 *  library. Applications use this for anything regarding libcdio.
Packit dd8086
 */
Packit dd8086
Packit dd8086
#ifndef CDIO_ISO9660_HPP_
Packit dd8086
#define CDIO_ISO9660_HPP_
Packit dd8086
Packit dd8086
#include <cdio/iso9660.h>
Packit dd8086
#include <cdio++/cdio.hpp>
Packit dd8086
#include <vector>               // vector class library
Packit dd8086
#include <cstdlib>
Packit dd8086
#include <cstring>
Packit dd8086
using namespace std;
Packit dd8086
Packit dd8086
/** ISO 9660 class.
Packit dd8086
*/
Packit dd8086
class ISO9660
Packit dd8086
{
Packit dd8086
Packit dd8086
public:
Packit dd8086
Packit dd8086
  class PVD  // Primary Volume ID
Packit dd8086
  {
Packit dd8086
  public:
Packit dd8086
Packit dd8086
    iso9660_pvd_t pvd;  // Make private?
Packit dd8086
Packit dd8086
    PVD()
Packit dd8086
    {
Packit dd8086
      memset(&pvd, 0, sizeof(pvd));
Packit dd8086
    }
Packit dd8086
Packit dd8086
    PVD(iso9660_pvd_t *p_new_pvd)
Packit dd8086
    {
Packit dd8086
      memcpy(&pvd, p_new_pvd, sizeof(pvd));
Packit dd8086
    };
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return the PVD's application ID.
Packit dd8086
      NULL is returned if there is some problem in getting this.
Packit dd8086
    */
Packit dd8086
    char * get_application_id();
Packit dd8086
Packit dd8086
    int get_pvd_block_size();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return the PVD's preparer ID.
Packit dd8086
      NULL is returned if there is some problem in getting this.
Packit dd8086
    */
Packit dd8086
    char * get_preparer_id();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return the PVD's publisher ID.
Packit dd8086
      NULL is returned if there is some problem in getting this.
Packit dd8086
    */
Packit dd8086
    char * get_publisher_id();
Packit dd8086
Packit dd8086
    const char *get_pvd_id();
Packit dd8086
Packit dd8086
    int get_pvd_space_size();
Packit dd8086
Packit dd8086
    uint8_t get_pvd_type();
Packit dd8086
Packit dd8086
    /*! Return the primary volume id version number (of pvd).
Packit dd8086
      If there is an error 0 is returned.
Packit dd8086
    */
Packit dd8086
    int get_pvd_version();
Packit dd8086
Packit dd8086
    /*! Return the LSN of the root directory for pvd.
Packit dd8086
      If there is an error CDIO_INVALID_LSN is returned.
Packit dd8086
    */
Packit dd8086
    lsn_t get_root_lsn();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return the PVD's system ID.
Packit dd8086
      NULL is returned if there is some problem in getting this.
Packit dd8086
    */
Packit dd8086
    char * get_system_id();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return the PVD's volume ID.
Packit dd8086
      NULL is returned if there is some problem in getting this.
Packit dd8086
    */
Packit dd8086
    char * get_volume_id();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return the PVD's volumeset ID.
Packit dd8086
      NULL is returned if there is some problem in getting this.
Packit dd8086
    */
Packit dd8086
    char * get_volumeset_id();
Packit dd8086
Packit dd8086
  };
Packit dd8086
Packit dd8086
  class Stat  // ISO 9660 file information
Packit dd8086
  {
Packit dd8086
  public:
Packit dd8086
Packit dd8086
    iso9660_stat_t *p_stat;
Packit dd8086
    typedef vector< ISO9660::Stat *> stat_vector_t;
Packit dd8086
Packit dd8086
    Stat(iso9660_stat_t *p_new_stat)
Packit dd8086
    {
Packit dd8086
      p_stat = p_new_stat;
Packit dd8086
    };
Packit dd8086
Packit dd8086
    Stat(const Stat& copy_in)
Packit dd8086
    {
Packit dd8086
      free(p_stat);
Packit dd8086
      p_stat = (iso9660_stat_t *)
Packit dd8086
        calloc( 1, sizeof(iso9660_stat_t)
Packit dd8086
                + strlen(copy_in.p_stat->filename)+1 );
Packit dd8086
      p_stat = copy_in.p_stat;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    const Stat& operator= (const Stat& right)
Packit dd8086
    {
Packit dd8086
      free(p_stat);
Packit dd8086
      this->p_stat = right.p_stat;
Packit dd8086
      return right;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    ~Stat()
Packit dd8086
    {
Packit dd8086
      iso9660_stat_free(p_stat);
Packit dd8086
      p_stat = NULL;
Packit dd8086
    }
Packit dd8086
Packit dd8086
  };
Packit dd8086
Packit dd8086
#ifdef FS
Packit dd8086
 #undef FS
Packit dd8086
#endif
Packit dd8086
  class FS : public CdioDevice // ISO 9660 Filesystem on a CD or CD-image
Packit dd8086
  {
Packit dd8086
  public:
Packit dd8086
Packit dd8086
    typedef vector< ISO9660::Stat *> stat_vector_t;
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Given a directory pointer, find the filesystem entry that contains
Packit dd8086
      lsn and return information about it.
Packit dd8086
Packit dd8086
      @return Stat * of entry if we found lsn, or NULL otherwise.
Packit dd8086
      Caller must release returned object using delete when done.
Packit dd8086
    */
Packit dd8086
    Stat *find_lsn(lsn_t i_lsn);
Packit dd8086
Packit dd8086
    /*! Read the Primary Volume Descriptor for a CD.  A
Packit dd8086
      PVD object is returned if read, and NULL if there was an error.
Packit dd8086
    */
Packit dd8086
    PVD *read_pvd ();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Read the Super block of an ISO 9660 image. This is the
Packit dd8086
      Primary Volume Descriptor (PVD) and perhaps a Supplemental Volume
Packit dd8086
      Descriptor if (Joliet) extensions are acceptable.
Packit dd8086
    */
Packit dd8086
    bool read_superblock (iso_extension_mask_t iso_extension_mask);
Packit dd8086
Packit dd8086
    /*! Read psz_path (a directory) and return a vector of iso9660_stat_t
Packit dd8086
      pointers for the files inside that directory. The caller must free the
Packit dd8086
      returned result.
Packit dd8086
    */
Packit dd8086
    bool readdir (const char psz_path[], stat_vector_t& stat_vector);
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return file status for path name psz_path. NULL is returned on
Packit dd8086
      error.
Packit dd8086
Packit dd8086
      If translate is true, version numbers in the ISO 9660 name are
Packit dd8086
      dropped, i.e. ;1 is removed and if level 1 ISO-9660 names are
Packit dd8086
      lowercased.
Packit dd8086
Packit dd8086
      @return file status object for psz_path. NULL is returned on
Packit dd8086
      error. Caller must release returned object using delete when done.
Packit dd8086
    */
Packit dd8086
    Stat *
Packit dd8086
    stat (const char psz_path[], bool b_translate=false)
Packit dd8086
    {
Packit dd8086
      if (b_translate)
Packit dd8086
        return new Stat(iso9660_fs_stat_translate (p_cdio, psz_path));
Packit dd8086
      else
Packit dd8086
        return new Stat(iso9660_fs_stat (p_cdio, psz_path));
Packit dd8086
    }
Packit dd8086
  };
Packit dd8086
Packit dd8086
  class IFS  // ISO 9660 filesystem image
Packit dd8086
  {
Packit dd8086
  public:
Packit dd8086
Packit dd8086
    typedef vector< ISO9660::Stat *> stat_vector_t;
Packit dd8086
Packit dd8086
    IFS()
Packit dd8086
    {
Packit dd8086
      p_iso9660=NULL;
Packit dd8086
    };
Packit dd8086
Packit dd8086
    ~IFS()
Packit dd8086
    {
Packit dd8086
      iso9660_close(p_iso9660);
Packit dd8086
      p_iso9660 = (iso9660_t *) NULL;
Packit dd8086
    };
Packit dd8086
Packit dd8086
    /*! Close previously opened ISO 9660 image and free resources
Packit dd8086
      associated with the image. Call this when done using using an ISO
Packit dd8086
      9660 image.
Packit dd8086
Packit dd8086
      @return true is unconditionally returned. If there was an error
Packit dd8086
      false would be returned.
Packit dd8086
    */
Packit dd8086
    bool close();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Given a directory pointer, find the filesystem entry that contains
Packit dd8086
      lsn and return information about it.
Packit dd8086
Packit dd8086
      Returns Stat*  of entry if we found lsn, or NULL otherwise.
Packit dd8086
      Caller must release returned object using delete when done.
Packit dd8086
    */
Packit dd8086
    Stat *find_lsn(lsn_t i_lsn);
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Get the application ID.  psz_app_id is set to NULL if there
Packit dd8086
      is some problem in getting this and false is returned.
Packit dd8086
    */
Packit dd8086
    bool get_application_id(/*out*/ char * &psz_app_id)
Packit dd8086
    {
Packit dd8086
      return iso9660_ifs_get_application_id(p_iso9660, &psz_app_id);
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return the Joliet level recognized.
Packit dd8086
    */
Packit dd8086
    uint8_t get_joliet_level();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Get the preparer ID.  psz_preparer_id is set to NULL if there
Packit dd8086
      is some problem in getting this and false is returned.
Packit dd8086
    */
Packit dd8086
    bool get_preparer_id(/*out*/ char * &psz_preparer_id)
Packit dd8086
    {
Packit dd8086
      return iso9660_ifs_get_preparer_id(p_iso9660, &psz_preparer_id);
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Get the publisher ID.  psz_publisher_id is set to NULL if there
Packit dd8086
      is some problem in getting this and false is returned.
Packit dd8086
    */
Packit dd8086
    bool get_publisher_id(/*out*/ char * &psz_publisher_id)
Packit dd8086
    {
Packit dd8086
      return iso9660_ifs_get_publisher_id(p_iso9660, &psz_publisher_id);
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Get the system ID.  psz_system_id is set to NULL if there
Packit dd8086
      is some problem in getting this and false is returned.
Packit dd8086
    */
Packit dd8086
    bool get_system_id(/*out*/ char * &psz_system_id)
Packit dd8086
    {
Packit dd8086
      return iso9660_ifs_get_system_id(p_iso9660, &psz_system_id);
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*! Return the volume ID in the PVD. psz_volume_id is set to
Packit dd8086
      NULL if there is some problem in getting this and false is
Packit dd8086
      returned.
Packit dd8086
    */
Packit dd8086
    bool get_volume_id(/*out*/ char * &psz_volume_id)
Packit dd8086
    {
Packit dd8086
      return iso9660_ifs_get_volume_id(p_iso9660, &psz_volume_id);
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*! Return the volumeset ID in the PVD. psz_volumeset_id is set to
Packit dd8086
      NULL if there is some problem in getting this and false is
Packit dd8086
      returned.
Packit dd8086
    */
Packit dd8086
    bool get_volumeset_id(/*out*/ char * &psz_volumeset_id)
Packit dd8086
    {
Packit dd8086
      return iso9660_ifs_get_volumeset_id(p_iso9660, &psz_volumeset_id);
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return true if ISO 9660 image has extended attrributes (XA).
Packit dd8086
    */
Packit dd8086
    bool is_xa ();
Packit dd8086
Packit dd8086
    /*! Open an ISO 9660 image for reading. Maybe in the future we will
Packit dd8086
      have a mode. NULL is returned on error. An open routine should be
Packit dd8086
      called before using any read routine. If device object was
Packit dd8086
      previously opened it is closed first.
Packit dd8086
Packit dd8086
      @param psz_path location of ISO 9660 image
Packit dd8086
      @param iso_extension_mask the kinds of ISO 9660 extensions will be
Packit dd8086
      considered on access.
Packit dd8086
Packit dd8086
      @return true if open succeeded or false if error.
Packit dd8086
Packit dd8086
      @see open_fuzzy
Packit dd8086
    */
Packit dd8086
    bool open(const char *psz_path,
Packit dd8086
              iso_extension_mask_t iso_extension_mask=ISO_EXTENSION_NONE)
Packit dd8086
    {
Packit dd8086
      if (p_iso9660) iso9660_close(p_iso9660);
Packit dd8086
      p_iso9660 = iso9660_open_ext(psz_path, iso_extension_mask);
Packit dd8086
      return NULL != (iso9660_t *) p_iso9660 ;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*! Open an ISO 9660 image for "fuzzy" reading. This means that we
Packit dd8086
      will try to guess various internal offset based on internal
Packit dd8086
      checks. This may be useful when trying to read an ISO 9660 image
Packit dd8086
      contained in a file format that libiso9660 doesn't know natively
Packit dd8086
      (or knows imperfectly.)
Packit dd8086
Packit dd8086
      Maybe in the future we will have a mode. NULL is returned on
Packit dd8086
      error.
Packit dd8086
Packit dd8086
      @see open
Packit dd8086
    */
Packit dd8086
    bool open_fuzzy (const char *psz_path,
Packit dd8086
                     iso_extension_mask_t iso_extension_mask
Packit dd8086
                     =ISO_EXTENSION_NONE,
Packit dd8086
                     uint16_t i_fuzz=20);
Packit dd8086
Packit dd8086
    /*! Read the Primary Volume Descriptor for an ISO 9660 image.  A
Packit dd8086
      PVD object is returned if read, and NULL if there was an error.
Packit dd8086
    */
Packit dd8086
    PVD *read_pvd ();
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Read the Super block of an ISO 9660 image but determine framesize
Packit dd8086
      and datastart and a possible additional offset. Generally here we are
Packit dd8086
      not reading an ISO 9660 image but a CD-Image which contains an ISO 9660
Packit dd8086
      filesystem.
Packit dd8086
Packit dd8086
      @see read_superblock
Packit dd8086
    */
Packit dd8086
    bool read_superblock (iso_extension_mask_t iso_extension_mask
Packit dd8086
                          =ISO_EXTENSION_NONE,
Packit dd8086
                          uint16_t i_fuzz=20);
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Read the Super block of an ISO 9660 image but determine framesize
Packit dd8086
      and datastart and a possible additional offset. Generally here we are
Packit dd8086
      not reading an ISO 9660 image but a CD-Image which contains an ISO 9660
Packit dd8086
      filesystem.
Packit dd8086
Packit dd8086
      @see read_superblock
Packit dd8086
    */
Packit dd8086
    bool
Packit dd8086
    read_superblock_fuzzy (iso_extension_mask_t iso_extension_mask
Packit dd8086
                           =ISO_EXTENSION_NONE,
Packit dd8086
                           uint16_t i_fuzz=20);
Packit dd8086
Packit dd8086
    /*! Read psz_path (a directory) and return a list of iso9660_stat_t
Packit dd8086
      pointers for the files inside that directory. The caller must free
Packit dd8086
      the returned result.
Packit dd8086
    */
Packit dd8086
    bool readdir (const char psz_path[], stat_vector_t& stat_vector)
Packit dd8086
    {
Packit dd8086
      CdioISO9660FileList_t *p_stat_list = iso9660_ifs_readdir (p_iso9660, psz_path);
Packit dd8086
Packit dd8086
      if (p_stat_list) {
Packit dd8086
        CdioListNode_t *p_entnode;
Packit dd8086
        _CDIO_LIST_FOREACH (p_entnode, p_stat_list) {
Packit dd8086
          iso9660_stat_t *p_statbuf =
Packit dd8086
            (iso9660_stat_t *) _cdio_list_node_data (p_entnode);
Packit dd8086
          stat_vector.push_back(new ISO9660::Stat(p_statbuf));
Packit dd8086
        }
Packit dd8086
	iso9660_filelist_free(p_stat_list);
Packit dd8086
        return true;
Packit dd8086
      } else {
Packit dd8086
        return false;
Packit dd8086
      }
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Seek to a position and then read n bytes. Size read is returned.
Packit dd8086
    */
Packit dd8086
    long int
Packit dd8086
    seek_read (void *ptr, lsn_t start, long int i_size=1)
Packit dd8086
    {
Packit dd8086
      return iso9660_iso_seek_read (p_iso9660, ptr, start, i_size);
Packit dd8086
    }
Packit dd8086
Packit dd8086
    /*!
Packit dd8086
      Return file status for pathname. NULL is returned on error.
Packit dd8086
      Caller must release returned object using delete when done.
Packit dd8086
    */
Packit dd8086
    Stat *
Packit dd8086
    stat (const char psz_path[], bool b_translate=false)
Packit dd8086
    {
Packit dd8086
      if (b_translate)
Packit dd8086
        return new Stat(iso9660_ifs_stat_translate (p_iso9660, psz_path));
Packit dd8086
      else
Packit dd8086
        return new Stat(iso9660_ifs_stat (p_iso9660, psz_path));
Packit dd8086
    }
Packit dd8086
Packit dd8086
  private:
Packit dd8086
    iso9660_t *p_iso9660;
Packit dd8086
  };
Packit dd8086
Packit dd8086
};
Packit dd8086
Packit dd8086
typedef vector< ISO9660::Stat *> stat_vector_t;
Packit dd8086
typedef vector <ISO9660::Stat *>::iterator stat_vector_iterator_t;
Packit dd8086
Packit dd8086
#endif /* CDIO_ISO9660_HPP_ */