Add iso9660 library and regression test.
Will be deleted from vcdimager-cdio branch. cd_types.c: forgot to add previously.
This commit is contained in:
@@ -13,5 +13,6 @@ libcdio*.tar.gz
|
||||
libtool
|
||||
libcdio.pc
|
||||
libcdio.spec
|
||||
libiso9660.pc
|
||||
ltmain.sh
|
||||
stamp-h1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.am,v 1.11 2003/08/09 11:52:00 rocky Exp $
|
||||
# $Id: Makefile.am,v 1.12 2003/08/17 05:31:19 rocky Exp $
|
||||
#
|
||||
# Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
#
|
||||
@@ -27,7 +27,7 @@ SUBDIRS = doc include lib src test
|
||||
|
||||
# pkg-config(1) related rules
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libcdio.pc
|
||||
pkgconfig_DATA = libiso9660.pc libcdio.pc
|
||||
|
||||
$(pkgconfig_DATA): config.status
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
dnl 02111-1307, USA.
|
||||
|
||||
AC_REVISION([$Id: configure.ac,v 1.32 2003/08/16 22:09:31 rocky Exp $])dnl
|
||||
AC_REVISION([$Id: configure.ac,v 1.33 2003/08/17 05:31:19 rocky Exp $])dnl
|
||||
AC_INIT(lib/cdio.c)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AM_INIT_AUTOMAKE(libcdio, 0.63)
|
||||
@@ -183,8 +183,10 @@ AC_HAVE_HEADERS( stdbool.h stdlib.h stdint.h stdio.h string.h strings.h linux/v
|
||||
|
||||
LIBCDIO_CFLAGS='-I$(top_srcdir)/lib/ -I$(top_srcdir)/include/'
|
||||
LIBCDIO_LIBS='$(top_builddir)/lib/libcdio.la'
|
||||
LIBISO9660_LIBS='$(top_builddir)/lib/libiso9660.la'
|
||||
AC_SUBST(LIBCDIO_CFLAGS)
|
||||
AC_SUBST(LIBCDIO_LIBS)
|
||||
AC_SUBST(LIBISO9660_LIBS)
|
||||
|
||||
ACLOCAL_AMFLAGS='-I .'
|
||||
AC_SUBST(ACLOCAL_AMFLAGS)
|
||||
@@ -288,10 +290,11 @@ AC_CONFIG_COMMANDS([checks],
|
||||
[chmod +x test/check_cue.sh; chmod +x test/check_nrg.sh
|
||||
])
|
||||
|
||||
AC_OUTPUT([ \
|
||||
AC_CONFIG_FILES([ \
|
||||
Makefile \
|
||||
libcdio.pc \
|
||||
libcdio.spec \
|
||||
libiso9660.pc \
|
||||
include/Makefile \
|
||||
include/cdio/Makefile \
|
||||
include/cdio/version.h \
|
||||
@@ -303,5 +306,6 @@ AC_OUTPUT([ \
|
||||
test/check_common_fn \
|
||||
test/Makefile \
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
echo "Using CD-ROM drivers: $cd_drivers"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.am,v 1.6 2003/08/16 15:34:58 rocky Exp $
|
||||
# $Id: Makefile.am,v 1.7 2003/08/17 05:31:19 rocky Exp $
|
||||
#
|
||||
# Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
#
|
||||
@@ -22,8 +22,15 @@
|
||||
#
|
||||
|
||||
libcdioincludedir=$(includedir)/cdio
|
||||
libcdioinclude_HEADERS = cdio.h cd_types.h logging.h sector.h \
|
||||
types.h util.h version.h
|
||||
libcdioinclude_HEADERS = \
|
||||
cdio.h \
|
||||
cd_types.h \
|
||||
iso9660.h \
|
||||
logging.h \
|
||||
sector.h \
|
||||
types.h \
|
||||
util.h \
|
||||
version.h
|
||||
|
||||
EXTRA_DIST = version.h.in
|
||||
BUILT_SOURCES = version.h
|
||||
|
||||
151
include/cdio/iso9660.h
Normal file
151
include/cdio/iso9660.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
$Id: iso9660.h,v 1.1 2003/08/17 05:31:19 rocky Exp $
|
||||
|
||||
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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
|
||||
*/
|
||||
|
||||
#ifndef __CDIO_ISO9660_H__
|
||||
#define __CDIO_ISO9660_H__
|
||||
|
||||
/* Will eventually need/use glib.h */
|
||||
#include <cdio/types.h>
|
||||
|
||||
#define MIN_TRACK_SIZE 4*75
|
||||
|
||||
#define MIN_ISO_SIZE MIN_TRACK_SIZE
|
||||
|
||||
#define ISO_BLOCKSIZE 2048
|
||||
|
||||
#define LEN_ISONAME 31
|
||||
#define MAX_ISONAME 37
|
||||
|
||||
#define MAX_ISOPATHNAME 255
|
||||
|
||||
#define ISO_FILE 0
|
||||
#define ISO_VD_PRIMARY 1
|
||||
#define ISO_DIRECTORY 2
|
||||
#define ISO_STANDARD_ID "CD001"
|
||||
|
||||
|
||||
#define ISO_PVD_SECTOR 16
|
||||
#define ISO_EVD_SECTOR 17
|
||||
|
||||
enum strncpy_pad_check {
|
||||
ISO9660_NOCHECK = 0,
|
||||
ISO9660_7BIT,
|
||||
ISO9660_ACHARS,
|
||||
ISO9660_DCHARS
|
||||
};
|
||||
|
||||
char *
|
||||
iso9660_strncpy_pad(char dst[], const char src[], size_t len,
|
||||
enum strncpy_pad_check _check);
|
||||
|
||||
int
|
||||
iso9660_isdchar (int c);
|
||||
|
||||
int
|
||||
iso9660_isachar (int c);
|
||||
|
||||
/* file/dirname's */
|
||||
bool
|
||||
iso9660_pathname_valid_p (const char pathname[]);
|
||||
|
||||
bool
|
||||
iso9660_dirname_valid_p (const char pathname[]);
|
||||
|
||||
char *
|
||||
iso9660_pathname_isofy (const char pathname[], uint16_t version);
|
||||
|
||||
/* volume descriptors */
|
||||
|
||||
void
|
||||
iso9660_set_pvd (void *pd, const char volume_id[], const char application_id[],
|
||||
const char publisher_id[], const char preparer_id[],
|
||||
uint32_t iso_size, const void *root_dir,
|
||||
uint32_t path_table_l_extent, uint32_t path_table_m_extent,
|
||||
uint32_t path_table_size);
|
||||
|
||||
void
|
||||
iso9660_set_evd (void *pd);
|
||||
|
||||
/* directory tree */
|
||||
|
||||
void
|
||||
iso9660_dir_init_new (void *dir, uint32_t self, uint32_t ssize,
|
||||
uint32_t parent, uint32_t psize);
|
||||
|
||||
void
|
||||
iso9660_dir_init_new_su (void *dir, uint32_t self, uint32_t ssize,
|
||||
const void *ssu_data, unsigned ssu_size,
|
||||
uint32_t parent, uint32_t psize,
|
||||
const void *psu_data, unsigned psu_size);
|
||||
|
||||
void
|
||||
iso9660_dir_add_entry_su (void *dir, const char name[], uint32_t extent,
|
||||
uint32_t size, uint8_t flags, const void *su_data,
|
||||
unsigned su_size);
|
||||
|
||||
unsigned
|
||||
iso9660_dir_calc_record_size (unsigned namelen, unsigned int su_len);
|
||||
|
||||
/* pathtable */
|
||||
|
||||
void
|
||||
iso9660_pathtable_init (void *pt);
|
||||
|
||||
unsigned int
|
||||
iso9660_pathtable_get_size (const void *pt);
|
||||
|
||||
uint16_t
|
||||
iso9660_pathtable_l_add_entry (void *pt, const char name[], uint32_t extent,
|
||||
uint16_t parent);
|
||||
|
||||
uint16_t
|
||||
iso9660_pathtable_m_add_entry (void *pt, const char name[], uint32_t extent,
|
||||
uint16_t parent);
|
||||
|
||||
lsn_t
|
||||
iso9660_get_root_lsn(struct iso_primary_descriptor const *pvd);
|
||||
|
||||
uint8_t
|
||||
iso9660_get_pvd_type(struct iso_primary_descriptor const *pvd);
|
||||
|
||||
const char *
|
||||
iso9660_get_pvd_id(struct iso_primary_descriptor const *pvd);
|
||||
|
||||
int
|
||||
iso9660_get_pvd_space_size(struct iso_primary_descriptor const *pvd);
|
||||
|
||||
int
|
||||
iso9660_get_pvd_block_size(struct iso_primary_descriptor const *pvd) ;
|
||||
|
||||
int
|
||||
iso9660_get_pvd_version(struct iso_primary_descriptor const *pvd) ;
|
||||
|
||||
|
||||
#endif /* __CDIO_ISO9660_H__ */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "gnu"
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
$Id: types.h,v 1.3 2003/06/07 10:44:14 rocky Exp $
|
||||
$Id: types.h,v 1.4 2003/08/17 05:31:19 rocky Exp $
|
||||
|
||||
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
Copyright (C) 2002,2003 Rocky Bernstein <rocky@panix.com>
|
||||
@@ -217,6 +217,13 @@ extern "C" {
|
||||
Constant for invalid LSN
|
||||
*/
|
||||
#define CDIO_INVALID_LSN 0xFFFFFFFF
|
||||
|
||||
/* Opaque types ... */
|
||||
|
||||
/* Defined fully in iso9660_private.h */
|
||||
typedef struct iso_primary_descriptor pvd_t;
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.am,v 1.8 2003/08/16 15:34:58 rocky Exp $
|
||||
# $Id: Makefile.am,v 1.9 2003/08/17 05:31:19 rocky Exp $
|
||||
#
|
||||
# Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
#
|
||||
@@ -46,7 +46,10 @@ libcdio_sources = \
|
||||
sector.c \
|
||||
util.c
|
||||
|
||||
lib_LTLIBRARIES = libcdio.la
|
||||
lib_LTLIBRARIES = libcdio.la libiso9660.la
|
||||
libcdio_la_SOURCES = $(libcdio_sources)
|
||||
libiso9660_la_SOURCES = \
|
||||
iso9660.c \
|
||||
iso9660_private.h
|
||||
|
||||
INCLUDES = -I$(LIBCDIO_CFLAGS)
|
||||
|
||||
289
lib/cd_types.c
Normal file
289
lib/cd_types.c
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
$Id: cd_types.c,v 1.1 2003/08/17 05:31:19 rocky Exp $
|
||||
|
||||
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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
|
||||
*/
|
||||
/*
|
||||
This tries to determine what kind of CD-image or filesystems on a
|
||||
track we've got.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <cdio/cdio.h>
|
||||
#include <cdio/logging.h>
|
||||
#include <cdio/util.h>
|
||||
#include <cdio/cd_types.h>
|
||||
|
||||
/*
|
||||
Subject: -65- How can I read an IRIX (EFS) CD-ROM on a machine which
|
||||
doesn't use EFS?
|
||||
Date: 18 Jun 1995 00:00:01 EST
|
||||
|
||||
You want 'efslook', at
|
||||
ftp://viz.tamu.edu/pub/sgi/software/efslook.tar.gz.
|
||||
|
||||
and
|
||||
! Robert E. Seastrom <rs@access4.digex.net>'s software (with source
|
||||
! code) for using an SGI CD-ROM on a Macintosh is at
|
||||
! ftp://bifrost.seastrom.com/pub/mac/CDROM-Jumpstart.sit151.hqx.
|
||||
|
||||
*/
|
||||
|
||||
static char buffer[6][CDIO_CD_FRAMESIZE_RAW]; /* for CD-Data */
|
||||
|
||||
/* Some interesting sector numbers stored in the above buffer. */
|
||||
#define ISO_SUPERBLOCK_SECTOR 16 /* buffer[0] */
|
||||
#define UFS_SUPERBLOCK_SECTOR 4 /* buffer[2] */
|
||||
#define BOOT_SECTOR 17 /* buffer[3] */
|
||||
#define VCD_INFO_SECTOR 150 /* buffer[4] */
|
||||
|
||||
|
||||
typedef struct signature
|
||||
{
|
||||
unsigned int buf_num;
|
||||
unsigned int offset;
|
||||
const char *sig_str;
|
||||
const char *description;
|
||||
} signature_t;
|
||||
|
||||
static signature_t sigs[] =
|
||||
{
|
||||
/*buffer[x] off look for description */
|
||||
{0, 1, "CD001", "ISO 9660"},
|
||||
{0, 1, "CD-I", "CD-I"},
|
||||
{0, 8, "CDTV", "CDTV"},
|
||||
{0, 8, "CD-RTOS", "CD-RTOS"},
|
||||
{0, 9, "CDROM", "HIGH SIERRA"},
|
||||
{0, 16, "CD-BRIDGE", "BRIDGE"},
|
||||
{0, 1024, "CD-XA001", "XA"},
|
||||
{1, 64, "PPPPHHHHOOOOTTTTOOOO____CCCCDDDD", "PHOTO CD"},
|
||||
{1, 0x438, "\x53\xef", "EXT2 FS"},
|
||||
{2, 1372, "\x54\x19\x01\x0", "UFS"},
|
||||
{3, 7, "EL TORITO", "BOOTABLE"},
|
||||
{4, 0, "VIDEO_CD", "VIDEO CD"},
|
||||
{4, 0, "SUPERVCD", "SVCD or Chaoji VCD"},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
/* The below index into the above sigs array. Make sure things match. */
|
||||
#define INDEX_ISOFS 0
|
||||
#define INDEX_CD_I 1
|
||||
#define INDEX_CDTV 2
|
||||
#define INDEX_CD_RTOS 3
|
||||
#define INDEX_HS 4
|
||||
#define INDEX_BRIDGE 5
|
||||
#define INDEX_XA 6
|
||||
#define INDEX_PHOTO_CD 7
|
||||
#define INDEX_EXT2 8
|
||||
#define INDEX_UFS 9
|
||||
#define INDEX_BOOTABLE 10
|
||||
#define INDEX_VIDEO_CD 11 /* Video CD */
|
||||
#define INDEX_SVCD 12 /* CVD *or* SVCD */
|
||||
|
||||
|
||||
/*
|
||||
Read a particular block into the global array to be used for further
|
||||
analysis later.
|
||||
*/
|
||||
static int
|
||||
_cdio_read_block(CdIo *cdio, int superblock, uint32_t offset, uint8_t bufnum,
|
||||
track_t track_num)
|
||||
{
|
||||
unsigned int track_sec_count = cdio_get_track_sec_count(cdio, track_num);
|
||||
memset(buffer[bufnum], 0, CDIO_CD_FRAMESIZE);
|
||||
|
||||
if ( track_sec_count < superblock) {
|
||||
cdio_debug("reading block %u skipped track %d has only %u sectors\n",
|
||||
superblock, track_num, track_sec_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cdio_debug("about to read sector %u\n", offset+superblock);
|
||||
|
||||
if (cdio_get_track_green(cdio, track_num)) {
|
||||
if (0 > cdio_read_mode2_sector(cdio, buffer[bufnum],
|
||||
offset+superblock, false))
|
||||
return -1;
|
||||
} else {
|
||||
if (0 > cdio_read_yellow_sector(cdio, buffer[bufnum],
|
||||
offset+superblock, false))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Return true if the previously read-in buffer contains a "signature" that
|
||||
matches index "num".
|
||||
*/
|
||||
static bool
|
||||
_cdio_is_it(int num)
|
||||
{
|
||||
signature_t *sigp=&sigs[num];
|
||||
int len=strlen(sigp->sig_str);
|
||||
|
||||
/* TODO: check that num < largest sig. */
|
||||
return 0 == memcmp(&buffer[sigp->buf_num][sigp->offset], sigp->sig_str, len);
|
||||
}
|
||||
|
||||
static int
|
||||
_cdio_is_hfs(void)
|
||||
{
|
||||
return (0 == memcmp(&buffer[1][512],"PM",2)) ||
|
||||
(0 == memcmp(&buffer[1][512],"TS",2)) ||
|
||||
(0 == memcmp(&buffer[1][1024], "BD",2));
|
||||
}
|
||||
|
||||
static int
|
||||
_cdio_is_3do(void)
|
||||
{
|
||||
return (0 == memcmp(&buffer[1][0],"\x01\x5a\x5a\x5a\x5a\x5a\x01", 7)) &&
|
||||
(0 == memcmp(&buffer[1][40], "CD-ROM", 6));
|
||||
}
|
||||
|
||||
static int
|
||||
_cdio_is_joliet(void)
|
||||
{
|
||||
return 2 == buffer[3][0] && buffer[3][88] == 0x25 && buffer[3][89] == 0x2f;
|
||||
}
|
||||
|
||||
/* ISO 9660 volume space in M2F1_SECTOR_SIZE byte units */
|
||||
static int
|
||||
_cdio_get_iso9660_fs_sec_count(void)
|
||||
{
|
||||
return ((buffer[0][80] & 0xff) |
|
||||
((buffer[0][81] & 0xff) << 8) |
|
||||
((buffer[0][82] & 0xff) << 16) |
|
||||
((buffer[0][83] & 0xff) << 24));
|
||||
}
|
||||
|
||||
static int
|
||||
_cdio_get_joliet_level( void )
|
||||
{
|
||||
switch (buffer[3][90]) {
|
||||
case 0x40: return 1;
|
||||
case 0x43: return 2;
|
||||
case 0x45: return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Try to determine what kind of CD-image and/or filesystem we
|
||||
have at track track_num. Return information about the CD image
|
||||
is returned in cdio_analysis and the return value.
|
||||
*/
|
||||
cdio_fs_anal_t
|
||||
cdio_guess_cd_type(/*in*/ CdIo *cdio, int start_session, track_t track_num,
|
||||
/*out*/ cdio_analysis_t *cdio_analysis)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ( _cdio_read_block(cdio, ISO_SUPERBLOCK_SECTOR, start_session,
|
||||
0, track_num) < 0 )
|
||||
return CDIO_FS_UNKNOWN;
|
||||
|
||||
/* We have something that smells of a filesystem. */
|
||||
if (_cdio_is_it(INDEX_CD_I) && _cdio_is_it(INDEX_CD_RTOS)
|
||||
&& !_cdio_is_it(INDEX_BRIDGE) && !_cdio_is_it(INDEX_XA)) {
|
||||
return CDIO_FS_INTERACTIVE;
|
||||
} else {
|
||||
/* read sector 0 ONLY, when NO greenbook CD-I !!!! */
|
||||
|
||||
if ( _cdio_read_block(cdio, 0, start_session, 1, track_num) < 0 )
|
||||
return ret;
|
||||
|
||||
if (_cdio_is_it(INDEX_HS))
|
||||
ret |= CDIO_FS_HIGH_SIERRA;
|
||||
else if (_cdio_is_it(INDEX_ISOFS)) {
|
||||
if (_cdio_is_it(INDEX_CD_RTOS) && _cdio_is_it(INDEX_BRIDGE))
|
||||
ret = CDIO_FS_ISO_9660_INTERACTIVE;
|
||||
else if (_cdio_is_hfs())
|
||||
ret = CDIO_FS_ISO_HFS;
|
||||
else
|
||||
ret = CDIO_FS_ISO_9660;
|
||||
cdio_analysis->isofs_size = _cdio_get_iso9660_fs_sec_count();
|
||||
sprintf(cdio_analysis->iso_label, buffer[0]+40);
|
||||
|
||||
#if 0
|
||||
if (_cdio_is_rockridge())
|
||||
ret |= CDIO_FS_ANAL_ROCKRIDGE;
|
||||
#endif
|
||||
|
||||
if (_cdio_read_block(cdio, BOOT_SECTOR, start_session, 3, track_num) < 0)
|
||||
return ret;
|
||||
|
||||
if (_cdio_is_joliet()) {
|
||||
cdio_analysis->joliet_level = _cdio_get_joliet_level();
|
||||
ret |= CDIO_FS_ANAL_JOLIET;
|
||||
}
|
||||
if (_cdio_is_it(INDEX_BOOTABLE))
|
||||
ret |= CDIO_FS_ANAL_BOOTABLE;
|
||||
|
||||
if (_cdio_is_it(INDEX_XA) && _cdio_is_it(INDEX_ISOFS)
|
||||
&& !_cdio_is_it(INDEX_PHOTO_CD)) {
|
||||
|
||||
if ( _cdio_read_block(cdio, VCD_INFO_SECTOR, start_session, 4,
|
||||
track_num) < 0 )
|
||||
return ret;
|
||||
|
||||
if (_cdio_is_it(INDEX_BRIDGE) && _cdio_is_it(INDEX_CD_RTOS)) {
|
||||
if (_cdio_is_it(INDEX_VIDEO_CD)) ret |= CDIO_FS_ANAL_VIDEOCDI;
|
||||
else if (_cdio_is_it(INDEX_SVCD)) ret |= CDIO_FS_ANAL_SVCD;
|
||||
} else if (_cdio_is_it(INDEX_SVCD)) ret |= CDIO_FS_ANAL_CVD;
|
||||
|
||||
}
|
||||
}
|
||||
else if (_cdio_is_hfs()) ret |= CDIO_FS_HFS;
|
||||
else if (_cdio_is_it(INDEX_EXT2)) ret |= CDIO_FS_EXT2;
|
||||
else if (_cdio_is_3do()) ret |= CDIO_FS_3DO;
|
||||
else {
|
||||
if ( _cdio_read_block(cdio, UFS_SUPERBLOCK_SECTOR, start_session, 2,
|
||||
track_num) < 0 )
|
||||
return ret;
|
||||
|
||||
if (_cdio_is_it(INDEX_UFS))
|
||||
ret |= CDIO_FS_UFS;
|
||||
else
|
||||
ret |= CDIO_FS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* other checks */
|
||||
if (_cdio_is_it(INDEX_XA)) ret |= CDIO_FS_ANAL_XA;
|
||||
if (_cdio_is_it(INDEX_PHOTO_CD)) ret |= CDIO_FS_ANAL_PHOTO_CD;
|
||||
if (_cdio_is_it(INDEX_CDTV)) ret |= CDIO_FS_ANAL_CDTV;
|
||||
return ret;
|
||||
}
|
||||
703
lib/iso9660.c
Normal file
703
lib/iso9660.c
Normal file
@@ -0,0 +1,703 @@
|
||||
/*
|
||||
$Id: iso9660.c,v 1.1 2003/08/17 05:31:19 rocky Exp $
|
||||
|
||||
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Public headers */
|
||||
#include <cdio/iso9660.h>
|
||||
#include <cdio/util.h>
|
||||
|
||||
/* Private headers */
|
||||
#include "iso9660_private.h"
|
||||
#include "cdio_assert.h"
|
||||
#include "bytesex.h"
|
||||
|
||||
static const char _rcsid[] = "$Id: iso9660.c,v 1.1 2003/08/17 05:31:19 rocky Exp $";
|
||||
|
||||
/* some parameters... */
|
||||
#define SYSTEM_ID "CD-RTOS CD-BRIDGE"
|
||||
#define VOLUME_SET_ID ""
|
||||
|
||||
static void
|
||||
pathtable_get_size_and_entries(const void *pt, unsigned *size,
|
||||
unsigned int *entries);
|
||||
|
||||
static void
|
||||
_idr_set_time (uint8_t _idr_date[], const struct tm *_tm)
|
||||
{
|
||||
memset (_idr_date, 0, 7);
|
||||
|
||||
if (!_tm)
|
||||
return;
|
||||
|
||||
_idr_date[0] = _tm->tm_year;
|
||||
_idr_date[1] = _tm->tm_mon + 1;
|
||||
_idr_date[2] = _tm->tm_mday;
|
||||
_idr_date[3] = _tm->tm_hour;
|
||||
_idr_date[4] = _tm->tm_min;
|
||||
_idr_date[5] = _tm->tm_sec;
|
||||
_idr_date[6] = 0x00; /* tz, GMT -48 +52 in 15min intervals */
|
||||
}
|
||||
|
||||
static void
|
||||
_pvd_set_time (char _pvd_date[], const struct tm *_tm)
|
||||
{
|
||||
memset (_pvd_date, '0', 16);
|
||||
_pvd_date[16] = (int8_t) 0; /* tz */
|
||||
|
||||
if (!_tm)
|
||||
return;
|
||||
|
||||
snprintf(_pvd_date, 17,
|
||||
"%4.4d%2.2d%2.2d" "%2.2d%2.2d%2.2d" "%2.2d",
|
||||
_tm->tm_year + 1900, _tm->tm_mon + 1, _tm->tm_mday,
|
||||
_tm->tm_hour, _tm->tm_min, _tm->tm_sec,
|
||||
0 /* 1/100 secs */ );
|
||||
|
||||
_pvd_date[16] = (int8_t) 0; /* tz */
|
||||
}
|
||||
|
||||
char *
|
||||
iso9660_strncpy_pad(char dst[], const char src[], size_t len,
|
||||
enum strncpy_pad_check _check)
|
||||
{
|
||||
size_t rlen;
|
||||
|
||||
cdio_assert (dst != NULL);
|
||||
cdio_assert (src != NULL);
|
||||
cdio_assert (len > 0);
|
||||
|
||||
switch (_check)
|
||||
{
|
||||
int idx;
|
||||
case ISO9660_NOCHECK:
|
||||
break;
|
||||
|
||||
case ISO9660_7BIT:
|
||||
for (idx = 0; src[idx]; idx++)
|
||||
if ((int8_t) src[idx] < 0)
|
||||
{
|
||||
cdio_warn ("string '%s' fails 7bit constraint (pos = %d)",
|
||||
src, idx);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISO9660_ACHARS:
|
||||
for (idx = 0; src[idx]; idx++)
|
||||
if (!iso9660_isachar (src[idx]))
|
||||
{
|
||||
cdio_warn ("string '%s' fails a-character constraint (pos = %d)",
|
||||
src, idx);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISO9660_DCHARS:
|
||||
for (idx = 0; src[idx]; idx++)
|
||||
if (!iso9660_isdchar (src[idx]))
|
||||
{
|
||||
cdio_warn ("string '%s' fails d-character constraint (pos = %d)",
|
||||
src, idx);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
cdio_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
rlen = strlen (src);
|
||||
|
||||
if (rlen > len)
|
||||
cdio_warn ("string '%s' is getting truncated to %d characters",
|
||||
src, (unsigned) len);
|
||||
|
||||
strncpy (dst, src, len);
|
||||
if (rlen < len)
|
||||
memset(dst+rlen, ' ', len-rlen);
|
||||
return dst;
|
||||
}
|
||||
|
||||
int
|
||||
iso9660_isdchar (int c)
|
||||
{
|
||||
if (!IN (c, 0x30, 0x5f)
|
||||
|| IN (c, 0x3a, 0x40)
|
||||
|| IN (c, 0x5b, 0x5e))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
iso9660_isachar (int c)
|
||||
{
|
||||
if (!IN (c, 0x20, 0x5f)
|
||||
|| IN (c, 0x23, 0x24)
|
||||
|| c == 0x40
|
||||
|| IN (c, 0x5b, 0x5e))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
iso9660_set_evd(void *pd)
|
||||
{
|
||||
struct iso_volume_descriptor ied;
|
||||
|
||||
cdio_assert (sizeof(struct iso_volume_descriptor) == ISO_BLOCKSIZE);
|
||||
|
||||
cdio_assert (pd != NULL);
|
||||
|
||||
memset(&ied, 0, sizeof(ied));
|
||||
|
||||
ied.type = to_711(ISO_VD_END);
|
||||
iso9660_strncpy_pad (ied.id, ISO_STANDARD_ID, sizeof(ied.id), ISO9660_DCHARS);
|
||||
ied.version = to_711(ISO_VERSION);
|
||||
|
||||
memcpy(pd, &ied, sizeof(ied));
|
||||
}
|
||||
|
||||
/* important date to celebrate (for me at least =)
|
||||
-- until user customization is implemented... */
|
||||
static const time_t _vcd_time = 269222400L;
|
||||
|
||||
void
|
||||
iso9660_set_pvd(void *pd,
|
||||
const char volume_id[],
|
||||
const char publisher_id[],
|
||||
const char preparer_id[],
|
||||
const char application_id[],
|
||||
uint32_t iso_size,
|
||||
const void *root_dir,
|
||||
uint32_t path_table_l_extent,
|
||||
uint32_t path_table_m_extent,
|
||||
uint32_t path_table_size)
|
||||
{
|
||||
struct iso_primary_descriptor ipd;
|
||||
|
||||
cdio_assert (sizeof(struct iso_primary_descriptor) == ISO_BLOCKSIZE);
|
||||
|
||||
cdio_assert (pd != NULL);
|
||||
cdio_assert (volume_id != NULL);
|
||||
cdio_assert (application_id != NULL);
|
||||
|
||||
memset(&ipd,0,sizeof(ipd)); /* paranoia? */
|
||||
|
||||
/* magic stuff ... thatis CD XA marker... */
|
||||
strcpy(((char*)&ipd)+ISO_XA_MARKER_OFFSET, ISO_XA_MARKER_STRING);
|
||||
|
||||
ipd.type = to_711(ISO_VD_PRIMARY);
|
||||
iso9660_strncpy_pad (ipd.id, ISO_STANDARD_ID, 5, ISO9660_DCHARS);
|
||||
ipd.version = to_711(ISO_VERSION);
|
||||
|
||||
iso9660_strncpy_pad (ipd.system_id, SYSTEM_ID, 32, ISO9660_ACHARS);
|
||||
iso9660_strncpy_pad (ipd.volume_id, volume_id, 32, ISO9660_DCHARS);
|
||||
|
||||
ipd.volume_space_size = to_733(iso_size);
|
||||
|
||||
ipd.volume_set_size = to_723(1);
|
||||
ipd.volume_sequence_number = to_723(1);
|
||||
ipd.logical_block_size = to_723(ISO_BLOCKSIZE);
|
||||
|
||||
ipd.path_table_size = to_733(path_table_size);
|
||||
ipd.type_l_path_table = to_731(path_table_l_extent);
|
||||
ipd.type_m_path_table = to_732(path_table_m_extent);
|
||||
|
||||
cdio_assert (sizeof(ipd.root_directory_record) == 34);
|
||||
memcpy(ipd.root_directory_record, root_dir, sizeof(ipd.root_directory_record));
|
||||
ipd.root_directory_record[0] = 34;
|
||||
|
||||
iso9660_strncpy_pad (ipd.volume_set_id, VOLUME_SET_ID, 128, ISO9660_DCHARS);
|
||||
|
||||
iso9660_strncpy_pad (ipd.publisher_id, publisher_id, 128, ISO9660_ACHARS);
|
||||
iso9660_strncpy_pad (ipd.preparer_id, preparer_id, 128, ISO9660_ACHARS);
|
||||
iso9660_strncpy_pad (ipd.application_id, application_id, 128, ISO9660_ACHARS);
|
||||
|
||||
iso9660_strncpy_pad (ipd.copyright_file_id , "", 37, ISO9660_DCHARS);
|
||||
iso9660_strncpy_pad (ipd.abstract_file_id , "", 37, ISO9660_DCHARS);
|
||||
iso9660_strncpy_pad (ipd.bibliographic_file_id, "", 37, ISO9660_DCHARS);
|
||||
|
||||
_pvd_set_time (ipd.creation_date, gmtime (&_vcd_time));
|
||||
_pvd_set_time (ipd.modification_date, gmtime (&_vcd_time));
|
||||
_pvd_set_time (ipd.expiration_date, NULL);
|
||||
_pvd_set_time (ipd.effective_date, NULL);
|
||||
|
||||
ipd.file_structure_version = to_711(1);
|
||||
|
||||
/* we leave ipd.application_data = 0 */
|
||||
|
||||
memcpy(pd, &ipd, sizeof(ipd)); /* copy stuff to arg ptr */
|
||||
}
|
||||
|
||||
unsigned
|
||||
iso9660_dir_calc_record_size(unsigned namelen, unsigned int su_len)
|
||||
{
|
||||
unsigned length;
|
||||
|
||||
length = sizeof(struct iso_directory_record);
|
||||
length += namelen;
|
||||
if (length % 2) /* pad to word boundary */
|
||||
length++;
|
||||
length += su_len;
|
||||
if (length % 2) /* pad to word boundary again */
|
||||
length++;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void
|
||||
iso9660_dir_add_entry_su(void *dir,
|
||||
const char name[],
|
||||
uint32_t extent,
|
||||
uint32_t size,
|
||||
uint8_t flags,
|
||||
const void *su_data,
|
||||
unsigned su_size)
|
||||
{
|
||||
struct iso_directory_record *idr = dir;
|
||||
uint8_t *dir8 = dir;
|
||||
unsigned offset = 0;
|
||||
uint32_t dsize = from_733(idr->size);
|
||||
int length, su_offset;
|
||||
|
||||
cdio_assert (sizeof(struct iso_directory_record) == 33);
|
||||
|
||||
if (!dsize && !idr->length)
|
||||
dsize = ISO_BLOCKSIZE; /* for when dir lacks '.' entry */
|
||||
|
||||
cdio_assert (dsize > 0 && !(dsize % ISO_BLOCKSIZE));
|
||||
cdio_assert (dir != NULL);
|
||||
cdio_assert (extent > 17);
|
||||
cdio_assert (name != NULL);
|
||||
cdio_assert (strlen(name) <= MAX_ISOPATHNAME);
|
||||
|
||||
length = sizeof(struct iso_directory_record);
|
||||
length += strlen(name);
|
||||
length = _cdio_ceil2block (length, 2); /* pad to word boundary */
|
||||
su_offset = length;
|
||||
length += su_size;
|
||||
length = _cdio_ceil2block (length, 2); /* pad to word boundary again */
|
||||
|
||||
/* find the last entry's end */
|
||||
{
|
||||
unsigned ofs_last_rec = 0;
|
||||
|
||||
offset = 0;
|
||||
while (offset < dsize)
|
||||
{
|
||||
if (!dir8[offset])
|
||||
{
|
||||
offset++;
|
||||
continue;
|
||||
}
|
||||
|
||||
offset += dir8[offset];
|
||||
ofs_last_rec = offset;
|
||||
}
|
||||
|
||||
cdio_assert (offset == dsize);
|
||||
|
||||
offset = ofs_last_rec;
|
||||
}
|
||||
|
||||
/* be sure we don't cross sectors boundaries */
|
||||
offset = _cdio_ofs_add (offset, length, ISO_BLOCKSIZE);
|
||||
offset -= length;
|
||||
|
||||
cdio_assert (offset + length <= dsize);
|
||||
|
||||
idr = (struct iso_directory_record*) &dir8[offset];
|
||||
|
||||
cdio_assert (offset+length < dsize);
|
||||
|
||||
memset(idr, 0, length);
|
||||
|
||||
idr->length = to_711(length);
|
||||
idr->extent = to_733(extent);
|
||||
idr->size = to_733(size);
|
||||
|
||||
_idr_set_time (idr->date, gmtime (&_vcd_time));
|
||||
|
||||
idr->flags = to_711(flags);
|
||||
|
||||
idr->volume_sequence_number = to_723(1);
|
||||
|
||||
idr->name_len = to_711(strlen(name) ? strlen(name) : 1); /* working hack! */
|
||||
|
||||
memcpy(idr->name, name, from_711(idr->name_len));
|
||||
memcpy(&dir8[offset] + su_offset, su_data, su_size);
|
||||
}
|
||||
|
||||
void
|
||||
iso9660_dir_init_new (void *dir,
|
||||
uint32_t self,
|
||||
uint32_t ssize,
|
||||
uint32_t parent,
|
||||
uint32_t psize)
|
||||
{
|
||||
iso9660_dir_init_new_su (dir, self, ssize, NULL, 0, parent, psize, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
iso9660_dir_init_new_su (void *dir,
|
||||
uint32_t self,
|
||||
uint32_t ssize,
|
||||
const void *ssu_data,
|
||||
unsigned ssu_size,
|
||||
uint32_t parent,
|
||||
uint32_t psize,
|
||||
const void *psu_data,
|
||||
unsigned psu_size)
|
||||
{
|
||||
cdio_assert (ssize > 0 && !(ssize % ISO_BLOCKSIZE));
|
||||
cdio_assert (psize > 0 && !(psize % ISO_BLOCKSIZE));
|
||||
cdio_assert (dir != NULL);
|
||||
|
||||
memset (dir, 0, ssize);
|
||||
|
||||
/* "\0" -- working hack due to padding */
|
||||
iso9660_dir_add_entry_su (dir, "\0", self, ssize, ISO_DIRECTORY, ssu_data,
|
||||
ssu_size);
|
||||
|
||||
iso9660_dir_add_entry_su (dir, "\1", parent, psize, ISO_DIRECTORY, psu_data,
|
||||
psu_size);
|
||||
}
|
||||
|
||||
void
|
||||
iso9660_pathtable_init (void *pt)
|
||||
{
|
||||
cdio_assert (sizeof (struct iso_path_table) == 8);
|
||||
|
||||
cdio_assert (pt != NULL);
|
||||
|
||||
memset (pt, 0, ISO_BLOCKSIZE); /* fixme */
|
||||
}
|
||||
|
||||
static const struct iso_path_table*
|
||||
pathtable_get_entry (const void *pt, unsigned entrynum)
|
||||
{
|
||||
const uint8_t *tmp = pt;
|
||||
unsigned offset = 0;
|
||||
unsigned count = 0;
|
||||
|
||||
cdio_assert (pt != NULL);
|
||||
|
||||
while (from_711 (*tmp))
|
||||
{
|
||||
if (count == entrynum)
|
||||
break;
|
||||
|
||||
cdio_assert (count < entrynum);
|
||||
|
||||
offset += sizeof (struct iso_path_table);
|
||||
offset += from_711 (*tmp);
|
||||
if (offset % 2)
|
||||
offset++;
|
||||
tmp = (uint8_t *)pt + offset;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!from_711 (*tmp))
|
||||
return NULL;
|
||||
|
||||
return (const void *) tmp;
|
||||
}
|
||||
|
||||
void
|
||||
pathtable_get_size_and_entries (const void *pt,
|
||||
unsigned *size,
|
||||
unsigned *entries)
|
||||
{
|
||||
const uint8_t *tmp = pt;
|
||||
unsigned offset = 0;
|
||||
unsigned count = 0;
|
||||
|
||||
cdio_assert (pt != NULL);
|
||||
|
||||
while (from_711 (*tmp))
|
||||
{
|
||||
offset += sizeof (struct iso_path_table);
|
||||
offset += from_711 (*tmp);
|
||||
if (offset % 2)
|
||||
offset++;
|
||||
tmp = (uint8_t *)pt + offset;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (size)
|
||||
*size = offset;
|
||||
|
||||
if (entries)
|
||||
*entries = count;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
iso9660_pathtable_get_size (const void *pt)
|
||||
{
|
||||
unsigned size = 0;
|
||||
pathtable_get_size_and_entries (pt, &size, NULL);
|
||||
return size;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
iso9660_pathtable_l_add_entry (void *pt,
|
||||
const char name[],
|
||||
uint32_t extent,
|
||||
uint16_t parent)
|
||||
{
|
||||
struct iso_path_table *ipt =
|
||||
(struct iso_path_table*)((char *)pt + iso9660_pathtable_get_size (pt));
|
||||
size_t name_len = strlen (name) ? strlen (name) : 1;
|
||||
unsigned entrynum = 0;
|
||||
|
||||
cdio_assert (iso9660_pathtable_get_size (pt) < ISO_BLOCKSIZE); /*fixme */
|
||||
|
||||
memset (ipt, 0, sizeof (struct iso_path_table) + name_len); /* paranoia */
|
||||
|
||||
ipt->name_len = to_711 (name_len);
|
||||
ipt->extent = to_731 (extent);
|
||||
ipt->parent = to_721 (parent);
|
||||
memcpy (ipt->name, name, name_len);
|
||||
|
||||
pathtable_get_size_and_entries (pt, NULL, &entrynum);
|
||||
|
||||
if (entrynum > 1)
|
||||
{
|
||||
const struct iso_path_table *ipt2
|
||||
= pathtable_get_entry (pt, entrynum - 2);
|
||||
|
||||
cdio_assert (ipt2 != NULL);
|
||||
|
||||
cdio_assert (from_721 (ipt2->parent) <= parent);
|
||||
}
|
||||
|
||||
return entrynum;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
iso9660_pathtable_m_add_entry (void *pt,
|
||||
const char name[],
|
||||
uint32_t extent,
|
||||
uint16_t parent)
|
||||
{
|
||||
struct iso_path_table *ipt =
|
||||
(struct iso_path_table*)((char *)pt + iso9660_pathtable_get_size (pt));
|
||||
size_t name_len = strlen (name) ? strlen (name) : 1;
|
||||
unsigned entrynum = 0;
|
||||
|
||||
cdio_assert (iso9660_pathtable_get_size(pt) < ISO_BLOCKSIZE); /* fixme */
|
||||
|
||||
memset(ipt, 0, sizeof (struct iso_path_table) + name_len); /* paranoia */
|
||||
|
||||
ipt->name_len = to_711 (name_len);
|
||||
ipt->extent = to_732 (extent);
|
||||
ipt->parent = to_722 (parent);
|
||||
memcpy (ipt->name, name, name_len);
|
||||
|
||||
pathtable_get_size_and_entries (pt, NULL, &entrynum);
|
||||
|
||||
if (entrynum > 1)
|
||||
{
|
||||
const struct iso_path_table *ipt2
|
||||
= pathtable_get_entry (pt, entrynum - 2);
|
||||
|
||||
cdio_assert (ipt2 != NULL);
|
||||
|
||||
cdio_assert (from_722 (ipt2->parent) <= parent);
|
||||
}
|
||||
|
||||
return entrynum;
|
||||
}
|
||||
|
||||
bool
|
||||
iso9660_dirname_valid_p (const char pathname[])
|
||||
{
|
||||
const char *p = pathname;
|
||||
int len;
|
||||
|
||||
cdio_assert (pathname != NULL);
|
||||
|
||||
if (*p == '/' || *p == '.' || *p == '\0')
|
||||
return false;
|
||||
|
||||
if (strlen (pathname) > MAX_ISOPATHNAME)
|
||||
return false;
|
||||
|
||||
len = 0;
|
||||
for (; *p; p++)
|
||||
if (iso9660_isdchar (*p))
|
||||
{
|
||||
len++;
|
||||
if (len > 8)
|
||||
return false;
|
||||
}
|
||||
else if (*p == '/')
|
||||
{
|
||||
if (!len)
|
||||
return false;
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
return false; /* unexpected char */
|
||||
|
||||
if (!len)
|
||||
return false; /* last char may not be '/' */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
iso9660_pathname_valid_p (const char pathname[])
|
||||
{
|
||||
const char *p = NULL;
|
||||
|
||||
cdio_assert (pathname != NULL);
|
||||
|
||||
if ((p = strrchr (pathname, '/')))
|
||||
{
|
||||
bool rc;
|
||||
char *_tmp = strdup (pathname);
|
||||
|
||||
*strrchr (_tmp, '/') = '\0';
|
||||
|
||||
rc = iso9660_dirname_valid_p (_tmp);
|
||||
|
||||
free (_tmp);
|
||||
|
||||
if (!rc)
|
||||
return false;
|
||||
|
||||
p++;
|
||||
}
|
||||
else
|
||||
p = pathname;
|
||||
|
||||
if (strlen (pathname) > (MAX_ISOPATHNAME - 6))
|
||||
return false;
|
||||
|
||||
{
|
||||
int len = 0;
|
||||
int dots = 0;
|
||||
|
||||
for (; *p; p++)
|
||||
if (iso9660_isdchar (*p))
|
||||
{
|
||||
len++;
|
||||
if (dots == 0 ? len > 8 : len > 3)
|
||||
return false;
|
||||
}
|
||||
else if (*p == '.')
|
||||
{
|
||||
dots++;
|
||||
if (dots > 1)
|
||||
return false;
|
||||
if (!len)
|
||||
return false;
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
if (dots != 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *
|
||||
iso9660_pathname_isofy (const char pathname[], uint16_t version)
|
||||
{
|
||||
char tmpbuf[1024] = { 0, };
|
||||
|
||||
cdio_assert (strlen (pathname) < (sizeof (tmpbuf) - sizeof (";65535")));
|
||||
|
||||
snprintf (tmpbuf, sizeof(tmpbuf), "%s;%d", pathname, version);
|
||||
|
||||
return strdup (tmpbuf);
|
||||
}
|
||||
|
||||
lsn_t
|
||||
iso9660_get_root_lsn(struct iso_primary_descriptor const *pvd)
|
||||
{
|
||||
if (NULL == pvd)
|
||||
return CDIO_INVALID_LSN;
|
||||
else {
|
||||
struct iso_directory_record *idr = (void *) pvd->root_directory_record;
|
||||
if (NULL == idr) return CDIO_INVALID_LSN;
|
||||
return(from_733 (idr->extent));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
iso9660_get_pvd_type(struct iso_primary_descriptor const *pvd)
|
||||
{
|
||||
if (NULL == pvd) return 255;
|
||||
return(pvd->type);
|
||||
}
|
||||
|
||||
const char *
|
||||
iso9660_get_pvd_id(struct iso_primary_descriptor const *pvd)
|
||||
{
|
||||
if (NULL == pvd) return "ERR";
|
||||
return(pvd->id);
|
||||
}
|
||||
|
||||
int
|
||||
iso9660_get_pvd_space_size(struct iso_primary_descriptor const *pvd)
|
||||
{
|
||||
if (NULL == pvd) return 0;
|
||||
return from_733(pvd->volume_space_size);
|
||||
}
|
||||
|
||||
int
|
||||
iso9660_get_pvd_block_size(struct iso_primary_descriptor const *pvd)
|
||||
{
|
||||
if (NULL == pvd) return 0;
|
||||
return from_723(pvd->logical_block_size);
|
||||
}
|
||||
|
||||
int
|
||||
iso9660_get_pvd_version(struct iso_primary_descriptor const *pvd)
|
||||
{
|
||||
if (NULL == pvd) return 0;
|
||||
return pvd->version;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "gnu"
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
120
lib/iso9660_private.h
Normal file
120
lib/iso9660_private.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
$Id: iso9660_private.h,v 1.1 2003/08/17 05:31:19 rocky Exp $
|
||||
|
||||
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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
|
||||
*/
|
||||
|
||||
#ifndef __CDIO_ISO9660_PRIVATE_H__
|
||||
#define __CDIO_ISO9660_PRIVATE_H__
|
||||
|
||||
#include <libvcd/types.h>
|
||||
|
||||
#define ISO_VD_END 255
|
||||
|
||||
#define ISO_VERSION 1
|
||||
|
||||
#define ISO_XA_MARKER_STRING "CD-XA001"
|
||||
#define ISO_XA_MARKER_OFFSET 1024
|
||||
|
||||
PRAGMA_BEGIN_PACKED
|
||||
|
||||
struct iso_volume_descriptor {
|
||||
uint8_t type; /* 711 */
|
||||
char id[5];
|
||||
uint8_t version; /* 711 */
|
||||
char data[2041];
|
||||
} GNUC_PACKED;
|
||||
|
||||
#define struct_iso_volume_descriptor_SIZEOF ISO_BLOCKSIZE
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
uint8_t type; /* 711 */
|
||||
char id[5];
|
||||
uint8_t version; /* 711 */
|
||||
char unused1[1];
|
||||
char system_id[32]; /* achars */
|
||||
char volume_id[32]; /* dchars */
|
||||
char unused2[8];
|
||||
uint64_t volume_space_size; /* 733 */
|
||||
char escape_sequences[32];
|
||||
uint32_t volume_set_size; /* 723 */
|
||||
uint32_t volume_sequence_number; /* 723 */
|
||||
uint32_t logical_block_size; /* 723 */
|
||||
uint64_t path_table_size; /* 733 */
|
||||
uint32_t type_l_path_table; /* 731 */
|
||||
uint32_t opt_type_l_path_table; /* 731 */
|
||||
uint32_t type_m_path_table; /* 732 */
|
||||
uint32_t opt_type_m_path_table; /* 732 */
|
||||
char root_directory_record[34]; /* 9.1 */
|
||||
char volume_set_id[128]; /* dchars */
|
||||
char publisher_id[128]; /* achars */
|
||||
char preparer_id[128]; /* achars */
|
||||
char application_id[128]; /* achars */
|
||||
char copyright_file_id[37]; /* 7.5 dchars */
|
||||
char abstract_file_id[37]; /* 7.5 dchars */
|
||||
char bibliographic_file_id[37]; /* 7.5 dchars */
|
||||
char creation_date[17]; /* 8.4.26.1 */
|
||||
char modification_date[17]; /* 8.4.26.1 */
|
||||
char expiration_date[17]; /* 8.4.26.1 */
|
||||
char effective_date[17]; /* 8.4.26.1 */
|
||||
uint8_t file_structure_version; /* 711 */
|
||||
char unused4[1];
|
||||
char application_data[512];
|
||||
char unused5[653];
|
||||
} GNUC_PACKED;
|
||||
|
||||
#define struct_iso_primary_descriptor_SIZEOF ISO_BLOCKSIZE
|
||||
|
||||
struct iso_path_table {
|
||||
uint8_t name_len; /* 711 */
|
||||
uint8_t xa_len; /* 711 */
|
||||
uint32_t extent; /* 731/732 */
|
||||
uint16_t parent; /* 721/722 */
|
||||
char name[EMPTY_ARRAY_SIZE];
|
||||
} GNUC_PACKED;
|
||||
|
||||
#define struct_iso_path_table_SIZEOF 8
|
||||
|
||||
struct iso_directory_record {
|
||||
uint8_t length; /* 711 */
|
||||
uint8_t ext_attr_length; /* 711 */
|
||||
uint64_t extent; /* 733 */
|
||||
uint64_t size; /* 733 */
|
||||
uint8_t date[7]; /* 7 by 711 */
|
||||
uint8_t flags;
|
||||
uint8_t file_unit_size; /* 711 */
|
||||
uint8_t interleave; /* 711 */
|
||||
uint32_t volume_sequence_number; /* 723 */
|
||||
uint8_t name_len; /* 711 */
|
||||
char name[EMPTY_ARRAY_SIZE];
|
||||
} GNUC_PACKED;
|
||||
|
||||
#define struct_iso_directory_record_SIZEOF 33
|
||||
|
||||
PRAGMA_END_PACKED
|
||||
|
||||
#endif /* __CDIO_ISO9660_PRIVATE_H__ */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "gnu"
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
11
libiso9660.pc.in
Normal file
11
libiso9660.pc.in
Normal file
@@ -0,0 +1,11 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libvcdinfo
|
||||
Description: ISO9660 library
|
||||
Version: @VERSION@
|
||||
Requires: glib-2.0 libcdio libvcd
|
||||
Libs: -L${libdir} -liso9660
|
||||
Cflags: -I${includedir}
|
||||
@@ -1,8 +1,12 @@
|
||||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
check_cue.sh
|
||||
check_common_fn
|
||||
check_nrg.sh
|
||||
testassert
|
||||
testischar
|
||||
*.dump
|
||||
*.cue
|
||||
*.bin
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.am,v 1.3 2003/04/28 02:02:41 rocky Exp $
|
||||
# $Id: Makefile.am,v 1.4 2003/08/17 05:31:19 rocky Exp $
|
||||
#
|
||||
# Copyright (C) 2003 Rocky Bernstein <rocky@panix.com>
|
||||
#
|
||||
@@ -20,8 +20,17 @@
|
||||
# Things to regression testing
|
||||
####################################################
|
||||
#
|
||||
noinst_PROGRAMS = testassert testischar
|
||||
|
||||
INCLUDES = -I$(top_srcdir) $(LIBCDIO_CFLAGS)
|
||||
|
||||
testassert_LDADD = $(LIBCDIO_LIBS)
|
||||
testischar_LDADD = $(LIBISO9660_LIBS) $(LIBCDIO_LIBS)
|
||||
|
||||
check_SCRIPTS = check_nrg.sh check_cue.sh check_opts.sh
|
||||
|
||||
check_PROGRAMS = testischar testassert
|
||||
|
||||
check_DATA = vcd_demo.right \
|
||||
videocd.right videocd.nrg \
|
||||
cdda.right cdda.cue cdda.bin \
|
||||
|
||||
36
test/testassert.c
Normal file
36
test/testassert.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
$Id: testassert.c,v 1.1 2003/08/17 05:31:19 rocky Exp $
|
||||
|
||||
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
/* Private headers */
|
||||
#include "cdio_assert.h"
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
cdio_assert (argc < 2);
|
||||
|
||||
cdio_assert_not_reached ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
71
test/testischar.c
Normal file
71
test/testischar.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
$Id: testischar.c,v 1.1 2003/08/17 05:31:19 rocky Exp $
|
||||
|
||||
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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
|
||||
*/
|
||||
/* Tests ISO9660 character sets. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cdio/iso9660.h>
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
int i, j;
|
||||
|
||||
printf (" ");
|
||||
|
||||
for (j = 0; j < 0x10; j++)
|
||||
printf (" %1.1x", j);
|
||||
|
||||
printf (" |");
|
||||
|
||||
for (j = 0; j < 0x10; j++)
|
||||
printf (" %1.1x", j);
|
||||
|
||||
printf ("\n");
|
||||
|
||||
for (i = 0; i < 0x10; i++)
|
||||
{
|
||||
|
||||
printf ("%1.1x ", i);
|
||||
|
||||
for (j = 0; j < 0x10; j++)
|
||||
{
|
||||
int c = (j << 4) + i;
|
||||
|
||||
printf (" %c", iso9660_isdchar (c) ? c : ' ');
|
||||
}
|
||||
|
||||
printf (" |");
|
||||
|
||||
for (j = 0; j < 0x10; j++)
|
||||
{
|
||||
int c = (j << 4) + i;
|
||||
|
||||
printf (" %c", iso9660_isachar (c) ? c : ' ');
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user