From b47a0e6884f7cc42103fca9d10b9f740e6b42347 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 28 Jul 2011 19:13:39 +0000 Subject: [PATCH] New API call burn_lookup_device_link() --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/drive.c | 84 +++++++++++++++++++++++++++++++++++++ libburn/libburn.h | 35 ++++++++++++++++ libburn/libburn.ver | 1 + 4 files changed, 121 insertions(+), 1 deletion(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index ec517b5..2d57d24 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2011.07.15.081325" +#define Cdrskin_timestamP "2011.07.28.191202" diff --git a/libburn/drive.c b/libburn/drive.c index ccf08a3..4373148 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -15,6 +15,7 @@ #include #include #include +#include /* ts A61007 */ /* #include */ @@ -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") */ diff --git a/libburn/libburn.h b/libburn/libburn.h index 446f136..3425040 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -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); diff --git a/libburn/libburn.ver b/libburn/libburn.ver index 4aa4e4b..ed12547 100644 --- a/libburn/libburn.ver +++ b/libburn/libburn.ver @@ -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;