With some violence I got iso file listing working
I don't know if code is leaking or what, the c files are full with unused code and globals and are quite dirty. But hey, it runs for meh!
This commit is contained in:
parent
b0e2658c15
commit
17f72fcbdf
6 changed files with 400 additions and 392 deletions
|
@ -6,229 +6,17 @@ import std.exception;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
import std.stdint;
|
import std.stdint;
|
||||||
|
|
||||||
private const int MAX_ISONAME_V2 = 207; /*254 - 33 - 14 (XA Record)*/
|
|
||||||
private const int MAX_ISONAME = MAX_ISONAME_V2;
|
|
||||||
private const int ISO_MULTIEXTENT = 128; /*Not final entry of a mult. ext. file*/
|
|
||||||
private const SECTOR_SIZE = 2048;
|
|
||||||
/*
|
|
||||||
* Use sector_offset != 0 (-N #) if we have an image file
|
|
||||||
* of a single session and we need to list the directory contents.
|
|
||||||
* This is the session block (sector) number of the start
|
|
||||||
* of the session when it would be on disk.
|
|
||||||
*/
|
|
||||||
private uint sector_offset = 0;
|
|
||||||
|
|
||||||
private int ISODCL(int from, int to) pure {
|
|
||||||
return to - from + 1;
|
|
||||||
}
|
|
||||||
private int ISO_BLOCKS(size_t X) pure {
|
|
||||||
return (cast(int)X / SECTOR_SIZE + ((cast(int)X % SECTOR_SIZE) ? 1 : 0));
|
|
||||||
}
|
|
||||||
private alias off_t = long;
|
|
||||||
|
|
||||||
extern(C) {
|
extern(C) {
|
||||||
struct iso_volume_descriptor {
|
alias iso_listing_callback = int function(void*,const(char)*,int);
|
||||||
char[ISODCL(1, 1)] type; /* 711 */
|
int scan_iso (const(char)* filename, iso_listing_callback callback, void* user_data);
|
||||||
char[ISODCL(2, 6)] id;
|
|
||||||
char[ISODCL(7, 7)] version_;
|
|
||||||
char[ISODCL(8, 2048)] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct iso_directory_record {
|
private int printer(void*, const(char)* path, int is_dir) {
|
||||||
byte [ISODCL(1, 1)] length; /* 711 */
|
writef("Entry \"%s\"", path.fromStringz);
|
||||||
char [ISODCL(2, 2)] ext_attr_length; /* 711 */
|
if (is_dir != 0) {
|
||||||
char [ISODCL(3, 10)] extent; /* 733 */
|
write(" (directory)");
|
||||||
char [ISODCL(11, 18)] size; /* 733 */
|
}
|
||||||
char [ISODCL(19, 25)] date; /* 7 by 711 */
|
write("\n");
|
||||||
byte [ISODCL(26, 26)] flags;
|
return 0;
|
||||||
char [ISODCL(27, 27)] file_unit_size; /* 711 */
|
|
||||||
char [ISODCL(28, 28)] interleave; /* 711 */
|
|
||||||
char [ISODCL(29, 32)] volume_sequence_number; /* 723 */
|
|
||||||
byte [ISODCL(33, 33)] name_len; /* 711 */
|
|
||||||
char [MAX_ISONAME+1] name; /* Not really, but we need something here */
|
|
||||||
};
|
|
||||||
|
|
||||||
version(USE_SCG) {
|
|
||||||
int readsecs (uint32_t startsecno, void* buffer, int sectorcount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct todo {
|
|
||||||
todo* next;
|
|
||||||
todo* prev;
|
|
||||||
string name;
|
|
||||||
int extent;
|
|
||||||
int length;
|
|
||||||
}
|
|
||||||
|
|
||||||
//int extent; /* Directory extent */
|
|
||||||
//int len; /* Directory size */
|
|
||||||
private void parse_dir(todo* dp, string rootname, int extent, int len) {
|
|
||||||
todo td;
|
|
||||||
int i;
|
|
||||||
iso_directory_record* idr;
|
|
||||||
iso_directory_record didr;
|
|
||||||
//stat dstat;
|
|
||||||
byte[2048] cl_buffer;
|
|
||||||
byte flags = 0;
|
|
||||||
long size = 0;
|
|
||||||
int sextent = 0;
|
|
||||||
int rlen;
|
|
||||||
int blen;
|
|
||||||
int rr_flags = 0;
|
|
||||||
static char* n = null;
|
|
||||||
static int nlen = 0;
|
|
||||||
byte[2048] buffer;
|
|
||||||
|
|
||||||
while (len > 0) {
|
|
||||||
version(USE_SCG) {
|
|
||||||
readsecs(extent - sector_offset, buffer.ptr, ISO_BLOCKS(buffer.length));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lseek(fileno(infile), (cast(off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
|
||||||
read(fileno(infile), buffer, sizeof (buffer));
|
|
||||||
}
|
|
||||||
len -= typeof(buffer).sizeof;
|
|
||||||
extent++;
|
|
||||||
i = 0;
|
|
||||||
/*
|
|
||||||
while (true) {
|
|
||||||
idr = cast(iso_directory_record*)&buffer[i];
|
|
||||||
if (idr->length[0] == 0)
|
|
||||||
break;
|
|
||||||
parse_de(idr);
|
|
||||||
if (use_rock) {
|
|
||||||
rr_flags = dump_rr(idr);
|
|
||||||
|
|
||||||
if (rr_flags & RR_FLAG_CL) {
|
|
||||||
// Need to reparse the child link
|
|
||||||
// but note that we parse "CL/."
|
|
||||||
// so we get no usable file name.
|
|
||||||
idr = (struct iso_directory_record *) cl_buffer;
|
|
||||||
parse_cl_dir(idr, cl_extent);
|
|
||||||
} else if (rr_flags & RR_FLAG_RE)
|
|
||||||
goto cont; // skip rr_moved
|
|
||||||
}
|
|
||||||
if (Xtract &&
|
|
||||||
(idr->flags[0] & 2) != 0 &&
|
|
||||||
idr->name_len[0] == 1 &&
|
|
||||||
idr->name[0] == 0) {
|
|
||||||
// The '.' entry.
|
|
||||||
didr = *idr;
|
|
||||||
dstat = fstat_buf;
|
|
||||||
}
|
|
||||||
blen = strlen(name_buf);
|
|
||||||
|
|
||||||
blen = rlen + blen + 1;
|
|
||||||
if (nlen < blen) {
|
|
||||||
n = ___realloc(n, blen, _("find_stat name"));
|
|
||||||
nlen = blen;
|
|
||||||
}
|
|
||||||
strcatl(n, rootname, name_buf, (char *)0);
|
|
||||||
if (name_buf[0] == '.' && name_buf[1] == '\0')
|
|
||||||
n[rlen] = '\0';
|
|
||||||
|
|
||||||
if ((idr->flags[0] & 2) != 0 &&
|
|
||||||
((rr_flags & RR_FLAG_CL) ||
|
|
||||||
(idr->name_len[0] != 1 ||
|
|
||||||
(idr->name[0] != 0 && idr->name[0] != 1)))) {
|
|
||||||
// This is a plain directory (neither "xxx/."
|
|
||||||
// nor "xxx/..").
|
|
||||||
// Add this directory to the todo list.
|
|
||||||
int dir_loop = 0;
|
|
||||||
int nextent;
|
|
||||||
struct todo *tp = dp;
|
|
||||||
|
|
||||||
nextent = isonum_733((unsigned char *)idr->extent);
|
|
||||||
while (tp) {
|
|
||||||
if (tp->extent == nextent) {
|
|
||||||
dir_loop = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tp = tp->prev;
|
|
||||||
}
|
|
||||||
if (dir_loop == 0) {
|
|
||||||
td = (struct todo *) malloc(sizeof (*td));
|
|
||||||
if (td == NULL)
|
|
||||||
comerr(_("No memory.\n"));
|
|
||||||
td->next = NULL;
|
|
||||||
td->prev = dp;
|
|
||||||
td->extent = isonum_733((unsigned char *)idr->extent);
|
|
||||||
td->length = isonum_733((unsigned char *)idr->size);
|
|
||||||
td->name = (char *) malloc(strlen(rootname)
|
|
||||||
+ strlen(name_buf) + 2);
|
|
||||||
if (td->name == NULL)
|
|
||||||
comerr(_("No memory.\n"));
|
|
||||||
strcpy(td->name, rootname);
|
|
||||||
strcat(td->name, name_buf);
|
|
||||||
strcat(td->name, "/");
|
|
||||||
|
|
||||||
*todo_pp = td;
|
|
||||||
todo_pp = &td->next;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (xtract && strcmp(xtract, n) == 0) {
|
|
||||||
extract_file(STDOUT_FILENO, idr, "stdout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (do_f &&
|
|
||||||
(idr->name_len[0] != 1 ||
|
|
||||||
(idr->name[0] != 0 && idr->name[0] != 1))) {
|
|
||||||
printf("%s\n", n);
|
|
||||||
}
|
|
||||||
if (do_listing || Xtract || do_find) {
|
|
||||||
// In case if a multi-extent file, remember the
|
|
||||||
// start extent number.
|
|
||||||
if ((idr->flags[0] & ISO_MULTIEXTENT) && size == 0)
|
|
||||||
sextent = isonum_733((unsigned char *)idr->extent);
|
|
||||||
|
|
||||||
if (debug ||
|
|
||||||
((idr->flags[0] & ISO_MULTIEXTENT) == 0 && size == 0)) {
|
|
||||||
if (dump_stat(rootname, idr, n,
|
|
||||||
isonum_733((unsigned char *)idr->extent))) {
|
|
||||||
if (Xtract) {
|
|
||||||
if ((idr->flags[0] & 2) != 0 &&
|
|
||||||
idr->name_len[0] != 1 &&
|
|
||||||
idr->name[0] != 1) {
|
|
||||||
char *p = n;
|
|
||||||
if (*p == '/')
|
|
||||||
p++;
|
|
||||||
makedirs(p,
|
|
||||||
S_IRUSR|S_IWUSR|S_IXUSR|
|
|
||||||
S_IRGRP|S_IWGRP|S_IXGRP|
|
|
||||||
S_IROTH|S_IWOTH|S_IXOTH,
|
|
||||||
FALSE);
|
|
||||||
} else {
|
|
||||||
if (myuid != 0 &&
|
|
||||||
S_ISDIR(fstat_buf.st_mode)) {
|
|
||||||
fstat_buf.st_mode |= S_IWUSR;
|
|
||||||
}
|
|
||||||
extract(rootname, idr, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (Xtract && find_stat(rootname, idr, n, sextent)) {
|
|
||||||
// Extract all multi extent files here...
|
|
||||||
extract(rootname, idr, n);
|
|
||||||
}
|
|
||||||
size += fstat_buf.st_size;
|
|
||||||
if ((flags & ISO_MULTIEXTENT) &&
|
|
||||||
(idr->flags[0] & ISO_MULTIEXTENT) == 0) {
|
|
||||||
fstat_buf.st_size = size;
|
|
||||||
if (!debug)
|
|
||||||
idr->flags[0] |= ISO_MULTIEXTENT;
|
|
||||||
dump_stat(rootname, idr, n, sextent);
|
|
||||||
if (!debug)
|
|
||||||
idr->flags[0] &= ~ISO_MULTIEXTENT;
|
|
||||||
}
|
|
||||||
flags = idr->flags[0];
|
|
||||||
if ((idr->flags[0] & ISO_MULTIEXTENT) == 0)
|
|
||||||
size = 0;
|
|
||||||
}
|
|
||||||
cont:
|
|
||||||
i += buffer[i];
|
|
||||||
if (i > 2048 - offsetof(struct iso_directory_record, name[0])) break;
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +27,8 @@ public string iso_to_serial (string path) {
|
||||||
// NPJH-50465|0D506D389F2AA444|0001|G
|
// NPJH-50465|0D506D389F2AA444|0001|G
|
||||||
// ULJM-05530|5A2E0CF722EF6299|0001|G
|
// ULJM-05530|5A2E0CF722EF6299|0001|G
|
||||||
|
|
||||||
|
scan_iso(path.toStringz, &printer, null);
|
||||||
|
|
||||||
return "UCES-00356"; //Tekken Dark Resurrection
|
return "UCES-00356"; //Tekken Dark Resurrection
|
||||||
//return "NPJH-50465"; //Hatsune Miku (missing from redump list)
|
//return "NPJH-50465"; //Hatsune Miku (missing from redump list)
|
||||||
//return "ULJM-05530"; //Undead Knights (missing from redump list)
|
//return "ULJM-05530"; //Undead Knights (missing from redump list)
|
||||||
|
|
|
@ -24,12 +24,16 @@ add_project_arguments(
|
||||||
c_compiler = meson.get_compiler('c')
|
c_compiler = meson.get_compiler('c')
|
||||||
|
|
||||||
cdrdeflt_dep = c_compiler.find_library('cdrdeflt')
|
cdrdeflt_dep = c_compiler.find_library('cdrdeflt')
|
||||||
|
scgcmd_dep = c_compiler.find_library('scgcmd')
|
||||||
|
schily_dep = c_compiler.find_library('schily')
|
||||||
|
scg_dep = c_compiler.find_library('scg')
|
||||||
|
siconv_dep = c_compiler.find_library('siconv')
|
||||||
public_inc = include_directories('include')
|
public_inc = include_directories('include')
|
||||||
|
|
||||||
libisoinfo = static_library(meson.project_name(),
|
libisoinfo = static_library(meson.project_name(),
|
||||||
'src/isoinfo.c',
|
'src/isoinfo.c',
|
||||||
'src/scsi.c',
|
'src/scsi.c',
|
||||||
dependencies: [cdrdeflt_dep],
|
dependencies: [cdrdeflt_dep, scgcmd_dep, schily_dep, scg_dep, siconv_dep],
|
||||||
install: false,
|
install: false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,14 @@
|
||||||
|
|
||||||
#define GET_UBYTE(a) a_to_u_byte(a)
|
#define GET_UBYTE(a) a_to_u_byte(a)
|
||||||
|
|
||||||
#define infile in_image
|
typedef int(*iso_listing_callback)(void*,const char*,int is_dir);
|
||||||
EXPORT FILE *infile = NULL;
|
|
||||||
|
enum ScanRetCode {
|
||||||
|
ScanRetCode_Ok = 100,
|
||||||
|
ScanRetCode_Disabled,
|
||||||
|
ScanRetCode_BadInput
|
||||||
|
};
|
||||||
|
|
||||||
EXPORT BOOL ignerr = FALSE;
|
EXPORT BOOL ignerr = FALSE;
|
||||||
LOCAL int use_rock = 0;
|
LOCAL int use_rock = 0;
|
||||||
LOCAL int use_joliet = 0;
|
LOCAL int use_joliet = 0;
|
||||||
|
@ -174,30 +180,35 @@ LOCAL struct todo **todo_pp = &todo_idr;
|
||||||
|
|
||||||
LOCAL int isonum_731 __PR((char * p));
|
LOCAL int isonum_731 __PR((char * p));
|
||||||
LOCAL int isonum_733 __PR((unsigned char * p));
|
LOCAL int isonum_733 __PR((unsigned char * p));
|
||||||
LOCAL int parse_rr __PR((unsigned char * pnt, int len,
|
LOCAL int parse_rr __PR((struct scsi_dev *dev, unsigned char * pnt,
|
||||||
int cont_flag));
|
int len, int cont_flag));
|
||||||
LOCAL void find_rr __PR((struct iso_directory_record * idr,
|
LOCAL void find_rr __PR((struct iso_directory_record * idr,
|
||||||
Uchar **pntp, int *lenp));
|
Uchar **pntp, int *lenp));
|
||||||
LOCAL int dump_rr __PR((struct iso_directory_record * idr));
|
LOCAL int dump_rr __PR((struct scsi_dev *dev,
|
||||||
|
struct iso_directory_record * idr));
|
||||||
LOCAL BOOL dump_stat __PR((char *rootname,
|
LOCAL BOOL dump_stat __PR((char *rootname,
|
||||||
struct iso_directory_record * idr,
|
struct iso_directory_record * idr,
|
||||||
char *fname,
|
char *fname,
|
||||||
int extent));
|
int extent));
|
||||||
LOCAL void extract __PR((char *rootname,
|
LOCAL void extract __PR((struct scsi_dev *dev,
|
||||||
|
char *rootname, struct iso_directory_record * idr,
|
||||||
|
char *fname));
|
||||||
|
LOCAL void extract_file __PR((struct scsi_dev *dev, int f,
|
||||||
struct iso_directory_record * idr,
|
struct iso_directory_record * idr,
|
||||||
char *fname));
|
char *fname));
|
||||||
LOCAL void extract_file __PR((int f,
|
LOCAL void parse_cl_dir __PR((struct scsi_dev *dev,
|
||||||
struct iso_directory_record * idr,
|
struct iso_directory_record *idr, int extent));
|
||||||
char *fname));
|
|
||||||
LOCAL void parse_cl_dir __PR((struct iso_directory_record *idr,
|
|
||||||
int extent));
|
|
||||||
LOCAL BOOL parse_de __PR((struct iso_directory_record *idr));
|
LOCAL BOOL parse_de __PR((struct iso_directory_record *idr));
|
||||||
LOCAL void parse_dir __PR((struct todo *dp,
|
LOCAL void parse_dir __PR((struct scsi_dev *dev, struct todo *dp,
|
||||||
char * rootname, int extent, int len));
|
char * rootname, int extent, int len,
|
||||||
|
iso_listing_callback callback, void* user_data));
|
||||||
LOCAL void list_locales __PR((void));
|
LOCAL void list_locales __PR((void));
|
||||||
LOCAL int time_cvt __PR((unsigned char *dp, int len));
|
LOCAL int time_cvt __PR((unsigned char *dp, int len));
|
||||||
LOCAL time_t iso9660_time __PR((unsigned char *date, int *hsecp,
|
LOCAL time_t iso9660_time __PR((unsigned char *date, int *hsecp,
|
||||||
BOOL longfmt));
|
BOOL longfmt));
|
||||||
|
LOCAL int run_scanning __PR((struct scsi_dev *dev,
|
||||||
|
iso_listing_callback callback, void *user_data));
|
||||||
|
LOCAL char* default_charset __PR((void));
|
||||||
|
|
||||||
LOCAL int
|
LOCAL int
|
||||||
isonum_731(p)
|
isonum_731(p)
|
||||||
|
@ -225,7 +236,8 @@ isonum_733(p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOCAL int
|
LOCAL int
|
||||||
parse_rr(pnt, len, cont_flag)
|
parse_rr(dev, pnt, len, cont_flag)
|
||||||
|
struct scsi_dev *dev;
|
||||||
unsigned char *pnt;
|
unsigned char *pnt;
|
||||||
int len;
|
int len;
|
||||||
int cont_flag;
|
int cont_flag;
|
||||||
|
@ -409,12 +421,12 @@ parse_rr(pnt, len, cont_flag)
|
||||||
unsigned char sector[2048];
|
unsigned char sector[2048];
|
||||||
|
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(cont_extent - sector_offset, sector, ISO_BLOCKS(sizeof (sector)));
|
readsecs(dev, cont_extent - sector_offset, sector, ISO_BLOCKS(sizeof (sector)));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(cont_extent - sector_offset)) << 11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(cont_extent - sector_offset)) << 11, SEEK_SET);
|
||||||
read(fileno(infile), sector, sizeof (sector));
|
read(fileno(infile), sector, sizeof (sector));
|
||||||
#endif
|
#endif
|
||||||
flag2 |= parse_rr(§or[cont_offset], cont_size, 1);
|
flag2 |= parse_rr(dev, §or[cont_offset], cont_size, 1);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* for symbolic links, strip out the last '/'
|
* for symbolic links, strip out the last '/'
|
||||||
|
@ -461,14 +473,15 @@ find_rr(idr, pntp, lenp)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL int
|
LOCAL int
|
||||||
dump_rr(idr)
|
dump_rr(dev, idr)
|
||||||
|
struct scsi_dev *dev;
|
||||||
struct iso_directory_record *idr;
|
struct iso_directory_record *idr;
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
unsigned char * pnt;
|
unsigned char * pnt;
|
||||||
|
|
||||||
find_rr(idr, &pnt, &len);
|
find_rr(idr, &pnt, &len);
|
||||||
return (parse_rr(pnt, len, 0));
|
return (parse_rr(dev, pnt, len, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL char *months[12] = {"Jan", "Feb", "Mar", "Apr",
|
LOCAL char *months[12] = {"Jan", "Feb", "Mar", "Apr",
|
||||||
|
@ -572,7 +585,8 @@ dump_stat(rootname, idr, fname, extent)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL void
|
LOCAL void
|
||||||
extract(rootname, idr, fname)
|
extract(dev, rootname, idr, fname)
|
||||||
|
struct scsi_dev *dev;
|
||||||
char *rootname;
|
char *rootname;
|
||||||
struct iso_directory_record *idr;
|
struct iso_directory_record *idr;
|
||||||
char *fname;
|
char *fname;
|
||||||
|
@ -682,7 +696,7 @@ static BOOL isfirst = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lseek(f, 0, SEEK_END);
|
lseek(f, 0, SEEK_END);
|
||||||
extract_file(f, idr, fname);
|
extract_file(dev, f, idr, fname);
|
||||||
if ((idr->flags[0] & ISO_MULTIEXTENT) == 0) {
|
if ((idr->flags[0] & ISO_MULTIEXTENT) == 0) {
|
||||||
#ifdef HAVE_FCHOWN
|
#ifdef HAVE_FCHOWN
|
||||||
fchown(f, fstat_buf.st_uid, fstat_buf.st_gid);
|
fchown(f, fstat_buf.st_uid, fstat_buf.st_gid);
|
||||||
|
@ -720,7 +734,8 @@ setmode:
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL void
|
LOCAL void
|
||||||
extract_file(f, idr, fname)
|
extract_file(dev, f, idr, fname)
|
||||||
|
struct scsi_dev *dev;
|
||||||
int f;
|
int f;
|
||||||
struct iso_directory_record *idr;
|
struct iso_directory_record *idr;
|
||||||
char *fname;
|
char *fname;
|
||||||
|
@ -737,7 +752,7 @@ extract_file(f, idr, fname)
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
tlen = (len > sizeof (buff) ? sizeof (buff) : len);
|
tlen = (len > sizeof (buff) ? sizeof (buff) : len);
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(extent - sector_offset, buff, ISO_BLOCKS(tlen));
|
readsecs(dev, extent - sector_offset, buff, ISO_BLOCKS(tlen));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
||||||
read(fileno(infile), buff, tlen);
|
read(fileno(infile), buff, tlen);
|
||||||
|
@ -751,7 +766,8 @@ extract_file(f, idr, fname)
|
||||||
|
|
||||||
|
|
||||||
LOCAL void
|
LOCAL void
|
||||||
parse_cl_dir(idr, extent)
|
parse_cl_dir(dev, idr, extent)
|
||||||
|
struct scsi_dev *dev;
|
||||||
struct iso_directory_record *idr;
|
struct iso_directory_record *idr;
|
||||||
int extent;
|
int extent;
|
||||||
{
|
{
|
||||||
|
@ -759,14 +775,14 @@ parse_cl_dir(idr, extent)
|
||||||
|
|
||||||
strlcpy(cl_name_buf, name_buf, sizeof (cl_name_buf));
|
strlcpy(cl_name_buf, name_buf, sizeof (cl_name_buf));
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(extent - sector_offset, idr, 1);
|
readsecs(dev, extent - sector_offset, idr, 1);
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
||||||
read(fileno(infile), idr, 2048);
|
read(fileno(infile), idr, 2048);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (parse_de(idr) && use_rock)
|
if (parse_de(idr) && use_rock)
|
||||||
dump_rr(idr);
|
dump_rr(dev, idr);
|
||||||
strlcpy(name_buf, cl_name_buf, sizeof (name_buf));
|
strlcpy(name_buf, cl_name_buf, sizeof (name_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,11 +903,14 @@ parse_de(idr)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL void
|
LOCAL void
|
||||||
parse_dir(dp, rootname, extent, len)
|
parse_dir(dev, dp, rootname, extent, len, callback, user_data)
|
||||||
|
struct scsi_dev *dev;
|
||||||
struct todo *dp;
|
struct todo *dp;
|
||||||
char *rootname;
|
char *rootname;
|
||||||
int extent; /* Directory extent */
|
int extent; /* Directory extent */
|
||||||
int len; /* Directory size */
|
int len; /* Directory size */
|
||||||
|
iso_listing_callback callback;
|
||||||
|
void *user_data;
|
||||||
{
|
{
|
||||||
struct todo *td;
|
struct todo *td;
|
||||||
int i;
|
int i;
|
||||||
|
@ -910,7 +929,7 @@ static int nlen = 0;
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
readsecs(dev, extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
||||||
read(fileno(infile), buffer, sizeof (buffer));
|
read(fileno(infile), buffer, sizeof (buffer));
|
||||||
|
@ -924,7 +943,7 @@ static int nlen = 0;
|
||||||
break;
|
break;
|
||||||
parse_de(idr);
|
parse_de(idr);
|
||||||
if (use_rock) {
|
if (use_rock) {
|
||||||
rr_flags = dump_rr(idr);
|
rr_flags = dump_rr(dev, idr);
|
||||||
|
|
||||||
if (rr_flags & RR_FLAG_CL) {
|
if (rr_flags & RR_FLAG_CL) {
|
||||||
/*
|
/*
|
||||||
|
@ -933,7 +952,7 @@ static int nlen = 0;
|
||||||
* so we get no usable file name.
|
* so we get no usable file name.
|
||||||
*/
|
*/
|
||||||
idr = (struct iso_directory_record *) cl_buffer;
|
idr = (struct iso_directory_record *) cl_buffer;
|
||||||
parse_cl_dir(idr, cl_extent);
|
parse_cl_dir(dev, idr, cl_extent);
|
||||||
} else if (rr_flags & RR_FLAG_RE)
|
} else if (rr_flags & RR_FLAG_RE)
|
||||||
goto cont; /* skip rr_moved */
|
goto cont; /* skip rr_moved */
|
||||||
}
|
}
|
||||||
|
@ -969,6 +988,8 @@ static int nlen = 0;
|
||||||
int nextent;
|
int nextent;
|
||||||
struct todo *tp = dp;
|
struct todo *tp = dp;
|
||||||
|
|
||||||
|
(*callback)(user_data, n, 1);
|
||||||
|
|
||||||
nextent = isonum_733((unsigned char *)idr->extent);
|
nextent = isonum_733((unsigned char *)idr->extent);
|
||||||
while (tp) {
|
while (tp) {
|
||||||
if (tp->extent == nextent) {
|
if (tp->extent == nextent) {
|
||||||
|
@ -996,9 +1017,13 @@ static int nlen = 0;
|
||||||
*todo_pp = td;
|
*todo_pp = td;
|
||||||
todo_pp = &td->next;
|
todo_pp = &td->next;
|
||||||
}
|
}
|
||||||
|
} else if ((idr->flags[0] & 2) &&
|
||||||
|
(idr->name[0] != 0 || idr->name[0] != 1)) {
|
||||||
|
/* this is . or .. */
|
||||||
} else {
|
} else {
|
||||||
|
callback(user_data, n, 0);
|
||||||
if (xtract && strcmp(xtract, n) == 0) {
|
if (xtract && strcmp(xtract, n) == 0) {
|
||||||
extract_file(STDOUT_FILENO, idr, "stdout");
|
extract_file(dev, STDOUT_FILENO, idr, "stdout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (do_f &&
|
if (do_f &&
|
||||||
|
@ -1035,7 +1060,7 @@ static int nlen = 0;
|
||||||
S_ISDIR(fstat_buf.st_mode)) {
|
S_ISDIR(fstat_buf.st_mode)) {
|
||||||
fstat_buf.st_mode |= S_IWUSR;
|
fstat_buf.st_mode |= S_IWUSR;
|
||||||
}
|
}
|
||||||
extract(rootname, idr, n);
|
extract(dev, rootname, idr, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1043,7 +1068,7 @@ static int nlen = 0;
|
||||||
/*
|
/*
|
||||||
* Extract all multi extent files here...
|
* Extract all multi extent files here...
|
||||||
*/
|
*/
|
||||||
extract(rootname, idr, n);
|
extract(dev, rootname, idr, n);
|
||||||
}
|
}
|
||||||
size += fstat_buf.st_size;
|
size += fstat_buf.st_size;
|
||||||
if ((flags & ISO_MULTIEXTENT) &&
|
if ((flags & ISO_MULTIEXTENT) &&
|
||||||
|
@ -1073,14 +1098,66 @@ static int nlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int
|
EXPORT int
|
||||||
main(argc, argv)
|
scan_iso (filename, callback, user_data)
|
||||||
int argc;
|
const char* filename;
|
||||||
char *argv[];
|
iso_listing_callback callback;
|
||||||
|
void* user_data;
|
||||||
|
{
|
||||||
|
struct scsi_dev *dev;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (NULL == filename || NULL == callback)
|
||||||
|
return ScanRetCode_BadInput;
|
||||||
|
|
||||||
|
dev = scsidev_file_open(filename);
|
||||||
|
retval = run_scanning(dev, callback, user_data);
|
||||||
|
scsidev_close(dev);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT int
|
||||||
|
scan_device (sdevname, callback, user_data)
|
||||||
|
const char* sdevname;
|
||||||
|
iso_listing_callback callback;
|
||||||
|
void* user_data;
|
||||||
|
{
|
||||||
|
#ifndef USE_SCG
|
||||||
|
return ScanRetCode_Disabled;
|
||||||
|
#else
|
||||||
|
struct scsi_dev *dev;
|
||||||
|
int retval;
|
||||||
|
char* devname;
|
||||||
|
|
||||||
|
if (NULL == callback)
|
||||||
|
return ScanRetCode_BadInput;
|
||||||
|
|
||||||
|
if (sdevname == NULL)
|
||||||
|
cdr_defaults(&devname, NULL, NULL, NULL, NULL);
|
||||||
|
if (devname == NULL)
|
||||||
|
return ScanRetCode_BadInput;
|
||||||
|
|
||||||
|
dev = scsidev_open(devname);
|
||||||
|
if (scsidev_has_error(dev)) {
|
||||||
|
retval = scsidev_error_code(dev);
|
||||||
|
scsidev_close(dev);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = run_scanning(dev, callback, user_data);
|
||||||
|
scsidev_close(dev);
|
||||||
|
return retval;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LOCAL int
|
||||||
|
run_scanning(dev, callback, user_data)
|
||||||
|
struct scsi_dev *dev;
|
||||||
|
iso_listing_callback callback;
|
||||||
|
void *user_data;
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *filename = NULL;
|
|
||||||
char *sdevname = NULL;
|
|
||||||
#if defined(USE_NLS)
|
#if defined(USE_NLS)
|
||||||
char *dir;
|
char *dir;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1120,63 +1197,7 @@ main(argc, argv)
|
||||||
|
|
||||||
myuid = getuid();
|
myuid = getuid();
|
||||||
|
|
||||||
#if defined(USE_NLS) && defined(HAVE_NL_LANGINFO) && defined(CODESET)
|
charset = default_charset();
|
||||||
/*
|
|
||||||
* If the locale has not been set up, nl_langinfo() returns the
|
|
||||||
* name of the default codeset. This should be either "646",
|
|
||||||
* "ISO-646", "ASCII", or something similar. Unfortunately, the
|
|
||||||
* POSIX standard does not include a list of valid locale names,
|
|
||||||
* so ne need to find all values in use.
|
|
||||||
*
|
|
||||||
* Observed:
|
|
||||||
* Solaris "646"
|
|
||||||
* Linux "ANSI_X3.4-1968" strange value from Linux...
|
|
||||||
*/
|
|
||||||
if (charset == NULL) {
|
|
||||||
char *codeset = nl_langinfo(CODESET);
|
|
||||||
Uchar *p;
|
|
||||||
|
|
||||||
if (codeset != NULL)
|
|
||||||
codeset = strdup(codeset);
|
|
||||||
if (codeset == NULL) /* Should not happen */
|
|
||||||
goto setcharset;
|
|
||||||
if (*codeset == '\0') /* Invalid locale */
|
|
||||||
goto setcharset;
|
|
||||||
|
|
||||||
for (p = (Uchar *)codeset; *p != '\0'; p++) {
|
|
||||||
if (islower(*p))
|
|
||||||
*p = toupper(*p);
|
|
||||||
}
|
|
||||||
p = (Uchar *)strstr(codeset, "ISO");
|
|
||||||
if (p != NULL) {
|
|
||||||
if (*p == '_' || *p == '-')
|
|
||||||
p++;
|
|
||||||
codeset = (char *)p;
|
|
||||||
}
|
|
||||||
if (strcmp("646", codeset) != 0 &&
|
|
||||||
strcmp("ASCII", codeset) != 0 &&
|
|
||||||
strcmp("US-ASCII", codeset) != 0 &&
|
|
||||||
strcmp("US_ASCII", codeset) != 0 &&
|
|
||||||
strcmp("USASCII", codeset) != 0 &&
|
|
||||||
strcmp("ANSI_X3.4-1968", codeset) != 0)
|
|
||||||
charset = nl_langinfo(CODESET);
|
|
||||||
|
|
||||||
if (codeset != NULL)
|
|
||||||
free(codeset);
|
|
||||||
|
|
||||||
#define verbose 1
|
|
||||||
if (verbose > 0 && charset != NULL) {
|
|
||||||
error(_("Setting input-charset to '%s' from locale.\n"),
|
|
||||||
charset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setcharset:
|
|
||||||
/*
|
|
||||||
* Allow to switch off locale with -input-charset "".
|
|
||||||
*/
|
|
||||||
if (charset != NULL && *charset == '\0')
|
|
||||||
charset = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (charset == NULL) {
|
if (charset == NULL) {
|
||||||
#if (defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__DJGPP__) || defined(__MINGW32__)) && !defined(IS_CYGWIN_1)
|
#if (defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__DJGPP__) || defined(__MINGW32__)) && !defined(IS_CYGWIN_1)
|
||||||
|
@ -1197,38 +1218,11 @@ setcharset:
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename != NULL && sdevname != NULL) {
|
|
||||||
errmsgno(EX_BAD, _("Only one of -i or dev= allowed\n"));
|
|
||||||
}
|
|
||||||
#ifdef USE_SCG
|
|
||||||
if (filename == NULL && sdevname == NULL)
|
|
||||||
cdr_defaults(&sdevname, NULL, NULL, NULL, NULL);
|
|
||||||
#endif
|
|
||||||
if (filename == NULL && sdevname == NULL) {
|
|
||||||
fprintf(stderr, _("ISO-9660 image not specified\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filename != NULL)
|
|
||||||
infile = fopen(filename, "rb");
|
|
||||||
else
|
|
||||||
filename = sdevname;
|
|
||||||
|
|
||||||
if (infile != NULL) {
|
|
||||||
/* EMPTY */;
|
|
||||||
#ifdef USE_SCG
|
|
||||||
} else if (scsidev_open(filename) < 0) {
|
|
||||||
#else
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
fprintf(stderr, _("Unable to open %s\n"), filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Absolute sector offset, so don't subtract sector_offset here.
|
* Absolute sector offset, so don't subtract sector_offset here.
|
||||||
*/
|
*/
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(16 + toc_offset, &ipd, ISO_BLOCKS(sizeof (ipd)));
|
readsecs(dev, 16 + toc_offset, &ipd, ISO_BLOCKS(sizeof (ipd)));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(16 + toc_offset)) <<11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(16 + toc_offset)) <<11, SEEK_SET);
|
||||||
read(fileno(infile), &ipd, sizeof (ipd));
|
read(fileno(infile), &ipd, sizeof (ipd));
|
||||||
|
@ -1240,7 +1234,7 @@ setcharset:
|
||||||
c = 17;
|
c = 17;
|
||||||
do {
|
do {
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
readsecs(dev, c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(c + toc_offset)) <<11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(c + toc_offset)) <<11, SEEK_SET);
|
||||||
read(fileno(infile), &jpd, sizeof (jpd));
|
read(fileno(infile), &jpd, sizeof (jpd));
|
||||||
|
@ -1248,7 +1242,7 @@ setcharset:
|
||||||
} while (++c < 32 && GET_UBYTE(jpd.type) != ISO_VD_END);
|
} while (++c < 32 && GET_UBYTE(jpd.type) != ISO_VD_END);
|
||||||
if (GET_UBYTE(jpd.type) == ISO_VD_END) do {
|
if (GET_UBYTE(jpd.type) == ISO_VD_END) do {
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
readsecs(dev, c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(c + toc_offset)) <<11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(c + toc_offset)) <<11, SEEK_SET);
|
||||||
read(fileno(infile), &jpd, sizeof (jpd));
|
read(fileno(infile), &jpd, sizeof (jpd));
|
||||||
|
@ -1274,12 +1268,12 @@ setcharset:
|
||||||
*/
|
*/
|
||||||
extent = isonum_733((unsigned char *)idr->extent);
|
extent = isonum_733((unsigned char *)idr->extent);
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
readsecs(dev, extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) <<11, SEEK_SET);
|
lseek(fileno(infile), ((off_t)(extent - sector_offset)) <<11, SEEK_SET);
|
||||||
read(fileno(infile), buffer, sizeof (buffer));
|
read(fileno(infile), buffer, sizeof (buffer));
|
||||||
#endif
|
#endif
|
||||||
c = dump_rr((struct iso_directory_record *) buffer);
|
c = dump_rr(dev, (struct iso_directory_record *) buffer);
|
||||||
if (c == 0 ||
|
if (c == 0 ||
|
||||||
(c & (RR_FLAG_SP | RR_FLAG_ER)) == 0 || su_version < 1 || rr_version < 1) {
|
(c & (RR_FLAG_SP | RR_FLAG_ER)) == 0 || su_version < 1 || rr_version < 1) {
|
||||||
if (!debug)
|
if (!debug)
|
||||||
|
@ -1324,7 +1318,7 @@ setcharset:
|
||||||
|
|
||||||
block++;
|
block++;
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
readsecs(block + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
readsecs(dev, block + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||||
#else
|
#else
|
||||||
lseek(fileno(infile),
|
lseek(fileno(infile),
|
||||||
((off_t)(block + toc_offset)) <<11, SEEK_SET);
|
((off_t)(block + toc_offset)) <<11, SEEK_SET);
|
||||||
|
@ -1363,17 +1357,15 @@ setcharset:
|
||||||
if (use_joliet)
|
if (use_joliet)
|
||||||
idr = (struct iso_directory_record *)jpd.root_directory_record;
|
idr = (struct iso_directory_record *)jpd.root_directory_record;
|
||||||
|
|
||||||
parse_dir(todo_idr, "/", isonum_733((unsigned char *)idr->extent),
|
parse_dir(dev, todo_idr, "/", isonum_733((unsigned char *)idr->extent),
|
||||||
isonum_733((unsigned char *)idr->size));
|
isonum_733((unsigned char *)idr->size), callback, user_data);
|
||||||
td = todo_idr;
|
td = todo_idr;
|
||||||
while (td) {
|
while (td) {
|
||||||
parse_dir(td, td->name, td->extent, td->length);
|
parse_dir(dev, td, td->name, td->extent, td->length, callback, user_data);
|
||||||
free(td->name);
|
free(td->name);
|
||||||
td = td->next;
|
td = td->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infile != NULL)
|
|
||||||
fclose(infile);
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1468,3 +1460,68 @@ iso9660_time(date, hsecp, longfmt)
|
||||||
t -= gmtoff * 15 * 60;
|
t -= gmtoff * 15 * 60;
|
||||||
return (t);
|
return (t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOCAL char*
|
||||||
|
default_charset(void)
|
||||||
|
{
|
||||||
|
char *charset = NULL;
|
||||||
|
|
||||||
|
#if defined(USE_NLS) && defined(HAVE_NL_LANGINFO) && defined(CODESET)
|
||||||
|
/*
|
||||||
|
* If the locale has not been set up, nl_langinfo() returns the
|
||||||
|
* name of the default codeset. This should be either "646",
|
||||||
|
* "ISO-646", "ASCII", or something similar. Unfortunately, the
|
||||||
|
* POSIX standard does not include a list of valid locale names,
|
||||||
|
* so ne need to find all values in use.
|
||||||
|
*
|
||||||
|
* Observed:
|
||||||
|
* Solaris "646"
|
||||||
|
* Linux "ANSI_X3.4-1968" strange value from Linux...
|
||||||
|
*/
|
||||||
|
if (charset == NULL) {
|
||||||
|
char *codeset = nl_langinfo(CODESET);
|
||||||
|
Uchar *p;
|
||||||
|
|
||||||
|
if (codeset != NULL)
|
||||||
|
codeset = strdup(codeset);
|
||||||
|
if (codeset == NULL) /* Should not happen */
|
||||||
|
goto setcharset;
|
||||||
|
if (*codeset == '\0') /* Invalid locale */
|
||||||
|
goto setcharset;
|
||||||
|
|
||||||
|
for (p = (Uchar *)codeset; *p != '\0'; p++) {
|
||||||
|
if (islower(*p))
|
||||||
|
*p = toupper(*p);
|
||||||
|
}
|
||||||
|
p = (Uchar *)strstr(codeset, "ISO");
|
||||||
|
if (p != NULL) {
|
||||||
|
if (*p == '_' || *p == '-')
|
||||||
|
p++;
|
||||||
|
codeset = (char *)p;
|
||||||
|
}
|
||||||
|
if (strcmp("646", codeset) != 0 &&
|
||||||
|
strcmp("ASCII", codeset) != 0 &&
|
||||||
|
strcmp("US-ASCII", codeset) != 0 &&
|
||||||
|
strcmp("US_ASCII", codeset) != 0 &&
|
||||||
|
strcmp("USASCII", codeset) != 0 &&
|
||||||
|
strcmp("ANSI_X3.4-1968", codeset) != 0)
|
||||||
|
charset = nl_langinfo(CODESET);
|
||||||
|
|
||||||
|
if (codeset != NULL)
|
||||||
|
free(codeset);
|
||||||
|
|
||||||
|
#define verbose 1
|
||||||
|
if (verbose > 0 && charset != NULL) {
|
||||||
|
error(_("Setting input-charset to '%s' from locale.\n"),
|
||||||
|
charset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setcharset:
|
||||||
|
/*
|
||||||
|
* Allow to switch off locale with -input-charset "".
|
||||||
|
*/
|
||||||
|
if (charset != NULL && *charset == '\0')
|
||||||
|
charset = NULL;
|
||||||
|
#endif
|
||||||
|
return charset;
|
||||||
|
}
|
||||||
|
|
63
subprojects/isoinfo/src/scgcmd/libscgcmd.h
Normal file
63
subprojects/isoinfo/src/scgcmd/libscgcmd.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/* @(#)libscgcmd.h 1.1 08/10/26 Copyright 1986-2008 J. Schilling */
|
||||||
|
|
||||||
|
#ifndef _LIBSCGCMD_H
|
||||||
|
#define _LIBSCGCMD_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* buffer.c
|
||||||
|
*/
|
||||||
|
extern int read_buffer __PR((SCSI *scgp, caddr_t bp, int cnt, int mode));
|
||||||
|
extern int write_buffer __PR((SCSI *scgp, char *buffer, long length, int mode, int bufferid, long offset));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* inquiry.c
|
||||||
|
*/
|
||||||
|
extern int inquiry __PR((SCSI *scgp, caddr_t, int));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* modes.c
|
||||||
|
*/
|
||||||
|
extern BOOL get_mode_params __PR((SCSI *scgp, int page, char *pagename,
|
||||||
|
Uchar *modep, Uchar *cmodep,
|
||||||
|
Uchar *dmodep, Uchar *smodep,
|
||||||
|
int *lenp));
|
||||||
|
extern BOOL set_mode_params __PR((SCSI *scgp, char *pagename, Uchar *modep,
|
||||||
|
int len, int save, int secsize));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* modesense.c
|
||||||
|
*/
|
||||||
|
extern BOOL __is_atapi __PR((void));
|
||||||
|
extern BOOL allow_atapi __PR((SCSI *scgp, BOOL new));
|
||||||
|
extern int mode_select __PR((SCSI *scgp, Uchar *, int, int, int));
|
||||||
|
extern int mode_sense __PR((SCSI *scgp, Uchar *dp, int cnt, int page, int pcf));
|
||||||
|
extern int mode_select_sg0 __PR((SCSI *scgp, Uchar *, int, int, int));
|
||||||
|
extern int mode_sense_sg0 __PR((SCSI *scgp, Uchar *dp, int cnt, int page, int pcf));
|
||||||
|
extern int mode_select_g0 __PR((SCSI *scgp, Uchar *, int, int, int));
|
||||||
|
extern int mode_select_g1 __PR((SCSI *scgp, Uchar *, int, int, int));
|
||||||
|
extern int mode_sense_g0 __PR((SCSI *scgp, Uchar *dp, int cnt, int page, int pcf));
|
||||||
|
extern int mode_sense_g1 __PR((SCSI *scgp, Uchar *dp, int cnt, int page, int pcf));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read.c
|
||||||
|
*/
|
||||||
|
extern int read_scsi __PR((SCSI *scgp, caddr_t, long, int));
|
||||||
|
extern int read_g0 __PR((SCSI *scgp, caddr_t, long, int));
|
||||||
|
extern int read_g1 __PR((SCSI *scgp, caddr_t, long, int));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* readcap.c
|
||||||
|
*/
|
||||||
|
extern int read_capacity __PR((SCSI *scgp));
|
||||||
|
#ifdef EOF /* stdio.h has been included */
|
||||||
|
extern void print_capacity __PR((SCSI *scgp, FILE *f));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ready.c
|
||||||
|
*/
|
||||||
|
extern BOOL unit_ready __PR((SCSI *scgp));
|
||||||
|
extern BOOL wait_unit_ready __PR((SCSI *scgp, int secs));
|
||||||
|
extern int test_unit_ready __PR((SCSI *scgp));
|
||||||
|
|
||||||
|
#endif /* _LIBSCGCMD_H */
|
|
@ -29,13 +29,18 @@ static UConst char sccsid[] =
|
||||||
#include <schily/stdlib.h>
|
#include <schily/stdlib.h>
|
||||||
#include <schily/unistd.h>
|
#include <schily/unistd.h>
|
||||||
#include <schily/schily.h>
|
#include <schily/schily.h>
|
||||||
|
#include <schily/nlsdefs.h>
|
||||||
|
#include <schily/string.h>
|
||||||
|
|
||||||
|
//#include "mkisofs.h"
|
||||||
|
#define SECTOR_SIZE (2048)
|
||||||
|
BOOL ignerr;
|
||||||
|
|
||||||
#include "mkisofs.h"
|
|
||||||
#include <scg/scsireg.h>
|
#include <scg/scsireg.h>
|
||||||
#include <scg/scsitransp.h>
|
#include <scg/scsitransp.h>
|
||||||
|
|
||||||
#include "libscgcmd.h"
|
#include "scgcmd/libscgcmd.h"
|
||||||
#include "cdrdeflt.h"
|
#include "cdrdeflt/cdrdeflt.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTICE: You should not make BUF_SIZE more than
|
* NOTICE: You should not make BUF_SIZE more than
|
||||||
|
@ -48,15 +53,36 @@ static UConst char sccsid[] =
|
||||||
*/
|
*/
|
||||||
#define BUF_SIZE (62*1024) /* Must be a multiple of 2048 */
|
#define BUF_SIZE (62*1024) /* Must be a multiple of 2048 */
|
||||||
|
|
||||||
LOCAL SCSI *scgp;
|
enum ScsiOpenErr {
|
||||||
|
ScsiOpenErr_Ok = 0,
|
||||||
|
ScsiOpenErr_CantOpen, /*Cannot open SCSI driver*/
|
||||||
|
ScsiOpenErr_CantIO, /*Cannot get SCSI I/O buffer*/
|
||||||
|
ScsiOpenErr_Timeout,
|
||||||
|
ScsiOpenErr_Invalid
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scsi_dev {
|
||||||
|
FILE *file;
|
||||||
|
SCSI *scgp;
|
||||||
|
int err;
|
||||||
|
};
|
||||||
|
|
||||||
LOCAL long bufsize; /* The size of the transfer buffer */
|
LOCAL long bufsize; /* The size of the transfer buffer */
|
||||||
|
|
||||||
EXPORT int readsecs __PR((UInt32_t startsecno, void *buffer, int sectorcount));
|
EXPORT int readsecs __PR((struct scsi_dev* src, UInt32_t startsecno, void *buffer, int sectorcount));
|
||||||
EXPORT int scsidev_open __PR((char *path));
|
EXPORT BOOL scsidev_has_error __PR((struct scsi_dev *dev));
|
||||||
EXPORT int scsidev_close __PR((void));
|
EXPORT int scsidev_error_code __PR((struct scsi_dev *dev));
|
||||||
|
EXPORT const char* scsidev_error_desc __PR((int code));
|
||||||
|
|
||||||
|
#ifdef USE_SCG
|
||||||
|
EXPORT struct scsi_dev* scsidev_open __PR((char *path));
|
||||||
|
EXPORT int scsidev_close __PR((struct scsi_dev *f));
|
||||||
|
#endif
|
||||||
|
EXPORT struct scsi_dev* scsidev_file_open __PR((const char *path));
|
||||||
|
|
||||||
EXPORT int
|
EXPORT int
|
||||||
readsecs(startsecno, buffer, sectorcount)
|
readsecs(src, startsecno, buffer, sectorcount)
|
||||||
|
struct scsi_dev *src;
|
||||||
UInt32_t startsecno;
|
UInt32_t startsecno;
|
||||||
void *buffer;
|
void *buffer;
|
||||||
int sectorcount;
|
int sectorcount;
|
||||||
|
@ -69,7 +95,7 @@ readsecs(startsecno, buffer, sectorcount)
|
||||||
char *bp;
|
char *bp;
|
||||||
long amt;
|
long amt;
|
||||||
|
|
||||||
if (in_image == NULL) {
|
if (src->file == NULL) {
|
||||||
/*
|
/*
|
||||||
* We are using the standard CD-ROM sectorsize of 2048 bytes
|
* We are using the standard CD-ROM sectorsize of 2048 bytes
|
||||||
* while the drive may be switched to 512 bytes per sector.
|
* while the drive may be switched to 512 bytes per sector.
|
||||||
|
@ -77,7 +103,7 @@ readsecs(startsecno, buffer, sectorcount)
|
||||||
* XXX We assume that secsize is no more than SECTOR_SIZE
|
* XXX We assume that secsize is no more than SECTOR_SIZE
|
||||||
* XXX and that SECTOR_SIZE / secsize is not a fraction.
|
* XXX and that SECTOR_SIZE / secsize is not a fraction.
|
||||||
*/
|
*/
|
||||||
secsize = scgp->cap->c_bsize;
|
secsize = src->scgp->cap->c_bsize;
|
||||||
amount = sectorcount * SECTOR_SIZE;
|
amount = sectorcount * SECTOR_SIZE;
|
||||||
secno = startsecno * (SECTOR_SIZE / secsize);
|
secno = startsecno * (SECTOR_SIZE / secsize);
|
||||||
bp = buffer;
|
bp = buffer;
|
||||||
|
@ -88,8 +114,8 @@ readsecs(startsecno, buffer, sectorcount)
|
||||||
amt = bufsize;
|
amt = bufsize;
|
||||||
secnum = amt / secsize;
|
secnum = amt / secsize;
|
||||||
|
|
||||||
if (read_scsi(scgp, bp, secno, secnum) < 0 ||
|
if (read_scsi(src->scgp, bp, secno, secnum) < 0 ||
|
||||||
scg_getresid(scgp) != 0) {
|
scg_getresid(src->scgp) != 0) {
|
||||||
#ifdef OLD
|
#ifdef OLD
|
||||||
return (-1);
|
return (-1);
|
||||||
#else
|
#else
|
||||||
|
@ -104,7 +130,7 @@ readsecs(startsecno, buffer, sectorcount)
|
||||||
return (SECTOR_SIZE * sectorcount);
|
return (SECTOR_SIZE * sectorcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
f = fileno(in_image);
|
f = fileno(src->file);
|
||||||
|
|
||||||
if (lseek(f, (off_t)startsecno * SECTOR_SIZE, SEEK_SET) == (off_t)-1) {
|
if (lseek(f, (off_t)startsecno * SECTOR_SIZE, SEEK_SET) == (off_t)-1) {
|
||||||
comerr(_("Seek error on old image\n"));
|
comerr(_("Seek error on old image\n"));
|
||||||
|
@ -125,13 +151,61 @@ readsecs(startsecno, buffer, sectorcount)
|
||||||
return (sectorcount * SECTOR_SIZE);
|
return (sectorcount * SECTOR_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int
|
EXPORT BOOL scsidev_has_error (src)
|
||||||
|
struct scsi_dev *src;
|
||||||
|
{
|
||||||
|
if (NULL == src || ScsiOpenErr_Ok != src->err)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT int scsidev_error_code (src)
|
||||||
|
struct scsi_dev *src;
|
||||||
|
{
|
||||||
|
if (NULL == src)
|
||||||
|
return ScsiOpenErr_Invalid;
|
||||||
|
else
|
||||||
|
return src->err;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT const char* scsidev_error_desc (code)
|
||||||
|
int code;
|
||||||
|
{
|
||||||
|
switch (code) {
|
||||||
|
case ScsiOpenErr_Timeout:
|
||||||
|
return "Timeout waiting for device";
|
||||||
|
case ScsiOpenErr_CantIO:
|
||||||
|
return "Cannot get SCSI I/O buffer";
|
||||||
|
case ScsiOpenErr_CantOpen:
|
||||||
|
return "Cannot open SCSI driver";
|
||||||
|
case ScsiOpenErr_Invalid:
|
||||||
|
return "Invalid device handle";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT struct scsi_dev*
|
||||||
|
scsidev_file_open (path)
|
||||||
|
const char* path;
|
||||||
|
{
|
||||||
|
struct scsi_dev *retval;
|
||||||
|
|
||||||
|
retval = (struct scsi_dev*)malloc(sizeof(*retval));
|
||||||
|
memset(retval, 0, sizeof(*retval));
|
||||||
|
retval->file = fopen(path, "rb");
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT struct scsi_dev*
|
||||||
scsidev_open(path)
|
scsidev_open(path)
|
||||||
char *path;
|
char *path;
|
||||||
{
|
{
|
||||||
char errstr[80];
|
char errstr[80];
|
||||||
char *buf; /* ignored, bit OS/2 ASPI layer needs memory which */
|
char *buf; /* ignored, bit OS/2 ASPI layer needs memory which */
|
||||||
/* has been allocated by scsi_getbuf() */
|
/* has been allocated by scsi_getbuf() */
|
||||||
|
struct scsi_dev *retval;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call scg_remote() to force loading the remote SCSI transport library
|
* Call scg_remote() to force loading the remote SCSI transport library
|
||||||
|
@ -142,42 +216,56 @@ scsidev_open(path)
|
||||||
|
|
||||||
cdr_defaults(&path, NULL, NULL, NULL, NULL);
|
cdr_defaults(&path, NULL, NULL, NULL, NULL);
|
||||||
/* path, debug, verboseopen */
|
/* path, debug, verboseopen */
|
||||||
scgp = scg_open(path, errstr, sizeof (errstr), 0, 0);
|
retval = (struct scsi_dev*)malloc(sizeof(*retval));
|
||||||
if (scgp == 0) {
|
memset(retval, 0, sizeof(*retval));
|
||||||
errmsg(_("%s%sCannot open SCSI driver.\n"), errstr, errstr[0]?". ":"");
|
|
||||||
return (-1);
|
retval->scgp = scg_open(path, errstr, sizeof (errstr), 0, 0);
|
||||||
|
if (retval->scgp == 0) {
|
||||||
|
retval->err = ScsiOpenErr_CantOpen;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufsize = scg_bufsize(scgp, BUF_SIZE);
|
bufsize = scg_bufsize(retval->scgp, BUF_SIZE);
|
||||||
if ((buf = scg_getbuf(scgp, bufsize)) == NULL) {
|
if ((buf = scg_getbuf(retval->scgp, bufsize)) == NULL) {
|
||||||
errmsg(_("Cannot get SCSI I/O buffer.\n"));
|
retval->err = ScsiOpenErr_CantIO;
|
||||||
scg_close(scgp);
|
scg_close(retval->scgp);
|
||||||
return (-1);
|
retval->scgp = NULL;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufsize = (bufsize / SECTOR_SIZE) * SECTOR_SIZE;
|
bufsize = (bufsize / SECTOR_SIZE) * SECTOR_SIZE;
|
||||||
|
|
||||||
allow_atapi(scgp, TRUE);
|
allow_atapi(retval->scgp, TRUE);
|
||||||
|
|
||||||
if (!wait_unit_ready(scgp, 60)) { /* Eat Unit att / Wait for drive */
|
if (!wait_unit_ready(retval->scgp, 60)) { /* Eat Unit att / Wait for drive */
|
||||||
return (-1);
|
retval->err = ScsiOpenErr_Timeout;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
scgp->silent++;
|
retval->scgp->silent++;
|
||||||
read_capacity(scgp); /* Set Capacity/Sectorsize for I/O */
|
read_capacity(retval->scgp); /* Set Capacity/Sectorsize for I/O */
|
||||||
scgp->silent--;
|
retval->scgp->silent--;
|
||||||
|
|
||||||
return (1);
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT int
|
EXPORT int
|
||||||
scsidev_close()
|
scsidev_close(struct scsi_dev *f)
|
||||||
{
|
{
|
||||||
if (in_image == NULL) {
|
int retval;
|
||||||
return (scg_close(scgp));
|
|
||||||
} else {
|
if (NULL == f)
|
||||||
return (fclose(in_image));
|
return 0;
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
if (f->scgp != NULL) {
|
||||||
|
retval = scg_close(f->scgp);
|
||||||
}
|
}
|
||||||
|
if (f->file != NULL) {
|
||||||
|
retval = fclose(f->file);
|
||||||
|
}
|
||||||
|
free(f);
|
||||||
|
return (retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_SCG */
|
#endif /* USE_SCG */
|
||||||
|
|
|
@ -10,11 +10,17 @@
|
||||||
/*
|
/*
|
||||||
* Implemented inside multi.c in case that USE_SCG has not been defined.
|
* Implemented inside multi.c in case that USE_SCG has not been defined.
|
||||||
*/
|
*/
|
||||||
extern int readsecs __PR((UInt32_t startsecno, void *buffer, int sectorcount));
|
struct scsi_dev;
|
||||||
|
|
||||||
|
extern int readsecs __PR((struct scsi_dev* src, UInt32_t startsecno, void *buffer, int sectorcount));
|
||||||
|
extern BOOL scsidev_has_error __PR((struct scsi_dev *dev));
|
||||||
|
extern int scsidev_error_code __PR((struct scsi_dev *dev));
|
||||||
|
extern const char* scsidev_error_desc __PR((int code));
|
||||||
|
|
||||||
#ifdef USE_SCG
|
#ifdef USE_SCG
|
||||||
extern int scsidev_open __PR((char *path));
|
extern struct scsi_dev* scsidev_open __PR((char *path));
|
||||||
extern int scsidev_close __PR((void));
|
extern struct scsi_dev* scsidev_file_open __PR((const char *path));
|
||||||
|
extern int scsidev_close __PR((struct scsi_dev *f));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _SCSI_H */
|
#endif /* _SCSI_H */
|
||||||
|
|
Loading…
Add table
Reference in a new issue