Taking into respect drive list from /proc/sys/dev/cdrom/info
This commit is contained in:
parent
98d742a4ef
commit
ea17318e18
@ -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 "May 17, 2008"
|
.TH CDRSKIN 1 "Aug 05, 2008"
|
||||||
.\" 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:
|
||||||
@ -1080,8 +1080,9 @@ Linux specific: Do not ask the operating system to prevent opening busy drives.
|
|||||||
Wether this leads to senseful behavior depends on operating system and kernel.
|
Wether this leads to senseful behavior depends on operating system and kernel.
|
||||||
.TP
|
.TP
|
||||||
.BI drive_scsi_dev_family= sr | scd | sg
|
.BI drive_scsi_dev_family= sr | scd | sg
|
||||||
Linux specific: Select a SCSI device file family to be used for drive command
|
Linux specific: Select a SCSI device file family to be scanned for by
|
||||||
transactions. Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
options --devices and -scanbus.
|
||||||
|
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
||||||
on kernels >= 2.6 . This option allows to explicitely override that default
|
on kernels >= 2.6 . This option allows to explicitely override that default
|
||||||
in order to meet other programs at a common device file for each drive.
|
in order to meet other programs at a common device file for each drive.
|
||||||
On kernel 2.4 families sr and scd will find no drives.
|
On kernel 2.4 families sr and scd will find no drives.
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2008.08.01.101053"
|
#define Cdrskin_timestamP "2008.08.05.175930"
|
||||||
|
@ -196,6 +196,31 @@ unsigned int burn_drive_count(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A80801 */
|
||||||
|
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
char drive_adr[BURN_DRIVE_ADR_LEN], off_adr[BURN_DRIVE_ADR_LEN];
|
||||||
|
|
||||||
|
ret = burn_drive_convert_fs_adr(path, off_adr);
|
||||||
|
if (ret <= 0)
|
||||||
|
strcpy(off_adr, path);
|
||||||
|
for (i = 0; i <= drivetop; i++) {
|
||||||
|
if (drive_array[i].global_index < 0)
|
||||||
|
continue;
|
||||||
|
ret = burn_drive_d_get_adr(&(drive_array[i]), drive_adr);
|
||||||
|
if (ret <= 0)
|
||||||
|
continue;
|
||||||
|
if(strcmp(off_adr, drive_adr) == 0) {
|
||||||
|
if (found != NULL)
|
||||||
|
*found= &(drive_array[i]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61125 : media status aspects of burn_drive_grab() */
|
/* ts A61125 : media status aspects of burn_drive_grab() */
|
||||||
int burn_drive_inquire_media(struct burn_drive *d)
|
int burn_drive_inquire_media(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
|
@ -131,4 +131,8 @@ int burn_drive_whitelist_count(void);
|
|||||||
char *burn_drive_whitelist_item(int idx, int flag);
|
char *burn_drive_whitelist_item(int idx, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A80801 */
|
||||||
|
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __DRIVE */
|
#endif /* __DRIVE */
|
||||||
|
@ -432,6 +432,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings
|
0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings
|
||||||
0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock
|
0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock
|
||||||
0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist
|
0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist
|
||||||
|
0x0002000a (FAILURE,HIGH) = Cannot accept '...' as SG_IO CDROM drive
|
||||||
|
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
||||||
|
|
||||||
General library operations:
|
General library operations:
|
||||||
|
|
||||||
|
@ -51,11 +51,17 @@ SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
|||||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
||||||
|
|
||||||
|
|
||||||
/* To hold the index number of the most recently delivered address from
|
/* To hold the position of the most recently delivered address from
|
||||||
device enumeration.
|
device enumeration.
|
||||||
*/
|
*/
|
||||||
|
struct burn_drive_enumerator_struct {
|
||||||
|
int pos;
|
||||||
|
int info_count;
|
||||||
|
char **info_list;
|
||||||
|
};
|
||||||
|
|
||||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||||
typedef int burn_drive_enumerator_t;
|
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
||||||
|
|
||||||
|
|
||||||
/* Parameters for sibling list. See sibling_fds, sibling_fnames */
|
/* Parameters for sibling list. See sibling_fds, sibling_fnames */
|
||||||
|
@ -1093,19 +1093,62 @@ static void sg_enumerate(void)
|
|||||||
|
|
||||||
#ifdef Libburn_drive_new_deaL
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
/* ts A80731 : Directly open the given address from a single-item whitlist */
|
|
||||||
int single_enumerate(int flag)
|
|
||||||
{
|
|
||||||
int wl_count, is_ata= 0, is_scsi= 0;
|
|
||||||
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
|
||||||
char *fname;
|
|
||||||
|
|
||||||
wl_count= burn_drive_whitelist_count();
|
/* ts A80805 : eventually produce the other official name of a device file */
|
||||||
if (wl_count != 1)
|
static int fname_other_name(char *fname, char other_name[80], int flag)
|
||||||
|
{
|
||||||
|
if(strncmp(fname, "/dev/sr", 7) == 0 &&
|
||||||
|
(fname[7] >= '0' && fname[7] <= '9') &&
|
||||||
|
(fname[8] == 0 ||
|
||||||
|
(fname[8] >= '0' && fname[8] <= '9' && fname[9] == 0))) {
|
||||||
|
sprintf(other_name, "/dev/scd%s", fname + 7);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(strncmp(fname, "/dev/scd", 8) == 0 &&
|
||||||
|
(fname[8] >= '0' && fname[8] <= '9') &&
|
||||||
|
(fname[9] == 0 ||
|
||||||
|
(fname[9] >= '0' && fname[9] <= '9' && fname[10] == 0))) {
|
||||||
|
sprintf(other_name, "/dev/sr%s", fname + 8);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
fname= burn_drive_whitelist_item(0, 0);
|
}
|
||||||
if (fname == NULL)
|
|
||||||
|
|
||||||
|
/* ts A80805 */
|
||||||
|
static int fname_drive_is_listed(char *fname, int flag)
|
||||||
|
{
|
||||||
|
char other_fname[80];
|
||||||
|
|
||||||
|
if (burn_drive_is_listed(fname, NULL, 0))
|
||||||
|
return 1;
|
||||||
|
if (fname_other_name(fname, other_fname, 0) > 0)
|
||||||
|
if (burn_drive_is_listed(other_fname, NULL, 0))
|
||||||
|
return 2;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A80731 : Directly open the given address.
|
||||||
|
@param flag bit0= do not compain about missing file
|
||||||
|
*/
|
||||||
|
static int fname_enumerate(char *fname, int flag)
|
||||||
|
{
|
||||||
|
int is_ata= 0, is_scsi= 0;
|
||||||
|
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
||||||
|
char msg[BURN_DRIVE_ADR_LEN + 80];
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
if (fname_drive_is_listed(fname, 0))
|
||||||
|
return 2;
|
||||||
|
if (stat(fname, &stbuf) == -1) {
|
||||||
|
sprintf(msg, "File object '%s' not found", fname);
|
||||||
|
if (!(flag & 1))
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002000b,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
is_ata = is_ata_drive(fname);
|
is_ata = is_ata_drive(fname);
|
||||||
if (is_ata < 0)
|
if (is_ata < 0)
|
||||||
@ -1126,6 +1169,124 @@ int single_enumerate(int flag)
|
|||||||
target_no, lun_no);
|
target_no, lun_no);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A80731 : Directly open the given address from a single-item whitlist */
|
||||||
|
static int single_enumerate(int flag)
|
||||||
|
{
|
||||||
|
int ret, wl_count;
|
||||||
|
char *fname, msg[BURN_DRIVE_ADR_LEN + 80];
|
||||||
|
|
||||||
|
wl_count= burn_drive_whitelist_count();
|
||||||
|
if (wl_count != 1)
|
||||||
|
return 0;
|
||||||
|
fname= burn_drive_whitelist_item(0, 0);
|
||||||
|
if (fname == NULL)
|
||||||
|
return 0;
|
||||||
|
ret = fname_enumerate(fname, 0);
|
||||||
|
if (ret <= 0) {
|
||||||
|
sprintf(msg, "Cannot access '%s' as SG_IO CDROM drive", fname);
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002000a,
|
||||||
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
msg, 0, 0);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A80801 : looking up drives listed in /proc/sys/dev/cdrom/info line like:
|
||||||
|
drive name: sr1 hdc hda sr0
|
||||||
|
@parm flag bit0= release list memory and exit
|
||||||
|
*/
|
||||||
|
static int proc_sys_dev_cdrom_info(char ***list, int *count, int flag)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char line[1024], fname[1024 + 5], *cpt, *retpt, *list_data;
|
||||||
|
int maxl= 0, pass, i;
|
||||||
|
|
||||||
|
if (*list != NULL) {
|
||||||
|
if ((*list)[0] != NULL)
|
||||||
|
free((*list)[0]);
|
||||||
|
free(*list);
|
||||||
|
*list = NULL;
|
||||||
|
*count = 0;
|
||||||
|
}
|
||||||
|
if (flag & 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
fp = fopen("/proc/sys/dev/cdrom/info", "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
return 0;
|
||||||
|
while (1) {
|
||||||
|
retpt = fgets(line, sizeof(line), fp);
|
||||||
|
if (retpt == NULL)
|
||||||
|
break;
|
||||||
|
if(strncmp(line, "drive name:", 11) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
if (retpt == NULL)
|
||||||
|
return 0;
|
||||||
|
strcpy(fname, "/dev/");
|
||||||
|
for(pass = 0; pass < 2; pass++) {
|
||||||
|
*count = 0;
|
||||||
|
cpt = line + 11;
|
||||||
|
while (*cpt != 0) {
|
||||||
|
for(; *cpt == ' ' || *cpt == '\t'; cpt++);
|
||||||
|
if (*cpt == 0 || *cpt == '\n')
|
||||||
|
break;
|
||||||
|
sscanf(cpt, "%s", fname + 5);
|
||||||
|
if (strlen(fname) > maxl)
|
||||||
|
maxl = strlen(fname);
|
||||||
|
if (pass == 1)
|
||||||
|
strcpy((*list)[*count], fname);
|
||||||
|
(*count)++;
|
||||||
|
for(cpt++; *cpt != ' ' && *cpt != '\t'
|
||||||
|
&& *cpt != 0 && *cpt != '\n'; cpt++);
|
||||||
|
}
|
||||||
|
if (pass == 0) {
|
||||||
|
list_data = calloc(*count + 1, maxl+1);
|
||||||
|
*list = calloc(*count + 1, sizeof(char *));
|
||||||
|
if(list_data == NULL || *list == NULL) {
|
||||||
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
|
0x00000003,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Out of virtual memory", 0, 0);
|
||||||
|
if (list_data != NULL)
|
||||||
|
free(list_data);
|
||||||
|
if (*list != NULL)
|
||||||
|
free((char *) *list);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i <= *count; i++)
|
||||||
|
(*list)[i] = list_data + i * (maxl + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int add_proc_info_drives(int flag)
|
||||||
|
{
|
||||||
|
int ret, list_count, count = 0, i;
|
||||||
|
char **list= NULL;
|
||||||
|
|
||||||
|
ret = proc_sys_dev_cdrom_info(&list, &list_count, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
return ret;
|
||||||
|
for (i = 0; i < list_count; i++) {
|
||||||
|
if (burn_drive_is_banned(list[i]))
|
||||||
|
continue;
|
||||||
|
ret = fname_enumerate(list[i], 1);
|
||||||
|
if (ret == 1)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
proc_sys_dev_cdrom_info(&list, &list_count, 1); /* free memory */
|
||||||
|
return 1 + count;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* Libburn_drive_new_deaL */
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
|
|
||||||
@ -1213,10 +1374,14 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
{
|
{
|
||||||
/* os-linux.h : typedef int burn_drive_enumerator_t; */
|
/* os-linux.h : typedef int burn_drive_enumerator_t; */
|
||||||
static int sg_limit = 32, ata_limit = 26;
|
static int sg_limit = 32, ata_limit = 26;
|
||||||
int baseno = 0;
|
int baseno = 0, i;
|
||||||
|
char other_name[80];
|
||||||
|
|
||||||
if (initialize == -1)
|
if (initialize == -1) {
|
||||||
|
proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count),
|
||||||
|
1);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sg_select_device_family();
|
sg_select_device_family();
|
||||||
if (linux_sg_device_family[0] == 0)
|
if (linux_sg_device_family[0] == 0)
|
||||||
@ -1224,30 +1389,56 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|||||||
if (linux_ata_device_family[0] == 0)
|
if (linux_ata_device_family[0] == 0)
|
||||||
ata_limit = 0;
|
ata_limit = 0;
|
||||||
|
|
||||||
if (initialize == 1)
|
if (initialize == 1) {
|
||||||
*idx = -1;
|
idx->pos = -1;
|
||||||
(*idx)++;
|
idx->info_count= 0;
|
||||||
if (*idx >= sg_limit)
|
idx->info_list= NULL;
|
||||||
|
proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
(idx->pos)++;
|
||||||
|
if (idx->pos >= sg_limit)
|
||||||
goto next_ata;
|
goto next_ata;
|
||||||
if (adr_size < 10)
|
if (adr_size < 11)
|
||||||
return -1;
|
return -1;
|
||||||
sprintf(adr, linux_sg_device_family, *idx);
|
sprintf(adr, linux_sg_device_family, idx->pos);
|
||||||
|
|
||||||
/* ts A80702 */
|
|
||||||
sg_exchange_scd_for_sr(adr, 0);
|
sg_exchange_scd_for_sr(adr, 0);
|
||||||
|
goto return_1_pre_proc;
|
||||||
|
|
||||||
return 1;
|
|
||||||
next_ata:;
|
next_ata:;
|
||||||
baseno += sg_limit;
|
baseno += sg_limit;
|
||||||
if (*idx - baseno >= ata_limit)
|
if (idx->pos - baseno >= ata_limit)
|
||||||
goto next_nothing;
|
goto next_proc_info;
|
||||||
if (adr_size < 9)
|
if (adr_size < 9)
|
||||||
return -1;
|
return -1;
|
||||||
sprintf(adr, linux_ata_device_family, 'a' + (*idx - baseno));
|
sprintf(adr, linux_ata_device_family, 'a' + (idx->pos - baseno));
|
||||||
return 1;
|
goto return_1_pre_proc;
|
||||||
next_nothing:;
|
|
||||||
|
next_proc_info:;
|
||||||
baseno += ata_limit;
|
baseno += ata_limit;
|
||||||
|
for (i = 0; i < idx->info_count; i++) {
|
||||||
|
if ((idx->info_list)[i][0] == 0)
|
||||||
|
continue;
|
||||||
|
if (baseno == idx->pos) {
|
||||||
|
if (adr_size < strlen((idx->info_list)[i]) + 1)
|
||||||
|
return -1;
|
||||||
|
strcpy(adr, (idx->info_list)[i]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
baseno++;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
return_1_pre_proc:;
|
||||||
|
for (i = 0; i < idx->info_count; i++) {
|
||||||
|
if (strcmp((idx->info_list)[i], adr) == 0)
|
||||||
|
(idx->info_list)[i][0] = 0;
|
||||||
|
if (fname_other_name(adr, other_name, 0) > 0)
|
||||||
|
if (strcmp((idx->info_list)[i], other_name) == 0)
|
||||||
|
(idx->info_list)[i][0] = 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1281,13 +1472,15 @@ int scsi_enumerate_drives(void)
|
|||||||
return -1;
|
return -1;
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* >>> ??? should one rather use /proc/sys/dev/cdrom/info ? */
|
|
||||||
|
|
||||||
#endif /* Libburn_drive_new_deaL */
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
sg_enumerate();
|
sg_enumerate();
|
||||||
ata_enumerate();
|
ata_enumerate();
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
add_proc_info_drives(0);
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1739,6 +1932,7 @@ int sg_is_enumerable_adr(char *adr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (first == 0)
|
||||||
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
|
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user