New cdrskin option --list_features

This commit is contained in:
Thomas Schmitt 2019-04-17 11:58:32 +02:00
parent c5bc9f6de7
commit 0e73afd17c
3 changed files with 181 additions and 3 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Version 1.5.1, Sep 16, 2018" .TH CDRSKIN 1 "Version 1.5.1, Apr 17, 2019"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -1471,6 +1471,46 @@ better buffer fills while still avoiding the problem:
Alphabetical list of options which are only intended for very special Alphabetical list of options which are only intended for very special
situations and not for normal use: situations and not for normal use:
.TP .TP
.BI \--list_features
List the SCSI/MMC features which were obtained from the drive when it was
last acquired or re-assessed. Although this is better readable than the
raw reply to SCSI command GET CONFIGURATION, the MMC specification text
is still needed for interpreting it.
.br
The list consists of line groups of the form
.br
Code +/- : Name : Version,P/N
.br
Raw feature data bytes as hex numbers
.br
Parsed info as Name=Value pairs
.br
The headline is the only one which has no blank at its start.
Code is given as 16 bit hex number.
.br
"+" marks a currently offered feature. "-" marks those which may be offered
under different circumstances.
.br
Name is the feature name as listed in MMC specs.
.br
"P" marks persistent features. "N" marks non-persistent features.
.br
The Raw data can occupy more than one line. No "=" occurs in such lines.
If no raw data are present, one line with some blanks is listed instead.
.br
The Parsed info shows some extracted field values with names which resemble
the names used in the MMC description of the particular feature. Parsed info
lines contain at least one Name=Value pair. More than one line is possible.
If no parsed info is produced, one line with some blanks is listed instead.
.br
Example:
.br
0107 - : Real Time Streaming : 4,N
.br
1f 00 00 00
.br
RBCB=1 , SCS=1 , MP2A=1 , WSPD=1 , SW=1
.TP
.BI \--abort_handler .BI \--abort_handler
Establish default signal handling not to leave a drive in busy state Establish default signal handling not to leave a drive in busy state
but rather to shut it down and to wait until it has ended the final operations. but rather to shut it down and to wait until it has ended the final operations.

View File

@ -1,6 +1,6 @@
/* /*
cdrskin.c , Copyright 2006-2018 Thomas Schmitt <scdbackup@gmx.net> cdrskin.c , Copyright 2006-2019 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
A cdrecord compatible command line interface for libburn. A cdrecord compatible command line interface for libburn.
@ -2904,6 +2904,7 @@ set_dev:;
printf(" --list_formats list format descriptors for loaded media.\n"); printf(" --list_formats list format descriptors for loaded media.\n");
printf(" --list_ignored_options list all ignored cdrecord options.\n"); printf(" --list_ignored_options list all ignored cdrecord options.\n");
printf(" --list_speeds list speed descriptors for loaded media.\n"); printf(" --list_speeds list speed descriptors for loaded media.\n");
printf(" --list_features list SCSI features reported by the drive\n");
printf(" --long_toc print overview of media content\n"); printf(" --long_toc print overview of media content\n");
printf(" modesty_on_drive=<options> no writing into full drive buffer\n"); printf(" modesty_on_drive=<options> no writing into full drive buffer\n");
printf(" --no_abort_handler exit even if the drive is in busy state\n"); printf(" --no_abort_handler exit even if the drive is in busy state\n");
@ -3409,6 +3410,7 @@ struct CdrskiN {
int do_atip; int do_atip;
int do_list_speeds; int do_list_speeds;
int do_list_formats; int do_list_formats;
int do_list_features;
int do_cdtext_to_textfile; int do_cdtext_to_textfile;
char cdtext_to_textfile_path[Cdrskin_strleN]; char cdtext_to_textfile_path[Cdrskin_strleN];
int do_cdtext_to_vt07; int do_cdtext_to_vt07;
@ -3676,6 +3678,7 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
o->do_atip= 0; o->do_atip= 0;
o->do_list_speeds= 0; o->do_list_speeds= 0;
o->do_list_formats= 0; o->do_list_formats= 0;
o->do_list_features= 0;
o->do_cdtext_to_textfile= 0; o->do_cdtext_to_textfile= 0;
o->cdtext_to_textfile_path[0]= 0; o->cdtext_to_textfile_path[0]= 0;
o->do_cdtext_to_vt07= 0; o->do_cdtext_to_vt07= 0;
@ -5956,6 +5959,128 @@ ex:;
} }
/* @param flag: bit0= do not print prefix on first line
bit1= plan for multiples of 4 hex words
*/
static int Feature_printf(char *prefix, char *text, int flag)
{
char *tpt, *npt;
int lp, lp0, line_size;
lp0= !(flag & 1);
tpt= text;
lp= strlen(prefix);
/* Plan 2 char shorter for possible comma inclusion */
line_size= 77;
if(flag & 2) {
line_size= (80 - lp) / 3;
line_size-= line_size % 4;
line_size= line_size * 3 - 1 + lp;
}
while(lp * lp0 + strlen(tpt) >= 80) {
/* Line size for 20 */
for(npt= tpt + line_size - lp * lp0; npt > tpt; npt--)
if(*npt == ' ')
break;
if(npt <= tpt) {
printf("%s%s\n", lp0 ? prefix : "", tpt);
return(2);
}
/* Keep comma in printed line */
if(*(npt + 1) == ',' && *(npt + 1) == ' ')
npt+= 2;
/* Print and advance */
*npt= 0;
printf("%s%s\n", lp0 ? prefix : "", tpt);
tpt= npt + 1;
lp0= 1;
}
printf("%s%s\n", lp0 ? prefix : "", tpt);
return(1);
}
/** Perform --list_features
@param flag Bitfield for control purposes:
@return <=0 error, 1 success
*/
int Cdrskin_list_features(struct CdrskiN *skin, int flag)
{
struct burn_drive *d;
int ret, count, i, j;
unsigned int *feature_codes= NULL;
unsigned char flags, additional_length, *feature_data = NULL;
char *feature_text = NULL, *cpt, *dpt;
ret= Cdrskin_grab_drive(skin,0);
if(ret <= 0)
return(ret);
d= skin->drives[skin->driveno].drive;
fprintf(stderr, "SCSI Features reported by the drive:\n");
fprintf(stderr,
" + = Current, - = Not Current, P = Persistent, N = Not Persistent\n");
fprintf(stderr, "Code C : Name : Version,Persistent\n");
fprintf(stderr, " Additional data if present (hex bytes)\n");
fprintf(stderr, " Parsed info if available (fieldname=content)\n");
fprintf(stderr, "\n");
burn_drive_get_feature_codes(d, &count, &feature_codes);
if(count <= 0) {
fprintf(stderr, "cdrskin: NOTE: The drive feature list is empty\n");
ret= 1; goto ex;
}
for(i= 0; i < count; i++) {
ret= burn_drive_get_feature(d, feature_codes[i], &flags, &additional_length,
&feature_data, &feature_text);
if(ret <= 0) {
fprintf(stderr, "cdrskin: SORRY: Cannot obtain data of feature %4.4x\n",
feature_codes[i]);
continue;
}
cpt= feature_text;
for(j= 0; j < 3 && cpt != NULL; j++)
cpt= strchr(cpt + 1, ':');
if(cpt != NULL) {
*cpt= 0;
cpt++;
}
Feature_printf(" ", feature_text, 1);
if(cpt != NULL) {
dpt= cpt;
if(*dpt == ' ')
dpt++;
for(j= 0; j < 1 && cpt != NULL; j++)
cpt= strchr(cpt + 1, ':');
if(cpt != NULL) {
*cpt= 0;
cpt++;
}
Feature_printf(" ", dpt, 2);
}
if(cpt != NULL) {
if(*cpt == ' ')
cpt++;
Feature_printf(" ", cpt, 0);
} else {
printf("\n");
}
if(feature_data != NULL)
free(feature_data);
feature_data= NULL;
if(feature_text != NULL)
free(feature_text);
feature_text= NULL;
}
ret= 1;
ex:;
if(feature_codes != NULL)
free(feature_codes);
return(ret);
}
int Cdrskin_read_textfile(struct CdrskiN *skin, char *path, int flag) int Cdrskin_read_textfile(struct CdrskiN *skin, char *path, int flag)
{ {
int ret, num_packs = 0; int ret, num_packs = 0;
@ -8843,6 +8968,10 @@ set_isrc:;
skin->do_list_speeds= 1; skin->do_list_speeds= 1;
skin->preskin->demands_cdrskin_caps= 1; skin->preskin->demands_cdrskin_caps= 1;
} else if(strcmp(argv[i],"--list_features")==0) {
skin->do_list_features= 1;
skin->preskin->demands_cdrskin_caps= 1;
} else if(strncmp(argv[i],"fallback_program=",17)==0) { } else if(strncmp(argv[i],"fallback_program=",17)==0) {
/* is handled in Cdrpreskin_setup() */; /* is handled in Cdrpreskin_setup() */;
@ -9711,6 +9840,15 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
if(ret<=0) if(ret<=0)
{*exit_value= 16; goto ex;} {*exit_value= 16; goto ex;}
} }
if(skin->do_list_features) {
if(skin->n_drives<=0)
{*exit_value= 20; goto no_drive;}
if(Cdrskin__is_aborting(0))
goto ex;
ret= Cdrskin_list_features(skin, 0);
if(ret<=0)
{*exit_value= 20; goto ex;}
}
if(skin->do_blank) { if(skin->do_blank) {
if(skin->n_drives<=0) if(skin->n_drives<=0)
{*exit_value= 8; goto no_drive;} {*exit_value= 8; goto no_drive;}

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2019.04.17.092323" #define Cdrskin_timestamP "2019.04.17.095742"