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.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) {
|
||||
struct iso_volume_descriptor {
|
||||
char[ISODCL(1, 1)] type; /* 711 */
|
||||
char[ISODCL(2, 6)] id;
|
||||
char[ISODCL(7, 7)] version_;
|
||||
char[ISODCL(8, 2048)] data;
|
||||
}
|
||||
alias iso_listing_callback = int function(void*,const(char)*,int);
|
||||
int scan_iso (const(char)* filename, iso_listing_callback callback, void* user_data);
|
||||
|
||||
struct iso_directory_record {
|
||||
byte [ISODCL(1, 1)] length; /* 711 */
|
||||
char [ISODCL(2, 2)] ext_attr_length; /* 711 */
|
||||
char [ISODCL(3, 10)] extent; /* 733 */
|
||||
char [ISODCL(11, 18)] size; /* 733 */
|
||||
char [ISODCL(19, 25)] date; /* 7 by 711 */
|
||||
byte [ISODCL(26, 26)] flags;
|
||||
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;
|
||||
} */
|
||||
private int printer(void*, const(char)* path, int is_dir) {
|
||||
writef("Entry \"%s\"", path.fromStringz);
|
||||
if (is_dir != 0) {
|
||||
write(" (directory)");
|
||||
}
|
||||
write("\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,6 +27,8 @@ public string iso_to_serial (string path) {
|
|||
// NPJH-50465|0D506D389F2AA444|0001|G
|
||||
// ULJM-05530|5A2E0CF722EF6299|0001|G
|
||||
|
||||
scan_iso(path.toStringz, &printer, null);
|
||||
|
||||
return "UCES-00356"; //Tekken Dark Resurrection
|
||||
//return "NPJH-50465"; //Hatsune Miku (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')
|
||||
|
||||
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')
|
||||
|
||||
libisoinfo = static_library(meson.project_name(),
|
||||
'src/isoinfo.c',
|
||||
'src/scsi.c',
|
||||
dependencies: [cdrdeflt_dep],
|
||||
dependencies: [cdrdeflt_dep, scgcmd_dep, schily_dep, scg_dep, siconv_dep],
|
||||
install: false,
|
||||
)
|
||||
|
||||
|
|
|
@ -119,8 +119,14 @@
|
|||
|
||||
#define GET_UBYTE(a) a_to_u_byte(a)
|
||||
|
||||
#define infile in_image
|
||||
EXPORT FILE *infile = NULL;
|
||||
typedef int(*iso_listing_callback)(void*,const char*,int is_dir);
|
||||
|
||||
enum ScanRetCode {
|
||||
ScanRetCode_Ok = 100,
|
||||
ScanRetCode_Disabled,
|
||||
ScanRetCode_BadInput
|
||||
};
|
||||
|
||||
EXPORT BOOL ignerr = FALSE;
|
||||
LOCAL int use_rock = 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_733 __PR((unsigned char * p));
|
||||
LOCAL int parse_rr __PR((unsigned char * pnt, int len,
|
||||
int cont_flag));
|
||||
LOCAL int parse_rr __PR((struct scsi_dev *dev, unsigned char * pnt,
|
||||
int len, int cont_flag));
|
||||
LOCAL void find_rr __PR((struct iso_directory_record * idr,
|
||||
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,
|
||||
struct iso_directory_record * idr,
|
||||
char *fname,
|
||||
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,
|
||||
char *fname));
|
||||
LOCAL void extract_file __PR((int f,
|
||||
struct iso_directory_record * idr,
|
||||
char *fname));
|
||||
LOCAL void parse_cl_dir __PR((struct iso_directory_record *idr,
|
||||
int extent));
|
||||
LOCAL void parse_cl_dir __PR((struct scsi_dev *dev,
|
||||
struct iso_directory_record *idr, int extent));
|
||||
LOCAL BOOL parse_de __PR((struct iso_directory_record *idr));
|
||||
LOCAL void parse_dir __PR((struct todo *dp,
|
||||
char * rootname, int extent, int len));
|
||||
LOCAL void parse_dir __PR((struct scsi_dev *dev, struct todo *dp,
|
||||
char * rootname, int extent, int len,
|
||||
iso_listing_callback callback, void* user_data));
|
||||
LOCAL void list_locales __PR((void));
|
||||
LOCAL int time_cvt __PR((unsigned char *dp, int len));
|
||||
LOCAL time_t iso9660_time __PR((unsigned char *date, int *hsecp,
|
||||
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
|
||||
isonum_731(p)
|
||||
|
@ -225,7 +236,8 @@ isonum_733(p)
|
|||
#endif
|
||||
|
||||
LOCAL int
|
||||
parse_rr(pnt, len, cont_flag)
|
||||
parse_rr(dev, pnt, len, cont_flag)
|
||||
struct scsi_dev *dev;
|
||||
unsigned char *pnt;
|
||||
int len;
|
||||
int cont_flag;
|
||||
|
@ -409,12 +421,12 @@ parse_rr(pnt, len, cont_flag)
|
|||
unsigned char sector[2048];
|
||||
|
||||
#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
|
||||
lseek(fileno(infile), ((off_t)(cont_extent - sector_offset)) << 11, SEEK_SET);
|
||||
read(fileno(infile), sector, sizeof (sector));
|
||||
#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 '/'
|
||||
|
@ -461,14 +473,15 @@ find_rr(idr, pntp, lenp)
|
|||
}
|
||||
|
||||
LOCAL int
|
||||
dump_rr(idr)
|
||||
dump_rr(dev, idr)
|
||||
struct scsi_dev *dev;
|
||||
struct iso_directory_record *idr;
|
||||
{
|
||||
int len;
|
||||
unsigned char * pnt;
|
||||
|
||||
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",
|
||||
|
@ -572,7 +585,8 @@ dump_stat(rootname, idr, fname, extent)
|
|||
}
|
||||
|
||||
LOCAL void
|
||||
extract(rootname, idr, fname)
|
||||
extract(dev, rootname, idr, fname)
|
||||
struct scsi_dev *dev;
|
||||
char *rootname;
|
||||
struct iso_directory_record *idr;
|
||||
char *fname;
|
||||
|
@ -682,7 +696,7 @@ static BOOL isfirst = TRUE;
|
|||
return;
|
||||
}
|
||||
lseek(f, 0, SEEK_END);
|
||||
extract_file(f, idr, fname);
|
||||
extract_file(dev, f, idr, fname);
|
||||
if ((idr->flags[0] & ISO_MULTIEXTENT) == 0) {
|
||||
#ifdef HAVE_FCHOWN
|
||||
fchown(f, fstat_buf.st_uid, fstat_buf.st_gid);
|
||||
|
@ -720,7 +734,8 @@ setmode:
|
|||
}
|
||||
|
||||
LOCAL void
|
||||
extract_file(f, idr, fname)
|
||||
extract_file(dev, f, idr, fname)
|
||||
struct scsi_dev *dev;
|
||||
int f;
|
||||
struct iso_directory_record *idr;
|
||||
char *fname;
|
||||
|
@ -737,7 +752,7 @@ extract_file(f, idr, fname)
|
|||
while (len > 0) {
|
||||
tlen = (len > sizeof (buff) ? sizeof (buff) : len);
|
||||
#ifdef USE_SCG
|
||||
readsecs(extent - sector_offset, buff, ISO_BLOCKS(tlen));
|
||||
readsecs(dev, extent - sector_offset, buff, ISO_BLOCKS(tlen));
|
||||
#else
|
||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
||||
read(fileno(infile), buff, tlen);
|
||||
|
@ -751,7 +766,8 @@ extract_file(f, idr, fname)
|
|||
|
||||
|
||||
LOCAL void
|
||||
parse_cl_dir(idr, extent)
|
||||
parse_cl_dir(dev, idr, extent)
|
||||
struct scsi_dev *dev;
|
||||
struct iso_directory_record *idr;
|
||||
int extent;
|
||||
{
|
||||
|
@ -759,14 +775,14 @@ parse_cl_dir(idr, extent)
|
|||
|
||||
strlcpy(cl_name_buf, name_buf, sizeof (cl_name_buf));
|
||||
#ifdef USE_SCG
|
||||
readsecs(extent - sector_offset, idr, 1);
|
||||
readsecs(dev, extent - sector_offset, idr, 1);
|
||||
#else
|
||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
||||
read(fileno(infile), idr, 2048);
|
||||
#endif
|
||||
|
||||
if (parse_de(idr) && use_rock)
|
||||
dump_rr(idr);
|
||||
dump_rr(dev, idr);
|
||||
strlcpy(name_buf, cl_name_buf, sizeof (name_buf));
|
||||
}
|
||||
|
||||
|
@ -887,11 +903,14 @@ parse_de(idr)
|
|||
}
|
||||
|
||||
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;
|
||||
char *rootname;
|
||||
int extent; /* Directory extent */
|
||||
int len; /* Directory size */
|
||||
iso_listing_callback callback;
|
||||
void *user_data;
|
||||
{
|
||||
struct todo *td;
|
||||
int i;
|
||||
|
@ -910,7 +929,7 @@ static int nlen = 0;
|
|||
|
||||
while (len > 0) {
|
||||
#ifdef USE_SCG
|
||||
readsecs(extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
||||
readsecs(dev, extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
||||
#else
|
||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
|
||||
read(fileno(infile), buffer, sizeof (buffer));
|
||||
|
@ -924,7 +943,7 @@ static int nlen = 0;
|
|||
break;
|
||||
parse_de(idr);
|
||||
if (use_rock) {
|
||||
rr_flags = dump_rr(idr);
|
||||
rr_flags = dump_rr(dev, idr);
|
||||
|
||||
if (rr_flags & RR_FLAG_CL) {
|
||||
/*
|
||||
|
@ -933,7 +952,7 @@ static int nlen = 0;
|
|||
* so we get no usable file name.
|
||||
*/
|
||||
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)
|
||||
goto cont; /* skip rr_moved */
|
||||
}
|
||||
|
@ -969,6 +988,8 @@ static int nlen = 0;
|
|||
int nextent;
|
||||
struct todo *tp = dp;
|
||||
|
||||
(*callback)(user_data, n, 1);
|
||||
|
||||
nextent = isonum_733((unsigned char *)idr->extent);
|
||||
while (tp) {
|
||||
if (tp->extent == nextent) {
|
||||
|
@ -996,9 +1017,13 @@ static int nlen = 0;
|
|||
*todo_pp = td;
|
||||
todo_pp = &td->next;
|
||||
}
|
||||
} else if ((idr->flags[0] & 2) &&
|
||||
(idr->name[0] != 0 || idr->name[0] != 1)) {
|
||||
/* this is . or .. */
|
||||
} else {
|
||||
callback(user_data, n, 0);
|
||||
if (xtract && strcmp(xtract, n) == 0) {
|
||||
extract_file(STDOUT_FILENO, idr, "stdout");
|
||||
extract_file(dev, STDOUT_FILENO, idr, "stdout");
|
||||
}
|
||||
}
|
||||
if (do_f &&
|
||||
|
@ -1035,7 +1060,7 @@ static int nlen = 0;
|
|||
S_ISDIR(fstat_buf.st_mode)) {
|
||||
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(rootname, idr, n);
|
||||
extract(dev, rootname, idr, n);
|
||||
}
|
||||
size += fstat_buf.st_size;
|
||||
if ((flags & ISO_MULTIEXTENT) &&
|
||||
|
@ -1073,14 +1098,66 @@ static int nlen = 0;
|
|||
}
|
||||
|
||||
EXPORT int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
scan_iso (filename, callback, user_data)
|
||||
const char* filename;
|
||||
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 ret = 0;
|
||||
char *filename = NULL;
|
||||
char *sdevname = NULL;
|
||||
#if defined(USE_NLS)
|
||||
char *dir;
|
||||
#endif
|
||||
|
@ -1120,63 +1197,7 @@ main(argc, argv)
|
|||
|
||||
myuid = getuid();
|
||||
|
||||
#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
|
||||
charset = default_charset();
|
||||
|
||||
if (charset == NULL) {
|
||||
#if (defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__DJGPP__) || defined(__MINGW32__)) && !defined(IS_CYGWIN_1)
|
||||
|
@ -1197,38 +1218,11 @@ setcharset:
|
|||
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.
|
||||
*/
|
||||
#ifdef USE_SCG
|
||||
readsecs(16 + toc_offset, &ipd, ISO_BLOCKS(sizeof (ipd)));
|
||||
readsecs(dev, 16 + toc_offset, &ipd, ISO_BLOCKS(sizeof (ipd)));
|
||||
#else
|
||||
lseek(fileno(infile), ((off_t)(16 + toc_offset)) <<11, SEEK_SET);
|
||||
read(fileno(infile), &ipd, sizeof (ipd));
|
||||
|
@ -1240,7 +1234,7 @@ setcharset:
|
|||
c = 17;
|
||||
do {
|
||||
#ifdef USE_SCG
|
||||
readsecs(c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||
readsecs(dev, c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||
#else
|
||||
lseek(fileno(infile), ((off_t)(c + toc_offset)) <<11, SEEK_SET);
|
||||
read(fileno(infile), &jpd, sizeof (jpd));
|
||||
|
@ -1248,7 +1242,7 @@ setcharset:
|
|||
} while (++c < 32 && GET_UBYTE(jpd.type) != ISO_VD_END);
|
||||
if (GET_UBYTE(jpd.type) == ISO_VD_END) do {
|
||||
#ifdef USE_SCG
|
||||
readsecs(c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||
readsecs(dev, c + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||
#else
|
||||
lseek(fileno(infile), ((off_t)(c + toc_offset)) <<11, SEEK_SET);
|
||||
read(fileno(infile), &jpd, sizeof (jpd));
|
||||
|
@ -1274,12 +1268,12 @@ setcharset:
|
|||
*/
|
||||
extent = isonum_733((unsigned char *)idr->extent);
|
||||
#ifdef USE_SCG
|
||||
readsecs(extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
||||
readsecs(dev, extent - sector_offset, buffer, ISO_BLOCKS(sizeof (buffer)));
|
||||
#else
|
||||
lseek(fileno(infile), ((off_t)(extent - sector_offset)) <<11, SEEK_SET);
|
||||
read(fileno(infile), buffer, sizeof (buffer));
|
||||
#endif
|
||||
c = dump_rr((struct iso_directory_record *) buffer);
|
||||
c = dump_rr(dev, (struct iso_directory_record *) buffer);
|
||||
if (c == 0 ||
|
||||
(c & (RR_FLAG_SP | RR_FLAG_ER)) == 0 || su_version < 1 || rr_version < 1) {
|
||||
if (!debug)
|
||||
|
@ -1324,7 +1318,7 @@ setcharset:
|
|||
|
||||
block++;
|
||||
#ifdef USE_SCG
|
||||
readsecs(block + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||
readsecs(dev, block + toc_offset, &jpd, ISO_BLOCKS(sizeof (jpd)));
|
||||
#else
|
||||
lseek(fileno(infile),
|
||||
((off_t)(block + toc_offset)) <<11, SEEK_SET);
|
||||
|
@ -1363,17 +1357,15 @@ setcharset:
|
|||
if (use_joliet)
|
||||
idr = (struct iso_directory_record *)jpd.root_directory_record;
|
||||
|
||||
parse_dir(todo_idr, "/", isonum_733((unsigned char *)idr->extent),
|
||||
isonum_733((unsigned char *)idr->size));
|
||||
parse_dir(dev, todo_idr, "/", isonum_733((unsigned char *)idr->extent),
|
||||
isonum_733((unsigned char *)idr->size), callback, user_data);
|
||||
td = todo_idr;
|
||||
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);
|
||||
td = td->next;
|
||||
}
|
||||
|
||||
if (infile != NULL)
|
||||
fclose(infile);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -1468,3 +1460,68 @@ iso9660_time(date, hsecp, longfmt)
|
|||
t -= gmtoff * 15 * 60;
|
||||
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/unistd.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/scsitransp.h>
|
||||
|
||||
#include "libscgcmd.h"
|
||||
#include "cdrdeflt.h"
|
||||
#include "scgcmd/libscgcmd.h"
|
||||
#include "cdrdeflt/cdrdeflt.h"
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
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 */
|
||||
|
||||
EXPORT int readsecs __PR((UInt32_t startsecno, void *buffer, int sectorcount));
|
||||
EXPORT int scsidev_open __PR((char *path));
|
||||
EXPORT int scsidev_close __PR((void));
|
||||
EXPORT int readsecs __PR((struct scsi_dev* src, UInt32_t startsecno, void *buffer, int sectorcount));
|
||||
EXPORT BOOL scsidev_has_error __PR((struct scsi_dev *dev));
|
||||
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
|
||||
readsecs(startsecno, buffer, sectorcount)
|
||||
readsecs(src, startsecno, buffer, sectorcount)
|
||||
struct scsi_dev *src;
|
||||
UInt32_t startsecno;
|
||||
void *buffer;
|
||||
int sectorcount;
|
||||
|
@ -69,7 +95,7 @@ readsecs(startsecno, buffer, sectorcount)
|
|||
char *bp;
|
||||
long amt;
|
||||
|
||||
if (in_image == NULL) {
|
||||
if (src->file == NULL) {
|
||||
/*
|
||||
* We are using the standard CD-ROM sectorsize of 2048 bytes
|
||||
* 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 and that SECTOR_SIZE / secsize is not a fraction.
|
||||
*/
|
||||
secsize = scgp->cap->c_bsize;
|
||||
secsize = src->scgp->cap->c_bsize;
|
||||
amount = sectorcount * SECTOR_SIZE;
|
||||
secno = startsecno * (SECTOR_SIZE / secsize);
|
||||
bp = buffer;
|
||||
|
@ -88,8 +114,8 @@ readsecs(startsecno, buffer, sectorcount)
|
|||
amt = bufsize;
|
||||
secnum = amt / secsize;
|
||||
|
||||
if (read_scsi(scgp, bp, secno, secnum) < 0 ||
|
||||
scg_getresid(scgp) != 0) {
|
||||
if (read_scsi(src->scgp, bp, secno, secnum) < 0 ||
|
||||
scg_getresid(src->scgp) != 0) {
|
||||
#ifdef OLD
|
||||
return (-1);
|
||||
#else
|
||||
|
@ -104,7 +130,7 @@ readsecs(startsecno, buffer, 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) {
|
||||
comerr(_("Seek error on old image\n"));
|
||||
|
@ -125,13 +151,61 @@ readsecs(startsecno, buffer, sectorcount)
|
|||
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)
|
||||
char *path;
|
||||
{
|
||||
char errstr[80];
|
||||
char *buf; /* ignored, bit OS/2 ASPI layer needs memory which */
|
||||
/* has been allocated by scsi_getbuf() */
|
||||
struct scsi_dev *retval;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/* path, debug, verboseopen */
|
||||
scgp = scg_open(path, errstr, sizeof (errstr), 0, 0);
|
||||
if (scgp == 0) {
|
||||
errmsg(_("%s%sCannot open SCSI driver.\n"), errstr, errstr[0]?". ":"");
|
||||
return (-1);
|
||||
retval = (struct scsi_dev*)malloc(sizeof(*retval));
|
||||
memset(retval, 0, sizeof(*retval));
|
||||
|
||||
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);
|
||||
if ((buf = scg_getbuf(scgp, bufsize)) == NULL) {
|
||||
errmsg(_("Cannot get SCSI I/O buffer.\n"));
|
||||
scg_close(scgp);
|
||||
return (-1);
|
||||
bufsize = scg_bufsize(retval->scgp, BUF_SIZE);
|
||||
if ((buf = scg_getbuf(retval->scgp, bufsize)) == NULL) {
|
||||
retval->err = ScsiOpenErr_CantIO;
|
||||
scg_close(retval->scgp);
|
||||
retval->scgp = NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
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 */
|
||||
return (-1);
|
||||
if (!wait_unit_ready(retval->scgp, 60)) { /* Eat Unit att / Wait for drive */
|
||||
retval->err = ScsiOpenErr_Timeout;
|
||||
return retval;
|
||||
}
|
||||
|
||||
scgp->silent++;
|
||||
read_capacity(scgp); /* Set Capacity/Sectorsize for I/O */
|
||||
scgp->silent--;
|
||||
retval->scgp->silent++;
|
||||
read_capacity(retval->scgp); /* Set Capacity/Sectorsize for I/O */
|
||||
retval->scgp->silent--;
|
||||
|
||||
return (1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
EXPORT int
|
||||
scsidev_close()
|
||||
scsidev_close(struct scsi_dev *f)
|
||||
{
|
||||
if (in_image == NULL) {
|
||||
return (scg_close(scgp));
|
||||
} else {
|
||||
return (fclose(in_image));
|
||||
int retval;
|
||||
|
||||
if (NULL == f)
|
||||
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 */
|
||||
|
|
|
@ -10,11 +10,17 @@
|
|||
/*
|
||||
* 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
|
||||
extern int scsidev_open __PR((char *path));
|
||||
extern int scsidev_close __PR((void));
|
||||
extern struct scsi_dev* scsidev_open __PR((char *path));
|
||||
extern struct scsi_dev* scsidev_file_open __PR((const char *path));
|
||||
extern int scsidev_close __PR((struct scsi_dev *f));
|
||||
#endif
|
||||
|
||||
#endif /* _SCSI_H */
|
||||
|
|
Loading…
Reference in a new issue