diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c index 323cb3b..004a60e 100644 --- a/cdrskin/cdrskin.c +++ b/cdrskin/cdrskin.c @@ -163,11 +163,13 @@ or #ifdef Cdrskin_libburn_0_2_3 #define Cdrskin_libburn_versioN "0.2.3" #define Cdrskin_libburn_from_pykix_svN 1 +#define Cdrskin_libburn_has_is_enumerablE 1 #endif #ifndef Cdrskin_libburn_versioN #define Cdrskin_libburn_versioN "0.2.3" #define Cdrskin_libburn_from_pykix_svN 1 +#define Cdrskin_libburn_has_is_enumerablE 1 #endif #ifdef Cdrskin_libburn_from_pykix_svN @@ -247,7 +249,6 @@ or #include -#include #include #include #include @@ -1153,6 +1154,9 @@ struct CdrpreskiN { /** Wether an option is given which needs a full bus scan */ int no_whitelist; + /** Wether the translated device address shall follow softlinks */ + int no_follow_links; + /** Wether bus scans shall exit!=0 if no drive was found */ int scan_demands_drive; @@ -1206,6 +1210,7 @@ int Cdrpreskin_new(struct CdrpreskiN **preskin, int flag) o->allow_setuid= 0; o->allow_fd_source= 0; o->no_whitelist= 0; + o->no_follow_links= 0; o->scan_demands_drive= 0; o->abort_on_busy_drive= 0; o->drive_exclusive= 1; @@ -1250,6 +1255,37 @@ int Cdrpreskin_destroy(struct CdrpreskiN **preskin, int flag) } +/** Evaluate wether the given address would surely be enumerated by libburn */ +int Cdrpreskin__is_enumerable_adr(char *adr, int flag) +{ + +#ifdef Cdrskin_libburn_has_is_enumerablE + int ret; + + ret= burn_drive_is_enumerable_adr(adr); + return(!!ret); + +#else + int i; + char dev[80]; + + for(i=0;i<32;i++) { + sprintf(dev,"/dev/sg%d",i); + if(strcmp(adr,dev)==0) + return(1); + } + for(i=0;i<26;i++) { + sprintf(dev,"/dev/hd%c",'a'+i); + if(strcmp(adr,dev)==0) + return(1); + } + return(0); + +#endif + +} + + /** Convert a cdrecord-style device address into a libburn device address or into a libburn drive number. It depends on the "scsibus" number of the cdrecord-style address which kind of libburn address emerges: @@ -1352,8 +1388,10 @@ return: 2 end program run (--help) */ { - int i,ret,bragg_with_audio= 0; - char *value_pt; + int i,k,ret,bragg_with_audio= 0; + char *value_pt,link_adr[Cdrskin_strleN+1]; + char link_target[Cdrskin_strleN+1]; + struct stat stbuf; #ifndef Cdrskin_extra_leaN if(argc>1) @@ -1564,6 +1602,7 @@ set_dev:; " --ignore_signals try to ignore any signals rather than to abort\n"); printf(" --no_abort_handler exit even if the drive is in busy state\n"); printf(" --no_blank_appendable refuse to blank appendable CD-RW\n"); + printf(" --no_follow_links with dev= do not resolve symbolic links\n"); printf( " --no_rc as first argument: do not read startup files\n"); printf( @@ -1670,6 +1709,9 @@ see_cdrskin_eng_html:; } else if(strcmp(argv[i],"--no_abort_handler")==0) { o->abort_handler= 0; + } else if(strcmp(argv[i],"--no_follow_links")==0) { + o->no_follow_links= 0; + } else if(strcmp(argv[i],"--no_rc")==0) { if(i!=1) fprintf(stderr, @@ -1748,6 +1790,33 @@ dev_too_long:; {ret= 0; goto ex;} } } + if(!o->no_follow_links) { + strcpy(link_adr,o->device_adr); + while(lstat(link_adr,&stbuf)!=-1) { + if(Cdrpreskin__is_enumerable_adr(link_adr,0)) + break; + if((stbuf.st_mode&S_IFMT)!=S_IFLNK) + break; + ret= readlink(link_adr,link_target,Cdrskin_strleN+1); + if(ret>=Cdrskin_strleN) { +link_too_long:; + fprintf(stderr, + "cdrskin: FATAL : Link target address too long (max. %d chars)\n", + Cdrskin_strleN-1); + {ret= 0; goto ex;} + } + for(k=0;kdevice_adr)!=0) { + fprintf(stderr,"cdrskin: NOTE : Followed link '%s' to target '%s'\n", + o->device_adr,link_adr); + if(strlen(link_adr)>=sizeof(o->device_adr)) + goto link_too_long; + strcpy(o->device_adr,link_adr); + } + } } ex:; @@ -3615,6 +3684,12 @@ int Cdrskin_eject(struct CdrskiN *skin, int flag) if(!skin->do_eject) return(1); + +/* not active yet : + if(skin->n_drives<=skin->driveno) + return(2); +*/ + for(i= 0;i0 || i>=max_try-1) @@ -4031,6 +4106,9 @@ gracetime_equals:; } else if(strcmp(argv[i],"--no_blank_appendable")==0) { skin->no_blank_appendable= 1; + } else if(strcmp(argv[i],"--no_follow_links")==0) { + /* is handled in Cdrpreskin_setup() */; + } else if(strcmp(argv[i],"--no_rc")==0) { /* is handled in Cdrpreskin_setup() */; @@ -4226,9 +4304,14 @@ ignore_unknown:; printf("cdrskin: will install abort handler in eventual burn loop.\n"); } - if(strlen(skin->preskin->raw_device_adr)>0) { - ret= Cdrskin_dev_to_driveno(skin,skin->preskin->raw_device_adr, - &(skin->driveno),0); + if(strlen(skin->preskin->raw_device_adr)>0 || + strlen(skin->preskin->device_adr)>0) { + if(strlen(skin->preskin->device_adr)>0) + ret= Cdrskin_dev_to_driveno(skin,skin->preskin->device_adr, + &(skin->driveno),0); + else + ret= Cdrskin_dev_to_driveno(skin,skin->preskin->raw_device_adr, + &(skin->driveno),0); if(ret<=0) return(ret); if(skin->verbosity>=Cdrskin_verbose_cmD) { diff --git a/libburn/drive.c b/libburn/drive.c index 9acc0b6..01332d3 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -663,3 +663,10 @@ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]) return 1; } +/* ts A60922 ticket 33 */ +/** Evaluate wether the given address would be enumerated by libburn */ +int burn_drive_is_enumerable_adr(char *adr) +{ + return sg_is_enumerable_adr(adr); +} + diff --git a/libburn/libburn.h b/libburn/libburn.h index aa64455..52182a3 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -579,6 +579,11 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[]); */ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]); +/* ts A60922 ticket 33 */ +/** Evaluate wether the given address would be enumerated by libburn + @return 1 means yes, 0 means no */ +int burn_drive_is_enumerable_adr(char *adr); + /** Grab a drive. This must be done before the drive can be used (for reading, writing, etc). diff --git a/libburn/sg.c b/libburn/sg.c index 7cfd6e8..d4e352c 100644 --- a/libburn/sg.c +++ b/libburn/sg.c @@ -56,6 +56,28 @@ static int sgio_test(int fd) return ioctl(fd, SG_IO, &s); } + +/* ts A60922 ticket 33 */ +int sg_is_enumerable_adr(char *adr) +{ + char fname[10]; + int i; + + for (i = 0; i < 26; i++) { + sprintf(fname, "/dev/hd%c", 'a' + i); + if (strcmp(adr, fname) == 0) + return 1; + } + for (i = 0; i < 32; i++) { + sprintf(fname, "/dev/sg%d", i); + if (strcmp(adr, fname) == 0) + return 1; + + } + return 0; +} + + void ata_enumerate(void) { struct hd_driveid tm; diff --git a/libburn/sg.h b/libburn/sg.h index 8f431c5..03666a9 100644 --- a/libburn/sg.h +++ b/libburn/sg.h @@ -9,6 +9,9 @@ struct command; enum response { RETRY, FAIL }; +/* ts A60922 ticket 33 */ +int sg_is_enumerable_adr(char *adr); + void sg_enumerate(void); void ata_enumerate(void); int sg_grab(struct burn_drive *);