New API call burn_lookup_device_link()

This commit is contained in:
Thomas Schmitt 2011-07-28 19:13:39 +00:00
parent 64f7f5d609
commit b47a0e6884
4 changed files with 121 additions and 1 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.07.15.081325"
#define Cdrskin_timestamP "2011.07.28.191202"

View File

@ -15,6 +15,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
/* ts A61007 */
/* #include <a ssert.h> */
@ -2045,6 +2046,7 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
return 0;
}
/* API */
/** Try to convert a given existing filesystem address into a persistent drive
address. */
int burn_drive_convert_fs_adr(char *path, char adr[])
@ -2056,6 +2058,88 @@ int burn_drive_convert_fs_adr(char *path, char adr[])
}
/* API */
int burn_lookup_device_link(char *dev_adr, char link_adr[],
char *dir_adr, char **ranks, int rank_count, int flag)
{
DIR *dirpt= NULL;
struct dirent *entry;
struct stat link_stbuf;
char *adr= NULL, *namept, *sys_adr= NULL;
int ret, name_rank, found_rank= 0x7fffffff, dirlen, i, rec_count = 0;
static char default_ranks_data[][8] =
{"dvdrw", "cdrw", "dvd", "cdrom", "cd"};
char *default_ranks[5];
link_adr[0] = 0;
if (ranks == NULL) {
for (i = 0; i < 5; i++)
default_ranks[i] = default_ranks_data[i];
ranks = default_ranks;
rank_count= 5;
}
dirlen= strlen(dir_adr) + 1;
if (strlen(dir_adr) + 1 >= BURN_DRIVE_ADR_LEN) {
/* >>> Issue warning about oversized directory address */;
{ret = 0; goto ex;}
}
BURN_ALLOC_MEM(adr, char, BURN_DRIVE_ADR_LEN);
BURN_ALLOC_MEM(sys_adr, char, BURN_DRIVE_ADR_LEN);
dirpt = opendir(dir_adr);
if (dirpt == NULL)
{ret = 0; goto ex;}
strcpy(adr, dir_adr);
strcat(adr, "/");
namept = adr + strlen(dir_adr) + 1;
while(1) {
entry = readdir(dirpt);
if(entry == NULL)
break;
if (strlen(entry->d_name) + dirlen >= BURN_DRIVE_ADR_LEN)
continue;
strcpy(namept, entry->d_name);
if(lstat(adr, &link_stbuf) == -1)
continue;
if((link_stbuf.st_mode & S_IFMT) != S_IFLNK)
continue;
/* Determine rank and omit uninteresting ones */
for(name_rank= 0; name_rank < rank_count; name_rank++)
if(strncmp(namept, ranks[name_rank],
strlen(ranks[name_rank])) == 0)
break;
/* we look for lowest rank */
if(name_rank >= rank_count ||
name_rank > found_rank ||
(name_rank == found_rank &&
strcmp(namept, link_adr + dirlen) >= 0))
continue;
/* Does name point to the same device as dev_adr ? */
ret= burn_drive_resolve_link(adr, sys_adr, &rec_count, 2);
if(ret < 0)
goto ex;
if(ret == 0)
continue;
if(strcmp(dev_adr, sys_adr) == 0) {
strcpy(link_adr, adr);
found_rank= name_rank;
}
}
ret= 2;
if(found_rank < 0x7fffffff)
ret= 1;
ex:;
if(dirpt != NULL)
closedir(dirpt);
BURN_FREE_MEM(adr);
BURN_FREE_MEM(sys_adr);
return(ret);
}
/** A pacifier function suitable for burn_abort.
@param handle If not NULL, a pointer to a text suitable for printf("%s")
*/

View File

@ -1059,6 +1059,39 @@ int burn_drive_convert_fs_adr(char *path, char adr[]);
int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
int target_no, int lun_no, char adr[]);
/* ts B10728 */
/** Try to convert a given persistent drive address into the address of a
symbolic link that points to this drive address.
Modern GNU/Linux systems may shuffle drive addresses from boot to boot.
The udev daemon is supposed to create links which always point to the
same drive, regardless of its system address.
This call tries to find such links.
@param dev_adr Should contain a drive address as returned by
burn_drive_scan().
@param link_adr An application provided array of at least
BURN_DRIVE_ADR_LEN characters size. The found link
address gets copied to it.
@param dir_adr The address of the directory where to look for links.
Normally: "/dev"
@param templ An array of pointers to name templates, which
links have to match. A symbolic link in dir_adr matches
a name template if it begins by that text. E.g.
link address "/dev/dvdrw1" matches template "dvdrw".
If templ is NULL, then the default array gets used:
{"dvdrw", "cdrw", "dvd", "cdrom", "cd"}
If several links would match, then a link will win,
which matches the template with the lowest array index.
Among these candidates, the one with the lowest strcmp()
rank will be chosen as link_adr.
@param num_templ Number of array elements in templ.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return <0 severe error, 0 failed to search, 2 nothing found
1 success, link_adr is valid
@since 1.1.2
*/
int burn_lookup_device_link(char *dev_adr, char link_adr[],
char *dir_adr, char **templ, int num_templ, int flag);
/* ts A60923 - A61005 */
/** Try to obtain bus,host,channel,target,lun from path. If there is an SCSI
address at all, then this call should succeed with a persistent
@ -3064,6 +3097,8 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
3= stdio-drive, sequential, write-only
4= stdio-drive, random access, read-only
(only if enabled by burn_allow_drive_role_4())
5= stdio-drive, random access, write-only
(only if enabled by burn_allow_drive_role_4())
@since 0.4.0
*/
int burn_drive_get_drive_role(struct burn_drive *d);

View File

@ -81,6 +81,7 @@ burn_guess_manufacturer;
burn_initialize;
burn_is_aborting;
burn_lba_to_msf;
burn_lookup_device_link;
burn_msf_to_lba;
burn_msf_to_sectors;
burn_msgs_obtain;